<?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:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Gridshore &#187; Architecture</title>
	<atom:link href="http://www.gridshore.nl/category/architecture/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.gridshore.nl</link>
	<description>A weblog about software engineering, Architecture, Technology an other things we like.</description>
	<lastBuildDate>Tue, 13 Dec 2011 15:36:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Learning Mongodb</title>
		<link>http://www.gridshore.nl/2010/09/20/learning-mongodb/</link>
		<comments>http://www.gridshore.nl/2010/09/20/learning-mongodb/#comments</comments>
		<pubDate>Mon, 20 Sep 2010 20:13:27 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[overview]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=1081</guid>
		<description><![CDATA[<p></p> <p>One of the technical fashionable terms is NoSQL. That is not really the reason why I wanted to have a look at it, but still it is a good reason to at least have an understanding of what it is. The best way to do this is to try it out. Together with [...]]]></description>
			<content:encoded><![CDATA[<p><img style="float: left;" src="http://www.gridshore.nl/wp-content/uploads/logo-mongodb.png" border="0" alt="logo-mongodb.png" width="217" height="90" /></p>
<p>One of the technical fashionable terms is NoSQL. That is not really the reason why I wanted to have a look at it, but still it is a good reason to at least have an understanding of what it is. The best way to do this is to try it out. Together with Allard I am creating a new sample for the <a href="http://www.axonframework.org">Axon framework</a>. This sample must support a lot of inserts and fast queries. This can be done using an sql database, but using a NoSQL database felt good as well. Therefore I started replacing the jpa implementation with a <a href="http://www.mongodb.org">Mongodb</a> implementation. This blog post is about the things I have learning while implementing Mongo. Be warned, I am not an expert, so if you spot improvement, please let me know.</p>
<p><span id="more-1081"></span><br />
<h2>Introduction</h2>
<p>First a warning, I am not going to explain a lot about the basics of Mongo. Still I&#8217;ll write down why I was curious enough to try it out and I give some pointers to where you can find more information.</p>
<p>So why MongoDB. They claim to have the ideal combination of storing documents in a flexible manner and still be able to search them in ways you would do with a relational database. Storing documents instead of rows in tables feels more natural. I have been using Hippo now for a few years. They use JackRabbit for a datastore. They store everything in trees. Performance and scalability are not very easy to accomplish. Therefore I am very curious what storing documents in MongoDB will bring. The way MongoDB deals with searches is interesting. You can create queries that use nested properties of a document to query on. I&#8217;ll have some samples, especially for things like sorting and paging through your results.</p>
<p>As you should know from this blog, I am a java programmer. Therefore I need to connect to Mongo through a java API. Mongo supports a lot of different Drivers to connect to it. Of course a java driver is available as well. I&#8217;ll show you some things that were harder to find in the normal api documentation.</p>
<p>You probably know Mongo does not have real transactions. Well that is the whole intention. MongoDB does support other mechanisms to make sure data is consistent, however, by default it is more optimized for speed. I&#8217;ll go over some things like &#8220;Write Concern&#8221;, &#8220;Batch inserts&#8221;.</p>
<p>As a jpa/hibernate user you are probably familiar with object relation mappings (ORM). Well we do not need an ORM tool, but still we need to transform query results into objects and objects into documents. Ok you might not need to immediately, but believe me there will be a moment that you need to. Therefore I&#8217;ll have a go at them as well.</p>
<p>Scalability is another beast that MongoDB should support pretty well. Therefore I started experimenting with the technology using a few virtual machines. In the last part of this blog I&#8217;ll discuss some of my findings.</p>
<h2>Basic stuff</h2>
<h3>Installation</h3>
<p>There are a number of ways to install MongoDB. For most common operating systems packages are available. Later on when I have created a few VMWare images I&#8217;ll use this installation guide:</p>
<p>﻿<a href="http://www.mongodb.org/display/DOCS/Ubuntu+and+Debian+packages">http://www.mongodb.org/display/DOCS/Ubuntu+and+Debian+packages</a></p>
<p>Most of the time I work with the binary download and start it up myself. Later on, this is also the most easy way to experiment with Replica sets. Just download the right package from the following location for your OS. Unpack and run the mongod script in the bin folder.</p>
<p>﻿<a href="http://www.mongodb.org/downloads">http://www.mongodb.org/downloads</a></p>
<h3>First steps</h3>
<p>Start up the mongodb instance and the client. When connected, execute the command <em>show dbs</em>, in my case this results in the following output:</p>
<pre>
﻿admin
axonframework
axontrader
local
</pre>
<p>I am using a sample application created with the axon framework. The sample is the axon trader. All the axonframework related items are stored in the axonframework database. This database contains the following collections, obtained with the command: <em>show collections</em>. Before you can do that, you need to choose the right database to start working with. In my case I start with the axonframework database: <em>use axonframework</em>.</p>
<pre>﻿
&gt; show collections
domainevents
system.indexes
</pre>
<p>Of course I am not going to explain all commands here, the last one I want to mention explicitly is the help command, really useful: <em>help</em>.</p>
<h3>Storing and searching</h3>
<p>Mongo is used to store documents. Documents are stored in collections. Storing is done using insert() or save(). The structure of the document is not really important. The following commands create a new database, collection and insert a document, query for all blog documents and drops the complete table again:</p>
<pre>﻿
use gridshore
db.blogs.insert({title:"my first blog", main:"And this is the content of my blog"})
db.blogs.find()
db.blogs.drop()
</pre>
<p>Now let us assume we have a lot of blogs and we want to search for all blogs with a tag &#8220;Mongo&#8221;. Creating such a document and searching for that document including the result is presented in the following lines.</p>
<pre>
&gt; db.blogs.insert({title:"my first blog", main:"And this is the content of my blog",tags:["Java", "Mongo"]})
&gt; db.blogs.find({tags:"Mongo"})
{ "_id" : ObjectId("4c95fa6830d8854d0fdece13"), "title" : "my first blog", "main" : "And this is the content of my blog", "tags" : [ "Java", "Mongo" ] }
</pre>
<p>Let us move on. Since I am mainly a java programmer, I need a java api. The next section is about the Java Driver</p>
<h2>Java driver</h2>
<p>From the mongodb website you can download the java driver, it is also available in the maven repository. After that it all starts with the class <em>com.mongodb.Mongo.</em> This class contains a number of constructors like the default constructor, a constructor with a host and port for the service to connect to, and a few others. One of them is used later on when I start talking about the Replication Sets. Your application should use a single Mongo instance. This instance uses a connection pool internally to provide connections. To obtain a connection, you provide the name of the database. Than you have a <em>DB</em> connection, using this connection you can obtain references to collections. Using the collection you obtain all items using the find method. The following code block shows them all in order.</p>
<pre class="brush: java; title: ; notranslate">
Mongo mongoDb = new Mongo();
DB db = ﻿mongoDb.getDB(&quot;axonframework&quot;);
﻿DBCollection domainevents = db.getCollection(&quot;domainevents&quot;);
﻿DBCursor db = Cursordomainevents.find();
</pre>
<p>That is the most basic query, there are other things you can do. Provide an instance of DBObject to filter the results. The DBObject is also used to sort the results. A special BasicDBObjectBuilder is available to create new DBObjects. The following code block shows them in action.</p>
<pre class="brush: java; title: ; notranslate">
DBObject mongoEntry = BasicDBObjectBuilder.start()
        .add(&quot;aggregateIdentifier&quot;,identifier.toString())
        .add(&quot;type&quot;, type)
        .get();
DBCursor dbCursor = mongo.domainEvents().find(mongoEntry).sort(new BasicDBObject(&quot;sequenceNumber&quot;,-1));
</pre>
<p>That is all about looking for data, of course we also need to insert data. The most basic case is almost to easy to show, still I want to, and just because I am the author of this blog, I can <img src='http://www.gridshore.nl/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> . In the next code sample aDomainEvent is  an instance of DBObject.</p>
<pre class="brush: java; title: ; notranslate">
mongoDb.getDB(&quot;axonframework&quot;).getCollection(&quot;domainevents&quot;).insert(aDomainEvent);
</pre>
<h2>Batch inserts</h2>
<p>In some situations you want to insert multiple documents at once. The java driver has a facility for that as well. You can use the batch insert like shown in the following code block.</p>
<pre class="brush: java; title: ; notranslate">
List&lt;DBObject&gt; entries = new ArrayList&lt;DBObject&gt;();
while (events.hasNext()) {
    DomainEvent event = events.next();
    DomainEventEntry entry = new DomainEventEntry(type, event, eventSerializer);
    DBObject mongoEntry = BasicDBObjectBuilder.start()
            .add(&quot;aggregateIdentifier&quot;, entry.getAggregateIdentifier().toString())
            .add(&quot;sequenceNumber&quot;, entry.getSequenceNumber())
            .add(&quot;timeStamp&quot;, entry.getTimeStamp().toString())
            .add(&quot;type&quot;, entry.getType())
            .add(&quot;serializedEvent&quot;, entry.getSerializedEvent())
            .get();
    entries.add(mongoEntry);
}
mongo.domainEvents().insert(entries.toArray(new DBObject[entries.size()]),WriteConcern.SAFE);
</pre>
<p>If you look closely at the last line, you see we pass an array of DBObject instances to the insert method. Did you see the last parameter? You can also pass a write concern, what that is? Check the next section.</p>
<h2>Write concern</h2>
<p>By default Mongo sends data to the store and if it is received it is ok. Sometimes you want more than that. It might be very important that content is stored in one node or maybe even in multiple nodes. By providing  a WriteConcern you can specify how much safeness you want. NORMAL is the default, just pass it and leave it like that. SAFE only waits for the master by using the getLastError. REPLICAS_SAFE does the same but also waits for the slaves. Be careful when using REPLICAS_SAFE in a test environment without slaves, it will wait and wait.</p>
<h2>Object mapping</h2>
<p>If you are using object that contain a not to complicated structure, it is not to hard to create a custom mapper for the object to document and document to object. If you do this regularly  and the work becomes repetitive you might want to have something easier. You could implement the DBObject interface yourself, that way mongo will create an instance of that object from the document in the datastore. With some basic implementations this might be an interesting way to create your mapping. Personally I do not think this is the way to go, it is to intrusive. Other mapping frameworks are available as well. Personally I think <a href="http://code.google.com/p/morphia/">Morphia</a> has the best papers for now. But it only support annotations, which is harder to use when you have library code. With the axon sample I wanted to checkout this approach. But it turns out to be a topic in itself. Therefore I decided no to do it right now. Documentation for the framework is being rewritten at the moment. Therefore I&#8217;ll come back to it in another post in the future.</p>
<h2>Replication</h2>
<p>Mongo supports two mechanisms for replication, Master-Slave and Replica Sets. With respect to scalability another thing called <em>sharding</em> is also very interesting. Sharding is about separating content over multiple Sets. So if you have a very large data set that can be separated like in online shops put the user information in one shard and the product data in another. That is all I am going to say about sharding for now. I&#8217;ll focus on replication for now. The documentation can be found at the following link. I strongly advise looking at the video mentioned on the page.</p>
<p><a href="http://www.mongodb.org/display/DOCS/Replication">﻿http://www.mongodb.org/display/DOCS/Replication</a></p>
<h3>Master-Slave</h3>
<p>The Master slave configuration is well known from other data sources. With Mongo the Master-slave configuration has been proved in production. Configuration is not hard and well documented. A few things I want to mention are:</p>
<ul>
<li>slavedelay, you can intentionally put a delay between a master and a slave. This is nice to use as a runtime backup. If you by accident to something stupid, you have an easy way to get things back.</li>
<li>db.printReplicationInfo(), returns information about the replication from the master perspective</li>
<li>db.printSlaveReplicationInfo(), returns information about the replication from the slave perspective</li>
</ul>
<p>Another thing that I definitely want to mention is the oplog. This is a log that is used by the slaves to stay up-to-date. I like the idea that the log is actually stored in the database itself. Be sure to make it big enough or else a longer downtime of your slave will be a big problem.</p>
<p>The biggest thing with Master-slave is that a security mechanism exists. You can configure security constraints based on collections of data. This is not (yet) available for Replica Sets. Other than that, Replica Sets are the way to go for Mongo 1.6 +.</p>
<h3>Replica Sets</h3>
<p>Some references are: <a href="http://www.slideshare.net/mongodb/mongodb-replica-sets">﻿http://www.slideshare.net/mongodb/mongodb-replica-sets</a>, <a href="http://www.slideshare.net/mongodb/mongodb-replica-sets">﻿http://www.mongodb.org/display/DOCS/Replica+Set+Tutorial</a></p>
<p>First start up three nodes for the Replica Set. The following commands start up three nodes</p>
<pre>
mongod --replSet axon --port 27017 --dbpath /data/r0 --rest
mongod --replSet axon --port 27018 --dbpath /data/r1 --rest
mongod --replSet axon --port 27019 --dbpath /data/r2 --rest
</pre>
<p>Nodes do not enter the replica set on their own. You have to explicitly add them to the set. You also have to initialize a replica set the first time you use it. The following lines show you just how to do this</p>
<pre>
&gt; cfg={_id:"axon",members : [{_id:0,host:"localhost:27017"},{_id:1,host:"localhost:27018"},{_id:2,host:"localhost:27019"}]}
&gt; rs.initiate(cfg);
{
	"info" : "Config now saved locally.  Should come online in about a minute.",
	"ok" : 1
}
</pre>
<p>Be sure to check out what happens when you add a node to the set. The following lines show the log of one of the slaves when the master goes down. After that the node that was the master is restarted</p>
<pre>
Sun Sep 19 13:14:46 [rs_sync] replSet syncThread: 10278 dbclient error communicating with server
Sun Sep 19 13:14:46 [conn4] end connection 127.0.0.1:59341
Sun Sep 19 13:14:47 [ReplSetHealthPollTask] replSet info localhost:27019 is now down (or slow to respond)
Sun Sep 19 13:14:47 [rs Manager] replSet info electSelf 0
Sun Sep 19 13:14:47 [rs Manager] replSet PRIMARY
Sun Sep 19 13:14:57 [initandlisten] connection accepted from 127.0.0.1:59478 #6
Sun Sep 19 13:16:03 [initandlisten] connection accepted from 127.0.0.1:59565 #7
Sun Sep 19 13:16:03 [ReplSetHealthPollTask] replSet info localhost:27019 is now up
Sun Sep 19 13:16:05 [initandlisten] connection accepted from 127.0.0.1:59567 #8
</pre>
<p>From the client you want to connect to the master, to find out which node in the set is the master, you can connect to one of the nodes and run the command <em>db.isMaster()</em>, the result is a document containing enough about the replica set to check for the node to connect to.</p>
<pre>
﻿&gt; db.isMaster()
{
	"setName" : "axon",
	"ismaster" : false,
	"secondary" : true,
	"hosts" : [
		"localhost:27019",
		"localhost:27018",
		"localhost:27017"
	],
	"primary" : "localhost:27018",
	"ok" : 1
}
</pre>
<p>As you can see my set contains 3 nodes and the primary node is on port 27018. You should always connect to the master node using the shell, or else you get messages like this:</p>
<pre>﻿Sun Sep 19 12:25:40 uncaught exception: error: { "$err" : "not master", "code" : 10107 }</pre>
<p>In my case I had to start the shell using <em>mongo localhost:27018</em>. With java things are less complicated, the driver selects the primary node by itself. The following xml block shows some example configuration for the Mongo instance using the spring configuration.</p>
<pre class="brush: xml; title: ; notranslate">
    &lt;bean id=&quot;mongoDb&quot; class=&quot;com.mongodb.Mongo&quot;&gt;
        &lt;constructor-arg index=&quot;0&quot;&gt;
            &lt;list value-type=&quot;com.mongodb.ServerAddress&quot;&gt;
                &lt;bean class=&quot;com.mongodb.ServerAddress&quot;&gt;
                    &lt;constructor-arg index=&quot;0&quot; value=&quot;localhost&quot;/&gt;
                    &lt;constructor-arg index=&quot;1&quot; value=&quot;27017&quot;/&gt;
                &lt;/bean&gt;
                &lt;bean class=&quot;com.mongodb.ServerAddress&quot;&gt;
                    &lt;constructor-arg index=&quot;0&quot; value=&quot;localhost&quot;/&gt;
                    &lt;constructor-arg index=&quot;1&quot; value=&quot;27018&quot;/&gt;
                &lt;/bean&gt;
                &lt;bean class=&quot;com.mongodb.ServerAddress&quot;&gt;
                    &lt;constructor-arg index=&quot;0&quot; value=&quot;localhost&quot;/&gt;
                    &lt;constructor-arg index=&quot;1&quot; value=&quot;27019&quot;/&gt;
                &lt;/bean&gt;
            &lt;/list&gt;
        &lt;/constructor-arg&gt;
    &lt;/bean&gt;
</pre>
<p>Not to hard is it? Of course this is only very basic usage. There is more to learn in this area, a lot more. One way to learn is to experiment, use the command <em>rs.help()</em> to learn about the commands you have available for the Replication Set. The last thing I want to mention is the web client that you can enable. Pass &#8211;rest to the startup command and you can browse to the following url: ﻿http://localhost:28019/ and for the status of the replication set: ﻿<a href="http://localhost:28019/_replSet">http://localhost:28019/_replSet</a>, This is by default available using the port for the mongodb instance added with 1000. The following screen dump shows the client in action:</p>
<p><img src="http://www.gridshore.nl/wp-content/uploads/Screen-shot-2010-09-19-at-13.06.36.png" border="0" alt="Screen shot 2010-09-19 at 13.06.36.png" width="600" height="292" /></p>
<p>That is enough for now, I&#8217;ll keep on working with Mongo. Stay tuned for more blog posts about Mongo.</p>
<p>If you want to learn more about Mongo I can recommend the book that is currently being written at manning:</p>
<p><a href="http://manning.com/banker/">http://manning.com/banker/</a></p>
<p>Not a lot of chapters available at the time of writing, but I like what I have seen so far.</p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2010%2F09%2F20%2Flearning-mongodb%2F&amp;title=Learning%20Mongodb&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2010/09/20/learning-mongodb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Yes! REST really is not the same as HTTP!!</title>
		<link>http://www.gridshore.nl/2010/08/16/yes-rest-really-is-not-the-same-as-http/</link>
		<comments>http://www.gridshore.nl/2010/08/16/yes-rest-really-is-not-the-same-as-http/#comments</comments>
		<pubDate>Mon, 16 Aug 2010 18:04:38 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Architecture]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=1072</guid>
		<description><![CDATA[<p>By now I&#8217;m sure everybody has at least heard of REpresentational State Transfer (REST). REST is an architectural style that was first properly described by Roy Fielding in his doctoral thesis. Since Fielding published his thesis in 2000 the term REST has become very popular among web developers. Mostly for the wrong reasons of [...]]]></description>
			<content:encoded><![CDATA[<p>By now I&#8217;m sure everybody has at least <em>heard</em> of <a href="http://en.wikipedia.org/wiki/Representational_State_Transfer">REpresentational State Transfer (REST)</a>. REST is an architectural style that was first properly described by <a href="http://roy.gbiv.com/">Roy Fielding</a> in his <a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm">doctoral thesis</a>. Since Fielding published his thesis in 2000 the term REST has become very popular among web developers. Mostly for the wrong reasons of course — REST and the derived term RESTful have morphed into marketing jargon for people who really mean &quot;building a web site&quot; when they say &quot;implementing a RESTful architecture&quot;.</p>
<p>One of the things that has gone wrong in the area of REST-the-popular-interpretation is that people think that &quot;doing REST&quot; is the same thing as &quot;using HTTP&quot; (another thing is that they think that REST is something you can <em>do</em>). The reason of course is simple: most people use the term REST to mean building a web site. And you use HTTP for that. And in fact I thought it was not a wholly unreasonable position because one of the constraints of the REST architectural style is such that you really would not want to use anything but HTTP as a rule. </p>
<p>However, today, all of a sudden, I stumbled on ultimate proof that REST really is as independent from HTTP as Fielding claims: a piece of software that uses the REST architectural style but not HTTP.</p>
<p><span id="more-1072"></span><br />
<h3>REST: the short, <em>short</em> version&#8230;</h3>
<p>Before we get to this marvelous, mythical piece of software let&#8217;s have a short recap of what REST entails. Real REST that is, not the bullshit about URI mappings, JSON and all the other nonsense that REST-the-marketing-buzzword has come to mean.</p>
<p>REST is not a codeword for building a web site. REST is also not something that you <em>do</em>. REST is an <em>architectural style</em>, which means that it is a general idea about what your application architecture should look like with some architectural choices already made for you. In particular the REST style is a general description of application architectures that make the following choices:</p>
<ul>
<li><strong><u>client-server:</u></strong> The entire application uses a client-server architecture. This principally covers the interaction between the end user and the core application, but if the application consists of multiple components they use client-server communication as well.</li>
<li><strong><u>stateless:</u></strong> All inter-component communication (including the end-user client to the application service layer) uses stateless communication. This does not mean that a component cannot have state at all (like a database), but it does mean there is no concept like a running session or a session context. It also means that all external information needed to complete a request must be in the request.</li>
<li><strong><u>cache-able:</u></strong> At the discretion of a component in the system, a response to a request may be marked as cache-able. This means that the requesting component <em>may</em> cache the answer for later reuse.</li>
<li><strong><u>uniform interface:</u></strong> All components in the system use the same interface, no matter what their specific functionality. This interface therefore also becomes the communication protocol of the entire system, which simplifies building communication clients. System functionality is achieved by adding a distinct, addressable resource that offers the functionality and that is controlled using the shared communication protocol.</li>
<li><strong><u>layered:</u></strong> This constraint means that you cannot see through a component that you send a request to. As long as the client doesn&#8217;t control the processing of the server, the system remains scalable.</li>
<li><strong><u>code-on-demand:</u></strong> As an optional extra a server might send code to the client for local execution.</li>
</ul>
<p>The architectural constraints above, in the sense of a preselected set of choices, are what makes REST. Anybody see any mention of JSON? No, neither do I&#8230;</p>
<h3>So where does HTTP come in?</h3>
<p>If you look at the architectural constraints again, you&#8217;ll see something else that isn&#8217;t mentioned (other than JSON): HTTP. REST does not imply HTTP. So why does everybody think it does? Just because Roy Fielding helped define HTTP? Because marketing guys want to sell web site work? No, it&#8217;s because of the uniform interface constraint. That constraint specifies that each component in the system is communicated with <em>and controlled</em> using a single protocol. Which means a single command set. In other words, no matter what the functionality of the component, it always answers to the same command set with the same possible parameters.</p>
<p>The uniform interface constraint is a very horrible idea. It is a complete contradiction of the principles of <a href="http://domaindrivendesign.org/">domain-driven design</a>: having a uniform interface for all your components which is also your communication protocol means that you must encode domain concepts and operations in terms of the uniform interface instead of making them explicit in a domain language. It means your attention is diverted away from the application domain and domain model and even at the level of the most basic lesson we all learned in programming (&quot;use explicit names for your identifiers&quot;) the uniform interface is a bad idea. Nobody in his right mind would ever use a uniform interface in a multi-component application they were designing.</p>
<p>In point of fact, there is only one situation in which you would want to employ a uniform interface in your application: in order to allow your application to become part of a larger, generally accessible system where participation brings you more users. Think plug-in architectures like the Eclipse platform&#8230; Or the World Wide Web, which runs on HTTP. So that&#8217;s why REST has become inextricably linked with HTTP: HTTP is the protocol for a network that is an ideal use case for the REST architectural style&#8230; and it&#8217;s practically the only example of a popular network that you would want to join in order to reach a large audience.</p>
<h3>And yet&#8230;</h3>
<p>So it looks (for good reason) like REST and HTTP are congruent. Everybody who &quot;does REST&quot; uses HTTP and the HTTP-based WWW is practically the only interesting vehicle for real REST-style applications. And yet, and yet, today, in the wild, out of the blue, I came across a perfect example of that mythical beast: a REST-style application that doesn&#8217;t use HTTP as a uniform interface. So what was this application? The <a href="http://www.ezmlm.org/">EZMLM</a> mailing list manager.</p>
<p>EZMLM is, as said, a mailing list manager. That is, it manages a list of email addresses which are subscribed to a list (i.e. get a mail forwarded that is sent to a certain email address). In order to perform this management the EZMLM offers a number of command resources, each of which is triggered by the delivery of a message to that resource. Each command resource is individually addressable (using an email address as a universal resource identifier). My claim is that this program uses the REST architectural style. In order to prove this I must show that the architecture of EZMLM meets the constraints as explained above:</p>
<ul>
<li><strong><u>client-server:</u></strong> EZMLM uses two components: a mail client (officially an SMTP user agent) and the EZMLM mail server. Like any SMTP-based email setup, this is a client-server application by definition.</li>
<li><strong><u>stateless:</u></strong> EZMLM has no concept of a session at all. Each request is somehow a mailing list management command which is atomic and no session is needed at all. The situation is somewhat deceptive because you might think that the mailing list itself is session state. However, this is not the case: EZMLM manages this list, that is true, but the list does not tie individual requests together into a session. Also, the list is not needed to make any request function correctly; all the information needed is in the mail message (usually that information consists of the contents of the FROM: header). This is true even for a command to the unsubscribe resource: the command still functions if the FROM: address is not on the list, it just cannot mutate the list (an error case is still correct processing).<br />Of course the mailing list does serve as server state, especially in case of a forward command (i.e. sending a mail to the list which is distributed to all list subscribers). However, the statelessness requirement doesn&#8217;t forbid server state. The important thing to realize is that the purpose of EZMLM is to manage the mailing list and that the mailing list does not function as session state information.</li>
<li><strong><u>cache-able:</u></strong> This requirement entails that the system might decide that some server responses may be cached. The client may then use its cache instead of talking to the server. This could be done using EZMLM, especially with the EZMLM response to the &quot;help&quot; command (the response is a list of command email addresses recognized by the EZMLM server). In practice EZMLM won&#8217;t do this, but the requirement is not that the system MUST have responses which it considers cacheable. Also, most user agents wouldn&#8217;t be able to handle caching of mails. But again, this is not a requirement.</li>
<li><strong><u>uniform interface:</u></strong> All one server components in the system use the SMTP protocol as uniform interface.</li>
<li><strong><u>layered:</u></strong> There is only one component in the system, so this requirement is trivially met. Still, if there were more components it is hard to see how their details would not be hidden behind the SMTP interface.</li>
<li><strong><u>code-on-demand:</u></strong> EZMLM does not use this optional constraint.</li>
</ul>
<p>Again, the essential point here is to understand that there is a difference between <em>managing</em> a mailing list as function of the application and using that list as session state. Another point is the definition of a component. EZMLM uses other software (particularly qmail and its shell hooks) to deliver its functionality. However, EZMLM is buildable and deployable as a single package with all functionality and must be administered and maintained as a single package. Perhaps somewhat tentatively I will consider this enough to consider EZMLM a single component.</p>
<h3>Conclusion</h3>
<p>Simply put: miracle of miracles, there really is software that uses a REST style architecture but doesn&#8217;t use HTTP. So yes, against all expectation it is true and REST really is independent of HTTP!</p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2010%2F08%2F16%2Fyes-rest-really-is-not-the-same-as-http%2F&amp;title=Yes%21%20REST%20really%20is%20not%20the%20same%20as%20HTTP%21%21&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2010/08/16/yes-rest-really-is-not-the-same-as-http/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Axon Framework 0.6 released</title>
		<link>http://www.gridshore.nl/2010/08/08/axon-framework-0-6-released/</link>
		<comments>http://www.gridshore.nl/2010/08/08/axon-framework-0-6-released/#comments</comments>
		<pubDate>Sun, 08 Aug 2010 17:53:45 +0000</pubDate>
		<dc:creator>Allard</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Axon Framework]]></category>
		<category><![CDATA[DDD]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[cqrs]]></category>
		<category><![CDATA[Domain Driven Design]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/2010/08/08/axon-framework-0-6-released/</guid>
		<description><![CDATA[<p>Today, I released version 0.6 of the Axon Framework. 0.6 has many new features and is another step towards full production readiness. There is still some work to do, but first, let’s take a look at what has changed…</p> <p></p> <p>Test fixtures are now part of the axon-test module. These fixtures allow you to [...]]]></description>
			<content:encoded><![CDATA[<p>Today, I released version 0.6 of the Axon Framework. 0.6 has many new features and is another step towards full production readiness. There is still some work to do, but first, let’s take a look at what has changed…</p>
<p><span id="more-1070"></span></p>
<p>Test fixtures are now part of the axon-test module. These fixtures allow you to test your command handling logic based on events and commands. You define these tests in a given-when-then style: given these past events, when I execute this command, I expect these events to occur.</p>
<p>The <tt>CommandBus</tt> interface now allows for asynchronous command dispatching. Instead of using a return value, a Callback can be given to the command bus if you wish to be notified of the result of command execution.</p>
<p>The repositories make use of a <tt>UnitOfWork</tt> instance, which keeps track of changed aggregates and generated events. Instead of saving each aggregate separately, the <tt>UnitOfWork</tt> can be committed, causing changed aggregates to be stored, and events to be dispatched. With the new <tt>SimpleUnitOfWorkInterceptor</tt> or the <tt>SpringTransactionalInterceptor</tt>, it is no longer necessary to call <tt>repository.save()</tt>. In fact, you are discouraged from doing so.</p>
<p>Repositories are now capable of detecting conflicting modifications. When loading an aggregate, you may pass in the expected version of the aggregate. An exception is raised if that version does not match the actual version.</p>
<p>Event sourcing repositories allow for a more advanced way of detecting conflicts. Sometimes, not all concurrent modification are in conflict with each other. One user may very well change the shipping address of an order, while another user is adding items. Other modifications, however, are clearly conflicting, such as one user marking an order as shipped, and another one adding a product. For this purpose, you can register a <tt>ConflictResolver</tt> with the repository. This conflict resolver can, based on unseen and newly applied events, decide whether the changes made by the second user are accepted.</p>
<p>Axon now provides a mechanism to trigger snapshot creation based on the number of events needed to load to reconstitute an aggregate. When the number of events exceeds a given threshold, a snapshot is created and stored in the Event Store.</p>
<p>The <tt>SimpleCommandBus</tt> and <tt>SimpleEventBus</tt> now expose statistics over JMX. Although currently quite limited, the statistics will be improved in the coming versions.</p>
<p>All of these features help making applications with CQRS-based architectures even easier. But we’re not there yet. The coming months, we will try to make it even easier with features like Event versioning, support for aggregates with multiple entities, and whatever comes to mind in Axon’s growing community.</p>
<p>For more information about the Axon Framework, see <a href="http://www.axonframework.org">www.axonframework.org</a>.</p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2010%2F08%2F08%2Faxon-framework-0-6-released%2F&amp;title=Axon%20Framework%200.6%20released&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2010/08/08/axon-framework-0-6-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Axon Framework 0.5 released</title>
		<link>http://www.gridshore.nl/2010/04/24/axon-framework-0-5-released/</link>
		<comments>http://www.gridshore.nl/2010/04/24/axon-framework-0-5-released/#comments</comments>
		<pubDate>Sat, 24 Apr 2010 15:27:59 +0000</pubDate>
		<dc:creator>Allard</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Axon Framework]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[cqrs]]></category>
		<category><![CDATA[DDD]]></category>
		<category><![CDATA[Domain Driven Design]]></category>
		<category><![CDATA[JTeam]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/2010/04/24/axon-framework-0-5-released/</guid>
		<description><![CDATA[<p> Today, I finalized the 0.5 release of the Axon Framework. There is quite a number of changes since the 0.4 version. The 0.5 version is a major step towards production readiness of the framework.</p> <p>Besides some changes to existing building blocks, such as the event bus, which is now much more powerful, the [...]]]></description>
			<content:encoded><![CDATA[<p><img style="margin: 5px; display: inline;" src="http://www.gridshore.nl/wp-content/uploads/axon_logo.png" alt="" align="left" /> Today, I finalized the 0.5 release of the Axon Framework. There is quite a number of changes since the 0.4 version. The 0.5 version is a major step towards production readiness of the framework.</p>
<p>Besides some changes to existing building blocks, such as the event bus, which is now much more powerful, the 0.5 version also includes some new features.</p>
<p>Read on to find out more.</p>
<p><span id="more-1047"></span></p>
<h2><strong>New features</strong></h2>
<ul>
<li><strong>Code restructuring.</strong> The package structure has been changed to better reflect the different architectural components Axon Framework provides. It should be easier to find the one you&#8217;re looking for.</li>
<li><strong>Command Bus.</strong> The command bus is added to Axon. It provides you the ability to explicitly define commands and dispatch them to your command handlers. Furthermore, the command bus provides you the ability to process commands regardless of their type using interceptors. This is useful for, for example, logging, authorization and correlation of incoming commands.</li>
<li><strong>JPA Event Store. </strong>The easiest CQRS configuration is on using full-consistency. That means everything should run within a single transaction. Since transactions over multiple data sources involve a huge performance penalty, Axon provides a JPA Event Store. Its performance is not as good as the FileSystem version, but is does provide transaction support.</li>
<li><strong>Easy switching between full-consistency and eventual consistency.</strong> You can easily choose to process all commands and related events inside a single transaction, or to handle events asynchronously. Choosing for consistency or high-performance is just a matter of configuration. No coding required.</li>
<li><strong>Per-event listener configuration of asynchronous processing.</strong> It is now possible to decide on synchronous vs asynchronous event processing for each event handler individually, just by adding an annotation. If you configure a transaction manager for your event listeners, Axon will process the events in batches and manage the transactions around them.</li>
<li><strong>Support for rolling snapshots.</strong> All event stores will automatically pick up snapshot events. Snapshot events are an important performance booster when aggregates generate a lot of events. Instead of reading all passed events, the event store just needs to read the last snapshot event and the regular events created since the snapshot.</li>
<li><strong>Transactional Event Processing.</strong> Configuring transactions in asynchronous event processing is now a lot easier. 0.5 includes a <tt>SpringTransactionManager</tt> you can use in combination with Spring&#8217;s <tt>PlatformTransactionManager</tt>.</li>
<li><strong>Major documentation update.</strong> The documentation has been restructured to make it easier to find what you&#8217;re looking for.</li>
</ul>
<h2><strong>Maven Central</strong></h2>
<p>Where the 0.4 version required configuration of a repository in your project’s pom.xml, the 0.5 version doesn’t. All required artifacts are available in the maven central repository.</p>
<h2>Workshop and professional support</h2>
<p>We believe that the 0.5 version of Axon Framework is a major step towards production readiness. Therefore, JTeam has decided to provide professional support for the Axon Framework and organize workshops to get you acquainted with the numerous features and choices involved with CQRS.</p>
<p>The first workshop is planned for Friday May 21st in Amsterdam, The Netherlands. For more information, visit <a href="http://www.jteam.nl/training/workshop/cqrs-axon-framework-training-workshop.html">http://www.jteam.nl/training/workshop/cqrs-axon-framework-training-workshop.html</a>.</p>
<h2>Getting started</h2>
<p>Want to get started? Visit <a href="http://www.axonframework.org">www.axonframework.org</a> and download the <a href="http://axonframework.googlecode.com/files/reference-guide-0.5.pdf">reference guide</a>. That should contain enough information to get you started. If you still have questions, drop me a message.</p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2010%2F04%2F24%2Faxon-framework-0-5-released%2F&amp;title=Axon%20Framework%200.5%20released&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2010/04/24/axon-framework-0-5-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Axon Framework &#8211; the CQRS framework for Java &#8211; version 0.4 released</title>
		<link>http://www.gridshore.nl/2010/02/21/axon-framework-the-cqrs-framework-for-java-version-0-4-released/</link>
		<comments>http://www.gridshore.nl/2010/02/21/axon-framework-the-cqrs-framework-for-java-version-0-4-released/#comments</comments>
		<pubDate>Sun, 21 Feb 2010 15:57:56 +0000</pubDate>
		<dc:creator>Allard</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[DDD]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Axon Framework]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/2010/02/21/axon-framework-the-cqrs-framework-for-java-version-0-4-released/</guid>
		<description><![CDATA[<p>Last week, I published the 0.4 release of the Axon Framework. Axon helps developers build high performance, scalable and extensible applications using the CQRS pattern. The 0.4 release is a major step towards 1.0, and includes transactional event handling, high-performance caching repositories and easy configuration of event sourcing support. Furthermore, we have also built [...]]]></description>
			<content:encoded><![CDATA[<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="logo" border="0" alt="logo" align="left" src="http://www.gridshore.nl/wp-content/uploads/logo1.png" width="100" height="100" />Last week, I published the 0.4 release of the Axon Framework. Axon helps developers build high performance, scalable and extensible applications using the CQRS pattern. The 0.4 release is a major step towards 1.0, and includes transactional event handling, high-performance caching repositories and easy configuration of event sourcing support. Furthermore, we have also built a demo application that uses Flex to get real-time updates pushed from the server.</p>
<p>Read on to find out more.</p>
<p> <span id="more-1008"></span><br />
<h2>About the Axon Framework</h2>
<p><a name="Axon_Framework"></a></p>
<p>Axon Framework helps build scalable, extensible and maintainable applications by supporting developers apply the Command Query Responsibility Segregation (CQRS) architectural pattern. It does so by providing implementations, sometimes complete, sometimes abstract, of the most important building blocks, such as aggregates, repositories and event the bus – the dispatching mechanism for events. Furthermore, Axon provides annotation support, which allows you to build aggregates and event listeners without tying your code to Axon specific logic. This allows you to focus on your business logic, instead of the plumbing, and helps you makes your code easier to test in isolation.</p>
<h2>Features available in 0.4</h2>
<p>We have made quite a few additions and changes since the 0.3 release. Unfortunately, this also means I had to make some minor API changes. There is now a bigger choice of abstract classes for most of the building blocks. This allows you to choose whether you want to use the logic provided by Axon, or prefer to develop more of your own. Whatever your wish is, there should be a class to help you on your way.</p>
<p>The biggest change since 0.3 is the addition of an Asynchronous Event Bus that supports transactional processing of events. Since it is asynchronous, it means that your command processing doesn’t have to wait for events to be processed. However, this Event Buss can also guarantee the order in which events are delivered to the event handlers. You can choose full concurrent processing (without any guarantees about ordering), full sequential processing (FiFo guarantee) or anything in between. You could, for example, guarantee the sequential processing of Events that come from the same aggregate.</p>
<p>The Event Bus also provides transaction support. That means you can tell the event bus to retry an event after a certain amount of time when processing fails, for example due to an error in the underlying mechanism, such as a database. For performance reasons, you can configure the event handler to process multiple events within a single transaction. Database updates are a lot faster if you process several events within a single transaction before committing it. Within your event handler, you can configure transactions. </p>
<p>Besides Domain Events, Axon now also allows you to explicitly define two other types of events: Application Events and System Events. Application Event can notify your event listeners that something interesting happened in your application. System Events are a special type of application events and can be used to indicate that a part of your application has changed state, for example when the database is no longer available. These System Events could provide interesting operational information about your application.</p>
<p>Another major change since 0.3 is the documentation. We have brought the documentation up to par with the code-base. All features are now extensively described in the reference guide. You can download the manual from the Axon Framework website: <a href="http://www.axonframework.org" target="_blank">www.axonframework.org</a>.</p>
<p>Last, but definitely not least, we have created a demo application that you can easily download and deploy to have a look at how you can use events to your advantage. This demo application is built using a Flex Client and an Axon-based server side component. The Flex Client registers itself as an event listener and will automatically process incoming events, at real time! That means that you can have 2 windows open, change something in one window, and see the change come in immediately on the other window, too. Check our <a href="http://code.google.com/p/axonframework/wiki/SampleInstallation" target="_blank">Sample Installation</a> page for more information.</p>
<h2>What to expect in upcoming releases</h2>
<p>The major components of the CQRS pattern are already available in the 0.4 release of Axon Framework. However, there is still a number of features we want to include in the 1.0 release. Although one of the advantages of CQRS is that it makes an application scalable and extensible, the 1.0 release of Axon Framework focuses on what happens inside a single JVM. Streaming events between JVM’s is not made impossible though, the Spring Integration connectors can be used to publish events to JMS, MQ, mail, HTTP and any other protocol supported by Spring Integration.</p>
<p>Some features to expect before the 1.0 release are rolling snapshots. When aggregates live for a long time, the number of events to read in each time the aggregate is loaded could easily run in the thousands. Reading in a thousand events takes a long time. Instead of reading in a thousand events, you can summarize all these events into a single snapshot event. Axon Framework will provide the plumbing necessary for you to build snapshot events.</p>
<p>Another feature that we’ll be spending some attention on is failure recovery. Unfortunately, applications sometimes behave unexpectedly and sometimes stop entirely. The reason of a crash won’t be the Axon Framework itself, of course. But since we have a reliable source of events in the events store, we can use this to recover from failure. Axon Framework will provide some building blocks that allow you to republish events to event handlers that did not get the chance to process them. This same mechanism will allow you to restore your application state from backups.</p>
<p>The last feature currently on the roadmap is JMX support. Since Axon Framework deals with the dispatching and invocation of event handlers, it has interesting information about an application’s performance and technical state. We are planning to expose this information using JMX MBeans.</p>
<p>If you have any other ideas, you can submit a feature request on <a href="http://www.axonframework.org/issues" target="_blank">www.axonframework.org/issues</a>. </p>
<h2>Getting started with Axon</h2>
<p>If you&#8217;re eager to get started using Axon Framework for your own application, check out the <a href="http://www.axonframework.org" target="_blank">Axon Framework website</a>. There, you can download the binaries, sources documentation and a sample application. If you use Maven, the reference manual will explain how you can configure the dependencies on the Axon binaries.</p>
<p>If the information on the website is not enough to get you started, don’t hesitate to send me a message or post a comment at the bottom of this blog entry.</p>
<h2>A special thanks to…</h2>
<p>Before I wrap up, I would like to thank Jettro Coenradie for his help on the sample project and the reference documentation. I think the sample turned out into a pretty cool demo environment for some of the advantages that Axon can provide.</p>
<p>Also many thanks to <a href="http://www.jteam.nl" target="_blank">JTeam</a> for the time they allowed me to spend on the project. Without it, I am sure I couldn’t have delivered this release. Thanks!</p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2010%2F02%2F21%2Faxon-framework-the-cqrs-framework-for-java-version-0-4-released%2F&amp;title=Axon%20Framework%20%26ndash%3B%20the%20CQRS%20framework%20for%20Java%20%26ndash%3B%20version%200.4%20released&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2010/02/21/axon-framework-the-cqrs-framework-for-java-version-0-4-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CQRS made easy with cqrs4j</title>
		<link>http://www.gridshore.nl/2009/12/21/cqrs-made-easy-with-cqrs4j/</link>
		<comments>http://www.gridshore.nl/2009/12/21/cqrs-made-easy-with-cqrs4j/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 08:37:00 +0000</pubDate>
		<dc:creator>Allard</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[DDD]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[cqrs]]></category>
		<category><![CDATA[Domain Driven Design]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=954</guid>
		<description><![CDATA[<p>&#160;</p> <p>Command Query Responsibility Segregation (CQRS) is an architectural style that makes a clear distinction between commands, which tell an application to do something, and queries, which are requests for information from an application. This distinction comes from the fact that the requirements (and thus also the model) for the execution and validation of [...]]]></description>
			<content:encoded><![CDATA[<p>&#160;<img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="cqrs4j_logo" border="0" alt="cqrs4j_logo" align="left" src="http://www.gridshore.nl/wp-content/uploads/logo_large.png" width="100" height="100" /></p>
<p>Command Query Responsibility Segregation (CQRS) is an architectural style that makes a clear distinction between commands, which tell an application to do something, and queries, which are requests for information from an application. This distinction comes from the fact that the requirements (and thus also the model) for the execution and validation of commands are significantly different than those for queries. Events play an important role in the synchronization of application state resulting from executed command.</p>
<p>Applying a CQRS style architecture involves the development of quite a lot of “plumbing” code: event dispatching, asynchronous event processing, transactions, etc. <em>cqrs4j</em>, an Apache 2 licensed open source framework, takes care of all the plumbing for you. Read on to find out how…</p>
<p> <span id="more-954"></span><br />
<h2>A brief introduction to CQRS</h2>
<p>As I stated above, CQRS makes a distinction between the model that validates and executes commands and the model that is used for providing state information. This is quite significantly different than how most (web)app applications are build nowadays. In fact, the model used for commands (the box named “Domain” in the image below), does not expose any state, at all. You might wonder, but how do I know what to show in the front end? That comes directly from your data sources using a thin data layer. I’ll explain how the data gets there in a minute.<a href="http://www.gridshore.nl/wp-content/uploads/cqrs_architecture.jpg"><img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="cqrs_architecture" border="0" alt="cqrs_architecture" src="http://www.gridshore.nl/wp-content/uploads/cqrs_architecture_thumb1.jpg" width="404" height="281" /></a></p>
<p>When a command comes in, it will load an <a href="http://dddstepbystep.com/wikis/ddd/aggregate.aspx" target="_blank">aggregate</a> from the <a href="http://dddstepbystep.com/wikis/ddd/repository.aspx" target="_blank">repository</a> and execute certain operations on it. As a result of these operations, the aggregate produces events, which are picked up for storage by the repository and for dispatching by the event bus. The event bus will dispatch each event to all (interested) event handlers. Some of these event handlers will perform actions on other (related) aggregates, some others will update the database tables they manage.</p>
<p>Having handlers update the data in the database means that your tables do not have to be normalized anymore. Instead, CQRS allows you to optimize your tables for the way you want to query them. This makes the data layer processing your queries really simple, and maintainable. </p>
<p>Furthermore, since all state changes are initiated by events, these events become a reliable source for an audit trail. By storing these events, you have an audit trail that you can use to replay the entire application history. Instead of just seeing “current application state” only, you can see all the changes that have led to the current state, providing valuable information trying to find bugs or deal with customer complaints.</p>
<p>The asynchronous and event driven nature of CQRS makes it extremely valuable for complex applications that have different views on the information in the application. Integration with third party systems that need to be notified of certain changes in your application –and vice versa–&#160; is a lot easier if you use an event driven approach. And since event handling is done asynchronously, the application is more responsive and easier to scale. </p>
<p>But as you notice, there is quite a lot of processing and pushing around of events. When you have a customer breathing up your neck, you don’t want to be developing infrastructure code. You would want to be focusing on the business logic, which is quite complex by itself.</p>
<h2>cqrs4j</h2>
<p>cqrs4j is a Spring-oriented framework that provides the most important building blocks of a CQRS architecture. Creating an aggregate becomes really simple. You don’t have to worry about managing the storage and dispatching of (uncommitted) events. Event sourcing becomes as easy as wiring two beans in your application context.</p>
<p><strong>Annotation support</strong></p>
<p>cqrs4j comes with out-of-the-box annotation support. This makes is really easy to wire event handler methods. cqrs4j can automatically subscribe all your event handlers to the event bus and delegate all relevant events to the appropriate event handlers. Enabling annotation support is as easy as wiring a single bean in your application context.</p>
<p><strong>Spring Integration support</strong></p>
<p>Spring Integration is a framework that allows easy developments of a Messaging systems using the pipes-and-filters architecture. This fits nicely with most of the event dispatching process of CQRS. cqrs4j has support for Spring Integration, which allows you to publish all events as messages on a Spring Integration channel. Sending messages through JMS queues, via email, or through file system storage will only take a few lines of (XML) configuration.</p>
<p><strong>Transaction support</strong></p>
<p>If you update your database tables through incoming events, dealing with them one-by-one in a transaction can become time consuming and take up too much resources of your database. With cqrs4j, you can configure transactions just by setting the @Transactional annotation on your event handlers. You can also configure how many events should be handled in a single transaction.</p>
<h2>cqrs4j project page</h2>
<p>cqrs4j is an open source project, licensed under the Apache 2 license. Visit the project home page for the latest downloads, documentation and source code at <a href="http://code.google.com/p/cqrs4j" target="_blank">code.google.com/p/cqrs4j</a>.</p>
<p><strong>We welcome your feedback</strong></p>
<p>If you have any requests, remarks or other feedback, please let us know. You can report bugs and improvement requests on the <a href="http://code.google.com/p/cqrs4j/issues/" target="_blank">issues page</a>. You can also leave a message via the <a href="http://www.gridshore.nl/contact/" target="_blank">contact page</a> or by leaving a comment.</p>
<h2>Further reading</h2>
<p>I have some more CQRS related blog articles coming up, but there are already quite a few around. Here is a few that helped me get started:</p>
<ul>
<li><a href="http://www.infoq.com/presentations/greg-young-unshackle-qcon08" target="_blank">Greg Young @ QCon: Unshackle your domain</a> </li>
<li><a href="http://elegantcode.com/2009/11/11/cqrs-la-greg-young/" target="_blank">CQRS a la Greg Young</a> </li>
<li><a href="http://elegantcode.com/2009/11/20/cqrs-the-domain-events/" target="_blank">CQRS – The Domain Events</a> </li>
<li><a href="http://elegantcode.com/2009/12/08/cqrs-domain-state/" target="_blank">CQRS – Domain State</a> </li>
<li><a href="http://jonathan-oliver.blogspot.com/2009/10/dddd-why-i-love-cqrs.html" target="_blank">DDDD – Why I love CQRS</a> </li>
</ul>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2009%2F12%2F21%2Fcqrs-made-easy-with-cqrs4j%2F&amp;title=CQRS%20made%20easy%20with%20cqrs4j&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2009/12/21/cqrs-made-easy-with-cqrs4j/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>User group for DDD enthusiasts in the Netherlands started</title>
		<link>http://www.gridshore.nl/2009/07/24/user-group-for-ddd-enthousiast-in-the-netherlands-started/</link>
		<comments>http://www.gridshore.nl/2009/07/24/user-group-for-ddd-enthousiast-in-the-netherlands-started/#comments</comments>
		<pubDate>Fri, 24 Jul 2009 14:00:43 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[DDD]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=834</guid>
		<description><![CDATA[<p>Today we release the website of a new User group for all Domain Driven Design enthusiasts. This user group is meant to facilitate all experienced DDD people to unity and share ideas/experiences. We also would like to help starters getting up to speed learning more about DDD</p> <p>What are we planning to do? We [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.gridshore.nl/wp-content/uploads/dddnl_logo.png" alt="dddnl_logo.png" border="0" width="152" height="95" align="left" />Today we release the website of a new User group for all Domain Driven Design enthusiasts. This user group is meant to facilitate all experienced DDD people to unity and share ideas/experiences. We also would like to help starters getting up to speed learning more about DDD</p>
<p>What are we planning to do? We are planning (bi-)monthly events. During these events people can share ideas in a presentation, discussions. We might have (international) guests coming in to talk about Domain Driven Design. Everything is focused around knowledge sharing. I suggest to <a href="http://www.dddnl.org">check the website</a> for more details.</p>
<p>The user group is connected to the <a href="http://www.domaindrivendesign.org">domain driven design</a> website hosted by Eric Evens and others.</p>
<p>If you are up to it, feel free to register for the kick-off event that is taking place the 8th of September. You can use the <a href="http://www.dddnl.org/node/9">form on the website</a> to register.</p>
<p>I hope all people get as enthusiastic as we are.</p>
<p>regards Jettro and Allard</p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2009%2F07%2F24%2Fuser-group-for-ddd-enthousiast-in-the-netherlands-started%2F&amp;title=User%20group%20for%20DDD%20enthusiasts%20in%20the%20Netherlands%20started&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2009/07/24/user-group-for-ddd-enthousiast-in-the-netherlands-started/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Designing the Repository interface</title>
		<link>http://www.gridshore.nl/2009/07/01/designing-the-repository-interface/</link>
		<comments>http://www.gridshore.nl/2009/07/01/designing-the-repository-interface/#comments</comments>
		<pubDate>Wed, 01 Jul 2009 19:58:49 +0000</pubDate>
		<dc:creator>Allard</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[DDD]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/2009/07/01/designing-the-repository-interface/</guid>
		<description><![CDATA[<p>In one of my most recent projects, I decided to design and build the application according to the principles of Domain Driven Design. One of the guidelines promoted by Domain Driven Design is the way the interface of the Repository is designed. This changed the way I look at both the design and the [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.gridshore.nl/wp-content/uploads/storage.jpg"><img style="border-right-width: 0px; margin: 0px 10px 0px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="storage" border="0" alt="storage" align="left" src="http://www.gridshore.nl/wp-content/uploads/storage_thumb.jpg" width="104" height="96" /></a>In one of my most recent projects, I decided to design and build the application according to the principles of <a href="http://domaindrivendesign.org/" target="_blank">Domain Driven Design</a>. One of the guidelines promoted by Domain Driven Design is the way the interface of the Repository is designed. This changed the way I look at both the design and the location of the <a href="http://www.martinfowler.com/eaaCatalog/repository.html" target="_blank">Repository</a> interface. It’s all gain, no pain.</p>
<p>&#160;</p>
<p> <span id="more-823"></span>
<p>Most of the applications I encounter in my <a href="http://www.jteam.nl" target="_blank">work</a> as Software Architect apply more or less the same layering. The well-known layers in an application are the web layer, application layer, persistence layer and domain layer. This layering provides some boundaries for different types of logic to keep an application maintainable in the long term. Typically, layers are placed in different modules (each with their own jar file) inside a project. However, for smaller projects it would suffice to just place each layer in its own package structure.</p>
<p><a href="http://www.gridshore.nl/wp-content/uploads/typicalapplicationlayering.jpg"><img style="border-right-width: 0px; margin: 0px 10px 0px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="typical-application-layering" border="0" alt="typical-application-layering" align="left" src="http://www.gridshore.nl/wp-content/uploads/typicalapplicationlayering_thumb.jpg" width="220" height="163" /></a> </p>
<p>Almost all applications I encounter have implemented a layering as shown in the image on the left. The arrows show the direction of the dependency of each module on the others.</p>
<p>As you can see, the Application Layer has a dependency on the Persistence layer. The need for that dependency comes from the fact that the persistence layer contains the Repository. Both the interface (since it is good practice to develop against interfaces) and its implementation. With my recent study of the Domain Driven Design principles, I gained the insight that it doesn’t really make a lot of sense to put the interface next (or near) to its implementation.</p>
<p>But why would you even bother to create an interface for the Repository at all? Well, there are a few good reasons (and probably some bad ones too) to do so. One of them is that it allows easy mocking and stubbing for tests. Another is that it allows you to replace or modify the implementation without the risk of breaking interaction (as long as the interface is maintained).</p>
<p>However, replacing the persistence layer with another one isn’t as easy as it seems when it contains the interface. To be able to do so, you must copy the interface into the new persistence layer implementation. And as any good developers knows, when you’re copying stuff, take your hands off the keyboard, and think for a second. You’re probably doing something wrong.</p>
<p>Quite recently, I had a small discussion with someone who said: “How often do you expect to change the implementation of your persistence layer?”. I didn’t really have an answer back then, but right now I am spending time on exactly that in one of my projects. And you’ll have to trust me on this: correctly designing the interface is well worth the trouble. Even if you only have to change the persistence implementation once every 100 projects. Furthermore, another project I recently started actually requires the ability to “plug in” different implementations of the persistence layer (no, not at runtime, it doesn’t have to be OSGi, unfortunately).</p>
<p><a href="http://www.gridshore.nl/wp-content/uploads/betterapplicationlayering.jpg"><img style="border-right-width: 0px; margin: 0px 0px 0px 10px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="better-application-layering" border="0" alt="better-application-layering" align="right" src="http://www.gridshore.nl/wp-content/uploads/betterapplicationlayering_thumb.jpg" width="220" height="163" /></a>Inspired by the <a href="http://www.domaindrivendesign.org/examples" target="_blank">DDD sample application</a>, I decided to place the interface in the Domain Layer. By doing this, there was no longer a need to have a (compile time) dependency from the Application layer to the Persistence layer. On paper that looks a bit cleaner.&#160; But we don’t design applications to look good on paper.</p>
<p>A good repository interface, as described by Martin Fowler and Eric Evans, gives it’s client the perception of an in-memory repository. In fact, it should hide any implementation choices you make about how and where data is really stored. And if you want to be able to replace persistence layers, that’s exactly what you need.</p>
<p>If you place the interface next to an implementation, you’re tempted to just use your IDE to extract an interface from your implementation. Chances are that your interface “leaks” information of your implementation choices. Instead, try to force yourself to design the interface first and develop an implementation that conforms to that interface later. This will help you achieve the “in-memory” perception.</p>
<p>A colleague of mine asked me why I chose to put the interface in the domain layer (see <a href="http://www.martinfowler.com/eaaCatalog/separatedInterface.html" target="_blank">Separated Interface Pattern</a>), and not the application layer, which is most likely to need the interface and call its implementation.I had three reasons. </p>
<p>First, the interface is described based on a small selection of domain entities. This gives the interface high coupling with these domain objects. High coupled classes are good candidates to share a package. In fact, you repository interface probably doesn’t require any import statements at all.</p>
<p>Secondly, it is probable that more than one service, perhaps located in different packages or modules, need to use the same repository. In that case, which package is most suitable to put the implementation in? Choosing even another package will result in lots of inter-package dependencies that aren’t really necessary. Unnecessary package dependencies decrease the ability to refactor your application .</p>
<p>And thirdly, the repositories provide access to your “aggregate roots”. If you have an aggregate root named, for example, “Order” and call your repository “OrderRepository”, your IDE will sort these classes in such a way, that you can easily find the most important entities in a blink of an eye.</p>
<p>Well, I hope this can help you in your projects as it could have helped me in the past. If you have any questions or concerns, don’t hesitate to leave a comment.</p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2009%2F07%2F01%2Fdesigning-the-repository-interface%2F&amp;title=Designing%20the%20Repository%20interface&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2009/07/01/designing-the-repository-interface/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Call for Action for the Java Hackers</title>
		<link>http://www.gridshore.nl/2009/06/30/call-for-action-for-the-java-hackers/</link>
		<comments>http://www.gridshore.nl/2009/06/30/call-for-action-for-the-java-hackers/#comments</comments>
		<pubDate>Tue, 30 Jun 2009 17:15:18 +0000</pubDate>
		<dc:creator>freddie</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/2009/06/30/call-for-action-for-the-java-hackers/</guid>
		<description><![CDATA[<p>I challenge the Java Hackers, read on&#8230;.</p> <p>As you probably all know by now, I have joined ISIS Papyrus a while ago and last week i was reading the Papyrus Objects Developer Guide again and suddenly lightning hit me and the question raised can this actually be done in Java and if so, how [...]]]></description>
			<content:encoded><![CDATA[<p>I challenge the Java Hackers, read on&#8230;.</p>
<p>As you probably all know by now, I have joined ISIS Papyrus a while ago and last week i was reading the Papyrus Objects Developer Guide again and suddenly lightning hit me and the question raised can this actually be done in Java and if so, how and how easy?</p>
<p>Be aware, reading further could put you in a depression but on the otherhand the real Hacker will find it a challenge. Are you the Hacker?</p>
<p><span id="more-815"></span>
<p>From the ISIS Papyrus Objects manual for Developers: Classes are the definitions of objects and their behavior designed by the Developer. Classes are required to define general properties of objects derived from these classes, namely attributes, methods, states, and child/parent reference definitions. All classes reside exclusively in the Repository. The object tree in the Repository reflects the inheritance chain. As child objects of a class reflect an inheritance relationship it inherits all properties (methods, attributes, states, state transitions, and parent/child relationships).</p>
<p><em>Big deal and obvious you may think. But did you noticed the fact that we talk here also about states, state transitions and parent/child relationships.</em></p>
<p>Papyrus has full support for those concepts without any line of programming. Besides this there is full support for Security (role, policy, privilege), Version control (you can even view the versions and each instance knows to what version it belongs). But more on that maybe later.</p>
<p>I would like to see and explained Java Implementations that cover the UML implementation of State Machine, Parent/Child and Constraints (OCL) as this is all standard in Papyrus Objects and does not require programming at all.</p>
<p><strong><em>Hackers, show me a simple application simulating for example a traffic light with some attributes and methods that have been constrained as well the state transition itself. You would be a super hacker if you also implement security.</em></strong></p>
<p>Need inspiration for your Java Hack? Read some parts of our ISIS Objects Manual for Developers and start Hacking. I am waiting for your solutions and i am sure other Hackers will comment on them so that at the end the best solution will be available to be compared to Papyrus Objects. SUCCESS</p>
<p><strong>Authorization Concepts</strong></p>
<p>In Papyrus Objects, authorization is established through Roles, Privileges, and Policies that give Users the authorization appropriate for their tasks. This structure allows the Security Administrator to precisely control access to objects, whatever the User&#8217;s needs are.</p>
<p>The Role/Policy concept used in Papyrus Objects is modelled after the CORBA standard of Role Based Access Control (RBAC). Since users are not assigned permissions directly, but only acquire them through their Role (or Roles), management of individual user rights becomes a matter of simply assigning the appropriate Role(s) to the user, which simplifies common operations such as adding a user, or changing a user&#8217;s department. The Policy controls the visibility and thus complex filtering for presentation into frames is not necessary if the Policies are well set.</p>
<p>Access to objects (and usually also their visibility) is granted by policies, i.e. the user must be using a Role that is referenced by any of the Policies defined on the object, to access it.</p>
<p>Access to attributes and methods of objects is granted by Privileges, i.e. the user must be using a Role with the required privilege. In addition this Role must also be referenced by any of the Policies defined on the object.</p>
<p><strong>State Machine</strong></p>
<p>A state machine consists of states and their state transitions, which define the life cycle of an object. Conditions can be defined, thus certain actions can only be applied to an object if it is currently in an appropriate state (e.g. Task in state &#8220;Completed&#8221; cannot be processed). The fields of the state machine in Papyrus Objects are similar to UML (Unified Modeling Language). The &#8220;state machine view&#8221; is a frame of the Class Editor and displays the whole state machine in a flow chart. It can be used as a graphical editor similar to the UML Case tools. The state machine lists the states that an instance can have, and the Transitions between those states. Therefore it defines the object&#8217;s behavior:</p>
<ul>
<li>What kind of information (event) is sent to other objects.</li>
<li>Which methods are available within the current state.</li>
<li>Which event sent by a program triggers a state transit</li>
</ul>
<p>The state change of an object can be:</p>
<ul>
<li>user driven</li>
<li>driven by events</li>
<li>driven by messages</li>
</ul>
<p>A State Change has Entry, Exit, and Do Events (actions).</p>
<p><strong>Child/Parent References</strong></p>
<p>Via child and parent references the relationship between parent and child objects can be defined. A child reference can be used to define which type of object may be added to the object via a parent reference it is possible to defined to which type of object the object may be added.</p>
<p><strong>Constraints</strong></p>
<p>Constraint fields are used to define whether access to or modifications on a part of an object is granted. This way it is possible to define conditions which decide that a state transition for instance may not be executed under certain circumstances or an attribute cannot be changed in a certain state. If the expression in a constraint field evaluates to TRUE (or the field is left blank) the respective part of the object may be accessed or modified. If a constraints field evaluates to a number, then any number other than zero is true, and zero is false.</p>
<p>The following sections of a class / template definition contain constraint fields:</p>
<ul>
<li>Object start (Constraints)</li>
<li>State (Send Modification Event if)</li>
<li>State Transitions (Change trigger, Guard)</li>
<li>Attribute (Constraints, View constraints, and Edit constraints)</li>
<li>Method (Pre constraints and Post constraints)</li>
<li>Child and Parent References (Constraints, View constraints, and Edit constraints)</li>
</ul>
<p><strong>Privileges</strong></p>
<p>To define which group of users should be able to call a method or view / edit an attribute, select the related Privilege(s) in the field &#8220;Privileges&#8221; of the method or &#8220;View Privileges&#8221; or &#8220;Edit Privileges&#8221; of the attribute. ISIS provides the following predefined Privileges, which are defined in the Privileges object below the Storage folder &#8220;Storage / System Collection&#8221;:</p>
<p><em>$_Developer &#8230; Create / modify classes and templates<br />
$_Administrator &#8230; Create / Modify templates<br />
$_Security Administrator &#8230; Manages access rights<br />
$_User &#8230; End user, cannot create / modify classes and templates, not all methods available.<br />
$_Guest &#8230; End user with very limited rights for viewing.<br />
$_Licence Administrator &#8230; Administrates product authorizations<br />
$_System Administrator &#8230; General administration (e.g. creation of Client Nodes, import of transfer files, etc.)<br />
$_Supervisor &#8230; System supervisor for the select of objects, which should generate an audit trail (with System Supervisor Role) or privileged end user for release tasks.</em></p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2009%2F06%2F30%2Fcall-for-action-for-the-java-hackers%2F&amp;title=Call%20for%20Action%20for%20the%20Java%20Hackers&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2009/06/30/call-for-action-for-the-java-hackers/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>XML is net zo overschat als de Magnetron</title>
		<link>http://www.gridshore.nl/2009/05/26/xml-is-net-zo-overschat-als-de-magnetron/</link>
		<comments>http://www.gridshore.nl/2009/05/26/xml-is-net-zo-overschat-als-de-magnetron/#comments</comments>
		<pubDate>Tue, 26 May 2009 05:46:09 +0000</pubDate>
		<dc:creator>freddie</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/2009/05/26/xml-is-net-zo-overschat-als-de-magnetron/</guid>
		<description><![CDATA[<p>Based on a discussion on Linkedin i have created a Dutch post on Computable on the premises of XML and if they came true. Feel free to leave a comment there.</p> ]]></description>
			<content:encoded><![CDATA[<p>Based on a discussion on Linkedin i have created a Dutch post on Computable on the <a href="http://www.computable.nl/artikel/ict_topics/ecm/2955023/1277020/xml-is-net-zo-overschat-als-de-magnetron.html">premises of XML </a> and if they came true. Feel free to leave a comment there.</p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2009%2F05%2F26%2Fxml-is-net-zo-overschat-als-de-magnetron%2F&amp;title=XML%20is%20net%20zo%20overschat%20als%20de%20Magnetron&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2009/05/26/xml-is-net-zo-overschat-als-de-magnetron/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

