<?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; jettro</title>
	<atom:link href="http://www.gridshore.nl/author/admin/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>Creating an rss feed using the latest features of Hippo</title>
		<link>http://www.gridshore.nl/2011/12/13/creating-an-rss-feed-using-the-latest-features-of-hippo/</link>
		<comments>http://www.gridshore.nl/2011/12/13/creating-an-rss-feed-using-the-latest-features-of-hippo/#comments</comments>
		<pubDate>Tue, 13 Dec 2011 15:36:57 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[server technology]]></category>
		<category><![CDATA[hippo]]></category>
		<category><![CDATA[rome]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=1216</guid>
		<description><![CDATA[<p>On my employers blog I wrote a piece about a new feature of Hippo called pipelines that can be used to create new content channels. We have created an rss feed using the standard components of Hippo combined with the Rome project. If you are interested you can read the blog post here:</p> <p>http://blog.dutchworks.nl/2011/12/13/embedding-rss-in-hippo-using-the-pipelines-feature/</p> ]]></description>
			<content:encoded><![CDATA[<p>On my employers blog I wrote a piece about a new feature of Hippo called pipelines that can be used to create new content channels. We have created an rss feed using the standard components of Hippo combined with the Rome project. If you are interested you can read the blog post here:</p>
<p><a href="http://blog.dutchworks.nl/2011/12/13/embedding-rss-in-hippo-using-the-pipelines-feature/">http://blog.dutchworks.nl/2011/12/13/embedding-rss-in-hippo-using-the-pipelines-feature/</a></p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2011%2F12%2F13%2Fcreating-an-rss-feed-using-the-latest-features-of-hippo%2F&amp;title=Creating%20an%20rss%20feed%20using%20the%20latest%20features%20of%20Hippo&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/12/13/creating-an-rss-feed-using-the-latest-features-of-hippo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Leaving JTeam joining Dutchworks</title>
		<link>http://www.gridshore.nl/2011/10/11/leaving-jteam-joining-dutchworks/</link>
		<comments>http://www.gridshore.nl/2011/10/11/leaving-jteam-joining-dutchworks/#comments</comments>
		<pubDate>Tue, 11 Oct 2011 19:48:20 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[dutchworks]]></category>
		<category><![CDATA[JTeam]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=1206</guid>
		<description><![CDATA[<p>In this post I want to share something that just happened to me this week. On monday I started as usual for the past three years or so. At the end of the day I left JTeam behind and started working for Dutchworks. Ok, I am trying to be funny. It most probably is [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.gridshore.nl/wp-content/uploads/dutchworks_logo.jpg" alt="Dutchworks logo" title="dutchworks_logo" width="300" height="44" style="float:left"/>In this post I want to share something that just happened to me this week. On monday I started as usual for the past three years or so. At the end of the day I left JTeam behind and started working for Dutchworks. Ok, I am trying to be funny. It most probably is not working. Or are you smiling?</p>
<p>Enough of the fun part, now seriously. JTeam has outgrown it&#8217;s name. The past year a lot has changed and a new name is the next logical step. I cannot explain this better than my CEO Steven Schuurman. If you are interested you can read his announcement here:</p>
<p><a href="http://blog.dutchworks.nl/2011/10/10/hot-off-the-press-as-of-today-“jteam”-will-be-known-as-“dutchworks”/">http://blog.dutchworks.nl/2011/10/10/hot-off-the-press-as-of-today-“jteam”-will-be-known-as-“dutchworks”/</a></p>
<p>Head over to our new website: <a href="http://www.dutchworks.nl">http://www.dutchworks.nl</a>. Help us spread the word.</p>
<p>Hope to see you back when we write our next technical blog.</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%2F10%2F11%2Fleaving-jteam-joining-dutchworks%2F&amp;title=Leaving%20JTeam%20joining%20Dutchworks&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/10/11/leaving-jteam-joining-dutchworks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cleaning up artifactory with a groovy script</title>
		<link>http://www.gridshore.nl/2011/10/03/cleaning-up-artifactory-with-a-groovy-script/</link>
		<comments>http://www.gridshore.nl/2011/10/03/cleaning-up-artifactory-with-a-groovy-script/#comments</comments>
		<pubDate>Mon, 03 Oct 2011 09:10:45 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[groovy and grails]]></category>
		<category><![CDATA[artifactory]]></category>
		<category><![CDATA[cleaning]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=1192</guid>
		<description><![CDATA[<p>On my employers blog I wrote an article about cleaning up your local maven repository. It gets polluted with old snapshot artifacts easily. It also leaves a lot of build around if you release regularly. After cleaning up your local copy you start thinking about the repository on the server. Would that also become [...]]]></description>
			<content:encoded><![CDATA[<p>On my employers blog I wrote an article about cleaning up your local maven repository. It gets polluted with old snapshot artifacts easily. It also leaves a lot of build around if you release regularly. After cleaning up your local copy you start thinking about the repository on the server. Would that also become as big as your local one? Of course. Therefore we need to clean that one up as well.</p>
<p>In most of our projects we use <a href="http://www.jfrog.com/">Artifactory</a>. It is nice that artifactory comes with a REST based api. The url&#8217;s can be a bit better and the content type of the response is not what I would expect. Still the documentation is good and lost of actions are possible. In this blog post I show you the basics of interacting with the REST api using groovy. Now let us shrink the repo.</p>
<p><span id="more-1192"></span><br />
<h2>Introducing the artifactory api</h2>
<p>The frog wiki has a wiki page dedicated to the api. This page shows the GET/DELETE/PUT requests that you can execute. It shows the url, the response and the content type. If you click the following link you jump to the definition of Folder Info. After the link an image with the same data at the time of writing.</p>
<p><a href="http://wiki.jfrog.org/confluence/display/RTF/Artifactory%27s+REST+API#Artifactory%27sRESTAPI-FolderInfo">http://wiki.jfrog.org/confluence/display/RTF/Artifactory%27s+REST+API#Artifactory%27sRESTAPI-FolderInfo</a><br/><br />
<img style="display:block; margin-left:auto; margin-right:auto;" src="http://www.gridshore.nl/wp-content/uploads/Screen-Shot-2011-09-26-at-16.08.39.png" alt="Screen Shot 2011 09 26 at 16 08 39" border="0" width="600" height="442" /></p>
<p>In the image you can also see the JSON response for the specific request. Have a look at the structure of the response. Look at the children. We will use it later on.</p>
<h2>Obtaining folder info</h2>
<p>Time to show some code. We will first have a look at a function to obtain information about the folder as provided by the caller. Since we group the functions in a class we have to look at configuration of this class as well. The constructor accepts a map that we call config. That way you can provided configuration for the server, the repository and the versions to remove. An example of the config map is.</p>
<pre class="brush: groovy; title: ; notranslate">
def config = [
    server: 'http://localhost:8080',
    repository: 'libs-release-local',
    versionsToRemove: ['/3.2.0-build-'],
    dryRun: false]
</pre>
<p>Than we can ask for information about a folder. The following code block shows two functions, one to obtain information about a folder and the other to ask for a connection with the server.</p>
<pre class="brush: groovy; title: ; notranslate">
def JSON folderInfo(path) {
    def binding = [repository: config.repository, path: path]
    def template = engine.createTemplate('''/artifactory/api/storage/$repository/$path''').make(binding)
    def query = template.toString()

    def server = obtainServerConnection()
    def resp = server.get(path: query)
    if (resp.status != 200) {
        println &quot;ERROR: problem obtaining folder info: &quot; + resp.status
        println query
        System.exit(-1)
    }
    return resp.data
}

private RESTClient obtainServerConnection() {
    def server = new RESTClient(config.server)
    server.parser.'application/vnd.org.jfrog.artifactory.storage.FolderInfo+json' = server.parser.'application/json'
    server.parser.'application/vnd.org.jfrog.artifactory.repositories.RepositoryDetailsList+json' = server.parser.'application/json'

    return server
}
</pre>
<p>We make use of the groovy <a href="http://groovy.codehaus.org/api/groovy/text/SimpleTemplateEngine.html">SimpleTemplateEngine</a>. As you can see we build the query string with placeholders and attach a map with parameters to the template engine. Next step is to generate the query. After obtaining the connection to the server we execute the GET request and obtain the JSON data from the response. Notice the lines in the obtainServerConnection. The last two lines add mappings for the artifactory provided content types. We want them to be treated as normal json responses or else our mapping framework (Jackson) will not be able to process the result.</p>
<h2>Removing items</h2>
<p>The goal for this blog post is to present a script to clean your artifactory repository. Now that we know how to obtain information about a folder in artifactory, it is time to have a look at cleaning. The idea is to take the provided path as a starting point. Go through all the folders recursively and check if we are in an artifact folder. An artifact folder contains artifacts and should not have other folders. If a folder is not an artifact folder we are dealing with a grouped (maven terms). In our case we could determine an artifact folder by its name. All artifacts have -build- in their name. Hence the following function.</p>
<pre class="brush: groovy; title: ; notranslate">
private def isArtifactFolder(child) {
    child.uri.contains(&quot;-build-&quot;)
}
</pre>
<p>The next utility function is to actually delete a folder. The next function removes the provided path if we are not doing a dry run. If we did configure a dry run, we only print a message and do not actually do the delete. We again use the groovy template technology to create the query. Notice that the artifactory api uses the DELETE request.</p>
<pre class="brush: groovy; title: ; notranslate">
private def removeItem(path, child) {
    println &quot;folder: &quot; + path + child.uri + &quot; DELETE&quot;
    def binding = [repository: config.repository, path: path + child.uri]
    def template = engine.createTemplate('''/artifactory/$repository/$path''').make(binding)
    def query = template.toString()
    if (!config.dryRun) {
        def server = new RESTClient(config.server)
        server.delete(path: query)
    }
}
</pre>
<p>The last piece of the puzzle is the recursive function to check a folder for subfolders and give the command to remove a folder if it is in the list of folder to be removed. The next code block shows this function.</p>
<pre class="brush: groovy; title: ; notranslate">
def cleanArtifactsRecursive(path) {
    def deleteCounter = 0
    JSON json = folderInfo(path)
    json.children.each {child -&gt;
        if (child.folder) {
            if (isArtifactFolder(child)) {
                config.versionsToRemove.each {toRemove -&gt;
                    if (child.uri.startsWith(toRemove)) {
                        removeItem(path, child)
                        deleteCounter++
                    }
                }
            } else {
                if (!child.uri.contains(&quot;ro-scripts&quot;)) {
                    deleteCounter += cleanArtifactsRecursive(path + child.uri)
                }
            }
        }
    }
    return deleteCounter
}
</pre>
<p>The code is available online through github, check the references.</p>
<h2>References</h2>
<dl>
<dt><a href="http://blog.jteam.nl/2011/08/01/cleaning-up-your-maven-repository">Cleaning up your maven repository</a></dt>
<dd>Other blogpost about groovy and cleaning your local maven repository automatically.</dd>
<dt><a href="http://www.jfrog.com/">Artifactory</a></dt>
<dd>Homepage of the creators of Artifactory, here you can also find commercial support</dd>
<dt><a href="http://wiki.jfrog.org/confluence/display/RTF/Artifactory%27s+REST+API">Artifactory REST api</a></p>
<dd>Documentation for the REST api that is provided by Artifactory</dd>
<dt><a href="https://github.com/jettro/small-scripts/blob/master/groovy/artifactory/Artifactory.groovy">The source code</a></dt>
<dd>Sourcecode of the script discussed in this article.</dd>
</dl>
<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%2F10%2F03%2Fcleaning-up-artifactory-with-a-groovy-script%2F&amp;title=Cleaning%20up%20artifactory%20with%20a%20groovy%20script&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/10/03/cleaning-up-artifactory-with-a-groovy-script/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cleaning up your maven repository with groovy</title>
		<link>http://www.gridshore.nl/2011/08/01/cleaning-up-your-maven-repository-with-groovy/</link>
		<comments>http://www.gridshore.nl/2011/08/01/cleaning-up-your-maven-repository-with-groovy/#comments</comments>
		<pubDate>Mon, 01 Aug 2011 09:25:21 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[groovy and grails]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[maven]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=1165</guid>
		<description><![CDATA[<p>Ever looked at the space used by your maven repository? Think that this is to much? Start reading the blog post I wrote on my employers blog about a groovy script that you can use to clean your local maven repository. It removes old snapshots stored in your repo as well as old versions [...]]]></description>
			<content:encoded><![CDATA[<p>Ever looked at the space used by your maven repository? Think that this is to much? Start reading the blog post I wrote on my employers blog about a groovy script that you can use to clean your local maven repository. It removes old snapshots stored in your repo as well as old versions of artifacts.</p>
<p><a href="http://blog.jteam.nl/2011/08/01/cleaning-up-your-maven-repository">http://blog.jteam.nl/2011/08/01/cleaning-up-your-maven-repository</a></p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2011%2F08%2F01%2Fcleaning-up-your-maven-repository-with-groovy%2F&amp;title=Cleaning%20up%20your%20maven%20repository%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/2011/08/01/cleaning-up-your-maven-repository-with-groovy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Combining java and Node.js through redis pub/sub and a json remote interface</title>
		<link>http://www.gridshore.nl/2011/07/28/combining-java-and-node-js-through-redis-pubsub-and-a-json-remote-interface/</link>
		<comments>http://www.gridshore.nl/2011/07/28/combining-java-and-node-js-through-redis-pubsub-and-a-json-remote-interface/#comments</comments>
		<pubDate>Thu, 28 Jul 2011 10:11:16 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[Axon Framework]]></category>
		<category><![CDATA[Frontend Technology]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[server technology]]></category>
		<category><![CDATA[axonframework]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[redis]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=1163</guid>
		<description><![CDATA[<p>Recently I have been doing a lot with Node.js. It is a nice server technology that enables you to program on the server like you program on the client. Wouldn&#8217;t it be nice to create a java based business logic backend but a light weight client and server backend. Communication between node.js and java [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I have been doing a lot with Node.js. It is a nice server technology that enables you to program on the server like you program on the client. Wouldn&#8217;t it be nice to create a java based business logic backend but a light weight client and server backend. Communication between node.js and java is done in two ways in the sample. We use http and json for querying the data and for providing new data. Next to that I have an event system that pushes events with new data to the clients using nowjs. The following image gives you an idea about the overall solution.</p>
<p><img style="display:block; margin-left:auto; margin-right:auto;" src="http://www.gridshore.nl/wp-content/uploads/NodejsAxonRedisBlogpost.jpg" alt="Overview solution" border="0" width="551" height="323" /></p>
<p>If you want to find out more about this sample read on.</p>
<p><span id="more-1163"></span><br />
<h2>Introducing the sample</h2>
<p>The sample is based on the famous address book from the axonframework project. We reuse the axon sample and create a rest like interface that returns json to the clients. The source code is in the rest-ui project within the axonframework source tree under samples. This project also contains the listener code for the Contact and Address based events. The listeners listen for events and publish content from these events to the redis pub/sub mechanism. More on this in the later sections.</p>
<p>The other part of the sample is a node.js application. This application makes use of the rest api to obtain the data via http requests. Events about data changes are received through redis, using the pub/sub mechanism. The node.js application is available on Github. If you want to follow along, you can find the sources here:</p>
<p><a href="https://github.com/jettro/axon-addressbook-nodejs">https://github.com/jettro/axon-addressbook-nodejs</a><br/><br />
<a href="http://code.google.com/p/axonframework/source/browse/trunk#trunk%2Fsample%2Faddressbook%2Frest-ui">http://code.google.com/p/axonframework/source/browse/trunk#trunk%2Fsample%2Faddressbook%2Frest-ui</a></p>
<p>The following screen dump gives you an idea about the application.</p>
<p><img style="display:block; margin-left:auto; margin-right:auto;" src="http://www.gridshore.nl/wp-content/uploads/Screen-Shot-2011-07-25-at-19.06.57.png" alt="Screen Shot 2011 07 25 at 19 06 57" border="0" width="600" height="470" /></p>
<p>In the screen you see the list of contacts. You can add a new contact, change the name of a contact and add addresses to contacts. On the right you see the messages pane. Here you receive messages about new contacts that have been created, changed or deleted.</p>
<p>Now let us have a look at some of the code. We start with the java backend and then continue with the node.js part.</p>
<h2>The java part of the sample</h2>
<p>Numerous blogs have been written about rest based clients using spring mvc. Therefore I do not want to lose to much time in that area. Most important spring configuration is within the web.xml and the <a href="http://code.google.com/p/axonframework/source/browse/trunk/sample/addressbook/rest-ui/src/main/webapp/WEB-INF/spring/dispatcher-config.xml">dispatcher-config.xml</a>. In the web.xml we configure that every request is going to the spring dispatcher. We do not have status resources, only json responses. Within spring we make use of annotation to configure the beans. To be able to respond with json we make us of Jackson to transform beans into json objects. All pretty straightforward spring. Check the config file for yourself if you want to see how it works.</p>
<p>Next step is the controller that handles all the requests.</p>
<h3>Handling requests in the Cntroller</h3>
<p>The Controller handles the following requests:</p>
<ul>
<li>/contacts : GET, returns the list of all contacts</li>
<li>/contacts : POST, creates a new contact</li>
<li>/contacts : PUT, changes an existing contact</li>
<li>/contacts : DELETE, removes a contact</li>
<li>/contacts/{identifier} : GET, returns the details of a contact</li>
<li>/contacts/{identifier}/address : PUT, creates a new address or updates an existing one based on address type</li>
<li>/contacts/{identifier}/address : DELETE, removes the address of provided type</li>
</ul>
<p>Let us have a look at one of the requests to show the flow. For example we take the request for details. The following code block shows the complete method.</p>
<pre class="brush: java; title: ; notranslate">
@RequestMapping(value = &quot;{identifier}&quot;, method = RequestMethod.GET)
public @ResponseBody Map&lt;String, Object&gt; details(@PathVariable String identifier) {
    List&lt;AddressEntry&gt; addressesForContact = repository.findAllAddressesForContact(identifier);
    String name;
    if (addressesForContact.size() &gt; 0) {
        name = addressesForContact.get(0).getName();
    } else {
        name = repository.loadContactDetails(identifier).getName();
    }
    Map&lt;String, Object&gt; map = new HashMap&lt;String, Object&gt;();
    map.put(&quot;addresses&quot;, addressesForContact);
    map.put(&quot;identifier&quot;, identifier);
    map.put(&quot;name&quot;, name);
    return map;
}
</pre>
<p>The RequestMapping annotation tells spring which requests need to be mapped to this method. The controller already maps all /contacts to this controller. The {identifier} now maps everything with a url like /contacts/{identifier} to this method, as long as it is a GET request. This identifier is also used as a parameter for the method. With the @PathVariable we tell spring to take the value for this parameter from the url or Path that was requested. The final annotation in the method declaration is the @ResponseBody. This tells spring to use the return value as the response body, so not as the name of the view to use. We have already configured to use jackson to transform the response body into json. In the code of the controller you see we return a map with three objects in it. A list of addresses, an identifier of the contact and the name of the contact. The json coming out of this is:</p>
<p>{<br />
    &quot;name&quot;:&quot;Jettro&quot;,<br />
    &quot;addresses&quot;:[<br />
    {<br />
        &quot;name&quot;:&quot;Jettro&quot;,<br />
        &quot;identifier&quot;:&quot;82b4fef5-3389-440d-8893-6831a64e200d&quot;,<br />
        &quot;addressType&quot;:&quot;PRIVATE&quot;,<br />
        &quot;streetAndNumber&quot;:&quot;Feyenoordlaan 010&quot;,<br />
        &quot;zipCode&quot;:&quot;3000AA&quot;,<br />
        &quot;city&quot;:&quot;Rotterdam&quot;<br />
    }],<br />
    &quot;identifier&quot;:&quot;82b4fef5-3389-440d-8893-6831a64e200d&quot;<br />
}</p>
<p>That is what you need to know about the rest api that I have created. If you want to have a look at the controller, <a href="http://code.google.com/p/axonframework/source/browse/trunk/sample/addressbook/rest-ui/src/main/java/org/axonframework/examples/addressbook/rest/ContactsController.java">check here</a>. The next step is about the listeners that listen for axon events related to the contacts and addresses and store information in redis.</p>
<h3>Listening for events</h3>
<p>We register listeners with axon for the contact related events as well as address related events. This is very easy with the annotations provided by the axonframework. The following code block shows how we register an event listener for the ContactCreatedEvent.</p>
<pre class="brush: java; title: ; notranslate">
@EventHandler
public void handleContactCreatedEvent(ContactCreatedEvent event) {
    ContactEntry value = new ContactEntry();
    value.setName(event.getName());
    value.setIdentifier(event.getContactIdentifier());
    Message&lt;ContactEntry&gt; message = new Message&lt;ContactEntry&gt;(&quot;contact-created&quot;, value);
    publisher.publish(message);
}
</pre>
<p>Notice the @EventHandler annotation. This registers the listener with axon. As you can see we take the information from the provided event and put it in a Message object. The message object contains a type and the content. The type can be used at the receiving side to better understand how to handle the received event. The publisher is auto injected by spring. In my case it is a redis publisher.</p>
<h3>Publishing to redis</h3>
<p>A library to talk with redis is <a href="https://github.com/xetorthio/jedis">jedis</a>. Jedis makes use of a pool which is configured in spring. Check the listener-context.xml to see how it works. Jedis does not have the most obvious api but it works. The following code block shows how a message is published to redis.</p>
<pre class="brush: java; title: ; notranslate">
public void publish(Message&lt;?&gt; message) {
    StringWriter writer = new StringWriter();
    try {
        mapper.writeValue(writer, message);
    } catch (IOException e) {
        logger.warn(&quot;Problem while writing ContactEntry to a string writer&quot;, e);
        return;
    }

    Jedis jedis;
    try {
        jedis = jedisPool.getResource();
    } catch (JedisConnectionException e) {
        logger.debug(&quot;Could not obtain redis connection from the pool&quot;);
        return;
    }
    try {
        jedis.publish(&quot;nl.axonframework.examples.addressbook&quot;, writer.toString());
    } finally {
        jedisPool.returnResource(jedis);
    }
}
</pre>
<p>The code is not very complicated. The important part here is that we use a jackson provided ObjectMapper to map the provided message to a json representation. Then you can see the nice jedis api at work. As you can see we publish a message to a queue. Our node.js client will subscribe to this queue. That is have the redis publish/subscribe works. Not very hard is it?</p>
<p>That is it for the java side. We now know how to get data using the rest api and we know where to get information about events that take place. Let us move on to the node.js side of the application.</p>
<h2>The Node.js part of the sample</h2>
<p>I do not want to go in setting up a node.js project. Do not want to explain all the different libraries that I use. I have written other blog posts on node.js that I do not want to copy. The most important one is this:</p>
<p><a href="http://blog.jteam.nl/2011/04/18/learning-node-js/">http://blog.jteam.nl/2011/04/18/learning-node-js/</a></p>
<p>The node.js project uses 4 libraries:</p>
<ul>
<li>express &#8211; doing the mvc part of the web application</li>
<li>jade &#8211; view templating</li>
<li>now &#8211; server push to the client (will explain this in a bit more detail)</li>
<li>redis &#8211; for redis interaction</li>
<p> </ul>
<h3>Project layout</h3>
<p>The public folder contains all the client related files like javascript, css and images. I will explain one file in here later on when discussing node.js. The test folder contains the test for the ContactRepository. Using this test helped me to verify that the integration between the java backend and the node.js application is working without having to start the application and go through the browser to check all requests. The views folder contains all the jade templates. Check mentioned blog post to find more information on jade. The app.&#8217;s initializes the application and maps all possible requests to methods in the ContactController. The controller knows where to get the data from and what page to render. The repository is responsible for obtaining data from the rest api on the java side.</p>
<h3>Initializing the node.js application</h3>
<p>As mentioned the app.js is the start of the application. Let us have a look at the different parts.</p>
<pre class="brush: jscript; title: ; notranslate">
var ContactController = require('./ContactController');
var repository = require('./ContactRepository').createRepo('localhost',8080);
var contactController = new ContactController(repository);
</pre>
<p>This part initializes our components. We will have a look at the createRepo method later on. But notice that we initialize the controller with an instance of the repository.</p>
<pre class="brush: jscript; title: ; notranslate">
app.get('/', contactController.listContacts);
app.get('/contact/new', contactController.newContactShowForm);
app.post('/contact/new', contactController.newContactPostForm);
app.get('/contact/:identifier',contactController.contact);
app.get('/contact/:identifier/edit',contactController.changeContactShowForm);
app.post('/contact/:identifier/edit',contactController.changeContactPostForm);
app.get('/contact/:identifier/delete',contactController.deleteContactShowForm);
app.post('/contact/:identifier/delete',contactController.deleteContactPostForm);
app.get('/contact/:identifier/address/new',contactController.newAddressShowForm);
app.post('/contact/:identifier/address/new',contactController.newAddressPostForm);
app.get('/contact/:identifier/address/:addressType/edit',contactController.changeAddressShowForm);
app.post('/contact/:identifier/address/:addressType/edit',contactController.changeAddressPostForm);
app.get('/contact/:identifier/address/:addressType/delete',contactController.deleteAddressShowForm);
app.post('/contact/:identifier/address/:addressType/delete',contactController.deleteAddressPostForm);
</pre>
<p>These are all the possible requests. The urls are easy to understand. As you can see, all urls are mapped to a method of the contactController</p>
<pre class="brush: jscript; title: ; notranslate">
var Now = require('now');
var everyone = Now.initialize(app);

var redis = require(&quot;redis&quot;),
    client = redis.createClient();

client.on(&quot;error&quot;, function (err) {
    console.log(&quot;Error %s&quot;, err);
});

client.on(&quot;message&quot;, function (channel, message) {
    everyone.now.receiveContact(message);
});
client.subscribe(&quot;nl.axonframework.examples.addressbook&quot;);
</pre>
<p>This is the harder bit. This has to do with receiving messages using the redis pub/sub mechanism and sending it to all connected clients using the nowjs library. I&#8217;ll discuss the now.js part later on.</p>
<h3>Request handling</h3>
<p>By using the repository object the controller becomes very easy. We only have to obtain the right data and render the right view. The most basic method is showing a list of contacts. The following code block shows the complete method.</p>
<pre class="brush: jscript; title: ; notranslate">
ContactController.prototype.listContacts = function(req, res) {
    repository.listContacts(function(contacts) {
        res.render('index', {locals: {contacts: contacts, nowjs: true}});
    });
};
</pre>
<p>Notice that we use a callback that is provided to the repository listContact method. Check that we provide the list of contacts to the view, together with a second parameter called nowjs. Remember this, on this page we enable nowjs, meaning that we can receive messages when looking at this page. Other methods are similar, have a look at the method that handles submitting a form to create a new contact.</p>
<pre class="brush: jscript; title: ; notranslate">
ContactController.prototype.newContactPostForm = function(req, res) {
    repository.newContact(req.body.new_name, function(code, message) {
        if (code == &quot;ok&quot;) {
            res.redirect(&quot;/&quot;);
        } else {
            res.render('newcontact', {locals: {error:message}});
        }
    });
};
</pre>
<p>In line 2 we obtain the form parameter <em>new_name</em> from the request body. Than we create a new contact. The callback method expects a code indicating whether the submission of the new contact was ok. If not, we render the form again with the error message. This happens when we try to create a contact with a name that already exists. The following image shows the screen with an error message.</p>
<p><img style="display:block; margin-left:auto; margin-right:auto;" src="http://www.gridshore.nl/wp-content/uploads/Screen-Shot-2011-07-28-at-10.07.30.png" alt="Screen showing the error message" border="0" width="600" height="459" /></p>
<p>Next up is the communication with a rest based application</p>
<h3>The Repository as a client to a rest application</h3>
<p>During the initialization of the application I already mentioned the createRepo method of the ContactRepository. The following code block shows the method. As you can see it initializes a repository with the default values for host and port.</p>
<pre class="brush: jscript; title: ; notranslate">
ContactRepository.createRepo = function(host, port) {
    var repo = new ContactRepository();
    repo.host = host;
    repo.port = port;
    return repo;
};
</pre>
<p>Again most of the interaction with the backend is the same. Therefore I use the create contact again as an example. I have created tests for all the repository methods. Let us have a look at the test first.</p>
<pre class="brush: jscript; title: ; notranslate">
function testNewContact() {
    logTestName(&quot;New contact&quot;);
    repository.newContact(&quot;My Test&quot;, function(code, message) {
        assert.equal(&quot;ok&quot;, code, &quot;This should be no problem and an ok should be returned: &quot; + code);
        // Check if the amount of contacts is increased
        repository.listContacts(function(contacts) {
            assert.equal(numContacts + 1, contacts.length, &quot;Number of contacts is not right, create did not work: &quot; + contacts.length);
            testAddAddress();
        });
    });
}
</pre>
<p>Notice that we check the return code and that the amount of contacts is increased. The following code block shows the implementation of the method of the repository.</p>
<pre class="brush: jscript; title: ; notranslate">
ContactRepository.prototype.newContact = function(name, callback) {
    var opts = createHttpRequestOpts('/contacts', 'POST');

    var req = http.request(opts, function(res) {
        res.setEncoding('utf8');
        res.on('data', function(data) {
            if (res.statusCode != 200) {
                console.log(data);
                callback('error', 'Maybe the name is already taken?');
            } else {
                callback('ok', 'The new contact has been send')
            }
        });
    });

    var contact = {};
    contact.name = name;

    req.write(JSON.stringify(contact));
    req.end();
};

function createHttpRequestOpts(path, method) {
    return {
        host: host,
        port: port,
        path:path,
        headers:{'Accept':'application/json','Content-Type':'application/json'},
        method: method
    };
}
</pre>
<p>I use the nodejs provided http request. Within the help function the opts object is created with the host, port, path, method and the headers. The headers are important to request json. Of course we provide a callback to handle the http response. Everything not 200 is an error as a response code. Here we call the provided callback to the repository method with the ok or error code. At the end of the method we do the actual request creation with the json request.</p>
<p>The final bit is the server push using the now.js library.</p>
<h3>Server push using now.js</h3>
<p>Node.js comes with a socket.io library. This makes server push very easy. Still it can be a lot easier. That is when using <a href="http://nowjs.com/">now.js</a>. Now.js enables you to call methods on the client that are actually on the server and vise versa. Let us have a look at the code for sending messages to the client when a redis event is received again.</p>
<pre class="brush: jscript; title: ; notranslate">
var Now = require('now');
var everyone = Now.initialize(app);
client.on(&quot;message&quot;, function (channel, message) {
    console.log(&quot;Received message: %s&quot;, message);
    everyone.now.receiveContact(message);
});
</pre>
<p>The important part here is the initialization of now and the line with everyone.now.receiveContact. Now we will call the connected clients method receiveContact and provide the message. Of course we need some client code for this. This code is available in the local.js file in the public folder.</p>
<pre class="brush: jscript; title: ; notranslate">
$(document).ready(function() {
    now.receiveContact = function(data) {
        var message = JSON.parse(data);
        var toWrite;
        switch(message.type) {
            case 'contact-removed':
                toWrite = &quot;Contact removed&quot;;
                break;
            case 'contact-created':
                toWrite = &quot;Contact with name &quot; + message.content.name + &quot; created&quot;;
                break;
            case 'contact-changed':
                toWrite = &quot;Contact changed name to &quot; + message.content.name;
                break;
            case 'address-created':
                toWrite = &quot;Added address of type &quot; + message.content.addressType + &quot; to contact &quot; + message.content.name;
                break;
            case 'address-removed':
                toWrite = &quot;Removed address of type &quot; + message.content.addressType + &quot; to contact &quot; + message.content.contact.name;
                break;
        }
        $(&quot;#messages&quot;).prepend(&quot;&lt;div&gt;&quot; + toWrite + &quot; &lt;/div&gt;&quot;);
    };
});
</pre>
<p>As you can see, we construct the message based on the type of the message and prepend a new div within the #messages div. Really that is all there is to it.</p>
<h2>Last remarks</h2>
<p>That is it. Again a long blog item. Hope you got some new knowledge out of it. Feel free to post comments if you have questions or even better improvements.</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%2F07%2F28%2Fcombining-java-and-node-js-through-redis-pubsub-and-a-json-remote-interface%2F&amp;title=Combining%20java%20and%20Node.js%20through%20redis%20pub%2Fsub%20and%20a%20json%20remote%20interface&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2011/07/28/combining-java-and-node-js-through-redis-pubsub-and-a-json-remote-interface/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Creating presentations with Node.js</title>
		<link>http://www.gridshore.nl/2011/06/15/creating-presentations-with-node-js/</link>
		<comments>http://www.gridshore.nl/2011/06/15/creating-presentations-with-node-js/#comments</comments>
		<pubDate>Wed, 15 Jun 2011 14:24:15 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[server technology]]></category>
		<category><![CDATA[express]]></category>
		<category><![CDATA[jade]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[nodejs]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=1157</guid>
		<description><![CDATA[<p>I am learning about Node.js. While learning I usually create a few demo&#8217;s. Another thing I am attending a training for is learning how to give good presentations. I had to prepare a 10 minute presentation. Would be nice if I could combine the learning about Node.js with the 10 minute presentation. I decided [...]]]></description>
			<content:encoded><![CDATA[<p>I am learning about Node.js. While learning I usually create a few demo&#8217;s. Another thing I am attending a training for is learning how to give good presentations. I had to prepare a 10 minute presentation. Would be nice if I could combine the learning about Node.js with the 10 minute presentation. I decided to create a Node.js application to give the presentation. So no Keynote for me this time.</p>
<p>In this blog post I present you an additional sample, focussed on creating presentations as a programmer. I&#8217;ll use a few node.js modules: Jade, Express.</p>
<p>On my employers blog I wrote an extensive article about Node.js, you can have a look at the article as well.</p>
<p><a href="http://blog.jteam.nl/2011/04/18/learning-node-js/">http://blog.jteam.nl/2011/04/18/learning-node-js/</a><br/><span id="more-1157"></span><br />
<h2>Requirements</h2>
<p>I want to have a tool that supports multiple presentations that can all be shown in a browser. I do not consider a lot of browsers. I like the css support and the full screen view of chrome on the Mac. Therefore I test my work with Chrome only. I guess most of the features work on other browsers as well, some small issues might arise. A big advantage of using the browser is that you have lots of libraries available to create nice looking slides.</p>
<p>The tool needs to be developer friendly, therefore slides are created with code. No hot deploys, no tools to just enter slides. The slides are within the code. This is not an end user tool, this is a developer tool.</p>
<p>Each presentation consists of a title, should be able to work with a chosen template and contains slides of course.</p>
<p>Giving or presenting the presentation should be easy as well. Therefore I want to be able to choose a slide, go to the next slide, the previous slide and the index of all presentations.</p>
<p>Going to a different presentation means using another url. For each presentation we provide a path and the slide index. A url for a presentation skills presentation than becomes:</p>
<pre>
<a href="http://dev.gridshore.nl:8018/presentation/create-presentation-nodejs">http://dev.gridshore.nl:8018/presentation/create-presentation-nodejs</a>
</pre>
<p>The first slide in that presentation than becomes:</p>
<pre>
<a href="http://dev.gridshore.nl:8018/presentation/create-presentation-nodejs/slide/1">http://dev.gridshore.nl:8018/presentation/create-presentation-nodejs/slide/1</a>
</pre>
<p>The final feature that would be nice is generating a handout. For now this will be a print view in the browser, maybe a pdf. An overview with all the slides on one page will be here:</p>
<p><a href="http://dev.gridshore.nl:8018/presentation/create-presentation-nodejs/all">http://dev.gridshore.nl:8018/presentation/create-presentation-nodejs/all</a></p>
<h2>Chosen technologies</h2>
<p>A slide consists of content, layout and styling. I want to limit the amount of styling information in the content. Still I want to make it simple. Therefore I have chosen to use a template engine for the front-end. I have some experience with Jade, which seems to do the job fine. The styling is done using css and where necessary, with additional components. An example is presenting source code on a slide.</p>
<p>When working with a web application and a browser it is wise to have a way to handle requests. Express.js is a nice node.js framework to use for url handling. I&#8217;ll get back with some sample code later on.</p>
<p>Since we are creating a web application, we need style sheets and images. I also use jQuery and a few plugins to position elements, to handle keyboard commands and to show source code. Please refer to the references section if you need more information about one of the technologies.</p>
<h2>The solution</h2>
<h3>Project layout</h3>
<p>An express.js application consists of an app.js, a public folder and a views folder. The app.js is the start of the application that you call with the node executable. In the public folder we have the static web resources. It contains the stylesheets, client-side javascripts and other static resources. The views folder contains the layout.jade file and all the jade views. Within the images and the views folder we have a subfolder for each presentation. I prefer to use the same path as the path specified for the url for the presentation. More on this later.</p>
<p>The project now has two dependencies: expressjs and jade. I like to manage my dependencies with npm.</p>
<h3>Creating the presentation</h3>
<p>The presentation is created as a separate component, have a look at <a href="https://github.com/jettro/nodejs-presenter/blob/master/presentation.js">presentation.js</a>. It contains the title of the presentation, the urlIdentifier, a description and the slides. The urlIdentifier is used in the url when requesting the presentation in a browser. The slides are also components. You can find the slide component in <a href="https://github.com/jettro/nodejs-presenter/blob/master/slide.js">slide.js</a>. The slide contains an identifier and a title. The identifier is important, this is used to find the right jade view file. The following code block shows the creation of the sample presentation.</p>
<pre class="brush: jscript; title: ; notranslate">
var createPresentationNodejs = [];
createPresentationNodejs.push(new Slide(&quot;intro&quot;,&quot;Creating a presentation with Node.js&quot;));
createPresentationNodejs.push(new Slide(&quot;goal&quot;,&quot;Goal&quot;));
createPresentationNodejs.push(new Slide(&quot;requirements&quot;,&quot;Requirements&quot;));
createPresentationNodejs.push(new Slide(&quot;technology&quot;,&quot;technology&quot;));
createPresentationNodejs.push(new Slide(&quot;urlhandling&quot;,&quot;Configure url handling&quot;));
createPresentationNodejs.push(new Slide(&quot;handlerequests&quot;,&quot;Handle requests&quot;));
createPresentationNodejs.push(new Slide(&quot;viewcontent&quot;,&quot;View content&quot;));
createPresentationNodejs.push(new Slide(&quot;thefuture&quot;,&quot;The Future&quot;));
createPresentationNodejs.push(new Slide(&quot;questions&quot;,&quot;Questions&quot;));

presentationController.addPresentation(new Presentation(&quot;Creating a presentation with Node.js&quot;,&quot;create-presentation-nodejs&quot;,
	createPresentationNodejs,
    &quot;For my work I had to prepare a short presentation of around 10 minutes. I decided to create a tool to create presentation &quot; +
            &quot;with and present about it. This is the result, a short presentation showing some of the ideas.&quot;));
</pre>
<p>In the first lines you can see how we create the array of slides. The last few lines show how we add a new presentation to the presentationController. We get back to this presentationController later on. First we have to look at express and url handling.</p>
<h3>Express and url handling</h3>
<p>Express is a web framework for node.js. You can do lots of things, in this blog post I do not want to give to much basics. Check the blog post I wrote on my employers blog: <a href="http://blog.jteam.nl/2011/04/18/learning-node-js/">http://blog.jteam.nl/2011/04/18/learning-node-js</a>.</p>
<p>THe thing I do want to mention is the url mapping for GET and POST requests. These are important for the flow of the application. You can also see the way that the PresentationController is used. Have a look at the following code block</p>
<pre class="brush: jscript; title: ; notranslate">
var presentationController = new PresentationController();

app.get('/', presentationController.allPresentations);
app.get('/presentation/:urlIdentifier', presentationController.index);
app.get('/presentation/:urlIdentifier/slide/:id', presentationController.slide);
app.post('/presentation/:urlIdentifier/slide/:id', presentationController.command);
app.get('/presentation/:urlIdentifier/all', presentationController.allSlides);
</pre>
<p>Going to the root of the application gives a list over presentations. Asking the presentation with the urlIdentifier of the presentation gives an overview of the presentation. You can also ask the /all, this will give all the slides. Check the section about a slide handout for more information on this.</p>
<p>The handling of the POST request is for navigation. Within the slide you can enter n for next, p for previous, a number for a specific slide and enter for the next slide. This will result in a command on the server using the post request. Creating this request can be found in the layout.jade. It is a normal form for the action to the url of the current slide number. Using the command and the current slide number we can determine the slide to select. The next block shows the client code, handling the post request is discussed in the next section.</p>
<pre class="brush: plain; title: ; notranslate">
form(action=&quot;/presentation/&quot;+urlIdentifier+&quot;/slide/&quot;+numSlide,method=&quot;POST&quot;)
    input(type=&quot;text&quot;, size=&quot;100&quot;, name=&quot;command&quot;, id=&quot;command&quot;)
</pre>
<p>Now we have seen the url handling, let us move on to the logic in the PresentationController</p>
<h3>The presentation controller</h3>
<p>The presentation controller contains the logic to handle a request and send the response back to the requestor. The following code block shows the the handling for the request to show all available presentations.</p>
<pre class="brush: jscript; title: ; notranslate">
PresentationController.prototype.allPresentations = function(req, res) {
    res.render('index', {locals: {presentations:presentations}});
};
</pre>
<p>The presentations is an internal array for the presentation controller. They are passed to the &#8216;index&#8217; view. More on the view with jade in the next section. The following code block is slightly more advanced. It contains the logic to show one slide.</p>
<pre class="brush: jscript; title: ; notranslate">
PresentationController.prototype.slide = function(req, res) {
    var id = req.params.id;
    var presentation = obtainPresentation(req.params.urlIdentifier);
    var slide = presentation.slides[id - 1];
    res.render(presentation.urlIdentifier + '/slide/' + slide.identifier,
            {locals: {
                numSlide:req.params.id,
                totalSlide:presentation.slides.length,
                titleSlide:slide.title,
                urlIdentifier:presentation.urlIdentifier
            }});
};

function obtainPresentation(urlIdentifier) {
    var len = presentations.length;
    for (var i = 0; i &amp;lt; len; i++) {
        var presentation = presentations[i];
        if (urlIdentifier == presentation.urlIdentifier) {
            return presentation;
        }
    }
    throw &quot;Could not find the url: &quot; + urlIdentifier;
}
</pre>
<p>The code contains a helper function to determine the presentation to show a slide for. The presentation is obtained by the url identifier. The page is rendered by using the specific jade template that is stored using the urlIdentifier in the slides folder. The name of the jade template is the same as the identifier as stored in the slide object.</p>
<p>The last bit I want to discuss is the command handling. We have a small form at the bottom of the page. This form accepts commands. We support &#8216;n&#8217; or &#8216;next&#8217;, &#8216;enter&#8217;, &#8216;p&#8217; or &#8216;previous&#8217; and the number of a slide. These all navigate between the slides. We also have the &#8216;home&#8217; command. This redirects to the root of the application. Handling the different commands is done with a very easy if-the-else structure. The following code block shows the idea.</p>
<pre class="brush: jscript; title: ; notranslate">
PresentationController.prototype.command = function(req, res) {
    var id = req.params.id;
    var urlIdentifier = req.params.urlIdentifier;
    var command = req.body.command;
    var presentation = obtainPresentation(urlIdentifier);
    var numSlides = presentation.slides.length;

    if (command == 'next' || command == 'n' || command == '') {
        if (id &lt; numSlides) id++;
    } else if (command == 'previous' || command == 'p' || command == 'prev') {
        if (id &gt; 1) id--;
    } else if (command == 'home') {
        res.redirect('/');
        return;
    } else if (!isNaN(command)) {
        var commandNum = parseInt(command);
        if (commandNum &gt; 0 &amp;&amp; commandNum &amp;lt;= numSlides) id = commandNum;
    }

    res.redirect('/presentation/' + urlIdentifier + '/slide/' + id);
};
</pre>
<p>Enough about logic, let us move on to the view side and discuss templating using Jade.</p>
<h3>Little bit of jade</h3>
<p>Again I do not want to go into all the details of jade. Jade is a very condensed format for creating html pages. It integrates nicely with express. Data is passed from express to jade. Jade uses a layout file, you can also use partial rendering without a layout file. More on this in a next section. In this case we include the header and the footer in the layout file. Each slide is presented in its own jade template file. The following code block shows the jade template for the intro slide in the sample.</p>
<pre class="brush: plain; title: ; notranslate">
img(src='/images/' + urlIdentifier + '/logo.jpg')
div.heading author
div.heading Jettro Coenradie
img(src='/images/' + urlIdentifier + '/nature.jpg', class=&quot;shadow&quot;)
</pre>
<p><img style="display:block; margin-left:auto; margin-right:auto;" src="http://www.gridshore.nl/wp-content/uploads/Screen-shot-2011-06-15-at-12.09.47.png" alt="Screen shot 2011 06 15 at 12 09 47" border="0" width="600" height="536" /></p>
<p>Another nice thing about using the web browser as a tool is that you can use nice plugins available for websites to create your slides. A good example is showing source code. This is what the next section is about.</p>
<h3>Showing code</h3>
<p>To show source code I use a <a href="http://alexgorbatchev.com/SyntaxHighlighter">syntax highlighter from alex gorbatchev</a>. The client side library files are included in the public folder. Showing code in a jade template looks like this.</p>
<pre class="brush: plain; title: ; notranslate">
pre(class=&quot;brush: js&quot;)
    | app.get('/', function(req, res) {
    |     res.render('index',
    |         {locals: {slides:slide.allSlides()}});
    | });
    | app.get('/slide/:id', slide.index);
    | app.post('/slide/:id', slide.command);
script(type=&quot;text/JavaScript&quot;)
    | SyntaxHighlighter.all()
</pre>
<p><img style="display:block; margin-left:auto; margin-right:auto;" src="http://www.gridshore.nl/wp-content/uploads/Screen-shot-2011-06-15-at-12.15.32.png" alt="Screen shot 2011 06 15 at 12 15 32" border="0" width="600" height="336" /></p>
<h3>Creating a slide handout</h3>
<p>One of the requirements of a presentation is often to have the slides available as a pdf document or other format that is able to share the slides. The path I am taking is using one page for a presentation that contains the complete presentation. I would love to have a pdf generated from the webpage. But for now this is one step to far. I did have a look at using node.js child processes to run a command line tool called wkhtmltopdf. I want to do some more experimentation here. Will get back when I have a good solution. Beneath are some references if you want to try it out yourself.</p>
<ul>
<li><a href="http://blog.darkhax.com/2010/11/29/2-node-js-apps-that-showed-me-the-light">http://blog.darkhax.com/2010/11/29/2-node-js-apps-that-showed-me-the-light</a></li>
<li><a href="http://code.google.com/p/wkhtmltopdf/">http://code.google.com/p/wkhtmltopdf/</a></li>
<p> </ul>
<p>To be able to create one page with all the slides I made use of the partial rendering of jade and express. The idea is to pass a the presentation to a view. The view steps over all the slides in the presentation and renders the views on one page. The following code block shows the view (all.jade).</p>
<pre class="brush: plain; title: ; notranslate">
div#All slides
h2 #{presentation.title}
ul
    - each slide in presentation.slides
        - var slideTemplate = presentation.urlIdentifier + '/slide/' + slide.identifier
        .slideAll
            - if(typeof(slide.title) != &quot;undefined&quot;)
                div.title #{slide.title}
            !=partial(slideTemplate, {'urlIdentifier':presentation.urlIdentifier})
</pre>
<p>The &#8220;presentation&#8221; object is provided by the express component. From this object we obtain the path in the views folder. The presentation object also contains the slides. Each slide has its own identifier. Using the slide identifier and the urlIdentifier we can find the jade template to render. The trick is in the last line <strong>!=partial(&#8230;)</strong>. This tells the engine to include the specific slide templates in he current view.</p>
<h2>The demo</h2>
<p>There is an online demo available at: <a href="http://dev.gridshore.nl:8018/">http://dev.gridshore.nl:8018/</a>. It contains only one presentation at the moment. But that is enough to get an idea. This blogpost also contains two screen dumps.</p>
<h2>The future</h2>
<p>I want to integrate the pdf generation within the application. I have some hints, but not the complete solution. Maybe extend the tool in a way that you can create new presentations on the fly, but I do not want to make an alternative to presentation tools that are already there. I also want to add more controls, would be nice to be able to use the arrow keys and maybe support remote controls that way.</p>
<h2>References</h2>
<ul>
<li><a href="http://nodejs.org/">http://nodejs.org/</a> &#8211; Node.js home page</li>
<li><a href="http://expressjs.com/">http://expressjs.com/</a>- Express.js</li>
<li><a href="http://jade-lang.com/">http://jade-lang.com/</a>- Jade</li>
<li><a href="http://alexgorbatchev.com/SyntaxHighlighter">http://alexgorbatchev.com/SyntaxHighlighter</a>- Code beautifier</li>
<li><a href="https://github.com/jettro/nodejs-presenter">https://github.com/jettro/nodejs-presenter</a> &#8211; the code for the sample.</li>
<li><a href="http://blog.darkhax.com/2010/11/29/2-node-js-apps-that-showed-me-the-light">http://blog.darkhax.com/2010/11/29/2-node-js-apps-that-showed-me-the-light</a> &#8211; inspiration for pdf export.</li>
<li><a href="http://code.google.com/p/wkhtmltopdf/">http://code.google.com/p/wkhtmltopdf/</a> &#8211; want to use for pdf export.</li>
<p> </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%2F2011%2F06%2F15%2Fcreating-presentations-with-node-js%2F&amp;title=Creating%20presentations%20with%20Node.js&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/06/15/creating-presentations-with-node-js/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Installing Node.js on my new Synology</title>
		<link>http://www.gridshore.nl/2011/04/04/installing-node-js-on-my-new-synology/</link>
		<comments>http://www.gridshore.nl/2011/04/04/installing-node-js-on-my-new-synology/#comments</comments>
		<pubDate>Mon, 04 Apr 2011 16:48:35 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[Frontend Technology]]></category>
		<category><![CDATA[server technology]]></category>
		<category><![CDATA[ds211+]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[nodejs]]></category>
		<category><![CDATA[synology]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=1149</guid>
		<description><![CDATA[<p>About a week a go I bought myself a Synology. A very nice product with reasonable value for money. Especially if you consider the options you have if you are not scared to get your hands dirty. Agreed the graphical admin console is nice, but the linux options are even nicer. I wanted to [...]]]></description>
			<content:encoded><![CDATA[<p>About a week a go I bought myself a <a href="http://www.synology.com/">Synology</a>. A very nice product with reasonable value for money. Especially if you consider the options you have if you are not scared to get your hands dirty. Agreed the graphical admin console is nice, but the linux options are even nicer. I wanted to have a cheap solution to host a node.js server at home. In the end I am glad I made the choice for this model.</p>
<p>In this blog post I will provided as much steps that I can remember and or wrote down while installing a node.js server on my Synology. This was not the easiest thing I have ever done. If I can help some others that want to get more out of their Synology my hours of work are worth it.</p>
<p><span id="more-1149"></span><br />
<h2>Terminal access</h2>
<p>The Synology comes with an installed firmware. In my case I started with the 3.1 DSM software.</p>
<p>Tweaking you Synology starts with obtaining Terminal access. You can enable this in the configuration panel of DSM. By default you can access your synology using DiskStation.local with the admin or root account. For the things we are going to do I recommend using the root account. The password for the root account is the same as for the admin account. Just so you know. Go on check if you have access</p>
<pre>
# ssh root@DiskStation.local
</pre>
<h2>ipkg</h2>
<p>The next step is to install ipkg, the package manager for you synology. There are multiple resources on the web that explain how to do this. Most of them point to <a href="http://forum.synology.com/wiki/index.php/Overview_on_modifying_the_Synology_Server,_bootstrap,_ipkg_etc#How_to_install_ipkg">this wiki page</a>. It is important to take the right version of the bootstrap for your synology system. The variations in processors used are big, therefore you have to use the right software. The processor can be obtained using <a href="http://forum.synology.com/wiki/index.php/What_kind_of_CPU_does_my_NAS_have">this page</a>. You can also find out more about your system from the command line.</p>
<pre>
DiskStation> uname -a
Linux DiskStation 2.6.32.12 #1605 Thu Mar 24 02:12:03 CST 2011 armv5tel GNU/Linux
</pre>
<p>For the DS211+ I needed the <em>Marvel Kirkwood mv6282 ARM</em>. The easiest way to get in onto your system is to use wget. Remember that tool, we will talk more about it.</p>
<pre>
<a href="http://wizjos.endofinternet.net/synology/archief/syno-mvkw-bootstrap_1.2-7_arm-ds111.xsh">wget http://wizjos.endofinternet.net/synology/archief/syno-mvkw-bootstrap_1.2-7_arm-ds111.xsh</a>
</pre>
<p>I created a downloads folder in the home folder of root. Executing the script is very easy</p>
<pre>
sh syno-mvkw-bootstrap_1.2-7_arm-ds111.xsh
</pre>
<p>Now we have ipkg installed. The best way to check if it works is to update and upgrade.</p>
<pre>
DiskStation> ipkg update
Downloading http://ipkg.nslu2-linux.org/feeds/optware/cs08q1armel/cross/unstable/Packages.gz
Inflating http://ipkg.nslu2-linux.org/feeds/optware/cs08q1armel/cross/unstable/Packages.gz
Updated list of available packages in /opt/lib/ipkg/lists/cross
Successfully terminated.
DiskStation> ipkg upgrade
Nothing to be done
Successfully terminated.
</pre>
<p>If you just want to install software that is available via ipkg, this is it. In my case I want to install node.js. This is not available via ipkg, therefore we need to compile it ourselves. This is where the problem starts. So in the next section we will have a look what you need to compile stuff.</p>
<h2>Compile from source</h2>
<p>Compiling source code on linus needs compilers (gcc) and headers files. The header files contain information about the libraries that are required during compilation of code that makes use of these libraries. Ipkg has the option to install development libraries that are required to compile source. To bad the current version does not work out of the box. With the help of some resources on the web and a lot of experimentation I finally got a working system. This part is the most important part of getting your system ready to compile node.js.</p>
<p>Usually you would install optware-devel with ipkg. But we start off with some other libraries that will not work with optware-devel.</p>
<pre>
ipkg remove wget
wget http://ipkg.nslu2-linux.org/feeds/optware/cs08q1armel/cross/unstable/wget-ssl_1.12-2_arm.ipk
wget http://ipkg.nslu2-linux.org/feeds/optware/cs08q1armel/cross/unstable/openssl_0.9.8p-1_arm.ipk
wget http://ipkg.nslu2-linux.org/feeds/optware/cs08q1armel/cross/unstable/libidn_1.19-1_arm.ipk
ipkg install libidn_1.19-1_arm.ipk
ipkg install openssl_0.9.8p-1_arm.ipk
ipkg install wget-ssl_1.12-2_arm.ipk
ipkg install openssl-dev
</pre>
<p>We are almost set, now I have a problem with my limited linux knowledge. I found some resources on the web and in the end I had to copy some resources around. So these steps might not be optimal, but they did work for me.</p>
<p>I took the first step from <a href="http://forum.synology.com/enu/viewtopic.php?f=90&#038;t=30132&#038;p=119287&#038;hilit=pthread#p120183">this post</a>.</p>
<pre>
mkdir /opt/arm-none-linux-gnueabi/lib_disabled
mv /opt/arm-none-linux-gnueabi/lib/libpthread* /opt/arm-none-linux-gnueabi/lib_disabled
cp /lib/libpthread.so.0 /opt/arm-none-linux-gnueabi/lib/
cd /opt/arm-none-linux-gnueabi/lib/
ln -s libpthread.so.0 libpthread.so
ln -s libpthread.so.0 libpthread-2.5.so
</pre>
<p>The final copying you need to do actually only appeared to me when running node.js. Therefore I am not completely sure if this is right, but again it works for me.</p>
<pre>
cp /opt/lib/libssl.so.0.9.8 /usr/lib
cp /opt/lib/libcrypto.so.0.9.8 /usr/lib
</pre>
<p>If I remember correct, now is the time to start downloading node.js and start compiling.</p>
<h2>Compiling node.js</h2>
<p>Before we start compiling we need to have some source. This page describes what you need to do:</p>
<p><a href="https://github.com/joyent/node/wiki/Installation">https://github.com/joyent/node/wiki/Installation</a></p>
<p>I downloaded node in the /root folder, called ./configure and put the results in /opt/node. Before you can do that you need to install git first. This is easily done using ipkg. Now the steps to perform:</p>
<pre>
ipkg install git
cd /root
git clone https://github.com/joyent/node.git
cd node
./configure --prefix=/opt/node
make
make install
</pre>
<p>Hope it all goes as aspected and no errors arise. Beware the make step can take a long time (15-30 minutes or something). The next step is to add node.js to your path. In the root folder you can find the .profile file. In here you will find a PATH variable. Change it to include the folder /opt/node/bin. Something like this</p>
<pre>
PATH="/opt/node/bin:$PATH:/bin:/sbin:/usr/bin:/usr/sbin:/usr/syno/bin:/usr/syno/sbin:/usr/local/bin:/usr/local/sbin"
</pre>
<p>That is the end of the journey. Now you can do your node things like install npm, express, jade, sass, socket.io, etc. If you have an application running you can execute it from the shell. The problem is that it does not keep running when you logout. There are multiple mechanisms to keep the process running. I found one that is actually itself a node.js application. It seems to do the trick for me.</p>
<p><a href="https://github.com/indexzero/forever">https://github.com/indexzero/forever</a></p>
<p>That is it, node.js running on your synology. if you want more information about what I am running on my synology, check the sources on Github or check my previous blog post.</p>
<p><a href="http://www.gridshore.nl/2011/03/16/first-steps-with-node-js/">http://www.gridshore.nl/2011/03/16/first-steps-with-node-js/</a><br/><br />
<a href="https://github.com/jettro/nodejstryout">https://github.com/jettro/nodejstryout</a></p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2011%2F04%2F04%2Finstalling-node-js-on-my-new-synology%2F&amp;title=Installing%20Node.js%20on%20my%20new%20Synology&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/04/04/installing-node-js-on-my-new-synology/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>First steps with Node.js</title>
		<link>http://www.gridshore.nl/2011/03/16/first-steps-with-node-js/</link>
		<comments>http://www.gridshore.nl/2011/03/16/first-steps-with-node-js/#comments</comments>
		<pubDate>Wed, 16 Mar 2011 20:53:42 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[Frontend Technology]]></category>
		<category><![CDATA[server technology]]></category>
		<category><![CDATA[express]]></category>
		<category><![CDATA[jade]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[nodejs]]></category>
		<category><![CDATA[sass]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=1147</guid>
		<description><![CDATA[<p>With a colleague I was talking about Node.js. My first though, &#8220;yeah right, JavaScript on the server!&#8221;. But you have to be open minded if you want to learn new stuff. Therefore I thought about giving it a spin. I started looking for resources on the web, read a few of them and ended [...]]]></description>
			<content:encoded><![CDATA[<p>With a colleague I was talking about Node.js. My first though, &#8220;yeah right, JavaScript on the server!&#8221;. But you have to be open minded if you want to learn new stuff. Therefore I thought about giving it a spin. I started looking for resources on the web, read a few of them and ended up at the article : <a href="http://howtonode.org/express-mongodb">express-mongo</a>. This article was the beginning of my Node.js journey.</p>
<p>In this blog item I want to show you the steps I took, the resources I found useful and some improvements to the article that seems a bit outdated. It is not an explanation of what Node.js is, but it does provide some help to get started on your own.</p>
<p><span id="more-1147"></span><br />
<h2>The source</h2>
<p>I took the sources from the article of Ciaran Jessup as my basis. So a lot of credits go to him. You can find my sources over at github:</p>
<p><a href="https://github.com/jettro/nodejstryout">https://github.com/jettro/nodejstryout</a></p>
<h2>Setting up my environment</h2>
<p>If you want to do something with nodejs, you have to install it first. I used MacPorts to install it, but lots of other ways are <a href="https://github.com/joyent/node/wiki/Installation">documented on the wiki</a>. Using MacPorts all you have to do is:</p>
<pre>
sudo port install nodejs
</pre>
<p>The next step is to install a package manager. The mentioned article uses kiwi, but the node.js documentation recommends npm. Therefore I chose to use npm as well. Installing npm is documented well on the website: <a href="https://github.com/isaacs/npm">https://github.com/isaacs/npm</a>. To be honest I am not sure anymore whether I installed using curl or using the download/make procedure. But in the end you should be able to install dependencies using npm. I just love the way npm is used to update modules. Not easy when using multiple projects that need different versions. But maybe there is a solution to that as well. For now, lets focus on installing some modules or dependencies. Everything needs to be done with sudo, just so you know. No worries, I&#8217;ll explain the different modules later on.</p>
<pre>
# sudo npm install express
# sudo npm install jade
# sudo npm install sass
</pre>
<p>Time to check if your environment works, try to execute the famous HelloWorld sample. But first issue the command: <strong>node &#8211;version</strong>. The following code block shows the sample as presented on the <a href="http://nodejs.org/">Node.js homepage</a>.</p>
<pre class="brush: jscript; title: ; notranslate">
var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(8124, &quot;127.0.0.1&quot;);
console.log('Server running at http://127.0.0.1:8124/');
</pre>
<p>Now start the server with node using : <strong>node helloworld.sh</strong> and point your browser to http://127.0.0.1:8124/.</p>
<p>Now you have your http server running, nice stuff.</p>
<h2>The sample</h2>
<p>The sample is all about providing a blog. The structure of the sample is based on the original sample. We have a public folder, a views folder and the application js files are in the root. These folders are used later on in the express code. Express is a web modules for Node.js. You can find out more about the module here: <a href="http://expressjs.com/">http://expressjs.com/</a>. The next section explains a bit more about using expressjs.</p>
<p>The sample can be started using the app.js file by calling node app.js. We start by analyzing the app.js file.</p>
<pre class="brush: jscript; title: ; notranslate">
var express = require('express');
var pub = __dirname + '/public';
var app = express.createServer();
var ArticleProvider = require('./articleprovider-memory').ArticleProvider;
var articleProvider = new ArticleProvider();
// ... more express stuff, will be discussed later on
app.listen(3000);
console.log('Express server started on port %s', app.address().port);
</pre>
<p>First we obtain the express modules, then we define a folder called pub that points to the public folder as mentioned before. In line 3 we create the express server and an ArticleProvider. The ArticleProvider is copied 1-on-1 from the article that was mentioned before. It is an in memory implementation for the datastore of the blog items. Check the sourcecode if you want to learn more about it. The final two lines are setting the port for the server to start, start the server and print a line to the console that the server has been started.</p>
<p>In the next section we will configure the express server.</p>
<h2>Express</h2>
<p>More information : <a href="http://expressjs.com/">http://expressjs.com/</a>.</p>
<p>The following code block is the remainder of the application. There are two parts in the code block. The first part is the configuration of the server, the second part configures the url handling. Within the server configuration we define the view engine (jade) and the folder where the views can be found. Another thing is the folder where the stylesheets in sass format are that need to be compiled. We also define the folder where the public files are using the <em>static</em> method. The last configuration is the bodyParser. This is required for handling the post. The second part about url handling is covered after the code.</p>
<pre class="brush: jscript; title: ; notranslate">
app.configure(function() {
    app.set('view engine', 'jade');
    app.set('views', __dirname + '/views');
    app.use(express.compiler({ src: pub, enable: ['sass'] }))
    app.use(express.methodOverride());
    app.use(express.static(pub));
    app.use(express.logger());
    app.use(express.bodyParser());
});

app.get('/', function(req, res) {
    articleProvider.findAll(function(error, docs) {
        res.render('blog', {locals: {docs: docs}});
    });
});

app.get('/blog/new', function (req, res) {
    res.render('blog_new', {locals: {title: 'New Blog Item'}});
});

app.post('/blog/new', function (req, res) {
    console.log('The provided title is : %s',req.body.new_title);
    articleProvider.save({title: req.body.new_title, body: req.body.new_body},
            function(error, docs) {
                res.redirect('/');
            });
});
</pre>
<p>Within the sourcecode you can identify three urls that are handled: /, /blog/new and a post to /blog/new. Notice that we use callbacks? This is what Node.js is all about, handling async callbacks. If you look at the app.get method for &#8216;/&#8217; you&#8217;ll see that we call the findAll method of the ArticleProvider. The result is used to render a view with the name <em>blog</em>. The part with locals is used to provide parameters to the view. In this case we provide the returned docs to the view. The next section will show you the very basics of jade, a template engine.</p>
<h2>Jade</h2>
<p>More information can be found here: <a href="https://github.com/visionmedia/jade">https://github.com/visionmedia/jade</a>.</p>
<p><cite>Jade is a high performance template engine heavily influenced by Haml and implemented with JavaScript for node.</cite></p>
<p>I am not going to give a lot of details about jade here. The following code block shows you the view with all the blog items.</p>
<pre class="brush: plain; title: ; notranslate">
h1 My blog
div
    a(href='/blog/new') New blog item
div#articles
    - each blog in docs
        div.article
            div.title #{blog.title}
            div.created_at #{blog.created_at}
            div.body #{blog.body}
</pre>
<p>As you can see, the code is very condensed. A good tool with code completion would be nice though. Still if you have some programming experience it should not be to hard to read. Check the mechanism for making a distinction between a class and an id. # is used to represent an idea and a &#8216;.&#8217; for a class. These both will be good to use in a stylesheet. Which is a nice bridge to the next section. This section is about sass that needs to be compiled in a stylesheet. The following code block shows the layout.jade file. This file contains the main template with the header of all pages. Check the way to define we use html 5.</p>
<pre class="brush: plain; title: ; notranslate">
!!! 5
html(lang=&quot;en&quot;)
  head
    title My Blog
    link(href=&quot;/style/style.css&quot;, media=&quot;screen&quot;, rel=&quot;stylesheet&quot;, type=&quot;text/css&quot;)
  body
    div!= body
</pre>
<h2>Sass</h2>
<p>More information can be found here: <a href="https://github.com/visionmedia/sass.js">https://github.com/visionmedia/sass.js</a>.</p>
<p>Is a condensed way of writing stylesheets. Before the stylesheets can actually be user they need to be compiled. This is done by express, check one of the earlier sections. The following codeblock shows the complete stylesheet. I guess it should not be to hard to follow if you have stylesheet experience.</p>
<pre class="brush: plain; title: ; notranslate">
body
  :font-family &quot;Helvetica Neue&quot;, &quot;Lucida Grande&quot;, &quot;Arial&quot;
  :font-size 13px
  :text-align center
  =text-stroke 1px rgba(255, 255, 255, 0.1)
  :color #555
h1, h2
  :margin 0
  :font-size 22px
  :color #343434
h1
  :text-shadow 1px 2px 2px #ddd
  :font-size 60px
#articles
  :text-align left
  :margin-left auto
  :margin-right auto
  :width 320px
  .article
    :margin 20px
    .created_at
      :display none
    .title
      :font-weight bold
      :text-decoration underline
      :background-color #eee
    .body
      :background-color #ffa
</pre>
<h2>Concluding</h2>
<p>There you have it, my first try on Node.js with extensive help of Ciaran Jessup. I do like Node.js., I love the speed of development. Would be nice to have some IDE support. I tried WebStorm, but it does not have Node.js support. It does help with the JavaScript coding. I will definitely continue playing around with Node.js. The next step is have a look at Rabbitmq.js. Finally I want to extend another sample of mine that makes use of the Axon framework with rabbitmq and Node.js for the front end. I also want to have a good look ar Socket.IO. So stay tuned for more blogs on this topic.</p>
<h2>Resources</h2>
<ul>
<li>https://github.com/jettro/nodejstryout</li>
<li>http://howtonode.org/express-mongodb</li>
<li>http://nodejs.org/</li>
<li>https://github.com/isaacs/npm</li>
<li>http://expressjs.com/guide.html</li>
<li>https://github.com/visionmedia/jade</li>
<li>https://github.com/visionmedia/sass.js</li>
<p> </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%2F2011%2F03%2F16%2Ffirst-steps-with-node-js%2F&amp;title=First%20steps%20with%20Node.js&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/03/16/first-steps-with-node-js/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Upgrade maven and switch between versions using bash on the mac</title>
		<link>http://www.gridshore.nl/2011/03/14/upgrade-maven-and-switch-between-versions-using-bash-on-the-mac/</link>
		<comments>http://www.gridshore.nl/2011/03/14/upgrade-maven-and-switch-between-versions-using-bash-on-the-mac/#comments</comments>
		<pubDate>Mon, 14 Mar 2011 17:25:17 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Mac OSX]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[macosx]]></category>
		<category><![CDATA[maven]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=1142</guid>
		<description><![CDATA[<p>Over three years a go I wrote a blog post explaining the steps to upgrade you maven installation on Mac OS X Leopard. I have been using snow leopard now for a while and things changed a bit. In one of the comments to that post Oskar Carlstedt mentioned the steps required on Snow [...]]]></description>
			<content:encoded><![CDATA[<p>Over three years a go I wrote a <a href="http://www.gridshore.nl/2008/01/28/upgrading-maven-on-the-mac/">blog post explaining the steps to upgrade you maven installation on Mac OS X Leopard</a>. I have been using snow leopard now for a while and things changed a bit. In one of the comments to that post Oskar Carlstedt mentioned the steps required on Snow Leopard. This is all fine if you upgrade a minor version, but with maven 3 things changed a lot. I have some projects that require maven 2, we did not have time yet to fix problems we have with maven 3. Still I prefer using maven 3. Therefore I have to change between versions often. I decided to create a bash script to help me out.</p>
<p>Within this blogpost I&#8217;ll explain the installation of maven on Snow Leopard and I&#8217;ll present the bash script that can help you to switch between installations of maven.</p>
<p><span id="more-1142"></span><br />
<h2>Maven on the Mac (Snow Leopard)</h2>
<p>By default maven is installed in the path: /usr/share/java. The maven executables are installed as maven-3.0.2 and maven-2.2.1. Since the upgrade path is a bit slow I tend to install my own maven binaries. I extract them as provided by apache using the apache-maven-x.x.x format.</p>
<p><img src="http://www.gridshore.nl/wp-content/uploads/Screen-shot-2011-03-14-at-10.45.03.png" alt="Maven installtions" border="0" width="600" height="217" /></p>
<p>A soft link is available in /usr/share/maven. This is the link that points to one of the maven binaries. This is the place where you switch between versions of maven. You can remove the soft link and create one to the right maven home folder. A small catch is that you need to be root to remove and create the link. Using sudo is good enough.</p>
<p>The commands to do this are:</p>
<pre>
cd /usr/share
sudo rm maven
ln -s /usr/share/java/apache-maven-3.0.2 maven
</pre>
<p>So not a lot of work, but just annoying to do one or more times a day. Therefore I have wanted to have a bash script to do it for me.</p>
<h2>Introducing bash</h2>
<p>When automating something on the Mac I tend to use bash. I am not an expert, but using google I can do interesting things. I&#8217;ll step to the script. To start off, define the two maven installations that I currently use:</p>
<pre>
maven2=apache-maven-2.2.1
maven3=apache-maven-3.0.2
</pre>
<p>Next step is to remove the current soft link if it exists.</p>
<pre>
if [ -e /usr/share/maven ]
then
	sudo rm /usr/share/maven
fi
</pre>
<p>Next is to store the maven implementation version in a variable</p>
<pre>
maven=$maven3

if [ $# == 0 ]
then
	echo "No Arguments supplied, using default maven 3"
elif [ $1 == 2 ]
then
	maven=$maven2
else
	echo "Using the default maven setting, provided argument [$1] is not recognized"
fi
</pre>
<p>The default is maven 3, than we check if arguments are provided to the script. If no arguments are provided, we do nothing and use the default. if an argument is provided we check if it is 2. If so, we set maven 2 as the implementation. If something else than 2 is provided we take the default which is maven 3. The final step is to create the soft link again.</p>
<pre>
sudo ln -s /usr/share/java/$maven /usr/share/maven
</pre>
<h3>Using spaces</h3>
<p>One thing that took me a few moments to understand is the use of spaces within bash. maven=$maven2 is not the same as maven = $maven2</p>
<h2>The complete script</h2>
<pre class="brush: bash; title: ; notranslate">
#!/bin/bash
echo &amp;quot;Setting the maven implementation version&amp;quot;

maven2=apache-maven-2.2.1
maven3=apache-maven-3.0.2

if [ -e /usr/share/maven ]
then
	echo &amp;quot;Remove the maven soft link.&amp;quot;
	sudo rm /usr/share/maven
else
	echo &amp;quot;Maven soft link could not be found.&amp;quot;
fi

maven=$maven3

if [ $# == 0 ]
then
	echo &amp;quot;No Arguments supplied, using default maven 3&amp;quot;
elif [ $1 == 2 ]
then
	echo &amp;quot;Setting maven to use to maven 2&amp;quot;
	maven=$maven2
else
	echo &amp;quot;Using the default maven setting, provided argument [$1] is not recognized&amp;quot;
fi

echo &amp;quot;Creating new soft link to $maven&amp;quot;
sudo ln -s /usr/share/java/$maven /usr/share/maven
</pre>
<h2>Room for improvement</h2>
<p>It would be nice to do a scan of the directory /usr/share/java and provide you with options to select from. You could also select the most recent version of maven 2 or 3 or even 2.2 and 3.0. If I have a need for that I&#8217;ll update the script <img src='http://www.gridshore.nl/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<h2>Concluding</h2>
<p>That is it, you now have a script that you can call with the implementation you want to set. I called mine setmaven.sh and you would call it like:</p>
<pre>
./setmaven.sh 2
</pre>
<p>You can check if it is working with the well known mvn &#8211;version command</p>
<p><img src="http://www.gridshore.nl/wp-content/uploads/Screen-shot-2011-03-14-at-18.59.53.png" alt="Screen shot 2011 03 14 at 18 59 53" border="0" width="600" height="388" /></p>
<p>Feel free to comment for improvements.</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%2F03%2F14%2Fupgrade-maven-and-switch-between-versions-using-bash-on-the-mac%2F&amp;title=Upgrade%20maven%20and%20switch%20between%20versions%20using%20bash%20on%20the%20mac&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/03/14/upgrade-maven-and-switch-between-versions-using-bash-on-the-mac/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Axonframework samples</title>
		<link>http://www.gridshore.nl/2011/02/21/axonframework-samples/</link>
		<comments>http://www.gridshore.nl/2011/02/21/axonframework-samples/#comments</comments>
		<pubDate>Mon, 21 Feb 2011 08:22:14 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[Axon Framework]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[axon]]></category>
		<category><![CDATA[axonframework]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=1138</guid>
		<description><![CDATA[<p> <p>Axon framework is rapidly moving to the 1.0 release. Just a few days a go Allard released the first release candidate. You can find more information in his blog item: First release candidate available. In the past I have created multiple samples that some aspect of axon or the integration of axon with [...]]]></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" style="float:left;" />
<p>Axon framework is rapidly moving to the 1.0 release. Just a few days a go Allard released the first release candidate. You can find more information in his blog item: <a href="http://blog.jteam.nl/2011/02/16/axon-framework-1-0-first-release-candidate-available/">First release candidate available</a>. In the past I have created multiple samples that some aspect of axon or the integration of axon with other technologies.</p>
<p>In this blog post I want to go over all the axon samples that I have created, some of them together with Allard. I will explain the intentions of all the samples and the technologies used.</p>
<p>If you are missing samples, have good ideas, please let me know and I&#8217;ll see what I can do.</p>
<p><span id="more-1138"></span><br />
<h2>Company HR</h2>
<table>
<tr>
<th>Sources</th>
<td>https://github.com/jettro/CompanyHr</td>
</tr>
<tr>
<th>Goal</th>
<td>Show the integration of Axon and the Google app engine</td>
</tr>
<tr>
<th>Technologies</th>
<td>Google app engine, Objectify, Spring security, Spring mvc</td>
</tr>
<tr>
<th>Blogposts</th>
<td><a href="http://blog.jteam.nl/2011/01/04/deploying-a-cqrs-application-based-on-the-axon-framework-on-google-app-engine/">http://blog.jteam.nl/2011/01/04/deploying-a-cqrs-application-based-on-the-axon-framework-on-google-app-engine/</a></td>
</tr>
</table>
<p>I started this sample to create a google app engine based event store. In the beginning I had to do some tweaks to the axon framework to make it work. Mostly serialization issues. By now Allard has created solutions to all these problems. The only thing I have to change is the XStream class. Some of the default Converters do not work on google app engine and the reflection provider needs to be the pure java one.</p>
<p>The code contains three classes: EventEntry, GaeEventStore, and GaeSnapshotter. Persistence is taken care of using the low level data api of google app engine. The sample also needs a query side implementation. For the query side I have chosen to use Objectify. If you want more details about the implementation check the source code or the mentioned blog post.</p>
<p>The security is taken care of using spring security. Again of course integrated with google app engine. Most important ideas for the implementation are taken from the samples from the spring security project.</p>
<h2>Axon address book sample</h2>
<table>
<tr>
<th>Sources</th>
<td>http://code.google.com/p/axonframework/source/browse/trunk#trunk%2Fsample%2Faddressbook</td>
</tr>
<tr>
<th>Goal</th>
<td>Show the basic usage of the axon framework with some front end technologies. At the moment two complete implementations are available: Flex using Parsley and normal web using spring mvc. A third client is in progress using the Vaadin project. All clients use the same app component with the command and query classes.</td>
</tr>
<tr>
<th>Technologies</th>
<td>Spring mvc, Parsley (flex), Vaadin</td>
</tr>
<tr>
<th>Blogposts</th>
<td><a href="http://www.gridshore.nl/2010/02/25/creating-a-sample-for-axon-using-flex-and-parsley/">http://www.gridshore.nl/2010/02/25/creating-a-sample-for-axon-using-flex-and-parsley/</a><br/><a href="http://www.gridshore.nl/2010/04/11/attaching-flex-to-axon-using-the-new-axon-commandbus/">http://www.gridshore.nl/2010/04/11/attaching-flex-to-axon-using-the-new-axon-commandbus/</a><br/></td>
</tr>
</table>
<p>This is the sample that comes with Axon. It is a nice introduction into some of the options that Axon has. The flex client shows a nice integration with the event listeners and a very generic component to send commands to the command bus. The only catch with this sample is that the used libraries are slightly outdated. I&#8217;ll try to do some upgrades in the nearby future.</p>
<p>The spring-mvc client is one of those clients a lot of people will create or at least something similar.</p>
<p>The client that is under construction is the Vaadin client. A very nice way of creating business oriented applications. More on this sample will follow in a later blog post.</p>
<h2>Axon address book Grails</h2>
<table>
<tr>
<th>Sources</th>
<td>https://github.com/jettro/axon-addressbook-grails</td>
</tr>
<tr>
<th>Goal</th>
<td>I wanted to show there is more to axon than java. Oke, groovy is also java, but it is perfectly possible to use Axon with groovy. In this sample I use grails to create the query side of the application and use the commands and events created in groovy to do the other part. The sample is the same usecase as the one coming with axon.</td>
</tr>
<tr>
<th>Technologies</th>
<td>Grails</td>
</tr>
<tr>
<th>Blogposts</th>
<td><a href="http://www.gridshore.nl/2010/04/08/use-grails-and-axon-to-create-a-cqrs-application-part-i/">http://www.gridshore.nl/2010/04/08/use-grails-and-axon-to-create-a-cqrs-application-part-i/</a><br/><a href="http://www.gridshore.nl/2010/04/16/use-grails-and-axon-to-create-a-cqrs-application-part-ii/">http://www.gridshore.nl/2010/04/16/use-grails-and-axon-to-create-a-cqrs-application-part-ii/</a><br/></td>
</tr>
</table>
<p>In this sample I show the groovy side of Axon. To be honest, I am not sure if this would be something that I would recommend. But it does work. I do like the query side with grails. I think doing the commands and events might be better of in plain java. Although omitting the getters and setters for all the duplicate properties is still nice in groovy. Maybe using a bit more type safeness could help.</p>
<h2>Axon trader</h2>
<table>
<tr>
<th>Sources</th>
<td>https://github.com/jettro/Axon-trader</td>
</tr>
<tr>
<th>Goal</th>
<td>Create an application that does more than the very basic stuff. The application will be the basis for load testing axon and in the future to do some remoting with axon as well. The sample is used to create the MongoDB Axon EventStore.</td>
</tr>
<tr>
<th>Technologies</th>
<td>MongoDB, Spring-mvc, Gradle</td>
</tr>
<tr>
<th>Blogposts</th>
<td><a href="http://www.gridshore.nl/2010/09/20/learning-mongodb/">http://www.gridshore.nl/2010/09/20/learning-mongodb/</a><br/><a href="http://www.gridshore.nl/2010/09/27/still-learning-mongodb/">http://www.gridshore.nl/2010/09/27/still-learning-mongodb/</a><br/></td>
</tr>
</table>
<p>This project was not meant to be using to much advanced technologies outside of MongoDB. During the creation of the sample we developed the MongoDB implementation of the Axon EventStore. By now this implementation is in the Axon core. This sample is mostly interesting for the domain. The trader engine is simplistic, but it works.</p>
<h2>Concluding</h2>
<p>As you can see there are some samples available. Others are also publishing samples, some googling will help you out in finding them.</p>
<p>If you feel that you are missing something in the samples please let me know or try the Axon mailing list.</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%2F02%2F21%2Faxonframework-samples%2F&amp;title=Axonframework%20samples&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/02/21/axonframework-samples/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

