<?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; Technology</title>
	<atom:link href="http://www.gridshore.nl/category/technology/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>Recap of the year 2010</title>
		<link>http://www.gridshore.nl/2011/01/04/recap-of-the-year-2010/</link>
		<comments>http://www.gridshore.nl/2011/01/04/recap-of-the-year-2010/#comments</comments>
		<pubDate>Tue, 04 Jan 2011 20:08:30 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[Axon Framework]]></category>
		<category><![CDATA[groovy and grails]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[recap]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=1125</guid>
		<description><![CDATA[<p>The new year has started, with it comes one of the last opportunities to look back at 2010. So what happened, what did I try out, what did I like and what didn&#8217;t I like. I also want to have a short look at what you liked, based on the number of visitors.</p> <p>This [...]]]></description>
			<content:encoded><![CDATA[<p>The new year has started, with it comes one of the last opportunities to look back at 2010. So what happened, what did I try out, what did I like and what didn&#8217;t I like. I also want to have a short look at what you liked, based on the number of visitors.</p>
<p>This post will nog contain new technical stuff, only old stuff <img src='http://www.gridshore.nl/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><span id="more-1125"></span><br />
<h2>Statistics</h2>
<p>On average I get 500 visitors each day. Some of the posts got a lot of attention and reached 1000 visits a day. The posts with the highest amount of visits are old ones. A lot of them are coming from my old blog and are about spring web services. The biggest link of 2010 is a blog from June 2009 about Roo : <a href="http://www.gridshore.nl/2009/06/11/why-spring-roo-is-not-my-thing/">Why Spring Roo is not my thing</a>. I think that is pretty funny but also sad. Of course I would like my new blog items to be on top. The first post in the list is from June 2010 and is about jmx and spring <a href="http://www.gridshore.nl/2010/06/02/using-jmx-within-a-spring-application/">Using JMX within a spring application</a>. The last one I want to mention is a blog item from november 2011. This post is somewhere around number 25 in 2010. Which is nice if you take into account that it just had less than 2 months to reach this position. The post is about the spring-social project: <a href="http://www.gridshore.nl/2010/11/04/connecting-to-linkedin-using-spring-social/">Connecting to Linkedin using spring-social</a></p>
<p>Where did all these people come from? Well most of them came through Google, a lot came through DZone and quite a few came through multiple project websites of spring-source [mostly spring-flex and spring-integration].</p>
<p>Most people use Firefox, and Google Chrome is rising. Internet Explorer is still twice as big than safari on my blog. But Firefox is 4 times the size of internet explorer.</p>
<p>Top Countries are Unites States and India followed by Germany and United Kingdom.</p>
<p>Enough statistics, let us move on to the content. What did I write about?</p>
<h2>What did I write about</h2>
<h3>Januari</h3>
<p>In Januari I wrote two blog posts about grails. The results can be found in the <a href="https://github.com/jettro/MyScheduling">MyScheduling sample</a> over at Github. At my employers blog I wrote a piece about <a href="http://blog.jteam.nl/2010/01/14/logging-to-the-syslog-from-a-java-application/">Logging to the syslog from a java application</a>.</p>
<h3>Februari</h3>
<p>In Februari I wrote more on flex. I discovered the Parsley library and I wrote a sample for the <a href="http://www.axonframework.org">Axon framework</a>. The blog post I wrote is <a href="http://www.gridshore.nl/2010/02/25/creating-a-sample-for-axon-using-flex-and-parsley/">Creating a sample for axon using flex and parsley</a>. The sample is part of the axon distribution. Another blogpost was about creating an rss feed with spring 3 and the Rome library. This post was coming from the work I did for a customer.</p>
<h3>April</h3>
<p>In march nothing really happened. In april I wrote about using groovy and I wrote a sample that combined Axon and Grails. This sample is still maintained and is a nice example of what you can do with groovy and axon. Three posts of April from my hand were axon and grails related. You can find the <a href="https://github.com/jettro/axon-addressbook-grails">sample over at Github</a>.</p>
<p>The reason for the quiet month of March was a very busy project. We went live in April, I wrote about it <a href="http://blog.jteam.nl/2010/04/05/jteam-en-rijksoverheid-nl/">on the JTeam blog</a>.</p>
<h3>June</h3>
<p>For the project I was working on I needed monitoring. I decided to use groovy for its flexibility and the integration with spring jmx for easy remote access and exposing beans through jmx. I wrote two posts, <a href="http://www.gridshore.nl/2010/06/02/using-jmx-within-a-spring-application/">Using JMX within a spring application</a> was a post with some screenshots and a lot of code.</p>
<h3>July/August</h3>
<p>These are traditionally the months that Ben gives us a few blog posts. Especially his post <a href="http://www.gridshore.nl/2010/08/16/yes-rest-really-is-not-the-same-as-http/">Yes! REST really is not the same as HTTP!!</a> was received very well.</p>
<p>I wrote a blog post on JTeam blog. Again about jmx and groovy. This time I wrote about <a href="http://blog.jteam.nl/2010/08/19/monitoring-hippo-connection-pool-using-jmx-and-groovy/">Monitoring Hippo Connection Pool using jmx and groovy</a>. Some ideas of this blogpost were used in the actual implementation of hippo repository connector.</p>
<h3>September</h3>
<p>This was the month for new things. Two blog posts about MongoDB. Together with Allard I created the EventStore implementation for Axon based on MongoDB. Sample project is available on Github:<a href="https://github.com/jettro/Axon-trader">https://github.com/jettro/Axon-trader</a>. The other blog post was about gradle. I am trying to find better build tools than maven.</p>
<h3>October</h3>
<p>The month of the JAOO or GOTO conference. No blog items on gridshore. But one post about Git that was read very often and had a lot of dzone votes. <a href="http://blog.jteam.nl/2010/10/08/git-tips-that-i-learned-from-the-master/">Git Tips That I Learned From The Master</a>. Had a lot of inspiration during the conference and some good drinks as well.</p>
<h3>November</h3>
<p>November was a very succesful spring month. I wrote two blog posts about two new spring projects. Spring-social and Spring-mobile. Both posts were received very well. I got some very positive feedback, especially by Keith Donald. He mentioned that parts of my blog post were an inspiration for new functionality in the M2 release of spring-mobile. He also wrote a <a href="http://blog.springsource.com/2010/12/21/social-coding-in-spring-projects/">very nice blog post</a> about using Git and he used the patch I could have created as a red line for his post. Fun to read. Code for the samples is again available on Github: <a href="https://github.com/jettro/GridshoreSamples">https://github.com/jettro/GridshoreSamples</a></p>
<h2>Other things I did</h2>
<p>I reviewed a book about Apache Felix (more on this later). I gave a presentation at the Hippo Gettogether that is available online. Of course I gave some presentations at JTeam tech evenings. I also read a lot of books, the book that made an impact on how I look at presentations: Presentation Zen by Garr Reynolds.</p>
<p>The last thing I want to mention in this chapter is that I bought myself some toys. Of course the iPad, but now I am also owner of Lego Mindstorms. I even did some java programming on the robot. More on that later this year.</p>
<h2>Highlights</h2>
<p>So a well spend year with blog posts about Axon, Grails, Groovy, Flex, JMX, Spring, Git, MongoDB, logging. I am sure 2011 will be as inspiring as 2010. To all of you, have a very good year and hope you will come back to read some of my posts.</p>
<p>Happy New Year, Jettro</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%2F2011%2F01%2F04%2Frecap-of-the-year-2010%2F&amp;title=Recap%20of%20the%20year%202010&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/2011/01/04/recap-of-the-year-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Still learning MongoDB</title>
		<link>http://www.gridshore.nl/2010/09/27/still-learning-mongodb/</link>
		<comments>http://www.gridshore.nl/2010/09/27/still-learning-mongodb/#comments</comments>
		<pubDate>Mon, 27 Sep 2010 14:10:15 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[Axon Framework]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[axon]]></category>
		<category><![CDATA[axonframework]]></category>
		<category><![CDATA[mongodb]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=1088</guid>
		<description><![CDATA[<p></p> <p>Some days a go I wrote a blogpost about Learning Mongo. Of course I did not stop learning. As a good habit, I wrote down the next things I learned and played around with. That is what this blogpost is about, next steps in the learning process of Mongo. This post mainly focussus [...]]]></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>Some days a go I wrote a blogpost about <a href="http://www.gridshore.nl/2010/09/20/learning-mongodb/">Learning Mongo</a>. Of course I did not stop learning. As a good habit, I wrote down the next things I learned and played around with. That is what this blogpost is about, next steps in the learning process of Mongo. This post mainly focussus on Replication Sets, object Identity, WriteConcern and a bit about Sharding.</p>
<p>The case for most of the code used in this blog is about creating an EventStore for the <a href="http://www.axonframework.org">Axonframework</a>.</p>
<p><span id="more-1088"></span>
<p> </p>
<h2>WriteConcern and batch inserts</h2>
<p>In my previous blog post I already wrote about WriteConcern and batch inserts. I even gave some example code for the batch insert. I mentioned the difference between WriteConcern SAFE and REPLICA_SAFE. To overcome the difference between test and production I played around with an environment setting to change the WriteConcern form SAFE to REPLICA_SAFE when working in a production environment. That way it is easier to test your application within a test environment and without to much hassle go into production.</p>
<h3>Configuring the Mongo Replica Set or the single instance</h3>
<p>To do this magic of switching, I used a spring factory bean. This factory bean creates a <em>Mongo</em> instance. If a <em>test.context</em> parameter is provided with a value <em>true</em>, a Mongo instance with the default settings is assumed. If not, a Replica Set of three servers is expected. The values are specified in a property file. The factory bean and the spring config are shown in the next two code blocks. The factory bean is not complete, only the important stuff is shown.</p>
<pre class="brush: java; title: ; notranslate">
public class MongoFactory implements FactoryBean, InitializingBean {
    private boolean testContext;
    private List mongoAddresses;
    private Mongo mongo;

    ...
    @Override
    public void afterPropertiesSet() throws Exception {
        if (testContext) {
            this.mongo = new Mongo();
        } else {
            if (mongoAddresses.isEmpty() || mongoAddresses.size() &lt; 3) {
                throw new IllegalStateException(&quot;Please configure at least 3 instances of Mongo for production.&quot;);
            }
            this.mongo = new Mongo(mongoAddresses);
        }
    }
}
</pre>
<pre class="brush: xml; title: ; notranslate">
&lt;bean id=&quot;mongoDb&quot; class=&quot;org.axonframework.samples.trader.app.eventstore.mongo.MongoFactory&quot;&gt;
    &lt;property name=&quot;testContext&quot; value=&quot;${test.context}&quot;/&gt;
    &lt;property name=&quot;mongoAddresses&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;${server1.host}&quot;/&gt;
                &lt;constructor-arg index=&quot;1&quot; value=&quot;${server1.port}&quot;/&gt;
            &lt;/bean&gt;
            &lt;bean class=&quot;com.mongodb.ServerAddress&quot;&gt;
                &lt;constructor-arg index=&quot;0&quot; value=&quot;${server2.host}&quot;/&gt;
                &lt;constructor-arg index=&quot;1&quot; value=&quot;${server2.port}&quot;/&gt;
            &lt;/bean&gt;
            &lt;bean class=&quot;com.mongodb.ServerAddress&quot;&gt;
                &lt;constructor-arg index=&quot;0&quot; value=&quot;${server3.host}&quot;/&gt;
                &lt;constructor-arg index=&quot;1&quot; value=&quot;${server3.port}&quot;/&gt;
            &lt;/bean&gt;
        &lt;/list&gt;
    &lt;/property&gt;
&lt;/bean&gt;
</pre>
<p>All nice, but in the end not very flexible. What if we want more than three nodes?</p>
<p>Well, that is not hard. These three nodes are not all the nodes known to the java Driver. They are just a starting point. Using these Nodes the driver will search for the other nodes. One of these nodes must be available when we initialize the Mongo connection. To prove this I provide only one node to the java Driver. Closing this node does not stop my application from functioning. The following shows you a line of the log of the application which shows that a new master is selected for the connection due to a connection problem with the old master.</p>
<pre>
paired mode, switching master b/c of: java.io.IOException: couldn't connect to [localhost/10.0.1.7:27017] bc:java.net.ConnectException: Connection refused
</pre>
<p>Now we create a new document and watch the logs of the master node. We can see that a connection is created.</p>
<pre>
Sun Sep 26 09:56:28 [initandlisten] connection accepted from 10.0.1.7:49424 #13
</pre>
<p>As long as the replication set is in the right state, the java driver can use it. It needs enough servers to be configured when starting up to find the complete replication set.</p>
<h3>Majority</h3>
<p>Within a replication set a majority must be available to function normally. If no majority in the set can be found, the set reaches an unworkable state. That is a good reason for the java driver to fail. In the log of the only server that is up you find these lines:</p>
<pre>
Mon Sep 27 09:40:14 [ReplSetHealthPollTask] replSet info localhost:27018 is now down (or slow to respond)
Mon Sep 27 09:40:14 [rs Manager] replSet can't see a majority of the set, relinquishing primary
Mon Sep 27 09:40:14 [rs Manager] replSet info relinquished primary state
Mon Sep 27 09:40:19 [rs Manager] replSet can't see a majority, will not try to elect self
</pre>
<p>Majority is important to Mongo. If no majority can be selected within a set, all nodes will remain in Secondary mode and stop functioning. So what is this majority thing?</p>
<p>After reading this blog post things became more clear to me: <a href="http://www.snailinaturtleneck.com/blog/2010/08/02/replica-sets-part-2-what-are-replica-sets/">What are Replica Sets?</a>.</p>
<p>Becoming the primary node has to do with voting. Getting a majority of <strong>YES</strong> votes makes you the primary node. By default each node has one vote. This explains why no majority could be found in the three server case, where two servers are down. Think about the implications of having four over three servers. If two go down, by default no majority is available.</p>
<p>If you have one big stable server and a few lesser servers, you might want to give the big server more votes. But be careful not to give to many votes, if it has to many votes it could cause the complete set to go down due to a majority problem when one server goes down.</p>
<p>This is the situation where the arbiter steps in.</p>
<h3>The Arbiter</h3>
<p>So what if you just need to nodes in two different data centers. One will be the primary node and the other a secondary. What if the connection between the two temporarily fails. Than your set becomes unusable. No majority can be found, so the set becomes unavailable. This is where an arbiter can help. An arbiter just has a vote, it cannot and will not contain data. It is just a way to make sure one of the servers becomes primary if there is no majority. Adding an arbiter is very easy. The following code shows how to add an arbiter and how this looks in the replication set configuration.</p>
<pre>
&gt; rs.addArb("localhost:27020");
{ "ok" : 1 }
&gt; rs.isMaster()
{
	"setName" : "axon",
	"ismaster" : true,
	"secondary" : false,
	"hosts" : [
		"localhost:27019",
		"localhost:27018",
		"localhost:27017"
	],
	"arbiters" : [
		"localhost:27020"
	],
	"ok" : 1
}
</pre>
<p>To see it in action we need a different replication set. Therefore I created one with two servers. The following block shows you the status after adding two servers without an agent and taking one down. Then we add an arbiter to the game and do the same thing again.</p>
<pre>
&gt; cfg={_id:"axon",members : [{_id:0,host:"localhost:27017"},{_id:1,host:"localhost:27018"}]}
&gt; rs.initiate(cfg)
&gt; rs.status()
{
	"set" : "axon",
	"date" : "Mon Sep 27 2010 10:58:56 GMT+0200 (CEST)",
	"myState" : 1,
    ...
    "ok" : 1
}
</pre>
<p>Close one of the servers. The log of the other server shows:</p>
<pre>
Mon Sep 27 11:01:43 [conn2] end connection 127.0.0.1:49424
Mon Sep 27 11:01:43 [rs_sync] replSet syncThread: 10278 dbclient error communicating with server
Mon Sep 27 11:01:44 [ReplSetHealthPollTask] replSet info localhost:27017 is now down (or slow to respond)
Mon Sep 27 11:01:44 [rs Manager] replSet can't see a majority, will not try to elect self
</pre>
<p>Now we start the other server again, add an arbiter. After that close it again and check the logs</p>
<pre>
> rs.status()
{
	"set" : "axon",
	"date" : "Mon Sep 27 2010 11:10:50 GMT+0200 (CEST)",
	"myState" : 1,
    ...
    "ok" : 1
}

Mon Sep 27 11:10:00 [conn2] end connection 127.0.0.1:49677
Mon Sep 27 11:10:02 [ReplSetHealthPollTask] replSet info localhost:27018 is now down (or slow to respond)
Mon Sep 27 11:10:02 [rs Manager] replSet info electSelf 0
Mon Sep 27 11:10:02 [rs Manager] replSet PRIMARY
</pre>
<h3>Experiment with WriteConcern</h3>
<p>Using the REPLICA_SAFE in a test environment with only one is not wise. Therefore my configuration is special for a test environment and I do not use REPLICA_SAFE. With only one node, I use SAFE. The easiest thing to test this is to create configure the production environment and just provide one node. You can wait for ever. But what if you do provide the REPLICA_SAFE and at a certain time an action is broken. Harder to test. That is what I took the debug perspective for. I waited with a write action within a debug session and closed 3 out of 4 nodes. Curious what happens? I cannot tell, since shutting down almost all nodes leavers the one available node in a state that no primary node is available. It is not possible to get a majority, so no primary node or master is selected. I am looking for other ways to test this, but I did not really find one. if you did please post a comment.</p>
<h2>Identification</h2>
<p>MongoDB creates a field _id and generates an unique identifier. It also installs an index on that field. If you have a good reason to provide your own identifier, you can easily provide it by adding a field with the name <strong>_id</strong>. Be sure that this field must be unique. The following code show the creation of a DBObject and the result through the Mongo shell. I show you an example from the MongoDB implementation of the Axon event store. One could use the aggregateIdentifier as identifier for Mongo as well. In the sample code I add the UUID of the aggregateIdentifier twice. In the real solution you would not do this of course.</p>
<pre class="brush: java; title: ; notranslate">
return BasicDBObjectBuilder.start()
        .add(&quot;_id&quot;, entry.getAggregateIdentifier().toString())
        .add(AGGREGATE_IDENTIFIER, entry.getAggregateIdentifier().toString())
        .add(SEQUENCE_NUMBER, entry.getSequenceNumber())
        .add(TIME_STAMP, entry.getTimeStamp().toString())
        .add(TYPE, entry.getType())
        .add(SERIALIZED_EVENT, entry.getSerializedEvent())
        .get();
</pre>
<pre>
{ "_id" : "35934d42-1943-4a75-867a-fccf86757624", "aggregateIdentifier" : "35934d42-1943-4a75-867a-fccf86757624", "sequenceNumber" : NumberLong( 0 ), "timeStamp" : "2010-09-23T18:24:20.013", "type" : "OrderBook", "serializedEvent" : BinData(2,"tgEAADxvcmcuYXhvbmZyYW1ld29yay5zYW1wbGVzLnRyYWRlci5hcHAuYXBpLk9yZGVyQm9va0NyZWF0ZWRFdmVudD48dGltZXN0YW1wPjIwMTAtMDktMjNUMTg6MjQ6MjAuMDEzPC90aW1lc3RhbXA+PGV2ZW50SWRlbnRpZmllcj5kNmU1MWZmOC0wMWRmLTQ5NDktOTBhZC1iMzJjNDg2OTM5N2Q8L2V2ZW50SWRlbnRpZmllcj48c2VxdWVuY2VOdW1iZXI+MDwvc2VxdWVuY2VOdW1iZXI+PGFnZ3JlZ2F0ZUlkZW50aWZpZXI+MzU5MzRkNDItMTk0My00YTc1LTg2N2EtZmNjZjg2NzU3NjI0PC9hZ2dyZWdhdGVJZGVudGlmaWVyPjx0cmFkZUl0ZW1JZGVudGlmaWVyPjVmYjY2MDllLTZhYjEtNGFmNi05YTJmLWU0MjhmZjhjZDQ0ZTwvdHJhZGVJdGVtSWRlbnRpZmllcj48L29yZy5heG9uZnJhbWV3b3JrLnNhbXBsZXMudHJhZGVyLmFwcC5hcGkuT3JkZXJCb29rQ3JlYXRlZEV2ZW50Pg==") }
</pre>
<p>You can see that the _id and the aggregateIdentifier are the same. Which is not the case if we omit the _id field. The following line show that.</p>
<pre>
{ "_id" : ObjectId("4c9b813a032447e454de036b"), "aggregateIdentifier" : "cbc79934-8cb6-4062-aa6e-205b3960901e", "sequenceNumber" : NumberLong( 0 ), "timeStamp" : "2010-09-23T18:32:58.738", "type" : "OrderBook", "serializedEvent" : BinData(2,"tgEAADxvcmcuYXhvbmZyYW1ld29yay5zYW1wbGVzLnRyYWRlci5hcHAuYXBpLk9yZGVyQm9va0NyZWF0ZWRFdmVudD48dGltZXN0YW1wPjIwMTAtMDktMjNUMTg6MzI6NTguNzM4PC90aW1lc3RhbXA+PGV2ZW50SWRlbnRpZmllcj5hNTEyNGI5Yi0zZDYyLTQ1OTQtODBjOS1jYmE0YzI2OGZkZjM8L2V2ZW50SWRlbnRpZmllcj48c2VxdWVuY2VOdW1iZXI+MDwvc2VxdWVuY2VOdW1iZXI+PGFnZ3JlZ2F0ZUlkZW50aWZpZXI+Y2JjNzk5MzQtOGNiNi00MDYyLWFhNmUtMjA1YjM5NjA5MDFlPC9hZ2dyZWdhdGVJZGVudGlmaWVyPjx0cmFkZUl0ZW1JZGVudGlmaWVyPjQ3MzAyMzIwLTRhZjktNDVjZS1hMWI0LTk2MDk0ZGRjNGJkMDwvdHJhZGVJdGVtSWRlbnRpZmllcj48L29yZy5heG9uZnJhbWV3b3JrLnNhbXBsZXMudHJhZGVyLmFwcC5hcGkuT3JkZXJCb29rQ3JlYXRlZEV2ZW50Pg==") }
</pre>
<p>Back to the situation where we do provide our own _id field. MongoDB does create the index even if we provide our own field. The following query shows the index :</p>
<pre>
&gt; db.domainevents.getIndexes()
[
	{
		"name" : "_id_",
		"ns" : "axonframework.domainevents",
		"key" : {
			"_id" : 1
		}
	}
]
</pre>
<p>By providing an index, you immediately assure that the content of that field is unique. This is something you can use for other fields as well. This is the topic for the next section.</p>
<h2>Unique documents</h2>
<p>The following line shows you how to create an index. In our example we will not use the aggregateIdentifier as _id, but we do want it to be unique and we want to search on it fast. Therefore we need an index. We will have a look at this next, but as promised first a sample of adding an index.</p>
<pre>
db.things.ensureIndex({firstname: 1, lastname: 1}, {unique: true});
</pre>
<p>Now let us have a look at our own example. First the proof, no index on aggregateIdentifier.</p>
<pre>
&gt; db.domainevents.getIndexes()
[
	{
		"name" : "_id_",
		"ns" : "axonframework.domainevents",
		"key" : {
			"_id" : 1
		}
	}
]
</pre>
<p>Now we add an index on the aggregateIdentifier</p>
<pre>
&gt; db.domainevents.ensureIndex({aggregateIdentifier:1},{unique:1})
&gt; db.domainevents.getIndexes()
[
	{
		"name" : "_id_",
		"ns" : "axonframework.domainevents",
		"key" : {
			"_id" : 1
		}
	},
	{
		"_id" : ObjectId("4c9b900dbfe62c324f170e85"),
		"ns" : "axonframework.domainevents",
		"key" : {
			"aggregateIdentifier" : 1
		},
		"name" : "aggregateIdentifier_1",
		"unique" : 1
	}
]
</pre>
<p>Notice that we have two indexes now. The one for _id is a special one, the one for aggregateIdentifier is just a document in Mongo as well. Therefore it has its own ObjectId. The _id_ index does not have the unique parameter. But because it is special, the values need to be unique. That is all nice, but a bit hard to test with an Axonframework sample I am creating. Another thing I need in the sample is a unique username. Therefore we create a special collection with the _id equal to the username. Let us watch what happens. For now I do it in the shell</p>
<pre>
&gt; db.users.insert({_id:"jettro"})
&gt; db.users.getIndexes()
[
	{
		"name" : "_id_",
		"ns" : "axonframework.users",
		"key" : {
			"_id" : 1
		}
	}
]
&gt; db.users.insert({_id:"allard"})
&gt; db.users.insert({_id:"jettro"})
E11000 duplicate key error index: axonframework.users.$_id_  dup key: { : "jettro" }
</pre>
<p>Ok, so I proved that. Don&#8217;t believe me? Try it out yourself, it is not hard.</p>
<p>There is a lot to tell about indexes, if you want to know everything, check the online manual (see later on). Some of the things that I think are interesting are the following:</p>
<ul>
<li>You can give an index an order, which is especially interesting for doing range queries in multi value indexes.</li>
<li>You can add uniqueness to an index, already showed that.</li>
<li>Indexes are case oriented</li>
<li>Preferably do not use a sort on a field that does not have an index</li>
</ul>
<p>To learn more about indexes and MongoDB go here : <a href="http://www.mongodb.org/display/DOCS/Indexes">http://www.mongodb.org/display/DOCS/Indexes</a></p>
<h2>MapReduce</h2>
<p>http://www.mongodb.org/display/DOCS/MapReduce</p>
</p>
<h2>Sharding</h2>
<p>Sharding is about horizontal scalability. If you have a large ordering website like amazon. Shards for the different locations seems logical. Order data for users in Europe are on a different shard than those for american customers. Mongo has two clear requirements for shards. They must be able to balance load over shards as well as support good failover within a shard. Failover is achieved by creating a shard out of a replica set.</p>
<p>Let us have a look at running a server farm with MongoDB sharding, on one local dev machine <img src='http://www.gridshore.nl/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> . You might want to have a look at the official documentation for <a href="http://www.mongodb.org/display/DOCS/Configuring+Sharding">sharding configuration</a>.</p>
<p>To set up the environment, we create two shards with one server each. We need a config server and a router server. I&#8217;ll show you aliases I use on my mac to start them.</p>
<pre>
alias mongoshard1="mongod --shardsvr --port 27017 --dbpath /data/s0 --rest"
alias mongoshard2="mongod --shardsvr --port 27018 --dbpath /data/s1 --rest"
alias mongoconfig="mongod --configsvr --port 27019 --dbpath /data/config --rest"
alias mongorouter="mongos --configdb localhost:27019 --port 27020"
</pre>
<p>Than we need to configure the shards, the config and the router. That is done in the next few lines</p>
<pre>
mongo localhost:27020
&gt; use admin
switched to db admin
&gt; db.runCommand( { addshard : "localhost:27017" } )
{ "shardAdded" : "shard0000", "ok" : 1 }
&gt; db.runCommand( { addshard : "localhost:27018" } )
{ "shardAdded" : "shard0001", "ok" : 1 }
&gt; db.runCommand( { enablesharding : "axonframework" } )
{ "ok" : 1 }
&gt; db.runCommand( { shardcollection : "axonframework.type", key : {name : 1} } )
{ "collectionsharded" : "axonframework.type", "ok" : 1 }
</pre>
<p>Now you are done. Ok, this is very basic. Do check the documentation I mentioned before. In the future I&#8217;ll give more info on this topic, but for now this is it.</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%2F27%2Fstill-learning-mongodb%2F&amp;title=Still%20learning%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/27/still-learning-mongodb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<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>My first steps with Gradle: creating a multi module java web project and running it with jetty.</title>
		<link>http://www.gridshore.nl/2010/09/08/my-first-steps-with-gradle-creating-a-multi-module-java-web-project-and-running-it-with-jetty/</link>
		<comments>http://www.gridshore.nl/2010/09/08/my-first-steps-with-gradle-creating-a-multi-module-java-web-project-and-running-it-with-jetty/#comments</comments>
		<pubDate>Wed, 08 Sep 2010 09:34:06 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[groovy and grails]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[gradle]]></category>
		<category><![CDATA[intellij]]></category>
		<category><![CDATA[jetty]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[wrapper]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=1077</guid>
		<description><![CDATA[<p>I am a experienced maven user. Sometime I love it, sometimes I hate it. I like it a lot better than ant, but in some situation you would like maven to be easier and more descriptive. The past year there was a lot of fuzz about Gradle. This would give you the best of [...]]]></description>
			<content:encoded><![CDATA[<p>I am a experienced maven user. Sometime I love it, sometimes I hate it. I like it a lot better than ant, but in some situation you would like maven to be easier and more descriptive. The past year there was a lot of fuzz about Gradle. This would give you the best of ant as well as the best of maven, and even more. My first encounter was not very positive, but I kept it in my mind to try it later with a more serious project. This blogpost is about that second more serious try. It will not teach the gradle experts anything, but it will be an easy introduction in to what gradle has to bring for people that are just interested in gradle.</p>
<p><span id="more-1077"></span><br />
<h2>Project structure</h2>
<p>The structure of the project is fairly straightforward, but big enough to demonstrate some of the features that gradle has to offer. It consists of two modules:</p>
<ul>
<li>App</li>
<li>Web-ui</li>
</ul>
<p>We are creating an <a href="http://www.axonframework.org">Axonframework</a> sample, the app contains the command handling and for now the query part as well. The web-ui contains the spring mvc app with the controllers and the authentication using the spring-security framework. For now we make use of an in memory database and we want to be able to start the application without a lot of hassle. Using jetty in this case.</p>
<p>The modules have some shared dependencies for testing and logging. We also want to centralize the definition of some dependency versions.</p>
<h2>Multi module gradle build</h2>
<p>Gradle was build with multi module support from the start. So what do you need to create a multi-module build. We need a settings.gradle that defines the available modules. Next to that we need the main build.gradle as well as the modules build.gradle. Oke you can do without the per module configuration, but in my case that was not the intention. Let us focus first on the main build.gradle.</p>
<h3>Main build.gradle</h3>
<p>The main build.gradle is used to define some of the versions of the dependencies. The following code block shows the complete script.</p>
<pre class="brush: groovy; title: ; notranslate">
axonVersion = &quot;0.6&quot;
springVersion = &quot;3.0.4.RELEASE&quot;
springSecurityVersion = &quot;3.0.3.RELEASE&quot;
slf4jVersion = &quot;1.5.8&quot;
sourceCompatibility = 1.6

subprojects {
    apply plugin: 'java'

    configurations {
        all*.exclude group: &quot;commons-logging&quot;, module: &quot;commons-logging&quot;
    }

    repositories {
        mavenCentral()
    }

    dependencies {
        compile &quot;org.slf4j:jcl-over-slf4j:$slf4jVersion&quot;,
                &quot;org.slf4j:jul-to-slf4j:$slf4jVersion&quot;
        runtime &quot;org.slf4j:slf4j-log4j12:$slf4jVersion&quot;

        compile(&quot;log4j:log4j:1.2.15&quot;) {
            exclude group: &quot;com.sun.jdmk&quot;, module: &quot;jmxtools&quot;
            exclude group: &quot;com.sun.jmx&quot;, module: &quot;jmxri&quot;
            exclude group: &quot;javax.mail&quot;, module: &quot;mail&quot;
            exclude group: &quot;javax.jms&quot;, module: &quot;jms&quot;
        }

        testCompile 'junit:junit:4.7'
    }

    group = 'org.axonframework.samples.trader'
    version = '1.0-SNAPSHOT'
    sourceCompatibility = 1.6
}
</pre>
<p>As you can see, the script starts with the definition of the versions of dependencies. Than the script contains information for all the subprojects. You see we define the java plugin for all subprojects. Next to that the repositories and the dependencies are defined. Have a look at the mechanism to exclude transitive dependencies. For log4j we explicitly exclude some transitive dependencies. We also use a mechanism to exclude commons-logging from the complete build. Using the configurations hook we exclude it for all phases.</p>
<p>Finally we also define the group, version and source compatibility in the build configuration.</p>
<p>That is it, the following code block shows the required settings.gradle and after that we move on with the build.gradle of the app and web-ui subprojects.</p>
<pre class="brush: groovy; title: ; notranslate">
include &quot;app&quot;, &quot;web-ui&quot;
</pre>
<h3>Subprojects build.gradle</h3>
<p>The build.gradle for the app project is almost to easy to show. But I promised I would, so here we go:</p>
<pre class="brush: groovy; title: ; notranslate">
dependencies {
    compile &quot;org.axonframework:axon-core:$axonVersion&quot;

    compile &quot;org.hibernate:hibernate-entitymanager:3.4.0.GA&quot;,
            &quot;c3p0:c3p0:0.9.1&quot;,
            &quot;org.hsqldb:hsqldb:1.8.0.10&quot;

    compile &quot;org.springframework:spring-tx:$springVersion&quot;,
            &quot;org.springframework:spring-orm:$springVersion&quot;,
            &quot;org.springframework:spring-jdbc:$springVersion&quot;

    compile &quot;com.thoughtworks.xstream:xstream:1.3.1&quot;

    testCompile &quot;org.axonframework:axon-test:$axonVersion&quot;
}
</pre>
<p>The configuration only contains dependencies. I would like to be able to simplify the dependencies on the spring projects. Would be nice if I could group them somehow, like:</p>
<p>compile group:&#8221;org.springframework&#8221;, version:&#8221;$springVersion&#8221;, module:["spring-webmvc", "spring-aop"]</p>
<p>But the build config looks pretty clean. Now we move on to the creation of the war for the web project.</p>
<pre class="brush: groovy; title: ; notranslate">
apply plugin: 'war'

dependencies {
    compile project(':app')

    compile &quot;org.springframework:spring-webmvc:$springVersion&quot;,
            &quot;org.springframework:spring-aop:$springVersion&quot;

    compile &quot;org.springframework.security:spring-security-web:$springSecurityVersion&quot;,
            &quot;org.springframework.security:spring-security-config:$springSecurityVersion&quot;

    compile &quot;javax.validation:validation-api:1.0.0.GA&quot;,
            &quot;org.hibernate:hibernate-validator:4.0.2.GA&quot;

    runtime &quot;javax.servlet:jstl:1.1.2&quot;,
            &quot;taglibs:standard:1.1.2&quot;,
            &quot;opensymphony:sitemesh:2.4.2&quot;

    providedCompile &quot;javax.servlet:servlet-api:2.5&quot;
}
</pre>
<p>Again a pretty straightforward config. We use more types of dependencies. We now introduce the providedCompile. Jars that need not be included in the war should have this config for the dependency. Do mark that we have an apply plugin line at the top for creating the war. Finally have a look at the mechanism to show we have a dependency on another module of the project. We use the <strong>compile project (&#8216;:app&#8217;) </strong>to make the war include this created jar as well.</p>
<h2>Running with Jetty</h2>
<p>You think the jetty plugin for maven is easy, well check this out. We have to change only one word in the web project config. Look for the first line with <strong>apply plugin</strong>. Change the word war into jetty and you are done. Now you can run jetty with the following command from the root of the project:</p>
<p><em>gradle :web-ui:jettyRun</em></p>
<h2>The wrapper</h2>
<p>People that have gradle installed on their system can easily build the project and run jetty. But some people might not have gradle installed. You can help them to make it very easy. Gradle comes with a wrapper that downloads gradle and makes sure it&#8217;s on your path etc. The only thing the user needs to do is the following in the root of the project:</p>
<p><em>gradlew build</em></p>
<p>Pay attention to the &#8216;w&#8217; at the end of the gradle command. Next step is to start jetty. This is done with the same command as before with one change, the w at the end. To help your users with this, you need to do one thing. You have to add the following task to the main build.gradle. Than run gradle wrapper, checkin the generated files into your source control system. The gradlew script can be used by the people to build the project. Good stuff or not?</p>
<pre class="brush: groovy; title: ; notranslate">
task wrapper(type: Wrapper) {
    gradleVersion = '0.9-rc-1'
    jarPath = 'wrapper'
}
</pre>
<h2>Intellij integration</h2>
<p>Oke, this kinda hurts to say, but intellij support is not at a level that you would like to. At least that is what I could find out. You can easily run gradle builds from intellij. That is all nice. But I am really missing the dependency management part. Would be great to have support like for maven to setup your complete project. Wouldn&#8217;t it be great to have the import from external model feature for gradle as well? For now let us all vote for this issue, it might help:</p>
<p><a href="http://youtrack.jetbrains.net/issue/IDEA-57755">﻿http://youtrack.jetbrains.net/issue/IDEA-57755</a></p>
<p>I hope someone from jetbrains reeds this at thinks I am important enough to start creating this plugin <img src='http://www.gridshore.nl/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<h2>Performance</h2>
<p>The last remarks I want to make are about the performance of gradle. At the moment I have this build for maven as well as gradle and maven2 is twice as fast as gradle. I know work is being done on this. Gradle 0.9.1 will support a new feature that at least will speed up building the project of you have to do it a lot during the day. It will do something with a running gradle service that you can call each time you start a build. There are some items on the mailing list about this specific topic if you are interested.</p>
<p><a href="http://gradle.markmail.org/thread/xbqna6lowvsmm4ve">http://gradle.markmail.org/thread/xbqna6lowvsmm4ve</a></p>
<h2>Concluding</h2>
<p>Well that was part one of the experiment. I have not touched everything by a long run. Still I found out I like the configuration of gradle a lot better than I like maven. It is a lot cleaner and let&#8217;s you focus on the things that are important. I prefer groovy for this kind of work over xml. Still gradle has some ground to cover. For starters, tool integration. We must have something that makes working with intellij a lot better. In the future I will have a better look at plugins for release management and other stuff that I think is necessary for a good project build.</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%2F08%2Fmy-first-steps-with-gradle-creating-a-multi-module-java-web-project-and-running-it-with-jetty%2F&amp;title=My%20first%20steps%20with%20Gradle%3A%20creating%20a%20multi%20module%20java%20web%20project%20and%20running%20it%20with%20jetty.&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/08/my-first-steps-with-gradle-creating-a-multi-module-java-web-project-and-running-it-with-jetty/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>An evening on the Go</title>
		<link>http://www.gridshore.nl/2010/07/28/an-evening-on-the-go/</link>
		<comments>http://www.gridshore.nl/2010/07/28/an-evening-on-the-go/#comments</comments>
		<pubDate>Tue, 27 Jul 2010 23:47:44 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/2010/07/28/an-evening-on-the-go/</guid>
		<description><![CDATA[<p>Last Thursday (July 22nd, 2010) Rob Pike, a Principal Engineer at Google, gave a talk at the O&#8217;Reilly Open Source conference. In this talk he stated that established languages such as C++ and Java are too complex and not adequately suited for today&#8217;s computing environments. He then proceeded with some criticism of dynamically typed [...]]]></description>
			<content:encoded><![CDATA[<p>Last Thursday (July 22nd, 2010) <a title="Rob Pike" href="http://research.google.com/people/r/index.html">Rob Pike</a>, a Principal Engineer at Google, gave a talk at the O&#8217;Reilly Open Source conference. In this talk he stated that established languages such as <a title="C++" href="http://en.wikipedia.org/w/index.php?title=C%2B%2B&amp;oldid=374538072">C++</a> and <a title="Java" href="http://en.wikipedia.org/w/index.php?title=Java_(programming_language)&amp;oldid=374887455">Java</a> are too complex and not adequately suited for today&#8217;s computing environments. He then proceeded with some criticism of dynamically typed languages (that I share) and finally ended up plugging the <a href="http://golang.org">Go language</a> (which he co-developed) as a solution to the problem.</p>
<p>Now, Rob Pike is not nobody (in addition to being a Google principle engineer he has C and Unix credentials), plus the Go language has the Google brand name on it, so I thought it would be a good idea to check it out&#8230;. </p>
<p><span id="more-1067"></span>
<p>&nbsp;</p>
<h3>Evaluating Go</h3>
<p>The <a href="http://golang.org">Go programming language</a> is described on the website as a language geared towards system programming. That is to say, it is a new(ish), general purpose programming language developed internally at Google to scratch an itch some of their developers had and they then decided to open source it.</p>
<p>Evidently, judging from Rob Pike&#8217;s talk at O&#8217;Reilly, it is also intended to be a simpler alternative to C++ and Java and a more robust alternative to dynamically typed languages such as Ruby, Python and such. It is this claim that I felt was particularly intriguing, so I took a look at the language this evening by reading through the <a href="http://golang.org/doc/go_spec.html">language spec</a> and briefly glancing at the <a href="http://golang.org/doc/go_tutorial.html">tutorials</a>.</p>
<p>&nbsp;</p>
<h3>Creak, creak&#8230;</h3>
<p>Well, let&#8217;s address the great big elephant in the room immediately: it would seem that &#8220;simpler alternative&#8221; is Google-speak (or Pike-speak) for &#8220;forty five years old&#8221;. It&#8217;s had a spit-polish plus language features and libraries added, but there&#8217;s no way around it — Go is a rehash of the C programming language with some Pascal thrown in for good measure. Not surprising of course, given Rob&#8217;s background, but perhaps not the great linguistic revolution you would have expected.</p>
<p>Just to reassure you all, I&#8217;m not exaggerating: Go is essentially C, including structs, pointers and reams of different (un)signed int types. It even includes everyone&#8217;s favorite cross-platform language feature: numeric types whose size is architecture-dependent.</p>
<p>&nbsp;</p>
<h4>Spit-shine</h4>
<p>That&#8217;s not to say that some improvements have not been made to cover up some of the glaring problems that made C and C++ hard to handle: extern is gone as a concept, as is pointer arithmetic. Plus Go has a type definition feature, so you don&#8217;t need macro&#8217;s anymore. Also, Go has some more built-in types (such as complex numbers), support for Unicode and it can insert semicolons where needed and has both escaped and unescaped strings (both borrowed from Bourne Shell). And it places the type behind the identifier instead of in front and uses := as an assignment to distinguish from equality (borrowing from Pascal).</p>
<p>&nbsp;</p>
<h4>Back from the dead</h4>
<p>&nbsp;</p>
<p>Nevertheless, not all is well with the world. Like it&#8217;s ancestors Go still relies on an ability to export named entities (including variables), meaning you can get into the global variable mess. And guess what&#8217;s back from the dead: the goto statement, in its <a href="http://userweb.cs.utexas.edu/users/EWD/transcriptions/EWD02xx/EWD215.html">full and glorious horror</a>.</p>
<p>&nbsp;</p>
<h3>So what else is new?</h3>
<p>At the core of it, Go is a component-based language. It&#8217;s main architectural feature for this is the <em>package</em>, which isn&#8217;t much like Java but rather borrows from the Unit found in Turbo Pascal: a collection of exported types and identifiers, with hidden implementations. Packages serve as libraries in the language and are the main strength and source of language functionality.</p>
<p>In the spirit of &#8220;this is your grandfather&#8217;s technology&#8221;, Go is not an object-oriented language. Instead it is fully procedural and uses the <a href="http://en.wikipedia.org/wiki/Abstract_data_type">abstract data type</a> as its main means of abstraction. Admittedly, this is a good combination with the Unit-like library. The ADT concept has been bolstered with real language support to keep ADT functions and data structures together though. Even though the main data structures are C-style structs, the language includes the concept of a method (which is a function that is sort of legoed into a data type, creating the effect of putting a function pointer into a struct in C). Methods directly associate a callable code block with a data structure, so it&#8217;s sort of like adding real behavior to your basic data type. That&#8217;s a pretty good concession to OO thinking sure enough, but encapsulation beyond the package level and inheritance are still out.</p>
<p>The other major feature of the language is built-in concurrency modeled on <a href="http://en.wikipedia.org/wiki/C._A._R._Hoare">Tony Hoare&#8217;s</a> <a href="http://en.wikipedia.org/wiki/Communicating_sequential_processes">Communicating Sequential Processes</a>. This is a brand of concurrency that is not based around the classic &#8220;multi-process, shared single memory&#8221; model but around a &#8220;multi-process, multi-memory&#8221; model whereby processes are linked together by channels. Each process can &#8220;toss&#8221; values to another process over a channel (or &#8220;catch&#8221; values coming in across a channel). These operations block until succeeded, which allows for synchronization. The mechanism has been proven equally powerful as <a href="http://en.wikipedia.org/wiki/Edsger_W._Dijkstra">Dijkstra&#8217;s</a> standard <a href="http://en.wikipedia.org/wiki/Semaphore_(programming)">semaphore</a> mechanism. This is once again a typical choice for someone with Rob Pike&#8217;s background as this mechanism is also included in the Bourne Shell in the form of <a href="http://en.wikipedia.org/wiki/Named_pipe">named pipes</a>. Of course in such a language it must also be easy to start threads or fork subprocesses and indeed this can be accomplished with the use of a single statement.</p>
<p>&nbsp;</p>
<h3>So what are we to make of this&#8230;</h3>
<p>The Go programming language is an interesting combination of proven language features and program architectures. Rooted firmly in the Pascal/C/Bourne Shell era, it seems a bit of a museum of 1960&#8242;s language design ideas geared towards the hardware systems environment of that era&#8217;s dreams (and possibly today&#8217;s reality): heavily multiprocessed with the distinction between local and distributed processing disappeared into the background, using ADT and component-based modularity to achieve separation of concerns.</p>
<p>&nbsp;</p>
<h3>&#8230; except perhaps a bonfire?</h3>
<p>&nbsp;</p>
<p>And yet, I can&#8217;t say that I&#8217;m overly impressed with Go. Mostly I don&#8217;t see the point. Sure, its well-suited to the multiprocessing environment that we have nowadays. But its support for domain modeling and domain driven design is poor, based as it is on the ADT concept — a serious failing in a modern language if you ask me. And a language that isn&#8217;t architecture independent in a Cloud-based platform era? Come on&#8230; But most of all I don&#8217;t see the new language idea that is supposed to make this language better than all others. I don&#8217;t see a refreshing combination of functional and OO paradigms like Scala, or an &#8220;easily-typed shell over a large Java class library&#8221; like Groovy. I don&#8217;t really see what Google thinks it has accomplished with Go.</p>
<p>In addition to that, I don&#8217;t see proof for the claim of simplicity. Sure, it covers up the worst pointer-related problems in C/C++. Sure, multithreading is less verbose than it is in Java. But on the whole the language is no simpler than Java, as far as I&#8217;m concerned. I don&#8217;t like the lacking encapsulation, the poor man&#8217;s OSGi modularity, the way methods are tacked on to external data types rather than syntactically part of data structures. And I don&#8217;t think first-class lambda functions (popularly called closures) are all that special and I don&#8217;t think that having channels as a built-in language element is a great advantage over having them in a separate library (like C++ or Java do).</p>
<p>So what do I think of Go&#8217;s future? Well, it certainly has one major weapon in its arsenal: the Google logo, which still makes everything cool that it touches. So Go might get somewhere based on that. But on its own merits I can&#8217;t think of any reason to prefer it over another language.</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%2F07%2F28%2Fan-evening-on-the-go%2F&amp;title=An%20evening%20on%20the%20Go&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/07/28/an-evening-on-the-go/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Upgraded wordpress and the atahualpa theme</title>
		<link>http://www.gridshore.nl/2010/06/19/upgraded-wordpress-and-the-atahualpa-theme/</link>
		<comments>http://www.gridshore.nl/2010/06/19/upgraded-wordpress-and-the-atahualpa-theme/#comments</comments>
		<pubDate>Sat, 19 Jun 2010 18:03:10 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=1062</guid>
		<description><![CDATA[<p>I have just upgraded the wordpress software to version 3. It all seemed to work fine. However I noticed errors in the archive pages. Therefore I wanted to upgrade to the latest and greatest atahualpa theme that I use for my blog. I should not promote it to much, or else everybody else starts [...]]]></description>
			<content:encoded><![CDATA[<p>I have just upgraded the <strong>wordpress</strong> software to version 3. It all seemed to work fine. However I noticed errors in the archive pages. Therefore I wanted to upgrade to the latest and greatest <strong>atahualpa</strong> theme that I use for my blog. I should not promote it to much, or else everybody else starts using it <img src='http://www.gridshore.nl/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .</p>
<p>To my opinion, the blog looks even better. The twitter items look better than before as well as the authors with the amount of blog items.</p>
<p>If you spot problems, please let me know.</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%2F06%2F19%2Fupgraded-wordpress-and-the-atahualpa-theme%2F&amp;title=Upgraded%20wordpress%20and%20the%20atahualpa%20theme&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/06/19/upgraded-wordpress-and-the-atahualpa-theme/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Creating a sample for axon using flex and parsley</title>
		<link>http://www.gridshore.nl/2010/02/25/creating-a-sample-for-axon-using-flex-and-parsley/</link>
		<comments>http://www.gridshore.nl/2010/02/25/creating-a-sample-for-axon-using-flex-and-parsley/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 10:46:37 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[Axon Framework]]></category>
		<category><![CDATA[Frontend Technology]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[axon]]></category>
		<category><![CDATA[BlazeDS]]></category>
		<category><![CDATA[flex]]></category>
		<category><![CDATA[parsley]]></category>
		<category><![CDATA[spring 3]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=1013</guid>
		<description><![CDATA[<p>The last weeks or maybe even months, I have spent time getting to understand the Axon Framework created by Allard. Axon is a framework that can help developers created a scalable and maintainable application based on Command Query Responsibility Segregation (CQRS) principles. Each morning Allard and I discussed the framework and the sample we [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.gridshore.nl/wp-content/uploads/axon_logo.png" alt="axon_logo.png" border="0" width="55" height="55" align="left" />The last weeks or maybe even months, I have spent time getting to understand the Axon Framework created by Allard. Axon is a framework that can help developers created a scalable and maintainable application based on Command Query Responsibility Segregation (CQRS) principles. Each morning Allard and I discussed the framework and the sample we wanted to have. Since I know my way around flex and Axon makes heavily use of events, I decided to create a flex client that could demonstrate some cool features of the Axon framework.</p>
<p><img src="http://www.gridshore.nl/wp-content/uploads/parsley-spicelib-vert.jpg" alt="parsley-spicelib-vert.jpg" border="0" width="156" height="40" align="left" />This post is mainly about flex and <a href="http://www.spicefactory.org/parsley/">Parsley</a>. We will go into depth of the architecture of the client and how to talk to the server. I will describe the communication with the application that makes use of the axon framework, but I will not go into a lot of details. If you want more information about the Axon Framework I suggest you go to the website <a href="http://www.axonframework.org">http://www.axonframework.org</a>. There is good documentation available in the reference manual. If you want to learn about flex and the Parsley framework in general, please read on.</p>
<p><span id="more-1013"></span><br />
<h2>What is Parsley and why use it?</h2>
<p>Parsley is all about decoupling. It is a dependency injection framework and is has strong support for messaging. I like the way the dependency injection as well as message handling is configured. By using [INJECT] on a parameter, you tell parsley to inject an object of the type as specified by the parameter. We will see examples of the usage later on. Other things to inject are the [MessageDispatcher] that enables dispatching messages from each component.</p>
<p>The final component I want to mention is the <strong>DynamicCommand object</strong>. I use it more as a controller, still it is an interesting concept. We create one component that receives a message, does a remote call and handles the result of that call. All in one object. Again, an example will follow later on.</p>
<h2>Structure of the Parsley solution</h2>
<p>The following image gives you an idea of the overall solution of parsley. The image shows you the relationship between the view components, the controllers and the model. Messages are send from the view to the controller. The controller interacts with the remote components, updates the model and determines which view should be active. The controllers can also respond to remote push notifications, more on that later on.</p>
<div style="text-align:center;"><img src="http://www.gridshore.nl/wp-content/uploads/parsley-overview.png" alt="parsley-overview.png" border="0" width="463" height="454" /></div>
<h3>Configure parsley</h3>
<p>To enable injection and message handling, parsley needs it&#8217;s own context to be setup. The easiest way to do this is using an mxml object and an mxml ContextBuilder object. The next code block shows you the complete configuration of the framework. Within the configuration you can see the controllers being configured as DynamicCommand objects. You also find there the RemoteObject, the Consumer and the model objects. They should all be familiar from the previous image.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;mx:Object xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot;
           xmlns:sf=&quot;http://www.spicefactory.org/parsley&quot;
           xmlns:commands=&quot;org.axonframework.examples.addressbook.commands.*&quot;
           xmlns:model=&quot;org.axonframework.examples.addressbook.model.*&quot;
           xmlns:cons=&quot;org.axonframework.examples.addressbook.consumer.*&quot;
        &gt;
    &lt;mx:RemoteObject
            id=&quot;remoteAddressService&quot;
            destination=&quot;addressService&quot;
            endpoint=&quot;messagebroker/amf&quot;
            showBusyCursor=&quot;true&quot;/&gt;
    &lt;cons:Consumer/&gt;

    &lt;sf:DynamicCommand type=&quot;{NewAddressController}&quot; messageType=&quot;{NewAddressMessage}&quot;/&gt;
    &lt;sf:DynamicCommand type=&quot;{NewContactController}&quot; messageType=&quot;{NewContactMessage}&quot;/&gt;
    &lt;sf:DynamicCommand type=&quot;{SearchAddressController}&quot; messageType=&quot;{SearchForAddressesMessage}&quot;/&gt;
    &lt;sf:DynamicCommand type=&quot;{SelectContactController}&quot; messageType=&quot;{SelectContactMessage}&quot;/&gt;
    &lt;sf:DynamicCommand type=&quot;{ShowContactsController}&quot; messageType=&quot;{ShowContactsMessage}&quot;/&gt;
    &lt;sf:DynamicCommand type=&quot;{UpdatedContactController}&quot; messageType=&quot;{UpdatedContactMessage}&quot;/&gt;
    &lt;sf:DynamicCommand type=&quot;{UpdatedContactAddressController}&quot; messageType=&quot;{UpdatedContactAddressMessage}&quot;/&gt;
    &lt;sf:DynamicCommand type=&quot;{RemoveAddressController}&quot; messageType=&quot;{RemoveAddressMessage}&quot;/&gt;
    &lt;sf:DynamicCommand type=&quot;{RemovedItemController}&quot; messageType=&quot;{RemovedItemMessage}&quot;/&gt;
    &lt;sf:DynamicCommand type=&quot;{RemoveContactController}&quot; messageType=&quot;{RemoveContactMessage}&quot;/&gt;

    &lt;model:AddressModel/&gt;
    &lt;model:ContactModel/&gt;

    &lt;mx:Script&gt;&lt;![CDATA[
        import org.axonframework.examples.addressbook.commands.*;
        import org.axonframework.examples.addressbook.messages.*;
        ]]&gt;&lt;/mx:Script&gt;
&lt;/mx:Object&gt;
</pre>
<p>That is all that parsley needs to know. The final step is to build the context using the special mxml tag. I have included the next tag in my Main.mxml.</p>
<pre>
	&lt;sf:ContextBuilder config="ParsleyConfiguration"/&gt;
</pre>
<p>Next we will focus on the different components</p>
<h3>Messages</h3>
<p>We make use of two types of messages:</p>
<ul>
<li>CommandMessage &#8211; tells the receiver to do something.</li>
<li>NotificationMessage &#8211; tells the receiver that something happened</li>
</ul>
<h3>View</h3>
<p>Each view component should focus on presenting data and sending messages. The data is injected as a model object. Messages can be dispatched by the special parsley provided dispatcher. Than parsley also provides a Context object that can be used when pop-ups are needed. The following code block shows you the configuration of these mentioned parameters from the <strong>ContactsView.mxml</strong> component. You can also find a function that is called by pushing a button to send a message to obtain details about a certain contact.</p>
<pre class="brush: jscript; title: ; notranslate">
[Inject]
[Bindable]
public var contactModel:ContactModel;
[MessageDispatcher]
public var dispatcher:Function;
[Inject]
public var context:Context;

private function showContactDetails(event:ListEvent):void {
    dispatcher(new SelectContactCommandMessage(event.currentTarget.selectedItem as Contact));
    currentState = 'detail';
}
</pre>
<p>This is all pretty straightforward, if you need the code check out the sources from the google code project. Let us follow what happens when obtain details button is pushed and the SelectContactMessage is dispatched. </p>
<h3>Controller</h3>
<p>By dispatching this message, parsley selects the <strong>SelectContactController</strong> since the argument of the execute method is that exact message. The following code block gives you the complete implementation of the SelectContactController. The super class of all controllers contains a method to handle the faults coming from the remote calls and it makes the dispatcher as well as the remote object available. This class is also in the code block. In the code check how the dispatcher, the RemoteObject and the contactModel are injected. Another thing to notice here is that we only go to the server if we have not cached the contact details locally. So what if the contact details get updated on the server? Or if new contacts are added on the server? More on that in the next section.</p>
<pre class="brush: jscript; title: ; notranslate">
public class BaseController {
    [MessageDispatcher]
    public var dispatcher:Function;

    [Inject(id=&quot;remoteAddressService&quot;)]
    public var addressService:RemoteObject;

    public function BaseController() {
        // default constructor
    }

    public function error(fault:Fault):void {
        dispatcher(new ErrorNotificationMessage(fault.faultString));
    }

}

public class SelectContactController extends BaseController {
    [Inject]
    public var contactModel:ContactModel;

    private var findAddressesFor:Contact;

    public function SelectContactController() {
        super();
    }

    public function execute(message:SelectContactCommandMessage):AsyncToken {
        var cachedContact:Contact = contactModel.findContactByIdentifier(message.contact.uuid);
        contactModel.selectedContact = cachedContact;
        findAddressesFor = cachedContact;

        if (!cachedContact.detailsLoaded) {
            return addressService.obtainContactAddresses(message.contact.uuid);
        }
        return null;
    }

    public function result(addresses:ArrayCollection):void {
        var cachedContact:Contact = contactModel.findContactByIdentifier(findAddressesFor.uuid);
        cachedContact.addresses = addresses;
        cachedContact.detailsLoaded = true;
    }
}
</pre>
<p>You have now seen the most important parts of the mechanism to go from a view to a controller. Did you notice that we send an <strong>ErrorNotificationMessage</strong> when something goes wrong in the server communication? The notification messages are handled in the <strong>OverallView</strong> component. Other notification messages are also handled in this component. The following code block gives a piece of code that handles the message.</p>
<pre class="brush: jscript; title: ; notranslate">
[MessageHandler]
public function handleActivityLogEvent(message:NotificationMessage):void {
    createNotification(message.message, Notification.INFO);
}
</pre>
<h2>Communication with the server</h2>
<p>The server is used to send data to and of course to obtain data from. The easiest way is when the flex client takes control. As we saw in the parsley configuration, the remote object is configured as you would in any flex client. In the code from the SelectContactController we can see the call to the server. The result function is called when the server returns a result. This is not very complicated to understand.</p>
<p>Let us have a look at how this is handled on the server. Using spring blazeds integration this becomes very easy as well</p>
<h3>BlazeDS and Spring BlazeDS Integration</h3>
<p>Doing flex remoting with the Spring BlazeDS integration is so easy that anybody can use it. In the web.xml you configure the dispatcher servlet. The config file is loaded using the following tag in a spring configuration file.</p>
<pre>
&lt;flex:message-broker services-config-path="classpath*:services-config.xml"/&gt;
</pre>
<p>Now I use annotations to explicitly export some of the functions as remote services. The following code block gives you the example of obtaining address details for a contact. Notice that the name of the method is the same as the method call used in the flex code. By adding the annotation @RemotingInclude we tell spring to expose this as a remote service using BlazeDS.</p>
<pre class="brush: java; title: ; notranslate">
    @RemotingInclude
    public List&lt;AddressDTO&gt; obtainContactAddresses(String contactIdentifier) {
        List&lt;AddressDTO&gt; foundAddresses = new ArrayList&lt;AddressDTO&gt;();

        List&lt;AddressEntry&gt; addressesForContact =
                repository.findAllAddressesForContact(UUID.fromString(contactIdentifier));
        for (AddressEntry entry : addressesForContact) {
            foundAddresses.add(AddressDTO.createFrom(entry));
        }
        return foundAddresses;
    }
</pre>
<p>The repository is based on the query database of Axon. I am not going into all the Axon Framework details here. Check the references if you want to learn more about Axon.</p>
<p>That is all there is to it, now you can obtain data from the server. Sending data to the server is done exactly the same.</p>
<h2>Receiving events</h2>
<p>I already mentioned that we cache data in the flex client. Still we want to have up-to-date data. Using the Axon framework and Spring BlazeDS integration it is not hard to push data to the client from the server when new or updated data is available. Again this blog does not have the intention to fully discuss the axon framework.</p>
<h3>Catching and dispatching events on the server</h3>
<p>We focus on the event that a new contact is created. The following code shows how you can register a listener for new contacts being created using the Axon framework. The listener makes use of the <strong>UpdateMessageProducerForFlex</strong>. Axon registers listeners based on the annotation @EventHandler and the argument of the method, in this case the <strong>ContactCreatedEvent</strong>.</p>
<pre class="brush: java; title: ; notranslate">
private UpdateMessageProducerForFlex producer;
@EventHandler
public void handleContactCreatedEvent(ContactCreatedEvent event) {
    logger.debug(&quot;Received and event with name {} and identifier {}&quot;, event.getName(), event.getEventIdentifier());
    ContactDTO contactDTO = new ContactDTO();
    contactDTO.setName(event.getName());
    contactDTO.setUuid(event.getAggregateIdentifier().toString());
    producer.sendContactUpdate(contactDTO);
}
</pre>
<p>This is the Axon part, the producer is used to send the message to the clients. Sending the message to the flex client is done using the spring BlazeDS integration. The following piece of code shows the producer. After that the configuration of the server.</p>
<pre class="brush: java; title: ; notranslate">
public class UpdateMessageProducerForFlex {
    private MessageTemplate template;

    @Autowired
    public UpdateMessageProducerForFlex(MessageTemplate template) {
        this.template = template;
    }

    public void sendContactUpdate(final ContactDTO contactDTO) {
        template.send(contactDTO);
    }
}
</pre>
<pre class="brush: xml; title: ; notranslate">
    &lt;flex:message-destination id=&quot;event-bus&quot;/&gt;

    &lt;bean id=&quot;defaultMessageTemplate&quot; class=&quot;org.springframework.flex.messaging.MessageTemplate&quot;&gt;
        &lt;property name=&quot;defaultDestination&quot; value=&quot;event-bus&quot;/&gt;
    &lt;/bean&gt;
</pre>
<p>The value for the default destination &#8220;<strong>event-bus</strong>&#8221; is very important. This needs to be configured in the client as well. Speaking of the client &#8230;</p>
<h3>Catching and dispatching events at the client</h3>
<p>Within the parsley configuration we have configured an object called Consumer. This object configures the client side of the poller and registers it on startup. This registration needs to be done at the right time. Parsleys provides the [Init] notation for that.</p>
<p>The consumer receives messages from the server and dispatches new Notification messages to the client side application. Controller objects pick up these events and update the model. The following code block shows the complete consumer object. Notice the configuration of the ChannelSet and the consumer.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;mx:Object xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot;&gt;
    &lt;mx:Script&gt;&lt;![CDATA[
        [Init]
        public function init():void {
            consumer.subscribe();
        }

        [MessageDispatcher]
        public var dispatcher:Function;

        public function messageHandler(event:MessageEvent):void {
            if (event.message.body is Contact) {
                dispatcher(new UpdatedContactNotificationMessage(event.message.body as Contact));
            } else if (event.message.body is Address) {
                dispatcher(new UpdatedContactAddressNotificationMessage(event.message.body as Address))
            } else if (event.message.body is Removed) {
                dispatcher(new RemovedItemNotificationMessage(event.message.body as Removed));
            }

        }

        public function faultHandler(event:Event):void {
            dispatcher(new ErrorNotificationMessage(&quot;Fault while receiving message&quot; + event.toString()))
        }

        ]]&gt;&lt;/mx:Script&gt;
    &lt;mx:Consumer id=&quot;consumer&quot; destination=&quot;event-bus&quot; channelSet=&quot;{cs}&quot; message=&quot;messageHandler(event)&quot;
                 fault=&quot; faultHandler(event)&quot;/&gt;

    &lt;mx:ChannelSet id=&quot;cs&quot;&gt;
        &lt;mx:AMFChannel url=&quot;messagebroker/pollingamf&quot;/&gt;
    &lt;/mx:ChannelSet&gt;

&lt;/mx:Object&gt;
</pre>
<h2>Wrapping up</h2>
<p>That is it. We have touched all components. I like how clean you can develop flex clients using Parsley and how easy it is to interact with a server using the Spring BlazeDS integration. Also the way to handle events using Axon makes this a very nice way to keep the data in your flex client up to date.</p>
<p>Hope you likes the sample, sources can be found in google code. Check the addressbook sample project of the axon framework.</p>
<p>The following image shows a screendump of the sample, after that are some references.</p>
<div style="text-align:center;"><img src="http://www.gridshore.nl/wp-content/uploads/Screen-shot-2010-02-18-at-13.49.13.png" alt="Screen shot 2010-02-18 at 13.49.13.png" border="0" width="1120" height="576" /></div>
<ul>
<li><a href="http://code.google.com/p/axonframework/source/browse">http://code.google.com/p/axonframework/source/browse</a></li>
<li><a href="http://www.spicefactory.org/parsley/">http://www.spicefactory.org/parsley/</a></li>
<li><a href="http://www.springsource.org/spring-flex">http://www.springsource.org/spring-flex</a></li>
<li><a href="http://www.axonframework.org">http://www.axonframework.org</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%2F2010%2F02%2F25%2Fcreating-a-sample-for-axon-using-flex-and-parsley%2F&amp;title=Creating%20a%20sample%20for%20axon%20using%20flex%20and%20parsley&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/25/creating-a-sample-for-axon-using-flex-and-parsley/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Creating a w3c validated rss feed using Rome and spring 3</title>
		<link>http://www.gridshore.nl/2010/02/16/creating-a-w3c-validated-rss-feed-using-rome-and-spring-3/</link>
		<comments>http://www.gridshore.nl/2010/02/16/creating-a-w3c-validated-rss-feed-using-rome-and-spring-3/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 11:16:00 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[rome]]></category>
		<category><![CDATA[rss]]></category>
		<category><![CDATA[spring 3]]></category>
		<category><![CDATA[Spring Framework]]></category>
		<category><![CDATA[w3c]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=999</guid>
		<description><![CDATA[<p> <p>For my current customer I had to create an rss feed. In the java domain you immediately grab Rome to do the job. There was a catch. My customer wants (with good reason) to have feeds validated by the w3c feed validator. This turned out to be a slightly more complicated job. Luckily [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.gridshore.nl/wp-content/uploads/romelogo-small.jpg" alt="romelogo-small.jpg" border="0" width="200" height="144" align="left" />
<p>For my current customer I had to create an rss feed. In the java domain you immediately grab <a href="https://rome.dev.java.net/">Rome</a> to do the job. There was a catch. My customer wants (with good reason) to have feeds validated by the <a href="http://validator.w3.org/feed/">w3c feed validator</a>. This turned out to be a slightly more complicated job. Luckily Rome has good support for extensions, so at least it was possible.</p>
<p>In this blog post I describe the challenges I had creating the validated feed. If you want more in depth information please check my post on my employers blog : <a href="http://blog.jteam.nl/2009/12/17/serving-a-heavy-load-rss-feed-with-spring-3-and-ehcache/">serving a heavy load rss feed with spring 3 and ehcache</a>.</p>
<p><span id="more-999"></span><br />
<h2>Rome extension</h2>
<p>At the moment I am missing the atom namespace in the resulting xml.</p>
<pre>
&lt;rss version="2.0" <strong>xmlns:atom="http://www.w3.org/2005/Atom</strong>"&gt;
</pre>
<p>I also miss the actual atom link:</p>
<pre>
&lt;atom:link href="http://dallas.example.com/rss.xml" rel="self" type="application/rss+xml" /&gt;
</pre>
<p>Now we must tell Rome how to generate this content. Rome supports a plugin structure. Detailed information can be found on this page:</p>
<p><a href="http://wiki.java.net/bin/view/Javawsxml/Rome05TutorialSampleModule">http://wiki.java.net/bin/view/Javawsxml/Rome05TutorialSampleModule</a></p>
<p>An extension consists of a module containing the data to be used by the extension, a generator if the extension needs to add items to the generated feed and a parser if the extension is about reading feeds. In my case I only need the module component and the generator. Finally you need to tell Rome about the extension, this is done in a configuration file that needs to be available on the classpath.</p>
<h3>Module</h3>
<p>The only data I need is the link for the atom element, the href. The module itself consists of an interface and an implementation. The interface defines the getters and setters. The implementation has a few additional methods. The following code block shows them both.</p>
<pre class="brush: java; title: ; notranslate">
public interface AtomNSModule extends Module {
    public static final String URI = &quot;http://www.w3.org/2005/Atom&quot;;
    String getLink();
    void setLink(String href);
}

public class AtomNSModuleImpl extends ModuleImpl implements AtomNSModule {
    private String link;

    public AtomNSModuleImpl() {
        super(AtomNSModule.class, URI);
    }

    public String getLink() {
        return link;
    }

    public void setLink(String link) {
        this.link = link;
    }

    public Class getInterface() {
        return AtomNSModule.class;
    }

    public void copyFrom(Object obj) {
        AtomNSModule module = (AtomNSModule) obj;
        module.setLink(this.link);
    }
}
</pre>
<p>The code is not to hard to understand. Concentrate on the <strong>copyForm</strong> method. Here we put the data from our model into the object that is used by the framework to extract data. This is why you need the interface as well.</p>
<h3>Generator</h3>
<p>Here we add the elements to the generated xml. JDom is used to generate xml from an object tree of Elements. The following code block shows the complete generator.</p>
<pre class="brush: java; title: ; notranslate">
public class AtomNSModuleGenerator implements ModuleGenerator {
    private static final Namespace ATOM_NS = Namespace.getNamespace(&quot;atom&quot;, AtomNSModule.URI);

    private static final Set NAMESPACES;

    static {
        Set nss = new HashSet();
        nss.add(ATOM_NS);
        NAMESPACES = Collections.unmodifiableSet(nss);
    }

    public String getNamespaceUri() {
        return AtomNSModule.URI;
    }

    public Set getNamespaces() {
        return NAMESPACES;
    }

    public void generate(Module module, Element element) {
        AtomNSModule atomNSModule = (AtomNSModule) module;
        Element root = element;
        while (root.getParent() != null &amp;&amp; root.getParent() instanceof Element) {
            root = (Element) element.getParent();
        }
        root.addNamespaceDeclaration(ATOM_NS);

        Element atomLink = new Element(&quot;link&quot;, ATOM_NS);
        atomLink.setAttribute(&quot;href&quot;, atomNSModule.getLink());
        atomLink.setAttribute(&quot;rel&quot;, &quot;self&quot;);
        atomLink.setAttribute(&quot;type&quot;, &quot;application/rss+xml&quot;);

        element.addContent(0, atomLink);
    }
}
</pre>
<p>Focus on the <strong>generate</strong> method. In this method we add the namespace declaration to the root element and we create a new element that is added to the provided element. The provided element is the channel element. The result of the feed now looks like this.</p>
<pre>
&lt;rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"&gt;
  &lt;channel&gt;
    &lt;atom:link href="http://localhost:8080/rss/nieuws.rss" rel="self" type="application/rss+xml" /&gt;
	...
  &lt;/channel&gt;
&lt;/rss&gt;
</pre>
<h3>Configuration</h3>
<p>The last part is telling Rome to use the new component. This is done by putting a rome.properties file on the classpath with the following contents.</p>
<pre>
rss_2.0.feed.ModuleGenerator.classes=nl.gridshore.rss.romeextension.AtomNSModuleGenerator
</pre>
<p>It is important to specify the rss_2.0 because multiple generators are available and this is the one that is used.</p>
<h2>Encoding &#8211; response type</h2>
<p>Another problem I had had to do with encoding. You can set the type of encoding in the generated xml, but the response of the spring controller/view combination does not follow this. Therefore you have to set the encoding of the response object explicitly. In the view component I added the following lines of code:</p>
<pre class="brush: java; title: ; notranslate">
    @Override
    protected void prepareResponse(HttpServletRequest request, HttpServletResponse response) {
        super.prepareResponse(request, response);
        response.setCharacterEncoding(CharacterEncodingConstants.UTF8);
    }
</pre>
<p>I hope this can help others to create better feeds as well, suggestions for improvements are of course welcome.</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%2F16%2Fcreating-a-w3c-validated-rss-feed-using-rome-and-spring-3%2F&amp;title=Creating%20a%20w3c%20validated%20rss%20feed%20using%20Rome%20and%20spring%203&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/16/creating-a-w3c-validated-rss-feed-using-rome-and-spring-3/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Analyzing beet results with groovy</title>
		<link>http://www.gridshore.nl/2009/11/20/analyzing-beet-results-with-groovy/</link>
		<comments>http://www.gridshore.nl/2009/11/20/analyzing-beet-results-with-groovy/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 20:27:32 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[groovy and grails]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[beet]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[jfreechart]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=931</guid>
		<description><![CDATA[<p>The recent weeks I have been playing around with grails. When working with grails you have to learn groovy as well. Sometimes I am just amazed by the easiness of doing things with groovy. That is why I started out using groovy for a very small project (at least with groovy) to analyze an [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.gridshore.nl/wp-content/uploads/logo_groovy.png" alt="logo_groovy.png" border="0" width="203" height="100" align="left" />The recent weeks I have been playing around with grails. When working with grails you have to learn groovy as well. Sometimes I am just amazed by the easiness of doing things with groovy. That is why I started out using groovy for a very small project (at least with groovy) to analyze an xml file as generated by the <a href="http://beet.sourceforge.net/">performance measurement framework Beet</a>.</p>
<p>In this blog post I go step-to-step through a solution that analyzes the xml file and plots the results in a chart generated with <a href="http://www.jfree.org/jfreechart/">jfreechart</a>.</p>
<p><span id="more-931"></span><br />
<h2>Introduction</h2>
<p><img src="http://www.gridshore.nl/wp-content/uploads/Screen-shot-2009-11-20-at-8.20.15-PM.png" alt="Screen shot 2009-11-20 at 8.20.15 PM.png" border="0" width="219" height="71" align="right" />In one of my previous posts I have discussed a nice framework for easy performance measurement called Beet. You can find this post here: <a href="http://www.gridshore.nl/2009/09/01/using-beet-to-monitor-your-spring-framework-application/">Using beet to monitor your (springframework) application</a>. The result of a monitor session with beet can be an xml file. Nice, but how do you analyze this file? By hand? No way, you need a tool. Excel or Numbers can be fine, but it can be a lot faster. Therefore I decided to create a small groovy application.</p>
<p>The first requirement for me was very easy, read the events in the xml file and calculate the average of all events of a certain type. I asked a few of my collegues about their estimated effort when having to do it in java. They varied from 1 hour (pretty optimistic) to half a day. Curious how much time it took me?</p>
<h2>First iteration</h2>
<p>The first iteration was to calculate the overall average, an optimist of 2 hour java work. First you locate the file, than you <em>slurp</em> the xml out of the file. With the xml file in your hand, you obtain all events with a child element type with the value <em>method</em>. The following code block shows these three lines of code, yes for real, three lines.</p>
<pre class="brush: groovy; title: ; notranslate">
def file = new File(&quot;beet-integration-web-perf.xml&quot;)
def xml = new XmlSlurper().parse(file)
def methodEvents = xml.event.findAll {it.type == &quot;method&quot;}
</pre>
<p>The next step is to take all durations from the found events. Using these durations, calculating the average is very easy.</p>
<pre class="brush: groovy; title: ; notranslate">
def file = new File(&quot;beet-integration-web-perf.xml&quot;)
def xml = new XmlSlurper().parse(file)
def methodEvents = xml.event.findAll {it.type == &quot;method&quot;}
def durations = methodEvents*.&quot;duration-ms&quot;
println &quot;Average duration is ${durations.sum {it.toBigDecimal()} / durations.size()}&quot;
</pre>
<p>That is it, this took me 10 minutes. And yes for 5 lines of code that is still a lot, but cut me some slag man, I am still learning groovy <img src='http://www.gridshore.nl/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  . What I forgot to mention is that I use the groovyConsole to create and run the application.</p>
<h2>Second iteration</h2>
<p>The total average is nice, but with hundreds of measurements, not very useful. Of course we want more information on the data. To stretch myself a little bit, I had the idea to take the average of each minute and print that on screen. The next code block does just that, it calculates the averages of all measurements in the same minute and prints the result on the screen. When reading the code, take this tip. We create an array with all durations for each minute and put the result in a map with the minute as a key and the array with durations as a value.</p>
<pre class="brush: groovy; title: ; notranslate">
def averages = [:]
def start = methodEvents[0].start.text()[0..16]
def minuteItems = []
methodEvents.each {
    def duration = it.&quot;duration-ms&quot;.toBigDecimal()
    def currentStart = it.start.text()[0..16]

    if (start == currentStart) {
        minuteItems.add duration
    } else {
        averages.put ((start),minuteItems)
        minuteItems = [duration]
        start = currentStart
    }
}

averages.each {key,value -&gt;
    println &quot;Minute : ${key} has average duration of ${value.sum {it.toBigDecimal()} / value.size()}&quot;
}
</pre>
<h2>Third and final iteration</h2>
<p>Having this data written to the screen is oke, but a nice graph would be even better. For this I used a <a href="http://groovy.codehaus.org/Plotting+graphs+with+JFreeChart">sample I found via google</a>. Since the code is pretty straightforward, I just copy it in here.</p>
<pre class="brush: groovy; title: ; notranslate">
def dataset = new DefaultCategoryDataset()
dataset.with{
    avarages.each {key,values -&gt;
    def value = (values.sum {it.toInteger()} / values.size())
        addValue value , &quot;average&quot;, key[-3..-1]
    }
}

def labels = [&quot;Registered events total ${methodEvents.size()}&quot;, &quot;Minute&quot;, &quot;Average&quot;]
def options = [true, true, true]
def chart = ChartFactory.createLineChart(*labels, dataset,Orientation.VERTICAL, *options)
def swing = new SwingBuilder()
def frame = swing.frame(title:'Groovy LineChart',
        defaultCloseOperation:WC.EXIT_ON_CLOSE) {
    panel(id:'canvas') { widget(new ChartPanel(chart)) }
}
frame.pack()
frame.show()
</pre>
<p>For those java people, check the way you can work with arrays in line 5. Counting from the end of the array, nice.</p>
<p>The result is shown in the next image.</p>
<p><img src="http://www.gridshore.nl/wp-content/uploads/Screen-shot-2009-11-20-at-9.20.31-PM.png" alt="Screen shot 2009-11-20 at 9.20.31 PM.png" border="0" width="770" height="532" /></p>
<p>That is about it, just two last things. First you need to add two jars to the classpath of groovy: jcommon-1.0.16.jar, jfreechart-1.0.13.jar. These are in the jfreechart download package. I used the mechanism to create a folder .groovy/lib in your root and add the jars to that folder.</p>
<p>The other thing I wanted to mention is the option to create a shell script from groovy. Just add the following line at the top and make your file executable and you are good to go.</p>
<pre>
#!/usr/bin/env groovy
</pre>
<p>That is it, in total 2 hours of work, not bad I think for a beginner in groovy with access to google. If you are good at groovy and you spot improvements, please let me know, I am eager to learn more.</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%2F11%2F20%2Fanalyzing-beet-results-with-groovy%2F&amp;title=Analyzing%20beet%20results%20with%20groovy&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/11/20/analyzing-beet-results-with-groovy/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Doing grails, yes I like it</title>
		<link>http://www.gridshore.nl/2009/11/09/doing-grails-yes-i-like-it/</link>
		<comments>http://www.gridshore.nl/2009/11/09/doing-grails-yes-i-like-it/#comments</comments>
		<pubDate>Mon, 09 Nov 2009 07:30:54 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[groovy and grails]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[google appengine]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[intellij]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=920</guid>
		<description><![CDATA[<p>Last week I attended a groovy &#038; grails training by SpringSource. My first introduction into grails is about 2 years a go. I attended a talk at the spring experience. Back than I liked it, tried it, but did not really use it. By now a lot has changed, most of all very good [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.gridshore.nl/wp-content/uploads/F0720E8F-2336-4FEE-BB96-7F8FA9B9FD9C.jpg" alt="F0720E8F-2336-4FEE-BB96-7F8FA9B9FD9C.jpg" border="0" width="134" height="117" align="left" />Last week I attended a <a href="http://www.springsource.com/training/grv001">groovy &#038; grails training</a> by SpringSource. My first introduction into grails is about 2 years a go. I attended a talk at the spring experience. Back than I liked it, tried it, but did not really use it. By now a lot has changed, most of all very good tool integration by <a href="http://www.jetbrains.com/idea/nextversion/">intellij</a>. Last week I had the change to go to a training, now I am motivated to start using grails more often.</p>
<p>This post I will talk you through a grails application I have created for a project of mine. I also take you through some of the things I learned last week. Finally I&#8217;ll show you that you can create a google app engine application using grails. There are ways to create grails applications, I&#8217;ll show you how to do it using the latest intellij 9 beta release.</p>
<p><span id="more-920"></span><br />
<h2>Training</h2>
<p>As mentioned in the introduction I attended the spring source groovy and grails training. The training was given by Peter Ledbrook, author of <a href="http://www.manning.com/gsmith/">grails in action</a>. I am not going to give a detailed description of the training. I did like the training, it gave a good overview of the possibilities of grails as well as the groovy language. And yes, I am now very interested in the options of groovy. Especially for creating web based applications with grails, groovy just shines. Not sure when I should use groovy and when normal java. Have to explore to find out. Some of the things I liked about groovy are:</p>
<ul>
<li>Assignment of parameters that are evaluated immediately ${age} or when used ${->age}</li>
<li>Using negative indexes in arrays: [1 .. -2] strips of the first and last item from an array</li>
<li>Groovy truth, explicit use of values in a comparison. null, 0, &#8220;&#8221; and [] are all false in a comparison</li>
<li>Closures, still hard to determine when to use a closure and when a method. But closures are used very often in groovy.</li>
<li>Out of the box test integration with things like: MockFor, Expando, and as a plugin GMock.</li>
</ul>
<p>Of course we learned a lot more than this, check the training or the book yourself if you want more. Next up was grails. I did look at grails before at grails, but tool support was pretty limited back than, and the plugins were not really widely available. A lot has changed since than. SpringSource came out with grails support in SpringSource Tool Suite, and Intellij has grails support as well. To be honest, intellij was much more productive than STS. Actually STS was almost not useable. Since it was the first release with grails support it will most probably improve the coming releases. Intellij worked very nice out of the box (I did use the beta version of intellij 9. Some of the features I liked during the training are:</p>
<ul>
<li>Gorm, I must mention this Groovy/Grails Object Relational Mapping framework first. This is very important for grails and why it is so productive. I just love these dynamic finders (more later).</li>
<li>Plugin architecture, the easy of installtion and usage of plugins is very nice. I like the db-util plugin for its simplicity and the help when working with internal memory databases. A killer plugin during development.</li>
<li>Scaffolding, for auto responding to CRUD like operations.</li>
<li>flash parameter to be used for adding something to the session for just one request. Ideal for passing messages.</li>
<li>Using templates, ideal for doing ajax calls and reuse of small view elements.</li>
</ul>
<p>Oke time to get our hands dirty, next up is a short introduction in the sample I am going to create. Than some code (which is acutally not that much)</p>
<h2>The application to create</h2>
<p>For a customer at <a href="http://www.jteam.nl">JTeam</a>, we have a large amount of servers that we need to prepare. The actual preparation is mostly done by the hosting provider. Sometime we have no idea what the status is of some servers. We started to use an excel sheet to communicate the status among our team. This is not ideal and I decided to create a small grails application for this. It&#8217;s all very basic, but useable.</p>
<p>Every server has a status, some comments and an external ip address. Each server is also part of a number of vlans and belongs to an environment (dev,test,accep,prod).</p>
<h2>The code</h2>
<p>The code is available online at github. Yes I know, it is not at google code. I got extra motivated to start using git since the training. Peter was working so flexible with his source code, I want that too. The best way to learn something is by doing it. Therefore I create a git repository at github. You can find out more at the following url. There is a very easy way to download the complete source code without using git, check the page.</p>
<p><a href="http://github.com/jettro/MyServerPark">http://github.com/jettro/MyServerPark</a></p>
<h2>The basics</h2>
<p>Starting a grails project is very well documented on the grails website. Except for one controller, the OverviewController, all controllers use: def scaffold = true. Which means I don&#8217;t write any code. Also not view components. I did create some domain classes that have relationships with each other. The next sections cover the different elements of the application.</p>
<h3>The domain model</h3>
<p><img src="http://www.gridshore.nl/wp-content/uploads/DomainModelServerpark.png" alt="DomainModelServerpark.png" border="0" width="555" height="376" align=" center" /></p>
<p>Some things to know about the domain model:</p>
<ul>
<li>belongsTo is used to declare a relationship of many-to-one, the next line gives an example for Comment. This gives the comment a property server.</li>
<p>static belongsTo = [server:Server]</p>
<li>The comment class also gives meta data about the mapping and the type used for the database as well as constraints. In the example we create a field for larger amounts of text.</li>
<pre class="brush: groovy; title: ; notranslate">
class Comment {
    String name
    String content

    static belongsTo = [server:Server]

    static mapping = {
        content type: &quot;text&quot;
    }

    static constraints = {
        name(blank:false, maxSize:50)
        content(blank:false, widget:&quot;textarea&quot;)
    }
}
</pre>
<li>The previous code block also shows one of the things that might be a bit strange. With <strong>widget:&#8221;textarea&#8221;</strong> you indicate the type of field to be used at the front end. Might be a bit strange in a domain model.</li>
<li>A one-to-many relationship is also easy to implement, check the following line from Environment:</li>
<p>static hasMany = [servers:Server]
</ul>
<p>Check the code for more examples of relationships.</p>
<h3>Scaffolding controllers and views</h3>
<p>Grails makes use of scaffolding, this can be static and dynamic. In the static case, code is being generated and can be altered. The dynamic case is evaluated runtime. In this project I tried to use dynamic scaffolding as much as possible. Usability might not always be what you want. In that case you should use static scaffolding or create something yourself. I managed to do well with the scaffolding on dynamic (except for the google app engine sample). But let us focus on the customer controller.</p>
<h2>The overview controller</h2>
<p>Grails makes use of convention over configuration. This is also true for controllers and views. The overview controller listens to the /overview url and points to the overview.gsp file. The following code block gives the complete OverviewController groovy class.</p>
<pre class="brush: groovy; title: ; notranslate">
class OverviewController {
    def show = {
        redirect(uri:&quot;/server/show/${params.id}&quot;)
    }

    def comments = {
        def currentServer = Server.findById(params.id.toLong())
        def allComments = Comment.withCriteria {
            server {
                eq(&quot;id&quot;,currentServer.id)
            }
        }
        render(template:&quot;/shared/comment&quot;,model:[comments:allComments, server:currentServer])
    }

    def index = {
        def environments = Environment.list()
        [environments:environments]
    }
}
</pre>
<p>There are three methods in the controller. The show does a redirect to the show method of the server controller. The index returns list of all environments and uses the view index.gsp. The comments method is a different cup of thee. This responds to an ajax call and returns a fragment. focus on the last line for now. You can see we use the render call. This makes use of a template. Using the render call, we obtain the html and push it back to the client. The section about views will give a bit more detail. Next up are the dynamic finders</p>
<h3>Dynamic finders</h3>
<p>The previous code block gives a few examples of finders. In index we obtain all the environments with <strong>Environment.list()</strong>. This is the most basic finder. Another finder is in the comments method. There we obtain the server by an id. The call is findServerById and you provided an id. Another calls could be: findByFunction, findByFunctionLike &#8220;%database%&#8221;, findByFunctionIlike &#8220;%DataBase%&#8221;. You can also make combinations with And/Or and multiple parameters. Pretty cool.</p>
<p>The comments method also shows the Criteria API for looking up all comments for a specific server. These type of queries, limited by a related item, are not supported by the dynamic finders.</p>
<h3>Gsp for views</h3>
<p>Creating the views is not very hard. If you want to learn how it works, I suggest generating the scaffolding views. I want to focus on something that is just a little bit more advanced. Ajax calls. In my project I want to obtain all comments for a server using an ajax call. In the overview page we use a special tag from grails, the remoteLink. This tag does an ajax call to the server and prints the result in the div with provided id.</p>
<p>&lt;g:remoteLink action=&#8221;comments&#8221; params=&#8221;[id:server.id]&#8221; update=&#8221;comments&#8221;&gt;comments&lt;/g:remoteLink&gt;</p>
<p>As you can see, we provide the <strong>server.id</strong> and we update the div with id <strong>comments</strong>.</p>
<p>This does not work out of the box, you must specify the prototype javascript library to be included. You can do this in the file:</p>
<p>views > layouts > main.gsp</p>
<p>Add the following line:</p>
<p>&lt;g:javascript library=&#8221;prototype&#8221; /&gt;</p>
<p>Now everything should be fine and you can test the application. A command like grails run-app should be enough.</p>
<h2>Documentation</h2>
<p>If you want more information about grails, try the following references:</p>
<ul>
<li><a href="http://grails.org/doc/1.1.x/">http://grails.org/doc/1.1.x/</a></li>
<li><a href="http://groovy.codehaus.org/groovy-jdk/">http://groovy.codehaus.org/groovy-jdk/</a></li>
<li><a href="http://www.manning.com/gsmith/">http://www.manning.com/gsmith/</a></li>
<li><a href="http://www.jetbrains.com/idea/nextversion/index.html">http://www.jetbrains.com/idea/nextversion/index.html</a></li>
<li><a href="http://www.springsource.com/training/grv001">http://www.springsource.com/training/grv001</a></li>
<li><a href="http://www.springsource.com/products/sts">http://www.springsource.com/products/sts</a></li>
</ul>
<h2>Grails and google app engine</h2>
<p>Grails uses plugins for all additional functionality. There is also a plugins available for google app engine. There is already good documentation available for this plugin. Therefore I keep this short. The following code block shows the commands. For more information, check the website of the plugin:</p>
<p><a href="http://grails.org/plugin/app-engine">http://grails.org/plugin/app-engine</a><br />
<br/></p>
<pre>
# grails create-app share-this
# grails uninstall-plugin hibernate
# grails install-plugin app-engine
choose jpa when asked
# export APPENGINE_HOME=&lt;path to your sdk install of google app engine&gt;
# grails app-engine run
# grails set-version 1
# grails app-engine package
# $APPENGINE_HOME/bin/appcfg.sh update ./target/war
# grails install-plugin gorm-jpa
</pre>
<p>Than I used intellij to create some domain classes and controllers. Take the following into consideration.</p>
<ul>
<li>Put domain classes in a package or it won&#8217;t work</li>
<li>Put Controller classes in the same package</li>
<li>generate views, the auto scaffolding seems not to work.</li>
</ul>
<p>You can look at the result here : <a href="http://share-this.appspot.com/">http://share-this.appspot.com/</a>. It could well be that the app does not start the first time, a refresh might help. I&#8217;ll have a look at this in the future. There is a problem with the CPU consumption and my grails application.</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%2F11%2F09%2Fdoing-grails-yes-i-like-it%2F&amp;title=Doing%20grails%2C%20yes%20I%20like%20it&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/11/09/doing-grails-yes-i-like-it/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

