<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Stefan Norberg&#039;s weblog</title>
	<atom:link href="http://stnor.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://stnor.wordpress.com</link>
	<description>Up and down the technology stack</description>
	<lastBuildDate>Fri, 20 Jan 2012 13:38:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='stnor.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Stefan Norberg&#039;s weblog</title>
		<link>http://stnor.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://stnor.wordpress.com/osd.xml" title="Stefan Norberg&#039;s weblog" />
	<atom:link rel='hub' href='http://stnor.wordpress.com/?pushpress=hub'/>
		<item>
		<title>An attempt at a developer friendly build pipe line</title>
		<link>http://stnor.wordpress.com/2011/12/29/an-attempt-at-developer-friendly-build-pipe-line/</link>
		<comments>http://stnor.wordpress.com/2011/12/29/an-attempt-at-developer-friendly-build-pipe-line/#comments</comments>
		<pubDate>Thu, 29 Dec 2011 19:55:29 +0000</pubDate>
		<dc:creator>Stefan Norberg</dc:creator>
				<category><![CDATA[devops]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Web Techology]]></category>
		<category><![CDATA[build pipeline]]></category>
		<category><![CDATA[configuration management]]></category>
		<category><![CDATA[continous delivery]]></category>
		<category><![CDATA[dbdeploy]]></category>
		<category><![CDATA[jenkins]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[nomp]]></category>
		<category><![CDATA[Puppet]]></category>
		<category><![CDATA[sql scripts]]></category>
		<category><![CDATA[yum]]></category>

		<guid isPermaLink="false">http://stnor.wordpress.com/?p=211</guid>
		<description><![CDATA[Background I&#8217;ve spent some evenings/nights over the christmas holiday improving the deployment of Nomp.se, a site where kids can practice math for free, that we run on EC2. The situation we had was that we deployed to the EC2 server &#8230; <a href="http://stnor.wordpress.com/2011/12/29/an-attempt-at-developer-friendly-build-pipe-line/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=stnor.wordpress.com&amp;blog=3757969&amp;post=211&amp;subd=stnor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h2>Background</h2>
<p>I&#8217;ve spent some evenings/nights over the christmas holiday improving the deployment of<a title="Practic math at Nomp" href="http://nomp.se" target="_blank"> Nomp.se, a site where kids can practice math for free,</a> that we run on EC2.</p>
<p>The situation we had was that we deployed to the EC2 server using a locally installed Jenkins CI-server, which built the artifact (a WAR) and used the maven tomcat plugin to deploy to the local tomcat server, which was a rpm package provided by Amazon (yum install tomcat6). The setup worked pretty ok, but it was a hack. Database changes were applied and tested manually &#8211; we had a folder &#8220;sql&#8221; that contained numbered sql files that should be applied in order.</p>
<p>Clearly a lot of room for improvement in this area!</p>
<h3>Goals with the new build pipeline</h3>
<p>I wanted to reach the following goals with the new build pipeline:</p>
<ul>
<li>One build from the build server all the way from my local Jenkins through test environments and into production.</li>
<li>100% control over configuration changes of all components (Apache httpd, Apache Tomcat, MySql database), so that changes can be tested in the normal pipeline without relying on manual hacks.</li>
<li>It should be developer friendly. A developer with basic understanding of Linux, maven and tomcat should be able to make changes to and work with the build pipe line.</li>
<li>Hence, it should only rely on basic tooling (ant, maven, rpm packages) for doing the heavy lifting and use capabilities of other tools, eg Jenkins, Puppet, Capistrano as (non-critical) value add.</li>
</ul>
<p>After a few iterations I was able to get to the following to deploy any configuration change on to a production server.</p>
<pre>on the build server:
 $ mvn deploy

on the target server:
 # yum -y update nomp-web nomp-tomcat nomp-dbdeploy
 # cd /opt/nomp-dbdeploy; ant
 # /etc/init.d/nomp restart</pre>
<p>That&#8217;s it. Four steps. There are no shell scripts involved. There is no rsync, there is no scp:ing of files. How I did it? Hold on, I will come to that in a minute or two <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>System configuration and prerequisites</h2>
<p>In order to make sure the server contains the prerequisite packages and configuration I used Puppet.</p>
<blockquote><p>&#8220;Puppet is a declarative language for expressing system configuration, a client and server for distributing it, and a library for realizing the configuration.</p>
<p>Rather than approaching server management by automating current techniques, Puppet reframes the problem by providing a language to express the relationships between servers, the services they provide, and the primitive objects that compose those services. Rather than handling the detail of how to achieve a certain configuration or provide a given service, Puppet users can simply express their desired configuration using the abstractions they’re used to handling, like service and node, and Puppet is responsible for either achieving the configuration or providing the user enough information to fix any encountered problems.&#8221;</p>
<p>from <a href="http://projects.puppetlabs.com/projects/puppet/wiki/Big_Picture" target="_blank">http://projects.puppetlabs.com/projects/puppet/wiki/Big_Picture</a></p></blockquote>
<p>I&#8217;m not going to go into detail how to setup Puppet in this text, but here&#8217;s what I do with Puppet in order to support the build pipe line:</p>
<ul>
<li>Ensure that the service accounts and groups exists on the target system</li>
<li>Ensure that software I rely on is installed (ant, apache httpd, mysqld)</li>
<li>Configuration management of a few configuration files such as httpd.conf, my.cnf etc.</li>
</ul>
<p><strong>Puppet config file example:</strong></p>
<pre>user { nomp:
 ensure =&gt; present,
 uid =&gt; 300,
 gid =&gt; 300,
 shell =&gt; '/bin/bash',
 home =&gt; '/opt/nomp',
 managehome =&gt; true,
 }
group { nomp:
 ensure =&gt; 'present',
 gid =&gt; 300
 }
package { "ant":
 ensure =&gt; "installed"
 }</pre>
<p>The above configuration means that Puppet will ensure that the user nomp and group nomp will exist on the system and that the ant package will be installed.<br />
I will do a whole lot more work with configuration management and provisioning with Puppet going forward, but the above is what was needed to meet my project goals.</p>
<h2>Getting started</h2>
<p>I started with trying package my existing WAR project as an rpm (or .deb). When Googling about for a while I found the RPM Maven Plugin (<a href="http://mojo.codehaus.org/rpm-maven-plugin/" target="_blank">http://mojo.codehaus.org/rpm-maven-plugin/</a>). It basically lets you build rpms using maven. The downside is that is relies on the &#8220;rpm&#8221; command installed in order to produce the final RPM from the spec file. In order to get a working maven environment on all platforms, I wrapped the rpm plugin in a maven build profile.</p>
<p>(Later I also found a pure java rpm tool (redline-rpm), but I haven&#8217;t looked into it yet).</p>
<p>The trickiest part was to get a good setup for artifact versions and RPM-release versions so that the maven release plugin could still be used without any manual changes.<br />
The rpm-plugin has some funky defaults (<a href="http://mojo.codehaus.org/rpm-maven-plugin/ident-params.html#release" target="_blank">http://mojo.codehaus.org/rpm-maven-plugin/ident-params.html#release</a>) that wasn&#8217;t going to work with &#8220;yum update&#8221;.<br />
It was a lot of experimentation, but in the end I settled for the Build Number Maven Plugin (<a href="http://mojo.codehaus.org/buildnumber-maven-plugin/" target="_blank">http://mojo.codehaus.org/buildnumber-maven-plugin/</a>).<br />
It&#8217;s a pretty simple plugin that checks the SCM for the revision number and exposes that as a maven variable.</p>
<p>Here&#8217;s the RPM-part of my WAR POM:</p>
<pre>&lt;profiles&gt;
  &lt;profile&gt;
    &lt;id&gt;rpm&lt;/id&gt;
    &lt;activation&gt;
      &lt;os&gt;
        &lt;name&gt;linux&lt;/name&gt;
      &lt;/os&gt;
    &lt;/activation&gt;
    &lt;build&gt;
      &lt;plugins&gt;
        &lt;plugin&gt;
          &lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt;
          &lt;artifactId&gt;rpm-maven-plugin&lt;/artifactId&gt;
          &lt;version&gt;2.1-alpha-1&lt;/version&gt;
          &lt;extensions&gt;true&lt;/extensions&gt;
          &lt;executions&gt;
            &lt;execution&gt;
              &lt;goals&gt;
                &lt;goal&gt;attached-rpm&lt;/goal&gt;
              &lt;/goals&gt;
            &lt;/execution&gt;
          &lt;/executions&gt;
          &lt;configuration&gt;
            &lt;copyright&gt;Copyright 2011 Selessia AB&lt;/copyright&gt;
            &lt;distribution&gt;Nomp&lt;/distribution&gt;
            &lt;group&gt;${project.groupId}&lt;/group&gt;
            &lt;packager&gt;${user.name}&lt;/packager&gt;
            &lt;!-- need to use the build number plugin here in order for yum upgrade to work in snapshots --&gt;
            &lt;release&gt;${buildNumber}&lt;/release&gt;
            &lt;defaultDirmode&gt;555&lt;/defaultDirmode&gt;
            &lt;defaultFilemode&gt;444&lt;/defaultFilemode&gt;
            &lt;defaultUsername&gt;nomp&lt;/defaultUsername&gt;
            &lt;defaultGroupname&gt;nomp&lt;/defaultGroupname&gt;
            &lt;requires&gt;
              &lt;require&gt;nomp-tomcat&lt;/require&gt;
            &lt;/requires&gt;
            &lt;mappings&gt;
              &lt;!-- webapps deployment --&gt;
              &lt;mapping&gt;
                &lt;directory&gt;${rpm.install.webapps}/${project.artifactId}&lt;/directory&gt;
                &lt;sources&gt;
                  &lt;source&gt;
                    &lt;location&gt;target/${project.artifactId}-${project.version}&lt;/location&gt;
                  &lt;/source&gt;
                &lt;/sources&gt;
              &lt;/mapping&gt;
            &lt;/mappings&gt;
          &lt;/configuration&gt;
        &lt;/plugin&gt;
      &lt;/plugins&gt;
    &lt;/build&gt;
  &lt;/profile&gt;
&lt;/profiles&gt;</pre>
<p>Here&#8217;s the build number plugin configuration:</p>
<pre>&lt;plugin&gt;
    &lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt;
    &lt;artifactId&gt;buildnumber-maven-plugin&lt;/artifactId&gt;
    &lt;version&gt;1.0&lt;/version&gt;
    &lt;executions&gt;
      &lt;execution&gt;
        &lt;phase&gt;validate&lt;/phase&gt;
        &lt;goals&gt;
          &lt;goal&gt;create&lt;/goal&gt;
        &lt;/goals&gt;
      &lt;/execution&gt;
    &lt;/executions&gt;
    &lt;configuration&gt;
      &lt;doCheck&gt;true&lt;/doCheck&gt;
      &lt;doUpdate&gt;true&lt;/doUpdate&gt;
    &lt;/configuration&gt;
  &lt;/plugin&gt;</pre>
<p>What all the configuration above does is that it adds a secondary artifact (the rpm) which gets uploaded to the Nexus maven repository on &#8220;mvn deploy&#8221;.</p>
<p>I don&#8217;t really need the WAR-file anymore, as I pack the RPM exploded. I might change the primary artifact type from WAR to RPM in the future, but I haven&#8217;t looked into that yet.</p>
<h2>Packaging the app server as an RPM</h2>
<p>The next thing I did was that I wanted to package the app server as an RPM as well. I feel it&#8217;s more developer friendly to build a tomcat rpm using maven as well rather that just grabbing some arbitrary rpm and using Puppet to fix the configuration. Also, we get full control over where it is installed and where log are.</p>
<p>One thing I really wanted to avoid was to having to check in the Tomcat distribution tar ball into Subversion. I <strong>hate</strong> blobs in SVN, so I was pleasantly surprised to learn that Nexus handles any types of files. I simply uploaded the latest tomcat distro tar (apache-tomcat-7.0.23.tar.gz) into my Nexus 3rd party repository.</p>
<p><strong>I created a sibling project &#8220;tomcat&#8221; with a pom that looks like this:</strong></p>
<pre>&lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"&gt;
  &lt;!-- avoid rpm here as classifier will differ and Nexus search will fail --&gt;
  &lt;packaging&gt;pom&lt;/packaging&gt;
  &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  &lt;parent&gt;
    &lt;artifactId&gt;nomp-parent&lt;/artifactId&gt;
    &lt;groupId&gt;se.nomp&lt;/groupId&gt;
    &lt;version&gt;2.1.0-SNAPSHOT&lt;/version&gt;
  &lt;/parent&gt;
  &lt;artifactId&gt;nomp-tomcat&lt;/artifactId&gt;
  &lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
  &lt;name&gt;Nomp Tomcat Server&lt;/name&gt;
  &lt;description&gt;Tomcat server for Nomp&lt;/description&gt;
  &lt;properties&gt;
    &lt;tomcat.version&gt;7.0.23&lt;/tomcat.version&gt;
    &lt;tomcat.build.dir&gt;${project.build.directory}/tomcat/apache-tomcat-${tomcat.version}&lt;/tomcat.build.dir&gt;
    &lt;rpm.install.basedir&gt;/opt/nomp&lt;/rpm.install.basedir&gt;
    &lt;rpm.install.logdir&gt;/var/log/nomp&lt;/rpm.install.logdir&gt;
  &lt;/properties&gt;
  &lt;profiles&gt;
    &lt;!-- Only run the RPM packaging on Linux as we need to rpm binary to build rpms using the rpm plugin --&gt;
    &lt;profile&gt;
      &lt;id&gt;rpm&lt;/id&gt;
      &lt;activation&gt;
        &lt;os&gt;
          &lt;name&gt;linux&lt;/name&gt;
        &lt;/os&gt;
      &lt;/activation&gt;
      &lt;build&gt;
        &lt;plugins&gt;
          &lt;plugin&gt;
            &lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt;
            &lt;artifactId&gt;rpm-maven-plugin&lt;/artifactId&gt;
            &lt;version&gt;2.1-alpha-1&lt;/version&gt;
            &lt;extensions&gt;true&lt;/extensions&gt;
            &lt;executions&gt;
              &lt;execution&gt;
                &lt;goals&gt;
                  &lt;goal&gt;attached-rpm&lt;/goal&gt;
                &lt;/goals&gt;
              &lt;/execution&gt;
            &lt;/executions&gt;
            &lt;configuration&gt;
              &lt;copyright&gt;Copyright 2011 Selessia AB&lt;/copyright&gt;
              &lt;distribution&gt;Nomp&lt;/distribution&gt;
              &lt;group&gt;${project.groupId}&lt;/group&gt;
              &lt;packager&gt;${user.name}&lt;/packager&gt;
              &lt;!-- need to use the build number plugin here in order for yum upgrade to work in snapshots --&gt;
              &lt;release&gt;${buildNumber}&lt;/release&gt;
              &lt;defaultDirmode&gt;755&lt;/defaultDirmode&gt;
              &lt;defaultFilemode&gt;444&lt;/defaultFilemode&gt;
              &lt;defaultUsername&gt;root&lt;/defaultUsername&gt;
              &lt;defaultGroupname&gt;root&lt;/defaultGroupname&gt;
              &lt;mappings&gt;
                &lt;mapping&gt;
                  &lt;directory&gt;${rpm.install.basedir}/logs&lt;/directory&gt;
                  &lt;sources&gt;
                    &lt;softlinkSource&gt;
                      &lt;location&gt;${rpm.install.logdir}&lt;/location&gt;
                    &lt;/softlinkSource&gt;
                  &lt;/sources&gt;
                &lt;/mapping&gt;
                &lt;mapping&gt;
                  &lt;directory&gt;${rpm.install.logdir}&lt;/directory&gt;
                  &lt;username&gt;nomp&lt;/username&gt;
                  &lt;groupname&gt;nomp&lt;/groupname&gt;
                &lt;/mapping&gt;
                &lt;mapping&gt;
                  &lt;directory&gt;${rpm.install.basedir}/bin&lt;/directory&gt;
                  &lt;filemode&gt;555&lt;/filemode&gt;
                  &lt;sources&gt;
                    &lt;source&gt;
                      &lt;location&gt;${tomcat.build.dir}/bin&lt;/location&gt;
                    &lt;/source&gt;
                  &lt;/sources&gt;
                &lt;/mapping&gt;
                &lt;mapping&gt;
                  &lt;directory&gt;${rpm.install.basedir}/conf&lt;/directory&gt;
                  &lt;sources&gt;
                    &lt;source&gt;
                      &lt;location&gt;${tomcat.build.dir}/conf&lt;/location&gt;
                    &lt;/source&gt;
                  &lt;/sources&gt;
                &lt;/mapping&gt;
                &lt;mapping&gt;
                  &lt;directory&gt;${rpm.install.basedir}/lib&lt;/directory&gt;
                  &lt;sources&gt;
                    &lt;source&gt;
                      &lt;location&gt;${tomcat.build.dir}/lib&lt;/location&gt;
                    &lt;/source&gt;
                  &lt;/sources&gt;
                &lt;/mapping&gt;
                &lt;mapping&gt;
                  &lt;directory&gt;${rpm.install.basedir}/work&lt;/directory&gt;
                  &lt;username&gt;nomp&lt;/username&gt;
                  &lt;groupname&gt;nomp&lt;/groupname&gt;
                &lt;/mapping&gt;
                &lt;mapping&gt;
                  &lt;directory&gt;${rpm.install.basedir}/temp&lt;/directory&gt;
                  &lt;username&gt;nomp&lt;/username&gt;
                  &lt;groupname&gt;nomp&lt;/groupname&gt;
                &lt;/mapping&gt;
                &lt;mapping&gt;
                  &lt;directory&gt;${rpm.install.basedir}/conf/Catalina&lt;/directory&gt;
                  &lt;username&gt;nomp&lt;/username&gt;
                  &lt;groupname&gt;nomp&lt;/groupname&gt;
                &lt;/mapping&gt;
                &lt;mapping&gt;
                  &lt;directory&gt;/etc/init.d&lt;/directory&gt;
                  &lt;directoryIncluded&gt;false&lt;/directoryIncluded&gt;
                  &lt;filemode&gt;555&lt;/filemode&gt;
                  &lt;sources&gt;
                    &lt;source&gt;
                      &lt;location&gt;src/main/etc/init.d&lt;/location&gt;
                    &lt;/source&gt;
                  &lt;/sources&gt;
                &lt;/mapping&gt;
              &lt;/mappings&gt;
            &lt;/configuration&gt;
          &lt;/plugin&gt;
        &lt;/plugins&gt;
      &lt;/build&gt;
    &lt;/profile&gt;
  &lt;/profiles&gt;

  &lt;build&gt;
    &lt;resources&gt;
      &lt;resource&gt;
         &lt;!-- overlay the contents in the resources src dir ontop of the unpacked tomcat --&gt;
         &lt;directory&gt;src/main/resources&lt;/directory&gt;
         &lt;filtering&gt;false&lt;/filtering&gt;
       &lt;/resource&gt;
     &lt;/resources&gt;
    &lt;plugins&gt;
      &lt;plugin&gt;
        &lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt;
        &lt;artifactId&gt;buildnumber-maven-plugin&lt;/artifactId&gt;
        &lt;version&gt;1.0&lt;/version&gt;
        &lt;executions&gt;
          &lt;execution&gt;
            &lt;phase&gt;validate&lt;/phase&gt;
            &lt;goals&gt;
              &lt;goal&gt;create&lt;/goal&gt;
            &lt;/goals&gt;
          &lt;/execution&gt;
        &lt;/executions&gt;
        &lt;configuration&gt;
          &lt;doCheck&gt;true&lt;/doCheck&gt;
          &lt;doUpdate&gt;true&lt;/doUpdate&gt;
        &lt;/configuration&gt;
      &lt;/plugin&gt;
      &lt;plugin&gt;
        &lt;artifactId&gt;maven-clean-plugin&lt;/artifactId&gt;
        &lt;version&gt;2.4.1&lt;/version&gt;
        &lt;executions&gt;
          &lt;execution&gt;
            &lt;id&gt;auto-clean&lt;/id&gt;
            &lt;phase&gt;initialize&lt;/phase&gt;
            &lt;goals&gt;
              &lt;goal&gt;clean&lt;/goal&gt;
            &lt;/goals&gt;
          &lt;/execution&gt;
        &lt;/executions&gt;
      &lt;/plugin&gt;
      &lt;plugin&gt;
        &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
        &lt;artifactId&gt;maven-resources-plugin&lt;/artifactId&gt;
        &lt;version&gt;2.5&lt;/version&gt;
        &lt;executions&gt;
          &lt;execution&gt;
            &lt;id&gt;resources&lt;/id&gt;
            &lt;!-- need to specify, as this is not default for pom packaging --&gt;
            &lt;phase&gt;process-resources&lt;/phase&gt;
            &lt;goals&gt;
              &lt;goal&gt;resources&lt;/goal&gt;
            &lt;/goals&gt;
            &lt;configuration&gt;
              &lt;encoding&gt;UTF-8&lt;/encoding&gt;
              &lt;outputDirectory&gt;${tomcat.build.dir}&lt;/outputDirectory&gt;
            &lt;/configuration&gt;
          &lt;/execution&gt;
        &lt;/executions&gt;
      &lt;/plugin&gt;
      &lt;plugin&gt;
        &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
        &lt;artifactId&gt;maven-dependency-plugin&lt;/artifactId&gt;
        &lt;version&gt;2.4&lt;/version&gt;
        &lt;executions&gt;
          &lt;execution&gt;
            &lt;id&gt;unpack-tomcat&lt;/id&gt;
            &lt;phase&gt;generate-resources&lt;/phase&gt;
            &lt;goals&gt;
              &lt;!-- unpack the tomcat dependency that's been downloaded from your local 3rd party repo --&gt;
              &lt;goal&gt;unpack-dependencies&lt;/goal&gt;
            &lt;/goals&gt;
            &lt;configuration&gt;
              &lt;outputDirectory&gt;${project.build.directory}/tomcat&lt;/outputDirectory&gt;
            &lt;/configuration&gt;
          &lt;/execution&gt;
        &lt;/executions&gt;
      &lt;/plugin&gt;
    &lt;/plugins&gt;
  &lt;/build&gt;
  &lt;dependencies&gt;
    &lt;!-- the tomcat distro that's been uploaded to the local third party maven repo --&gt;
    &lt;dependency&gt;
       &lt;groupId&gt;org.apache.tomcat&lt;/groupId&gt;
       &lt;artifactId&gt;apache-tomcat&lt;/artifactId&gt;
       &lt;version&gt;${tomcat.version}&lt;/version&gt;
       &lt;type&gt;tar.gz&lt;/type&gt;
     &lt;/dependency&gt;
   &lt;/dependencies&gt;
&lt;/project&gt;</pre>
<p>Note that the Tomcat artifact is just a normal maven dependency. I used the maven-dependency-plugin to automatically unpack the archive.<br />
I then overlay the configuration files I want to change with the well known maven-resources-plugin.</p>
<p>Okay. Now I was pretty happy. I was building two good RPM:s with proper version and release numbers that were deployed to my Nexus on &#8220;mvn deploy&#8221;.</p>
<h2>Distributing the packages</h2>
<p>The next step was then to export these files into a yum repository. Or so I thought&#8230;<br />
I was pleasantly surprised, or more like super-excited when I realized that some awesome folks had made a plugin for Nexus (nexus-yum-plugin <a href="http://code.google.com/p/nexus-yum-plugin/" target="_blank">http://code.google.com/p/nexus-yum-plugin/</a>) that exposes a Nexus Maven repo as a yum repo!</p>
<p>If you have yum installed, just add a repository configuration to your target server (I use Puppet to automate this).</p>
<p><strong>Here&#8217;s how it looks:</strong></p>
<pre>root@manny:/etc/yum/repos.d# cat nexus-snapshot.repo
 [nexus-snapshots]
 name=Nomp Nexus - Snapshots
 baseurl=http://manny:8082/nexus/content/repositories/snapshots/
 enabled=1
 gpgcheck=0</pre>
<p>You need to add one config for your snapshot repo and another for your release repo.<br />
Test your setup with &#8220;yum list&#8221; (you need to redeploy at least one RPM artifact in each repo in order for the yum-plugin to create the RPM-repo).</p>
<pre>root@manny:/etc/yum/repos.d# yum list
Installed Packages
 nomp-dbdeploy.noarch 0.0.2-1788 @maven-snapshots
 nomp-tomcat.noarch 0.0.1-1788 @maven-snapshots
 nomp-web.noarch 2.1.0-1788 @maven-snapshots
Available Packages
 nomp-dbdeploy.noarch 0.0.2-1793 maven-snapshots
 nomp-tomcat.noarch 0.0.1-1793 maven-snapshots
 nomp-web.noarch 2.1.0-1793 maven-snapshots</pre>
<p>In order to transfer the RPM packages and install the software, you just type:</p>
<pre># yum -y install nomp-web</pre>
<p>or if already installed:</p>
<pre># yum -y update nomp-web nomp-tomcat</pre>
<p>Pretty sweet! It&#8217;s so easy for anyone to find out what is installed/deployed on a server using rpm packages!</p>
<h2>The database is code too</h2>
<p>In order to ensure that database scripts are tested throughout the deploy pipeline, we also need to treat our database scripts as code that should be run in each environment.<br />
I like to use dbdeploy (<a href="http://code.google.com/p/dbdeploy/" target="_blank">http://code.google.com/p/dbdeploy/</a>) for database patch script packaging. Dbdeploy is a simple Database Change Management tool that applies SQL files in a specified order.  It can be run from the command line or from ant. It has a Maven plugin as well, but I don&#8217;t want to use that as I don&#8217;t want maven installed on the production servers.</p>
<p>I ended up making a separate rpm with the sql change scripts for the application and packaged the maven dependencies with the rpm. The main application is a build.xml script for nomp.</p>
<p>The build.xml I use for the dbdeploy package looks like this:</p>
<pre>&lt;project name="MyProject" default="dbdeploy" basedir="."&gt;
    &lt;description&gt;dbdeploy script for nomp&lt;/description&gt;
    &lt;record name="dbdeploy.log" loglevel="verbose" action="start" /&gt;
    &lt;path id="dbdeploy.classpath" &gt;
        &lt;fileset dir="lib"&gt;
            &lt;include name="*.jar" /&gt;
        &lt;/fileset&gt;
    &lt;/path&gt;

    &lt;taskdef name="dbdeploy" classname="com.dbdeploy.AntTarget" classpathref="dbdeploy.classpath" /&gt;

    &lt;target name="dbdeploy" depends="create-log-table"&gt;
        &lt;dbdeploy driver="${jdbc.driverClassName}" url="${jdbc.url}" userid="${jdbc.username}" password="${jdbc.password}" dir="sql" /&gt;
    &lt;/target&gt;

    &lt;target name="create-log-table"&gt;
        &lt;sql classpathref="dbdeploy.classpath" driver="${jdbc.driverClassName}" url="${jdbc.url}" userid="${jdbc.username}" password="${jdbc.password}" src="ddl/createSchemaVersionTable.mysql.sql" /&gt;
    &lt;/target&gt;
&lt;/project&gt;</pre>
<p>I also improved the dbdeploy distribution mysql script a bit so that it wont fail if it&#8217;s run again and again:</p>
<pre>CREATE TABLE IF NOT EXISTS changelog (
 change_number BIGINT NOT NULL,
 complete_dt TIMESTAMP NOT NULL,
 applied_by VARCHAR(100) NOT NULL,
 description VARCHAR(500) NOT NULL,
 CONSTRAINT Pkchangelog PRIMARY KEY (change_number)
 );</pre>
<p>When the RPM is installed, one only runs &#8220;ant&#8221; to run the needed sql change sets.</p>
<pre>root@manny:/opt/nomp-dbdeploy# ant
 Buildfile: /opt/nomp-dbdeploy/build.xml
create-log-table:
 [sql] Executing resource: /opt/nomp-dbdeploy/ddl/createSchemaVersionTable.mysql.sql
 [sql] 1 of 1 SQL statements executed successfully
dbdeploy:
 [dbdeploy] dbdeploy 3.0M3
 [dbdeploy] Reading change scripts from directory /opt/nomp-dbdeploy/sql...
 [dbdeploy] Changes currently applied to database:
 [dbdeploy] 1, 2
 [dbdeploy] Scripts available:
 [dbdeploy] 1, 2
 [dbdeploy] To be applied:
 [dbdeploy] (none)
BUILD SUCCESSFUL
 Total time: 0 seconds</pre>
<h2>Final step &#8211; setting up Jenkins</h2>
<p>I will assume that the reader knows how to setup and configure Jenkins jobs. I did a vanilla Jenkins install, and added the build pipeline plugin (<a href="https://wiki.jenkins-ci.org/display/JENKINS/Build+Pipeline+Plugin" target="_blank">https://wiki.jenkins-ci.org/display/JENKINS/Build+Pipeline+Plugin</a>) for a nice gui and the manual triggers.</p>
<h3>My pipeline<strong></strong></h3>
<p>The pipeline runs automatically for each check in.</p>
<h4>Job #1 &#8211; &#8220;Nomp build&#8221;</h4>
<p>Builds the root pom with goal &#8220;deploy&#8221;. Note: add flags for -Dusername -Dpassword for svn credentials as the build-number-plugin is used)</p>
<h4>Job #2 &#8211; &#8220;Nomp deploy to test&#8221;</h4>
<pre>ssh jenkins@test-server "yum -y update nomp-web nomp-tomcat nomp-dbdeploy;
cd /opt/nomp-dbdeploy; ant; /etc/init.d/nomp restart"</pre>
<p>note: you need to add jenkins to sudoers (using the NOPASSWD option) on the target and use ssh key auth of course (Puppet does this for me).</p>
<h4>Job #3 &#8211; &#8220;Nomp deploy to production&#8221; (manual trigger)</h4>
<p>A manual step after smoke tests have been run (not automated for Nomp yet), to release to production. Exactly like the above, except different target server.</p>
<h2>Next steps</h2>
<p>For Nomp, the next step will be more Puppet config. I want to be able to build and start up a fully working web server and db server from a standard EC2 AMI without any manual steps. This isn&#8217;t hard, but I can&#8217;t find the time right now. Need to add new features to the customers too <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  After that, I&#8217;d love to look at using Capistrano (<a href="https://github.com/capistrano/capistrano/wiki" target="_blank">https://github.com/capistrano/capistrano/wiki</a>) for deploy automation to many hosts. Currently Nomp only has a few servers, so ssh from Jenkins works fine for now.</p>
<p>Thank you for reading all the way to here. I&#8217;d love feedback if you think this is useful or not and if you agree on it being &#8220;developer friendly&#8221;. I have a pretty solid background in *nix admin, but I think most developers will understand and be able to maintain this setup, as compared to a solution more focused on using a sysadmin&#8217;s toolbox.</p>
<p>Lastly, please contribute with improvements if you find any.</p>
<p>I&#8217;ll try find time and energy to clean up the pom:s and provide a skeleton project that has a simple war, a tomcat and the dbdeploy rpm config for download in a week or so.</p>
<p>Added: Here&#8217;s an overview of the current continuous deployment environment at Nomp.se</p>
<p><a href="http://stnor.files.wordpress.com/2011/12/deployment-002.png"><img class="alignnone  wp-image-226" title="Nomp Continous Deployment architecture" src="http://stnor.files.wordpress.com/2011/12/deployment-002.png?w=357&#038;h=266" alt="Nomp Continous Deployment architecture" width="357" height="266" /></a></p>
<p>(click for full size image)</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/stnor.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/stnor.wordpress.com/211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/stnor.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/stnor.wordpress.com/211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/stnor.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/stnor.wordpress.com/211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/stnor.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/stnor.wordpress.com/211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/stnor.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/stnor.wordpress.com/211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/stnor.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/stnor.wordpress.com/211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/stnor.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/stnor.wordpress.com/211/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=stnor.wordpress.com&amp;blog=3757969&amp;post=211&amp;subd=stnor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://stnor.wordpress.com/2011/12/29/an-attempt-at-developer-friendly-build-pipe-line/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0549aa2d0fe182ce9d16167256e64f3d?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">stnor</media:title>
		</media:content>

		<media:content url="http://stnor.files.wordpress.com/2011/12/deployment-002.png" medium="image">
			<media:title type="html">Nomp Continous Deployment architecture</media:title>
		</media:content>
	</item>
		<item>
		<title>Backing up EC2 MySQL and configuration files to S3</title>
		<link>http://stnor.wordpress.com/2011/08/01/backing-up-ec2-mysql-and-configuration-files-to-s3/</link>
		<comments>http://stnor.wordpress.com/2011/08/01/backing-up-ec2-mysql-and-configuration-files-to-s3/#comments</comments>
		<pubDate>Mon, 01 Aug 2011 22:20:02 +0000</pubDate>
		<dc:creator>Stefan Norberg</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Everyday stuff]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[ec2]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[s3]]></category>

		<guid isPermaLink="false">http://stnor.wordpress.com/?p=202</guid>
		<description><![CDATA[I&#8217;ve been spending a few hours setting up a good back-up strategy for my EC2 server, running NOMP.se. The service runs on a single reserved small instance at present. It&#8217;s using Amazon&#8217;s Linux distro with an Elastic Block Storage (EBS) &#8230; <a href="http://stnor.wordpress.com/2011/08/01/backing-up-ec2-mysql-and-configuration-files-to-s3/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=stnor.wordpress.com&amp;blog=3757969&amp;post=202&amp;subd=stnor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been spending a few hours setting up a good back-up strategy for my EC2 server, running NOMP.se.</p>
<p>The service runs on a single reserved small instance at present. It&#8217;s using Amazon&#8217;s Linux distro with an Elastic Block Storage (EBS) root disk.</p>
<p>The first thing you should do after setting up an EC2 host is to make an EBS snapshot. An EBS snapshot is a full disk device dump (like &#8220;dd&#8221; produces if you&#8217;re a Unix hacker). While EBS snapshots are a great feature, and should be a cornerstone in any EC2 backup strategy, they are full volume dumps, and hence take a lot space.</p>
<p>To compliment my EBS snapshots, which I run manually before and after bigger changes (yum update, package installs etc), I hacked together a little shell script in 1337 bytes (really) to backup my MySQL databases in a supported manner (mysqldump) and also backing up a number of configuration files from the file system. The script makes use of a great tool called s3cmd which is used to upload files to S3 (Amazon&#8217;s Simple Storage Service).</p>
<p>How to set up the script (all steps as root):</p>
<ol>
<li><a href="http://s3tools.org/download">Install s3cmd</a></li>
<li>Run s3cmd &#8211;configure</li>
<li>Copy the generated .s3cfg file to /etc</li>
<li>Download the <a href="https://s3-eu-west-1.amazonaws.com/nomp-backup/backup-to-s3" title="The backup script">S3 backup script</a> to <strong>/etc/cron.daily/</strong></li>
<li>Edit the script to suit your needs.</li>
</ol>
<p>I hope someone finds this useful!</p>
<div id="attachment_207" class="wp-caption alignnone" style="width: 310px"><a href="http://stnor.files.wordpress.com/2011/08/s3.png"><img src="http://stnor.files.wordpress.com/2011/08/s3.png?w=300&#038;h=166" alt="" title="The s3 console after a successful run" width="300" height="166" class="size-medium wp-image-207" /></a><p class="wp-caption-text">The s3 console after a successful run</p></div>
<p>Here&#8217;s what the script looks like:</p>
<pre>
## Specify data base schemas to backup and credentials
DATABASES="nompdb wp_blog"

## Syntax databasename as per above _USER and _PW
## _USER is mandatory _PW is optional
nompdb_USER=root
wp_blog_USER=root

## Specify directories to backup (it's clever to use relaive paths)
DIRECTORIES="root etc/cron.daily etc/httpd etc/tomcat6 tmp/jenkinsbackup" 

## Initialize some variables
DATE=$(date +%Y%m%d)
DATETIME=$(date +%Y%m%d-%H%m)
BACKUP_DIRECTORY=/tmp/backups
S3_CMD="/usr/bin/s3cmd --config /etc/s3cfg"

## Specify where the backups should be placed
S3_BUCKET_URL=s3://nomp-backup/$DATE/

## The script
cd /
mkdir -p $BACKUP_DIRECTORY
rm -rf $BACKUP_DIRECTORY/*

## Backup MySQL:s
for DB in $DATABASES
do
BACKUP_FILE=$BACKUP_DIRECTORY/${DATETIME}_${DB}.sql
if [ ! -n "${DB}_PW"  ]
then
  PASSWORD=$(eval echo \$${DB}_PW)
  USER=$(eval echo \$${DB}_USER)
  /usr/bin/mysqldump -v --user $USER --password $PASSWORD -h localhost -r $BACKUP_FILE $DB 2&gt;&amp;1
else
  /usr/bin/mysqldump -v --user $USER -h localhost -r $BACKUP_FILE $DB 2&gt;&amp;1
fi
/bin/gzip $BACKUP_FILE 2&gt;&amp;1
$S3_CMD put ${BACKUP_FILE}.gz $S3_BUCKET_URL 2&gt;&amp;1
done

## Backup of config directories
for DIR in $DIRECTORIES
do
BACKUP_FILE=${DATETIME}_$(echo $DIR | sed 's/\//-/g').tgz
/bin/tar zcvf ${BACKUP_FILE} $DIR 2&gt;&amp;1
$S3_CMD put ${BACKUP_FILE} $S3_BUCKET_URL 2&gt;&amp;1
done
</pre>
<p>&nbsp;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/stnor.wordpress.com/202/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/stnor.wordpress.com/202/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/stnor.wordpress.com/202/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/stnor.wordpress.com/202/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/stnor.wordpress.com/202/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/stnor.wordpress.com/202/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/stnor.wordpress.com/202/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/stnor.wordpress.com/202/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/stnor.wordpress.com/202/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/stnor.wordpress.com/202/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/stnor.wordpress.com/202/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/stnor.wordpress.com/202/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/stnor.wordpress.com/202/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/stnor.wordpress.com/202/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=stnor.wordpress.com&amp;blog=3757969&amp;post=202&amp;subd=stnor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://stnor.wordpress.com/2011/08/01/backing-up-ec2-mysql-and-configuration-files-to-s3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0549aa2d0fe182ce9d16167256e64f3d?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">stnor</media:title>
		</media:content>

		<media:content url="http://stnor.files.wordpress.com/2011/08/s3.png?w=300" medium="image">
			<media:title type="html">The s3 console after a successful run</media:title>
		</media:content>
	</item>
		<item>
		<title>Freemarker, slf4j and spring</title>
		<link>http://stnor.wordpress.com/2011/05/26/freemarker-slf4j-and-spring/</link>
		<comments>http://stnor.wordpress.com/2011/05/26/freemarker-slf4j-and-spring/#comments</comments>
		<pubDate>Thu, 26 May 2011 18:19:57 +0000</pubDate>
		<dc:creator>Stefan Norberg</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web Techology]]></category>
		<category><![CDATA[Freemarker]]></category>
		<category><![CDATA[SLF4J]]></category>
		<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false">http://stnor.wordpress.com/?p=186</guid>
		<description><![CDATA[I&#8217;ve just spent three hours trying to get Freemarker to stop spitting out &#8220;DEBUG cache:81&#8243; messages in my Spring application. Freemarker recently hacked in SLF4J support into 2.3, but I had a hard time finding out how to enable it, &#8230; <a href="http://stnor.wordpress.com/2011/05/26/freemarker-slf4j-and-spring/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=stnor.wordpress.com&amp;blog=3757969&amp;post=186&amp;subd=stnor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just spent three hours trying to get Freemarker to stop spitting out <strong>&#8220;DEBUG cache:81&#8243;</strong> messages in my Spring application.</p>
<p>Freemarker recently hacked in SLF4J support into 2.3, but I had a hard time finding out how to enable it, so I reckoned I&#8217;d share my experiences.</p>
<p>FreeMarker 2.3 looks for logging libraries in this order (by default) with the class-loader of the FreeMarker classes: Log4J, Avalon, java.util.logging. The first that it founds in this list will be the one used for logging.</p>
<p>I found out that you can override this behavior in 2.3.18 by calling:</p>
<pre>freemarker.log.Logger.
    selectLoggerLibrary(freemarker.log.Logger.LIBRARY_SLF4J);</pre>
<p>However, this code need to run before any Freemarker classes are initialized.</p>
<p>After trying a few different tricks, such as having a load-on-startup Servlet&#8217;s init() configure the logger, I ended up with a fairly clean solution.</p>
<p>I extended Spring&#8217;s <code>FreeMarkerConfigurer</code> class like this:</p>
<pre> public class PluxFreeMarkerConfigurer extends FreeMarkerConfigurer {
    private Logger logger = LoggerFactory
            .getLogger(PluxFreeMarkerConfigurer.class);

    @Override
    public void afterPropertiesSet() throws IOException, TemplateException {
        fixFreemarkerLogging();
        super.afterPropertiesSet();
    }

    private void fixFreemarkerLogging() {
        try {
            freemarker.log.Logger
              .selectLoggerLibrary(freemarker.log.Logger.LIBRARY_SLF4J);
            logger.info("Switched broken Freemarker logging to slf4j");
        } catch (ClassNotFoundException e) {
            logger.warn("Failed to switch broken Freemarker logging to slf4j");
        }
    }
}</pre>
<p>and changed my Spring-config to use my class to initialize Freemarker instead:</p>
<pre>  &lt;!-- FreeMarker engine that configures Freemarker for SLF4J--&gt;
  &lt;bean id="freemarkerConfig" class="com.selessia.plux.web.PluxFreeMarkerConfigurer"
 ...
 &lt;/bean&gt;</pre>
<p>Hope this helps someone.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/stnor.wordpress.com/186/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/stnor.wordpress.com/186/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/stnor.wordpress.com/186/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/stnor.wordpress.com/186/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/stnor.wordpress.com/186/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/stnor.wordpress.com/186/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/stnor.wordpress.com/186/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/stnor.wordpress.com/186/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/stnor.wordpress.com/186/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/stnor.wordpress.com/186/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/stnor.wordpress.com/186/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/stnor.wordpress.com/186/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/stnor.wordpress.com/186/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/stnor.wordpress.com/186/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=stnor.wordpress.com&amp;blog=3757969&amp;post=186&amp;subd=stnor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://stnor.wordpress.com/2011/05/26/freemarker-slf4j-and-spring/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0549aa2d0fe182ce9d16167256e64f3d?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">stnor</media:title>
		</media:content>
	</item>
		<item>
		<title>Speedment &#8211; Snake-oil caching</title>
		<link>http://stnor.wordpress.com/2011/05/02/speedment-snake-oil-caching/</link>
		<comments>http://stnor.wordpress.com/2011/05/02/speedment-snake-oil-caching/#comments</comments>
		<pubDate>Mon, 02 May 2011 11:09:30 +0000</pubDate>
		<dc:creator>Stefan Norberg</dc:creator>
				<category><![CDATA[Architecture]]></category>

		<guid isPermaLink="false">http://stnor.wordpress.com/?p=183</guid>
		<description><![CDATA[It&#8217;s not everyday that people walk into our office claiming to be 1000x faster than the competition. Especially not in the highly competitive landscape of data-caching, where we have some big names in technology present for 5+ years, such as &#8230; <a href="http://stnor.wordpress.com/2011/05/02/speedment-snake-oil-caching/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=stnor.wordpress.com&amp;blog=3757969&amp;post=183&amp;subd=stnor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s not everyday that people walk into our office claiming to be 1000x faster than the competition. Especially not in the highly competitive landscape of data-caching, where we have some big names in technology present for 5+ years, such as Terracotta, Oracle, Gigaspaces et.c.</p>
<p>This is what Speedment did.</p>
<p>Speedment is basically a non-coherent, non-shardable, read-only, write-through java-cache that can use off-heap storage, much like EhCache with big memory. However, you need to rewrite your application in leverage the cache to Speedment&#8217;s own API:s. I fail to see what makes it even remotely attractive compared to the competition. It leverages database triggers to keep the caches up to date, which I would guess hurts database write performance.</p>
<p>According to <a href="http://www.speedment.com">Speedment&#8217;s web site</a> (only available in Swedish) they are in the &#8220;Elastic Caching Platform&#8221;-business and they got funding from Första Entreprenörsfonden and from ALMI Invest. I feel truly sorry for these investors, as  some technical due diligence could have saved them some money. It&#8217;s not that Speedment is all bad, it&#8217;s just not very good compared to the competition (including the FOSS competition).</p>
<p>Rather than an Elastic Caching Platform, I consider Speedment to be a <a href="http://en.wikipedia.org/wiki/Snake_oil_%28cryptography%29">Snake-oil caching</a> platform.</p>
<p>There is a PDF in English <a href="http://www.speedment.com/databas_accelerator/pdfs/Product%20sheet-%20Speedment%20Accelerator.pdf">here </a>if you want to check out the sales pitch.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/stnor.wordpress.com/183/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/stnor.wordpress.com/183/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/stnor.wordpress.com/183/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/stnor.wordpress.com/183/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/stnor.wordpress.com/183/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/stnor.wordpress.com/183/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/stnor.wordpress.com/183/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/stnor.wordpress.com/183/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/stnor.wordpress.com/183/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/stnor.wordpress.com/183/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/stnor.wordpress.com/183/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/stnor.wordpress.com/183/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/stnor.wordpress.com/183/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/stnor.wordpress.com/183/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=stnor.wordpress.com&amp;blog=3757969&amp;post=183&amp;subd=stnor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://stnor.wordpress.com/2011/05/02/speedment-snake-oil-caching/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0549aa2d0fe182ce9d16167256e64f3d?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">stnor</media:title>
		</media:content>
	</item>
		<item>
		<title>Unibet Privacy Proxy for Firefox and Internet Explorer</title>
		<link>http://stnor.wordpress.com/2010/03/23/unibet-privacy-proxy-for-firefox-and-internet-explore/</link>
		<comments>http://stnor.wordpress.com/2010/03/23/unibet-privacy-proxy-for-firefox-and-internet-explore/#comments</comments>
		<pubDate>Tue, 23 Mar 2010 08:52:22 +0000</pubDate>
		<dc:creator>Stefan Norberg</dc:creator>
				<category><![CDATA[Content Delivery]]></category>
		<category><![CDATA[Everyday stuff]]></category>
		<category><![CDATA[Web Techology]]></category>
		<category><![CDATA[bypass blocking]]></category>
		<category><![CDATA[Unibet Privacy Proxy]]></category>

		<guid isPermaLink="false">http://stnor.wordpress.com/?p=171</guid>
		<description><![CDATA[Unibet Privacy Proxy for Firefox and Internet Explorer is now live <a href="http://stnor.wordpress.com/2010/03/23/unibet-privacy-proxy-for-firefox-and-internet-explore/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=stnor.wordpress.com&amp;blog=3757969&amp;post=171&amp;subd=stnor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>A little over a year ago, I came up with a <a href="http://stnor.wordpress.com/2009/02/18/unibet-privacy-proxy/">neat idea</a> how to bypass any potential blocking of Unibet&#8217;s websites.</p>
<ol>
<li>As of today, we&#8217;re running this in production and there is an updated version of the <a href="https://addons.mozilla.org/en-US/firefox/addon/10759">Firefox add-on</a>.</li>
<li>The big news for <strong>Internet Explorer</strong> users, and the users of <strong>our Poker software</strong>, just <a href="http://78.24.214.10/upp.vbs">run this script active the proxy settings</a> to ensure functionality.</li>
</ol>
<p>I hope you will find this useful!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/stnor.wordpress.com/171/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/stnor.wordpress.com/171/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/stnor.wordpress.com/171/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/stnor.wordpress.com/171/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/stnor.wordpress.com/171/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/stnor.wordpress.com/171/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/stnor.wordpress.com/171/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/stnor.wordpress.com/171/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/stnor.wordpress.com/171/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/stnor.wordpress.com/171/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/stnor.wordpress.com/171/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/stnor.wordpress.com/171/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/stnor.wordpress.com/171/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/stnor.wordpress.com/171/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=stnor.wordpress.com&amp;blog=3757969&amp;post=171&amp;subd=stnor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://stnor.wordpress.com/2010/03/23/unibet-privacy-proxy-for-firefox-and-internet-explore/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0549aa2d0fe182ce9d16167256e64f3d?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">stnor</media:title>
		</media:content>
	</item>
		<item>
		<title>Domain Event Driven Architecture</title>
		<link>http://stnor.wordpress.com/2010/03/15/domain-event-driven-architecture/</link>
		<comments>http://stnor.wordpress.com/2010/03/15/domain-event-driven-architecture/#comments</comments>
		<pubDate>Mon, 15 Mar 2010 00:25:11 +0000</pubDate>
		<dc:creator>Stefan Norberg</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[EDA]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[Unibet. Domain Event Driven Architecture]]></category>

		<guid isPermaLink="false">http://stnor.wordpress.com/?p=163</guid>
		<description><![CDATA[<em><strong>Domain EDA:</strong> By exposing relevant Domain Events on a shared event bus we can isolate cross cutting functions to separate systems </em> <a href="http://stnor.wordpress.com/2010/03/15/domain-event-driven-architecture/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=stnor.wordpress.com&amp;blog=3757969&amp;post=163&amp;subd=stnor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>While working on my presentation for Qcon London 2010, I came to the following conclusions:</p>
<ol>
<li>SOA is all about dividing domain logic into separate systems and exposing it as services</li>
<li>Some domain logic will, by its very nature, be spread out over many systems</li>
<li>The result is domain pollution and bloat in the SOA systems </li>
</ol>
<p><em><strong>Domain EDA:</strong> By exposing relevant Domain Events on a shared event bus we can isolate cross cutting functions to separate systems </em></p>
<ul>
<li>SOA+Domain EDA will reduce time-to-market for new functionality</li>
<li>SOA+Domain EDA will enable a layer of high-value services that have a visible impact on the bottom line of the business</li>
</ul>
<p>Here is the full presentation:<br />
<iframe src='http://www.slideshare.net/slideshow/embed_code/3395407' width='584' height='479'></iframe></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/stnor.wordpress.com/163/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/stnor.wordpress.com/163/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/stnor.wordpress.com/163/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/stnor.wordpress.com/163/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/stnor.wordpress.com/163/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/stnor.wordpress.com/163/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/stnor.wordpress.com/163/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/stnor.wordpress.com/163/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/stnor.wordpress.com/163/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/stnor.wordpress.com/163/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/stnor.wordpress.com/163/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/stnor.wordpress.com/163/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/stnor.wordpress.com/163/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/stnor.wordpress.com/163/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=stnor.wordpress.com&amp;blog=3757969&amp;post=163&amp;subd=stnor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://stnor.wordpress.com/2010/03/15/domain-event-driven-architecture/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0549aa2d0fe182ce9d16167256e64f3d?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">stnor</media:title>
		</media:content>
	</item>
		<item>
		<title>Looking for mentor!</title>
		<link>http://stnor.wordpress.com/2010/02/28/looking-for-mentor/</link>
		<comments>http://stnor.wordpress.com/2010/02/28/looking-for-mentor/#comments</comments>
		<pubDate>Sat, 27 Feb 2010 23:49:28 +0000</pubDate>
		<dc:creator>Stefan Norberg</dc:creator>
				<category><![CDATA[Architecture]]></category>

		<guid isPermaLink="false">http://stnor.wordpress.com/?p=156</guid>
		<description><![CDATA[I live for learning new things and hence I have been thinking for quite some time of getting a mentor. My current career goal is CTO/CIO at a company where IT is considered a strategic investment. I am interested in &#8230; <a href="http://stnor.wordpress.com/2010/02/28/looking-for-mentor/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=stnor.wordpress.com&amp;blog=3757969&amp;post=156&amp;subd=stnor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div id="_mcePaste">I live for learning new things and hence I have been thinking for quite some time of getting a mentor.</div>
<div>
<ul>
<li>My current career goal is CTO/CIO at a company where IT is considered a strategic investment.</li>
<li>I am interested in learning more about the strategical and day-to-day challenges of a C-level executive or a board member.</li>
<li>I currently have experience from the e-gaming, finance, banking, insurance, government and IT consulting industries. I have been self-employed two times, for a total of seven years. I consider myself an entrepreneurial spirit.</li>
<li>I have over 17 years of hands-on IT experience. I have worked with all aspects of IT (from operations, IT security and systems development to procurement, software architecture and enterprise architecture).</li>
</ul>
</div>
<div>Would you know anyone interested in mentoring of a business-minded technical expert such as myself?</div>
<div></div>
<div>Thanks,</div>
<div id="_mcePaste">Stefan</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/stnor.wordpress.com/156/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/stnor.wordpress.com/156/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/stnor.wordpress.com/156/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/stnor.wordpress.com/156/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/stnor.wordpress.com/156/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/stnor.wordpress.com/156/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/stnor.wordpress.com/156/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/stnor.wordpress.com/156/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/stnor.wordpress.com/156/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/stnor.wordpress.com/156/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/stnor.wordpress.com/156/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/stnor.wordpress.com/156/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/stnor.wordpress.com/156/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/stnor.wordpress.com/156/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=stnor.wordpress.com&amp;blog=3757969&amp;post=156&amp;subd=stnor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://stnor.wordpress.com/2010/02/28/looking-for-mentor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0549aa2d0fe182ce9d16167256e64f3d?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">stnor</media:title>
		</media:content>
	</item>
		<item>
		<title>RTWaaS?</title>
		<link>http://stnor.wordpress.com/2009/10/15/real-time-web-as-a-service/</link>
		<comments>http://stnor.wordpress.com/2009/10/15/real-time-web-as-a-service/#comments</comments>
		<pubDate>Thu, 15 Oct 2009 13:40:47 +0000</pubDate>
		<dc:creator>Stefan Norberg</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Content Delivery]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Web Techology]]></category>
		<category><![CDATA[cloud computing]]></category>
		<category><![CDATA[edge computing]]></category>
		<category><![CDATA[Real time web]]></category>
		<category><![CDATA[Software as a service]]></category>

		<guid isPermaLink="false">http://stnor.wordpress.com/?p=141</guid>
		<description><![CDATA[A giant hurdle for buying a system/solution as a software is the need to buy hardware, install it, configure and manage it. You need to train people on the products' operational aspects and retain that skill within the company. <a href="http://stnor.wordpress.com/2009/10/15/real-time-web-as-a-service/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=stnor.wordpress.com&amp;blog=3757969&amp;post=141&amp;subd=stnor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>A giant hurdle for buying a system/solution as a software is the need to buy hardware, install it, configure and manage it. You need to train people on the products&#8217; operational aspects and retain that skill within the company.</p>
<p>(Free) Open Source Software (FOSS) is great to spread, to get adoption and support for a product. You enable the developers and architects to play around with the stuff! The real challenge for FOSS (and other software) products is to go beyond the happy and content developer and also provide a painless path for the adopters to provide business value without a huge investment hurdle in terms of hardware, software, traning or services.</p>
<p>I think the reason why something like Google Analytics or Salesforce.com is successful is that it is extremely painless to start using it. You can focus on the business problem rather than the IT stuff. Obviously this is nothing new, and the examples I gave has been around for years. Software as a Service is great.</p>
<p>Then, you have all the talk about the real-time web and putting information quickly, as it happens &#8211; &#8220;real time&#8221; &#8211; on the users&#8217; desktops. This is what Twitter and Facebook is about, but real-time web is also needed for e-commerce and gaming and a lot of other areas. There are even <a href="http://realtimesummit.eventbee.com/">conferences</a> about it, so it must be happening <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Lastly, the final piece of the puzzle are Service Level Agreements. In order to provide &#8220;real time web&#8221; messaging as a service there is a clear advantage of being close to the information consumers, both in terms of scaling out and in terms of guaranteed latency. I think it is going to be hard to commit meaningful SLA:s without being in the edge.</p>
<p>If you remove the need to invest in infrastructure, the need to train people on the operational aspects and then get excellent scalability and low latency <em>guaranteed</em> by contract, I&#8217;d buy it in a second. Who will provide me with the Real Time Web as a service?</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/stnor.wordpress.com/141/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/stnor.wordpress.com/141/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/stnor.wordpress.com/141/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/stnor.wordpress.com/141/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/stnor.wordpress.com/141/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/stnor.wordpress.com/141/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/stnor.wordpress.com/141/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/stnor.wordpress.com/141/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/stnor.wordpress.com/141/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/stnor.wordpress.com/141/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/stnor.wordpress.com/141/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/stnor.wordpress.com/141/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/stnor.wordpress.com/141/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/stnor.wordpress.com/141/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=stnor.wordpress.com&amp;blog=3757969&amp;post=141&amp;subd=stnor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://stnor.wordpress.com/2009/10/15/real-time-web-as-a-service/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0549aa2d0fe182ce9d16167256e64f3d?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">stnor</media:title>
		</media:content>
	</item>
		<item>
		<title>Open Source strategy at Unibet.com</title>
		<link>http://stnor.wordpress.com/2009/08/21/open-source-strategy-at-unibet-com/</link>
		<comments>http://stnor.wordpress.com/2009/08/21/open-source-strategy-at-unibet-com/#comments</comments>
		<pubDate>Fri, 21 Aug 2009 18:44:22 +0000</pubDate>
		<dc:creator>Stefan Norberg</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[unibet]]></category>

		<guid isPermaLink="false">http://stnor.wordpress.com/2009/08/21/open-source-strategy-at-unibet-com/</guid>
		<description><![CDATA[Just this week we made a tough call between a fairly proven commercial solution and a mix of new, fun, exciting and (fairly) unproven open source for messaging and last mile push technology. We went for the latter. Why? To &#8230; <a href="http://stnor.wordpress.com/2009/08/21/open-source-strategy-at-unibet-com/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=stnor.wordpress.com&amp;blog=3757969&amp;post=130&amp;subd=stnor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Just this week we made a tough call between a fairly proven commercial solution and a mix of new, fun, exciting and (fairly) unproven open source for messaging and last mile push technology. We went for the latter. Why?</p>
<p>To be honest, it came down to a gut-feeling decision. Would I prefer working for a company that used proven, stable commercial software &#8211; or would I prefer a company that thought it could get a competitive edge by using something new (and cool)?</p>
<p>I believe that in order to attract talent, we need to use cool, open source, technology. </p>
<p>On the way to work this morning I felt I should put my thoughts around our architectural strategy in writing. Here is what I came up with:</p>
<blockquote><p>We will always favor free, open source software (FOSS) as components in our architecture.</p>
<p><strong>Free as in &#8220;freedom of speech&#8221;</strong><br />
While we do not mind paying for consultancy services and quality support, it is important for us to avoid vendor lock-in, and any software we use should have a right-to-use license without any cost attached.</p>
<p>Open source software and open standards should always be our first choice.</p>
<p>Commercial, propriatary software need to show <strong>exceptional business value</strong> (over Free solutions) in order to be considered.</p>
<p>We will strive to contribute to the community by buying support from a company backing a FOSS solution or paying for product improvements that will also benefit the community.</p>
<p>These are the guiding principles for all software used at Unibet.
</p></blockquote>
<p>I&#8217;ll close with a quote:</p>
<blockquote><p>Unibet has the most exciting, up-to-date architecture I have ever seen at any company.<br />
&#8211; Jonas Bonér
</p></blockquote>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/stnor.wordpress.com/130/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/stnor.wordpress.com/130/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/stnor.wordpress.com/130/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/stnor.wordpress.com/130/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/stnor.wordpress.com/130/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/stnor.wordpress.com/130/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/stnor.wordpress.com/130/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/stnor.wordpress.com/130/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/stnor.wordpress.com/130/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/stnor.wordpress.com/130/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/stnor.wordpress.com/130/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/stnor.wordpress.com/130/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/stnor.wordpress.com/130/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/stnor.wordpress.com/130/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=stnor.wordpress.com&amp;blog=3757969&amp;post=130&amp;subd=stnor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://stnor.wordpress.com/2009/08/21/open-source-strategy-at-unibet-com/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0549aa2d0fe182ce9d16167256e64f3d?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">stnor</media:title>
		</media:content>
	</item>
		<item>
		<title>I am nerdier than 98% of all people</title>
		<link>http://stnor.wordpress.com/2009/05/14/i-am-nerdier-than-98-of-all-people/</link>
		<comments>http://stnor.wordpress.com/2009/05/14/i-am-nerdier-than-98-of-all-people/#comments</comments>
		<pubDate>Thu, 14 May 2009 19:08:50 +0000</pubDate>
		<dc:creator>Stefan Norberg</dc:creator>
				<category><![CDATA[Everyday stuff]]></category>
		<category><![CDATA[nerd test]]></category>

		<guid isPermaLink="false">http://stnor.wordpress.com/?p=127</guid>
		<description><![CDATA[I took the nerd test and it told me: &#8220;All hail the monstrous nerd. You are by far the SUPREME NERD GOD!!!&#8221;&#8230;<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=stnor.wordpress.com&amp;blog=3757969&amp;post=127&amp;subd=stnor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I took the nerd test and it told me: &#8220;All hail the monstrous nerd. You are by far the SUPREME NERD GOD!!!&#8221;&#8230;</p>
<p><a href="http://www.nerdtests.com/ft_nq.php"><br />
<img src="http://www.nerdtests.com/images/ft/nq/21991e3bef.gif" alt="I am nerdier than 98% of all people. Are you a nerd? Click here to take the Nerd Test, get nerdy images and jokes, and talk on the nerd forum!"></a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/stnor.wordpress.com/127/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/stnor.wordpress.com/127/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/stnor.wordpress.com/127/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/stnor.wordpress.com/127/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/stnor.wordpress.com/127/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/stnor.wordpress.com/127/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/stnor.wordpress.com/127/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/stnor.wordpress.com/127/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/stnor.wordpress.com/127/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/stnor.wordpress.com/127/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/stnor.wordpress.com/127/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/stnor.wordpress.com/127/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/stnor.wordpress.com/127/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/stnor.wordpress.com/127/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=stnor.wordpress.com&amp;blog=3757969&amp;post=127&amp;subd=stnor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://stnor.wordpress.com/2009/05/14/i-am-nerdier-than-98-of-all-people/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0549aa2d0fe182ce9d16167256e64f3d?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">stnor</media:title>
		</media:content>

		<media:content url="http://www.nerdtests.com/images/ft/nq/21991e3bef.gif" medium="image">
			<media:title type="html">I am nerdier than 98% of all people. Are you a nerd? Click here to take the Nerd Test, get nerdy images and jokes, and talk on the nerd forum!</media:title>
		</media:content>
	</item>
	</channel>
</rss>
