<?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>Callista Blog</title>
	<atom:link href="http://blog.callistaenterprise.se/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.callistaenterprise.se</link>
	<description>Our consultants share their reflections on IT architecture.</description>
	<lastBuildDate>Thu, 29 Mar 2012 07:24:38 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Remote deploy to Tomcat 7 using Cargo</title>
		<link>http://blog.callistaenterprise.se/2012/03/12/remote-deploy-to-tomcat-7-using-cargo/</link>
		<comments>http://blog.callistaenterprise.se/2012/03/12/remote-deploy-to-tomcat-7-using-cargo/#comments</comments>
		<pubDate>Mon, 12 Mar 2012 13:34:17 +0000</pubDate>
		<dc:creator>Marcus Krantz</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Build]]></category>
		<category><![CDATA[Build automation]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.callistaenterprise.se/?p=1465</guid>
		<description><![CDATA[One of the last days in my current project I was about to freeze the codebase and finish things up. Luckily, I had a couple of hours left to play around with something that I have been thinking about throughout the project but never had time to implement. My mission was to deploy the application [...]]]></description>
			<content:encoded><![CDATA[<p>One of the last days in my current project I was about to freeze the codebase and finish things up. Luckily, I had a couple of hours left to play around with something that I have been thinking about throughout the project but never had time to implement. My mission was to deploy the application to a remote tomcat container. The requirements I made up was:</p>
<ul>
<li>Maven-based (no custom schell scripting <img src='http://blog.callistaenterprise.se/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> )</li>
<li>Minimal configuration</li>
<li>Multiple servers (test, qa, production)</li>
<li>Application server independent</li>
</ul>
<p>After some research, I found Cargo that seemed to meet my requirements and I decided to try it out. I used the following setup to test Cargo:</p>
<ul>
<li>Apache Tomcat 7.0.26</li>
<li>Maven 3.0.3</li>
<li>example.war deployed in my local maven repository</li>
</ul>
<h1>1. Create maven deployer project</h1>
<p>First of all I created a new empty project called example-deployer, the idea was to use this project to deploy my example.war to various servers:</p>
<pre class="brush: powershell; title: ; notranslate">
mvn archetype:generate -Dversion=1.0-SNAPSHOT -DgroupId=org.example -DartifactId=example-deployer -Dpackaging=pom
</pre>
<h1>2. Create maven profiles</h1>
<p>Next, I wanted to be able to deploy to two different servers: qa, and production. Since I used different ports, different protocols and different context paths for these two environment I created two Maven profiles that can be activated using the env-property. In these two profiles I set property values for each environment.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;profiles&gt;
  	&lt;profile&gt;
  		&lt;id&gt;prod&lt;/id&gt;
  		&lt;activation&gt;
  			&lt;property&gt;
  				&lt;name&gt;env&lt;/name&gt;
  				&lt;value&gt;prod&lt;/value&gt;
  			&lt;/property&gt;
  		&lt;/activation&gt;
  		&lt;properties&gt;
  			&lt;remote.protocol&gt;https&lt;/remote.protocol&gt;
  			&lt;remote.port&gt;443&lt;/remote.port&gt;
  			&lt;remote.hostname&gt;prod.example.org&lt;/remote.hostname&gt;
  			&lt;remote.context&gt;/&lt;/remote.context&gt;
  		&lt;/properties&gt;
  	&lt;/profile&gt;
  	&lt;profile&gt;
  		&lt;id&gt;qa&lt;/id&gt;
  		&lt;activation&gt;
  			&lt;property&gt;
  				&lt;name&gt;env&lt;/name&gt;
  				&lt;value&gt;qa&lt;/value&gt;
  			&lt;/property&gt;
  		&lt;/activation&gt;
  		&lt;properties&gt;
  			&lt;remote.protocol&gt;http&lt;/remote.protocol&gt;
  			&lt;remote.hostname&gt;qa.example.org&lt;/remote.hostname&gt;
  			&lt;remote.port&gt;8080&lt;/remote.port&gt;
  			&lt;remote.context&gt;/qa&lt;/remote.context&gt;
  		&lt;/properties&gt;
  	&lt;/profile&gt;
  &lt;/profiles&gt;
</pre>
<p>It is now possible to activate the qa or prod profile by adding <code>-Denv=prod</code> or <code>-Denv=qa</code></p>
<h1>3. Configure Cargo</h1>
<p>I was surprised how easy it was to configure Cargo&#8217;s maven plugin. There are basically three blocks of configuration 1) The container to use, 2) Configuration how to access the container and 3) the war-artifact to deploy to the remote container.</p>
<p>Since I do not want to exploit the username and password to the application server, I enter these manually during deploy time. Here is the configuration used:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;build&gt;
  	&lt;plugins&gt;
  		&lt;plugin&gt;
  			&lt;groupId&gt;org.codehaus.cargo&lt;/groupId&gt;
  			&lt;artifactId&gt;cargo-maven2-plugin&lt;/artifactId&gt;
  			&lt;version&gt;1.2.0&lt;/version&gt;
  			&lt;configuration&gt;

  				&lt;container&gt;
					&lt;containerId&gt;tomcat7x&lt;/containerId&gt;
					&lt;type&gt;remote&lt;/type&gt;
				&lt;/container&gt;

				&lt;configuration&gt;
					&lt;type&gt;runtime&lt;/type&gt;
					&lt;properties&gt;
						&lt;cargo.hostname&gt;${remote.hostname}&lt;/cargo.hostname&gt;
						&lt;cargo.protocol&gt;${remote.protocol}&lt;/cargo.protocol&gt;
						&lt;cargo.servlet.port&gt;${remote.port}&lt;/cargo.servlet.port&gt;
						&lt;cargo.remote.username&gt;${remote.user}&lt;/cargo.remote.username&gt;
						&lt;cargo.remote.password&gt;${remote.pass}&lt;/cargo.remote.password&gt;
					&lt;/properties&gt;
				&lt;/configuration&gt;

				&lt;deployer&gt;
					&lt;type&gt;remote&lt;/type&gt;
					&lt;deployables&gt;
						&lt;deployable&gt;
							&lt;groupId&gt;${project.groupId}&lt;/groupId&gt;
							&lt;artifactId&gt;example-web&lt;/artifactId&gt;
							&lt;type&gt;war&lt;/type&gt;
							&lt;properties&gt;
								&lt;context&gt;${remote.context}&lt;/context&gt;
							&lt;/properties&gt;
						&lt;/deployable&gt;
					&lt;/deployables&gt;
				&lt;/deployer&gt;

  			&lt;/configuration&gt;
  		&lt;/plugin&gt;
  	&lt;/plugins&gt;
  &lt;/build&gt;
</pre>
<p>The last thing we need to add to the configuration is to include a dependency to the war-artifcact that we want to deploy.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;dependencies&gt;
  	&lt;dependency&gt;
  		&lt;groupId&gt;org.example&lt;/groupId&gt;
  		&lt;artifactId&gt;example-web&lt;/artifactId&gt;
  		&lt;version&gt;${project.version}&lt;/version&gt;
  		&lt;type&gt;war&lt;/type&gt;
  	&lt;/dependency&gt;
  &lt;/dependencies&gt;
</pre>
<p>It is now possible to deploy to out qa or prod server. Note that if we don&#8217;t want to expose the username and password in the script (that probably is in our source code repo) we can force the user to specify them on the command line. We are now ready to deploy, execute the following command:</p>
<pre>mvn cargo:deploy -Denv=qa -Dremote.user= -Dremote.pass=</pre>
<p>The example above does not work out of the box without some configuration of the application server. For example, in the Apache Tomcat case, you will need the manager web application to be deployed and configured to allow username/password access of a certain user. You can find all the details in the reference documentation as well as in the Apache Tomcat container documentation:</p>
<ul>
<li><a href="http://cargo.codehaus.org/Maven2+Plugin+Reference+Guide">Cargo Reference Documentation</a></li>
<li><a href="http://cargo.codehaus.org/Tomcat+7.x">Cargo Tomcat Reference</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.callistaenterprise.se/2012/03/12/remote-deploy-to-tomcat-7-using-cargo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Firefox for Enterprises, from proposal to action</title>
		<link>http://blog.callistaenterprise.se/2012/01/12/firefox-for-enterprises-from-proposal-to-action/</link>
		<comments>http://blog.callistaenterprise.se/2012/01/12/firefox-for-enterprises-from-proposal-to-action/#comments</comments>
		<pubDate>Thu, 12 Jan 2012 10:50:37 +0000</pubDate>
		<dc:creator>Christian Hilmersson</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[enterprise]]></category>
		<category><![CDATA[web applications]]></category>

		<guid isPermaLink="false">http://blog.callistaenterprise.se/?p=1446</guid>
		<description><![CDATA[According to the Mozilla Blog, Firefox is about to be released in an enterprise version, with releases once every year instead of once every 6:th week.
The new version of the Firefox is called Firefox Extended Support Release or simply Firefox ESR. The intention is to provide security updates continously but let the web and add-ons [...]]]></description>
			<content:encoded><![CDATA[<p>According to the Mozilla Blog, Firefox is about to be released in an enterprise version, with releases once every year instead of once every 6:th week.</p>
<p>The new version of the Firefox is called Firefox Extended Support Release or simply Firefox ESR. The intention is to provide security updates continously but let the web and add-ons platform be stable throughout the 1 year release.</p>
<p>I have experience from developing and maintaining both web frameworks and web applications at big companies and  have noticed that Firefox&#8217;s recent 6 weeks release  cycle have created problems for developers keeping up with certifying the quality of their software with the latest browser release. Firefox ESR might be a welcome change for framework and application developer&#8217;s in enterprises since it, in my humble opinion, might ease the the task of choosing Firefox as a tactical appointed enterprise platform for internal web-applications.</p>
<p>For more info, see the post at the Mozilla blog:</p>
<p><a href="http://blog.mozilla.com/blog/2012/01/10/delivering-a-mozilla-firefox-extended-support-release/" target="_blank">http://blog.mozilla.com/blog/2012/01/10/delivering-a-mozilla-firefox-extended-support-release/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.callistaenterprise.se/2012/01/12/firefox-for-enterprises-from-proposal-to-action/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Experiences from Rich Web Experience 2011</title>
		<link>http://blog.callistaenterprise.se/2011/12/08/experiences-from-rich-web-experience-2011/</link>
		<comments>http://blog.callistaenterprise.se/2011/12/08/experiences-from-rich-web-experience-2011/#comments</comments>
		<pubDate>Thu, 08 Dec 2011 01:16:09 +0000</pubDate>
		<dc:creator>Christian Hilmersson</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.callistaenterprise.se/?p=1418</guid>
		<description><![CDATA[Just came home from a very interesting conference a couple of days ago. I still feel a bit jet lagged after the long trip over the atlantic ocean from Fort Lauderdale, Florida, but it was really worth the effort.
Fort Lauderdale was greeting us with a comfortable wintery weather with temperatures at around 25°C so it [...]]]></description>
			<content:encoded><![CDATA[<p>Just came home from a very interesting conference a couple of days ago. I still feel a bit jet lagged after the long trip over the atlantic ocean from Fort Lauderdale, Florida, but it was really worth the effort.</p>
<p>Fort Lauderdale was greeting us with a comfortable wintery weather with temperatures at around 25°C so it was very refreshing to take a walk outside during the lunch breaks.</p>
<p>The conference was hosted by No Fluff Just Stuff whose conferences aim to be stuffed with as much information as possible without the usual exhibition and advertisements seen at many other conferences. I think they have a really good concept there, which makes it easier to connect with fellow software engineers without worrying about what they are selling.</p>
<p>The Rich Web Experience is a conference aimed at web client development in all it forms; browser web applications, mobile web applications, native mobile apps etc etc. It was this year colocated with the Project Automation Experience where the focus was more on build systems, CI, cloud computing etc.</p>
<p>Since I have a big interest in client development, most of the sessions I attended were from the Rich Web Experience.</p>
<p>One of the most interesting things that I noticed was that almost noone at all was talking about server generated HTML anymore. Almost everyone talked about self contained JavaScript/HTML5 clients consuming services published by their respective back end systems. I attended a presentation hosted by Dan Allen from JBoss who was presenting his idea of future mobile web applications and even he (with some past influence in the JSF 2.0 project) was also leaning towards abandoning server rendered HTML. Instead he says that JBoss are (amongst other solutions I suppose) looking at a solution based on GWT, Errai and POH5, Plain Old HTML 5. When I asked him a direct question about the future for JSF he was a bit slippery but he said it is definitely time to start looking around on what&#8217;s out there and that it wasn&#8217;t impossible that JSF would transform to something else in the future, unknown what.</p>
<p>I also had a quick after session chat with<em> </em> Dylan Schiemann, co-founder of Dojo Toolkit which was really inspiring. He said they are working on a new Grid component for Dojo called dgrid which sounded very interesting. It is designed to be more light-weight and way faster than previous grids to fit even into mobile devices.</p>
<p>Other highlights from the conference was Venkat Subramaniam&#8217;s iOS and JavaScript sessions, Tim Berglunds poetic coding examples, Gabriel Dayley&#8217;s and Tom Valletta&#8217;s excellent talks on HTML5, node.js and WebSockets and of course Eric Wendelin&#8217;s JavaScript test automation presentation.</p>
<p>I can really recommend the RWX 2012 if you are interested in client development.</p>
<p>Some links for the interested reader to look more at:</p>
<p><a href="http://mustache.github.com/" target="_blank">http://mustache.github.com/</a> &#8211; Logic less templating system, amongst others for JavaScript</p>
<p><a href="http://requirejs.org/" target="_blank">http://requirejs.org/</a> &#8211; JavaScript file and module loader</p>
<p><a href="http://documentcloud.github.com/underscore/" target="_blank">http://documentcloud.github.com/underscore/</a> &#8211; Utility-belt library for JavaScript</p>
<p><a href="http://nodejs.org/" target="_blank">http://nodejs.org/</a> &#8211; Server side JavaScript, a must have</p>
<p><a href="http://maqetta.org/" target="_blank">http://maqetta.org/</a> &#8211; WYSIWYG editor for HTML5, looks interesting at first glance</p>
<p><a href="http://coffeescript.org/" target="_blank">http://coffeescript.org/</a> &#8211; A language that compiles to JavaScript and adds syntactic sugar. CoffeeScript is almost to JavaScript what Groovy or Scala is for Java</p>
<p><a href="http://www.dartlang.org/" target="_blank">http://www.dartlang.org/</a> &#8211; Google&#8217;s new language for the web</p>
<p><a href="http://www.html5rocks.com/en/tutorials/device/orientation/" target="_blank">http://www.html5rocks.com/en/tutorials/device/orientation/</a> &#8211; How to code mobile applications that make use of device motion tracking (accelerometer etc).</p>
<p><a href="https://github.com/SitePen/dgrid" target="_blank">https://github.com/SitePen/dgrid</a> &#8211; Home of the Dojo dgrid project</p>
<p><a href="http://spinejs.com/" target="_blank">http://spinejs.com/</a> &#8211; A minimalistic MVC utility for JavaScript</p>
<p><a href="http://code.google.com/p/js-test-driver/" target="_blank">http://code.google.com/p/js-test-driver/</a> &#8211; Drives your JavaScript tests from the browser</p>
<p><a href="http://pivotal.github.com/jasmine/" target="_blank">http://pivotal.github.com/jasmine/</a> &#8211; BDD style tests for your JavaScript application</p>
<p><a href="http://www.jboss.org/errai" target="_blank">http://www.jboss.org/errai</a> &#8211; A framework for building GWT applications.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.callistaenterprise.se/2011/12/08/experiences-from-rich-web-experience-2011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android &#8211; TLS/SSL Mutual Authentication</title>
		<link>http://blog.callistaenterprise.se/2011/11/24/android-tlsssl-mutual-authentication/</link>
		<comments>http://blog.callistaenterprise.se/2011/11/24/android-tlsssl-mutual-authentication/#comments</comments>
		<pubDate>Thu, 24 Nov 2011 08:49:13 +0000</pubDate>
		<dc:creator>Marcus Krantz</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://blog.callistaenterprise.se/?p=1279</guid>
		<description><![CDATA[Due to the explosion of smart phones on the market, the need for exposing existing enterprise systems through the mobile channel is growing rapidly. One of the first questions that will come up is how we can establish a secure communication channel with the existing enterprise system.
In this article, I will cover both how to [...]]]></description>
			<content:encoded><![CDATA[<p>Due to the explosion of smart phones on the market, the need for exposing existing enterprise systems through the mobile channel is growing rapidly. One of the first questions that will come up is how we can establish a secure communication channel with the existing enterprise system.</p>
<p>In this article, I will cover both how to trust a server certificate for secure communication with the server, as well as providing a client certificate to the server for mutual authentication. The client certificate is bundled with the app and of course, the server needs to trust this certificate.</p>
<h1>Setup</h1>
<p>Before we can start, keys and certificates need to be in place. My article <a href="http://blog.callistaenterprise.se/2011/11/24/creating-self-signed-certificates-for-use-on-android/">&#8220;Creating self-signed certificates for use on Android&#8221;</a> covers how to create keys and certificates as well as importing them into supported key stores. If you don&#8217;t have any keys or certificates, create the required files by reading that article.</p>
<h2>Android and self-signed certificates</h2>
<p>I assume that you already figured out how to create a simple Android app. However, I do not assume that you have put clienttruststore.bks or client.bks in your Android project’s res/raw directory. Before you continue, make sure the two files are there. These files were created in &#8220;Creating self-signed certificates for use on Android&#8221; but you can replace them with your own, just make sure that your keystores uses the <a href="http://www.bouncycastle.org/latest_releases.html">Bouncy Castle Provider</a>.</p>
<h1>Implementation</h1>
<p>This section covers how you can implement a custom HttpClient by registering a scheme for https communication and load a keystore and a truststore into a SSLSocketFactory.</p>
<h2>Extend HttpClient</h2>
<p>Android uses Apache Commons HttpClient but since we want communicate securely we must extend the DefaultHttpClient with some custom behavior (load our keystores). Therefore, we start by creating SecureHttpClient.java and extend the HttpClient.</p>
<pre lang="java">public class SecureHttpClient extends DefaultHttpClient {
    private int securePort;

    public SecureHttpClient(final int port) {
        this.securePort = port;
    }
}</pre>
<p>Simply put, we need to do two things to get our mutual authentication to work. 1) Create an SSLSocketFactory where we load our keystores and 2) Register a scheme for https communication that uses our custom SSLSocketFactory. This method will load our keystores.</p>
<h2>Create SSLSocketFactory and load the keystores</h2>
<p>Extend the SecureHttpClient with the two new methods found below. If you do not want to use mutual authentication you can just load the trust store in which the server&#8217;s certificate is. The resulting SSLSocketFactory will later be used when creating a scheme for https-communication.</p>
<pre lang="java">private SSLSocketFactory createSSLSocketFactory(final Context context) {
    Log.d(TAG, "Creating SSL socket factory");

    final KeyStore truststore = this.loadStore(context.getResources().openRawResource(R.raw.clienttruststore, "password", "BKS");
    final KeyStore keystore = this.loadStore(context.getResources().openRawResource(R.raw.client, "password", "BKS");

    return this.createFactory(keystore, this.keystorePassword, truststore);
}

private SSLSocketFactory createFactory(final KeyStore keystore, final String keystorePassword, final KeyStore truststore) {

    SSLSocketFactory factory;
    try {
        factory = new SSLSocketFactory(keystore, this.getKeystorePassword(), truststore);
        factory.setHostnameVerifier((X509HostnameVerifier) SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
    } catch (Exception e) {
        Log.e(TAG, "Caught exception when trying to create ssl socket factory. Reason: " + e.getMessage());
        throw new RuntimeException(e);
    }

    return factory;
}</pre>
<p>We now have a method that loads our keystores and return an SSLSocketFactory.</p>
<h2>Register a scheme for https</h2>
<p>Before we can communicate with our server, we must register a scheme for https communication that uses our SSLSocketFactory. The createConnectionManager() in HttpClient allows us to register our scheme. Override the createConnectionManager() method and provide the following implementation:</p>
<pre lang="java">@Override
protected ClientConnectionManager createClientConnectionManager() {

    Log.d(TAG, "Creating client connection manager");

    final SchemeRegistry registry = new SchemeRegistry();

    Log.d(TAG, "Adding https scheme for port " + securePort);
    registry.register(new Scheme("https", this.createSSLSocketFactory(), this.securePort));

    return new SingleClientConnManager(getParams(), registry);
}</pre>
<p>That&#8217;s about it. We now have the SecureHttpClient class that we can use from our Android app to communicate over Https.</p>
<h1>Using the Secure client</h1>
<p>It is time to use our SecureHttpClient and make a call to a web server. Since this is just a test, we can basically make the call from anywhere in the app and I choose to make it in an Activity&#8217;s onCreate()-method. The test server I used is a simple Jetty server (jetty-maven-plugin) where I added configuration for SSL containing a trust store and the server&#8217;s certificate. You can see how a simple server with SSL can be setup in the article: &#8220;Quick Start &#8211; Jetty, Maven and SSL&#8221;.</p>
<p>To make a https call to the server, simply provide an implementation like the one below:</p>
<pre lang="java">@Override
public void onCreate(Bundle savedInstanceState) {
    final HttpClient client = new SecureHttpClient(443);

    // Provide ip or address to where your test server is runnning
    final HttpGet request = new HttpGet("https://192.168.0.10:8443/example-server")
    final HttpResponse response = client.execute(request);

    Log.d("ExampleActivity", "Response code: " + response.getStatusLine().getStatusCode());
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.callistaenterprise.se/2011/11/24/android-tlsssl-mutual-authentication/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Quick Start &#8211; Jetty&#8217;s maven plugin with SSL</title>
		<link>http://blog.callistaenterprise.se/2011/11/24/quick-start-jettys-maven-plugin-with-ssl/</link>
		<comments>http://blog.callistaenterprise.se/2011/11/24/quick-start-jettys-maven-plugin-with-ssl/#comments</comments>
		<pubDate>Thu, 24 Nov 2011 08:49:03 +0000</pubDate>
		<dc:creator>Marcus Krantz</dc:creator>
				<category><![CDATA[Build]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.callistaenterprise.se/?p=1351</guid>
		<description><![CDATA[Speed is the key. I often need a web server in order to run a web application I developed to try things out. Setting up this infrastructure can often be quite tedious but if the only thing you need is a servlet container I often use the approach described in this article. We start out [...]]]></description>
			<content:encoded><![CDATA[<p>Speed is the key. I often need a web server in order to run a web application I developed to try things out. Setting up this infrastructure can often be quite tedious but if the only thing you need is a servlet container I often use the approach described in this article. We start out with nothing except Maven and Java installed.</p>
<p>Create a web application project:</p>
<pre lang="java">mvn archetype:generate -DgroupId=org.example -DartifactId=example-server -DarchetypeArtifactId=maven-archetype-webapp -Dversion=1.0</pre>
<p>This gives us a new directory (example-server) which is a Maven web application project. To run the web application, we configure the maven-jetty-plugin. Add the following configuration to project&#8217;s pom.xml</p>
<pre lang="xml">&lt;build&gt;
 &lt;finalName&gt;example-server&lt;/finalName&gt;
 &lt;plugins&gt;
   &lt;plugin&gt;
     &lt;groupId&gt;org.mortbay.jetty&lt;/groupId&gt;
     &lt;artifactId&gt;maven-jetty-plugin&lt;/artifactId&gt;
     &lt;version&gt;6.1.26&lt;/version&gt;
   &lt;/plugin&gt;
 &lt;/plugins&gt;
&lt;/build&gt;</pre>
<p>Enter the example-server directory and do:</p>
<pre>mvn jetty:run</pre>
<p>As soon as the server is started you can enter the following url in your browser.</p>
<pre>http://localhost:8080/example-server</pre>
<p>As you can see, the server is started and listens on port 8080 by default. If you want to change this, it can easily be configured. Just extend the plugin with a configuration element and add a connector.</p>
<pre>&lt;plugin&gt;
 &lt;groupId&gt;org.mortbay.jetty&lt;/groupId&gt;
 &lt;artifactId&gt;maven-jetty-plugin&lt;/artifactId&gt;
 &lt;version&gt;6.1.26&lt;/version&gt;
 &lt;configuration&gt;
   &lt;connectors&gt;
     &lt;connector implementation="org.mortbay.jetty.nio.SelectChannelConnector"&gt;
       &lt;port&gt;9090&lt;/port&gt;
     &lt;/connector&gt;
   &lt;/connectors&gt;
 &lt;/configuration&gt;
&lt;/plugin&gt;</pre>
<h2>Adding TLS/SSL support</h2>
<p>Assume you want to communicate in a secure way. The only thing you need to do is to add another connector element and specify a keystore containing the server&#8217;s certificate. If you don&#8217;t know how to create a certificate for your server, you can read my other blog post <a href="http://blog.callistaenterprise.se/2011/11/24/creating-self-signed-certificates-for-use-on-android/">&#8220;Creating self-signed certificates for use on Android&#8221;</a>. Simply add the following connector element and make sure the server.jks is located in your example-server directory:</p>
<pre>&lt;connector implementation="org.mortbay.jetty.security.SslSocketConnector"&gt;
 &lt;port&gt;9443&lt;/port&gt;
 &lt;keystore&gt;${basedir}/server.jks&lt;/keystore&gt;
 &lt;password&gt;password&lt;/password&gt;
 &lt;keyPassword&gt;password&lt;/keyPassword&gt;
&lt;/connector&gt;</pre>
<p>You can test this in a nice way using openssl to see what the server returns when you try to access it on port 9443.</p>
<pre>openssl s_client -connect localhost:9443</pre>
<p>Finally, if you for some reason want mutual authentication, you also need to specify a trust store in which the server keeps certificates of trusted clients. Extend the previous connector with the following information:</p>
<pre>&lt;connector implementation="org.mortbay.jetty.security.SslSocketConnector"&gt;
 &lt;port&gt;9443&lt;/port&gt;
 &lt;keystore&gt;${basedir}/server.jks&lt;/keystore&gt;
 &lt;password&gt;password&lt;/password&gt;
 &lt;keyPassword&gt;password&lt;/keyPassword&gt;
 &lt;truststore&gt;${basedir}/serverTruststore.jks&lt;/truststore&gt;
 &lt;trustPassword&gt;password&lt;/trustPassword&gt;
 &lt;needClientAuth&gt;true&lt;/needClientAuth&gt;
&lt;/connector&gt;</pre>
<p>Now you have a web server up and running your web application with mutual authentication. The clients must provide a valid certificate in order to communicate with the server. At last I just want to add a final element to our configuration. Since TLS/SSL can be quite horrible to troubleshoot, I add the following configuration which gives a lot of nice output <img src='http://blog.callistaenterprise.se/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<pre>&lt;systemProperties&gt;
  &lt;systemProperty&gt;
    &lt;name&gt;javax.net.debug&lt;/name&gt;
    &lt;value&gt;ssl&lt;/value&gt;
  &lt;/systemProperty&gt;
&lt;systemProperties&gt;
</pre>
<p>Have fun!</p>
<h2>References</h2>
<ul>
<li><a href="http://docs.codehaus.org/display/JETTY/Maven+Jetty+Plugin">Maven Jetty Plugin</a></li>
<li><a href="http://maven.apache.org/guides/mini/guide-webapp.html">Maven Webapp Archetype</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.callistaenterprise.se/2011/11/24/quick-start-jettys-maven-plugin-with-ssl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating self-signed certificates for use on Android</title>
		<link>http://blog.callistaenterprise.se/2011/11/24/creating-self-signed-certificates-for-use-on-android/</link>
		<comments>http://blog.callistaenterprise.se/2011/11/24/creating-self-signed-certificates-for-use-on-android/#comments</comments>
		<pubDate>Thu, 24 Nov 2011 08:48:50 +0000</pubDate>
		<dc:creator>Marcus Krantz</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://blog.callistaenterprise.se/?p=1253</guid>
		<description><![CDATA[A while ago I started to implement TLS/SSL mutual authentication on Android. How to actually implement the functionality on the Android platform is covered in my other article &#8220;Android &#8211; TLS/SSL Mutual Authentication&#8221;. Before such implementation can be done, it is important to have the keys and certificates prepared. In this article demonstrate how you [...]]]></description>
			<content:encoded><![CDATA[<p>A while ago I started to implement TLS/SSL mutual authentication on Android. How to actually implement the functionality on the Android platform is covered in my other article <a href="http://blog.callistaenterprise.se/2011/11/24/android-tlsssl-mutual-authentication/">&#8220;Android &#8211; TLS/SSL Mutual Authentication&#8221;</a>. Before such implementation can be done, it is important to have the keys and certificates prepared. In this article demonstrate how you can create these. However, this article is not just applicable to Android and should be usable in other scenarios as well.</p>
<p>For this article to be useful, the required tools are: openssl, Java&#8217;s Keytool and the BouncyCastle-provider (<a href="http://www.bouncycastle.org/latest_releases.html">Click here</a> to download). There are also some resources that I strongly recommend and has been very useful:</p>
<ul>
<li><a href="http://www.tldp.org/HOWTO/SSL-Certificates-HOWTO/">SSL Certificates Howto</a></li>
<li><a href="http://www.openssl.org/docs/HOWTO/keys.txt">OpenSSL Keys Howto</a></li>
<li><a href="http://www.openssl.org/docs/HOWTO/certificates.txt">OpenSSL Certificates Howto</a></li>
<li><a href="http://download.oracle.com/javase/6/docs/technotes/tools/solaris/keytool.html">Java Keytool</a></li>
</ul>
<p>One might argue why I don&#8217;t use keytool to generate the keys and certificates and use them right away. Well, I was very curious about learning more about openssl and how to deal with various formats of keys and certificates.</p>
<h1>1. Create private keys</h1>
<p>Let&#8217;s start from scratch. First of all we need private keys. We use openssl to create these:</p>
<pre>openssl genrsa -des3 -out client_key.pem 2048</pre>
<pre>openssl genrsa -des3 -out server_key.pem 2048</pre>
<p>This will create the two keys; client.pem and server.pem. We will use these in the next step to sign our certificates with. In normal cases we would create a CA-signing request, that is sent to a CA who will issue your certificates. But since we want to self-sign our certificates this step is redundant.</p>
<h1>2. Create self-signed certificates</h1>
<pre>openssl req -new -x509 -key client_key.pem -out client.pem -days 365</pre>
<pre>openssl req -new -x509 -key server_key.pem -out server.pem -days 365</pre>
<p>Additionally, instead of being prompted for the certificate&#8217;s subject line you can use the &lt;pre&gt;-subj&lt;/pre&gt; parameter and pass it to the &lt;pre&gt;openssl req&lt;/pre&gt; command. What we just did was basically creating a CA signing request using our private keys to sign the outgoing x509-certificates. The certificates will be coded in pem-format and valid for 365 days.</p>
<h1>3. Create trust stores</h1>
<p>In order to use our keys and certificates in Java applications we need to import them into keystores. First of all, we want the client to trust the server certificate. To do this we must create a client trust store and import the server’s certificate.</p>
<pre>keytool –importcert -trustcacerts –keystore clienttruststore.bks –storetype bks –storepass &lt;truststore_password&gt; -file server.pem -provider org.bouncycastle.jce.provider.BouncyCastleProvider –providerpath &lt;path_to_bcprov_jar&gt;</pre>
<blockquote><p><strong>Note:</strong> On the client side, which in our case will be an Android app we use Bouncy Castle as our provider since it is supported on the Android platform.</p></blockquote>
<p>Create a trust store for the server and import the client&#8217;s certificate into it.</p>
<pre>keytool –importcert -trustcacerts –keystore  servertruststore.jks –storetype jks –storepass &lt;server_truststore_password&gt; -file client.pem</pre>
<p>Currently, we have two trust stores one for the server in which we imported the client’s certificate and one for the client in which we imported the server’s certificate.</p>
<h1>4. Combine keys and certificates</h1>
<p>A problem with Java’s keytool application is that it won’t let us do such a simple thing as importing an existing private key into a keystore. The workaround to this problem is to combine the private key with the certificate into a pkcs12-file (which is understood by Java’s keytool) and then import this pkcs12 keystore into a regular keystore.</p>
<p>Combine the certificate and the private key for the server and client respectively:</p>
<pre>openssl pkcs12 –export –inkey  client_key.pem –in client.pem –out  client.p12</pre>
<pre>openssl pkcs12 –export –inkey server_key.pem –in server.pem –out server.p12</pre>
<h1>5. Convert from pkcs12</h1>
<p>Import the created keystores to new ones with common formats:</p>
<pre>keytool –importkeystore –srckeystore client.p12 –srcstoretype pkcs12 –destkeystore client.bks –deststoretype bks –provider org.bouncycastle.jce.provider.BouncyCastleProvider –providerpath &lt;path_to_bcprov_jar&gt;</pre>
<pre>keytool –importkeystore –srckeystore server.p12 –srcstoretype pkcs12 –destkeystore server.jks –deststoretype jks</pre>
<p>We should now have all files we need for a successful TLS/SSL mutual authentication. The files we move to our Android project will be: clienttruststore.bks and client.bks. The files we move to our server will be: servertruststore.jks and server.jks.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.callistaenterprise.se/2011/11/24/creating-self-signed-certificates-for-use-on-android/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Configure your spring web application</title>
		<link>http://blog.callistaenterprise.se/2011/11/17/configure-your-spring-web-application/</link>
		<comments>http://blog.callistaenterprise.se/2011/11/17/configure-your-spring-web-application/#comments</comments>
		<pubDate>Wed, 16 Nov 2011 23:38:49 +0000</pubDate>
		<dc:creator>Anders Asplund</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.callistaenterprise.se/?p=1291</guid>
		<description><![CDATA[This post is the first in a series of two blog posts where I will try to give some usefull tips on how to make your spring applications more configurable. Too often I see application configuration files embedded somewhere deep down in the application referenced only by its classpath location.
&#60;context:property-placeholder location="classpath:config.properties" /&#62;
By injecting the configurations [...]]]></description>
			<content:encoded><![CDATA[<p>This post is the first in a series of two blog posts where I will try to give some usefull tips on how to make your spring applications more configurable. Too often I see application configuration files embedded somewhere deep down in the application referenced only by its classpath location.</p>
<p><code>&lt;context:property-placeholder location="classpath:config.properties" /&gt;</code></p>
<p>By injecting the configurations this way they will be packaged inside the application in and you will have to rebuild and deploy it if you need to make any changes. Considered you have environment specific configurations you will also have to build an artifact for each and every environment. </p>
<p>A better way to handle the configuration files is to put them outside of the application in a separate location on the server. Changing configuration using this setup will at most force you to restart your application to make Spring reload them. I normally put the configuration files in a separate folder under my home catalog, i.e. <em>~/.myapp/config.properties</em>. In the spring config file you will inject the configurations using:</p>
<p><code>&lt;context:property-placeholder location="file:${user.home}/.myapp/config.properties" /&gt;</code></p>
<p>user.home is a standard JVM system property which is resolved by Spring using the <em>${&#8230;}</em> placeholder to the home catalog of the user running the server. You can even make the configuration location configurable through an environment variable:</p>
<p><code>&lt;context:property-placeholder location="file:${MY_APP_CONFIG}" /&gt;</code></p>
<p>But what if you want to package some default configurations within you application but still give the opportunity to manipulate them without the need to rebuild and make it possible to choose your own config location? No problem use:</p>
<p><code>&lt;context:property-placeholder location="classpath:config.properties, file:${user.home}/config.properties, file:${MY_APP_CONFIG}" /&gt;</code></p>
<p>Spring will read and merge the configuration files in the order they appear and will override duplicated configurations. This means that you can override the default configurations by adding them in ${user.home}/config.properties or ${MY_APP_CONFIG}.</p>
<p>Ok, now I showed how to configure the property files but what if you want to configure the Spring application context? What if you want to configure the way your application is put together? Lets take an example: If an application uses JNDI to retrieve the database connection you will first need to configure your server with a database connection and a JNDI-name. Secondly you will need to create a datasource bean in you application context which is injected into your DAO:s, i.e:</p>
<p>The dao:<br />
<code>public class OrderDao {<br />
  private JdbcTemplate jdbcTemplate;<br />
  public void setDataSource(DataSource dataSource) {<br />
    this.jdbcTemplate = new JdbcTemplate(dataSource);<br />
  }<br />
}<br />
</code></p>
<p>The spring config file dao-config.xml:<br />
<code>&lt;bean id="myDao" class="com.example.OrderDao"&gt;<br />
  &lt;property name="dataSource" ref="dataSource"/&gt;<br />
&lt;/bean&gt;<br />
</code></p>
<p>Using JNDI will force you to configure the server to before you can run the application. But as a developer of you don&#8217;t change the JNDI configuration on your server for every application you work on. Instead it would be great if you could create a direct connection using Spring, this would remove the need of server configuration. Here is two example showing the datasource bean configured to use JNDI in the first case and a direct connection in the second case:</p>
<p>JNDI &#8211; datasource-jndi-config.xml:<br />
<code>&lt;bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"&gt;<br />
  &lt;property name="jndiName" value="${datasource.jndiName}" /&gt;<br />
&lt;/bean&gt;<br />
</code></p>
<p>Direct &#8211; datasource-direct-config.xml:<br />
<code>&lt;bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"&gt;<br />
  &lt;property name="driverClassName" value="${datasource.driverClassName}" /&gt;<br />
  &lt;property name="url" value="${datasource.url}" /&gt;<br />
  &lt;property name="username" value="${datasource.username}" /&gt;<br />
  &lt;property name="password" value="${datasource.password}" /&gt;<br />
&lt;/bean&gt;<br />
</code></p>
<p>In the dao-config.xml it is now possible choose which one of the two datasources I would like to use by importing the corresponding file.  When deploying on the dev. environment use:</p>
<p><code>&lt;import resource="datasource-direct-config.xml" /&gt;</code></p>
<p>and when deploying to production use:</p>
<p><code>&lt;import resource="datasource-jndi-config.xml" /&gt;</code></p>
<p>It could be quite annoying having to switch like this, but luckily Spring has a solution for this. Using the ${&#8230;} placeholder we can inject which type of datasource connector we would like to use, we could even give it a default value incase we don&#8217;t inject a connector type. This is done by adding a <img src='http://blog.callistaenterprise.se/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> colon) in the placeholder like this:</p>
<p><code>&lt;import resource="datasource-${datasource.connector:jndi}-config.xml" /&gt;</code></p>
<p>The ${&#8230;} placeholder picks up parameters from System properties, environment variables and the property files we injected earlier. So this mean that we Now have an application context that is externally configurable. By setting a property named datasource.connector=direct we could easily change the application to use a direct connection to the database instead of retrieve it from JNDI. </p>
<p>Great we are done? No, unfortunately the ${&#8230;} placeholder is unable to pick up an property from a property file injected to a property-placeholder bean if it is used in an import-tag, why I will explain in the next blog post. This will limit us to set the datasource connector using either a System property (i.e. use -Ddatasource.connector=direct when starting you server) or an environment variable. To be really happy want to keep all configuration parameters in config.properties but in the way Spring works this is not possible out of the box. In my next blog post I will explain why this isn&#8217;t possible and I will also show a solution to the problem.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.callistaenterprise.se/2011/11/17/configure-your-spring-web-application/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>(Swedish) Kan OAuth2 vara dörren till att öppna journalerna för marknaden?</title>
		<link>http://blog.callistaenterprise.se/2011/11/13/swedish-kan-oauth2-vara-dorren-till-att-oppna-journalerna-for-marknaden/</link>
		<comments>http://blog.callistaenterprise.se/2011/11/13/swedish-kan-oauth2-vara-dorren-till-att-oppna-journalerna-for-marknaden/#comments</comments>
		<pubDate>Sun, 13 Nov 2011 19:10:32 +0000</pubDate>
		<dc:creator>Johan Eltes</dc:creator>
				<category><![CDATA[Quality]]></category>
		<category><![CDATA[RESTFul]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[eHealth]]></category>

		<guid isPermaLink="false">http://blog.callistaenterprise.se/?p=1247</guid>
		<description><![CDATA[(Sorry for writing this up in Swedish &#8211; the post is in the context of Swedish e-health. If this moves forwards I&#8217;ll wright the next post in english&#8230;hrmmm&#8230;well.. Swinglish)
Kim Nordlander (SLL) och Åke Rosander (Cehis) presenterade projektet Mina Hälsotjänster under nationella eHälsodagen här om veckan: http://www.nationellehalsa.se/program.html. Ett sätt att dela upp tjänster (i betydelsen IT-stöd) för [...]]]></description>
			<content:encoded><![CDATA[<p>(Sorry for writing this up in Swedish &#8211; the post is in the context of Swedish e-health. If this moves forwards I&#8217;ll wright the next post in english&#8230;hrmmm&#8230;well.. Swinglish)</p>
<p>Kim Nordlander (SLL) och Åke Rosander (Cehis) presenterade projektet Mina Hälsotjänster under nationella eHälsodagen här om veckan: <a href="http://www.nationellehalsa.se/program.html">http://www.nationellehalsa.se/program.html</a>. Ett sätt att dela upp tjänster (i betydelsen IT-stöd) för invånaren är att utgå från avsändaren. Om vård och omsorg är avsändaren kan marknaden leverera e-tjänster till invånaren, men det måste förmodligen ske genom att sälja tjänsten till landstingen. Det betyder (som jag uppfattat saken) att e-tjänsten måste ligga inom ramen för landstingets uppdrag &#8211; dvs ha direkt koppling till vårdprocessen. Några exempel kan vara tidbokningstjänster för invånaren och visualisering av mina remissers status i remissprocessen.</p>
<p>Men det talas allt mer om tjänster invånaren själv väljer för att samla, hantera och utbyta information kring sin hälsa. Dessa tjänster går under många namn:<br />
- Mitt Hälsokonto<br />
- Min hälsodagbok<br />
- PHR &#8211; Personal Health Record</p>
<p>Dessa kan användas för att samla in och sammanställa information från träningsdagböcker (t.ex. Runkeeper), från egen privat hälsotillståndsmätning (en växande marknad av gadgets för såväl hypokondriker som olika former av kroniker) eller helt enkelt egna observationer. Informationen kan användas i sociala medier riktade mot olika sjukdomstillstånd eller kanske som underlag för en &#8220;second opinion&#8221; för den som känner osäkerhet kring kvalitén i hanteringen av ett hälsoärende.</p>
<p>Denna typ av invånar-tjänster söker man själv upp. Det är ett privat beslut att &#8220;hoppa på&#8221; en specifik &#8220;app&#8221;. Man byter kanske till en annan om det dyker upp en bättre, eller om en annan tjänst fått en större community och därför över tiden visat sig vara ett bättre val. Så vad har det då med Mina Hälsotjänster att göra? En tanke som sysselsatt mig ett tag är vad det skulle innebära att öppna upp dagens vård-data-api:er till denna typ av applikationer för privat hälsodata.</p>
<p>Idag kan en app anslutas till nationella api:er mot landstingens vårdsystem så länge appen har en vårdhuvudman som avsändare. Den bakomliggande säkerhetsmodellen är okomplicerad och beprövad: så kallad organisationstillit. Det betyder lite förenklar att man kan &#8220;öppna informationskanalerna&#8221; mellan parternas system så länge parterna är betrodda organisationer (läs vårdgivare). Tekniskt sett upprättas tilliten med enkla medel så som klient-authenitiserade (funktionscertifikat) krypterade kanaler (TLS).</p>
<p>Men hur gör man för att en app som marknaden byggt och som invånaren själv beslutat använda för sin hälsodata ska kunna hämta in data från vårdens verksamhetssystem? Jag kanske vill integrera information från mina labbsvar i min hälsodatabas? Ett annat scenaro är att min vårdgivare vill få in mina egna mätningar som bilaga till journalen. Eller en bokningsfunktion som liksom hotell-och flygbokningsagenter aggregerar en mängd underliggande tjänster för min bekvämlighet? Det behövs något sätt att låta invånaren ta ansvar för vilka appar som får läsa och påverka infromation hos vårdgivarna under invånarens identitet.</p>
<p>Det juridiska perspektivet måste förstås belysas. Patientdata-juristen Andreas Hager har gjort en<a href="http://patientdatajuridik.wordpress.com/2011/10/19/skillnaden-mellan-direktatkomst-och-adb-utlamnande/"> genomlysning</a> som indikerar att det kan finnas stöd i lagar och författningar. Jag tänker mig att det vore ung. samma frågeställning som om jag kunde logga in i Mina vårdkontakter, se mina labbsvar och sedan gavs möjlighet att ladda ner dem (&#8220;spara som &#8230;&#8221;) till min dator för att sedan importera filen till min valda &#8220;hälsodagboksapp&#8221;. Men att appar jag väljer istället kan göra jobbet åt mig &#8211; dvs utan manuell filhantering.</p>
<p>I presentationen nedan har jag försökt skissa en arkitektur för invånarstyrd informationsåtkomst. Det är mina funderingar och representerar alltså inte någon av mina uppdragsgivares strategier eller beslut.</p>
<p>Vad tror du? Finns behovet? Är OAuth2 i så fall rätt väg? Skulle du låta Google Health läsa labbsvar från dina hälsoärenden i vård och omsorg? Skulle du låta en facebookapp som jag utvecklat läsa din medicinlista från journalen hos en vårdenhet för att ge dig påminnelser när du ska ta dina mediciner? Är detta den gyllene länken mellan patienten, dagens journalsystem och marknadens innovatörer?</p>
<div style="width:595px" id="__ss_10142296"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/johaneltes/invnar-styrd-tkomst-av-patientdata" title="Invånar styrd åtkomst av patientdata" target="_blank">Invånar styrd åtkomst av patientdata</a></strong> <object id="__sse10142296" width="595" height="497"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=invnar-styrdinformationstkomst-111113125825-phpapp01&#038;rel=0&#038;stripped_title=invnar-styrd-tkomst-av-patientdata&#038;userName=johaneltes" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse10142296" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=invnar-styrdinformationstkomst-111113125825-phpapp01&#038;rel=0&#038;stripped_title=invnar-styrd-tkomst-av-patientdata&#038;userName=johaneltes" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="595" height="497"></embed></object>
<div style="padding:5px 0 12px"> View more <a href="http://www.slideshare.net/" target="_blank">presentations</a> from <a href="http://www.slideshare.net/johaneltes" target="_blank">Johan Eltes</a> </div>
</p></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.callistaenterprise.se/2011/11/13/swedish-kan-oauth2-vara-dorren-till-att-oppna-journalerna-for-marknaden/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Getting started with git</title>
		<link>http://blog.callistaenterprise.se/2011/10/26/getting-started-with-git/</link>
		<comments>http://blog.callistaenterprise.se/2011/10/26/getting-started-with-git/#comments</comments>
		<pubDate>Wed, 26 Oct 2011 06:30:27 +0000</pubDate>
		<dc:creator>Jan Västernäs</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.callistaenterprise.se/?p=1235</guid>
		<description><![CDATA[Having used subversion for a long time I wanted to learn how to use a distributed versioning system. The selling points for these products are very interesting.
For instance the possibility to separate commit from delivery seems like a nice option.
If you work on something that takes a couple of days to do, you want to [...]]]></description>
			<content:encoded><![CDATA[<p>Having used subversion for a long time I wanted to learn how to use a distributed versioning system. The selling points for these products are very interesting.</p>
<p>For instance the possibility to separate commit from delivery seems like a nice option.<br />
If you work on something that takes a couple of days to do, you want to commit often even when only parts of the work is ready without disturbing your colleagues. You want to commit even if all tests are not green. You want to be able to experiment and throw some stuff away by going back to previous committed versions. With a DVCS (Distributed Versioning Control System) you do all of this in your local repository and only when you are finished you deliver to the project repository where other people then can use it.</p>
<p>Which product should you use ? Git and Mercurial seems to be the popular choices.<br />
Based on the post &#8220;Git is McGywer and Mercurial is James Bond&#8221; http://importantshock.wordpress.com/2008/08/07/git-vs-mercurial/ i choose git, although<br />
I&#8217;m not a command-line wizard.</p>
<p>Installation on OS-X is very easy as expected. I used http://git-scm.com/download<br />
In windows it is a bit more complicated because you have to choose between 2 different setups. I choose the option without cyg-win and running bash in command windows. I wonder who has the balls to choose the third option in this question ?</p>
<p><a href="http://blog.callistaenterprise.se/wp-content/uploads/Screen-Shot-2011-09-17-at-13.46.14-.png"><img class="alignnone size-full wp-image-1236" title="Screen Shot 2011-09-17 at 13.46.14" src="http://blog.callistaenterprise.se/wp-content/uploads/Screen-Shot-2011-09-17-at-13.46.14-.png" alt="" width="517" height="400" /></a></p>
<p>Anyway creating a repository and checking files in is very easy</p>
<p><a href="http://blog.callistaenterprise.se/wp-content/uploads/Screen-Shot-2011-10-26-at-07.51.00-.png"><img class="alignnone size-full wp-image-1237" title="Screen Shot 2011-10-26 at 07.51.00" src="http://blog.callistaenterprise.se/wp-content/uploads/Screen-Shot-2011-10-26-at-07.51.00-.png" alt="" width="499" height="261" /></a></p>
<p>The init command will create the repository. The only bit of magic is the git add command. It will add one or many files to something called the index. Only changes added to the index will we affected by the next git commit.</p>
<p>Now you can start playing around with creating branches, make changes and merging branches. Working with branches is much less expensive than you thing and a recommended way of using git.</p>
<p>But having only a single repository probably is not want you want to do. Collaboration between different team members is of course the next thing to try out. In order to understand how that work I did like this.</p>
<p><a href="http://blog.callistaenterprise.se/wp-content/uploads/Screen-Shot-2011-10-26-at-08.08.34-.png"><img class="alignnone size-full wp-image-1239" title="Screen Shot 2011-10-26 at 08.08.34" src="http://blog.callistaenterprise.se/wp-content/uploads/Screen-Shot-2011-10-26-at-08.08.34-.png" alt="" width="412" height="280" /></a></p>
<p>Now you have three complete repositories. You can imagine that clone1 and clone2 are local repositories at different users and that repo the a project common repository. I used three different command windows, one for each repo. Then it was easy to change something in clone1, push it to repo an pull the changes to clone2. Also simulating conflicts and how to resolve them is very easy since you have full control of all three repos.</p>
<p><a href="http://blog.callistaenterprise.se/wp-content/uploads/Screen-Shot-2011-10-26-at-08.18.17-.png"><img class="alignnone size-full wp-image-1240" title="Screen Shot 2011-10-26 at 08.18.17" src="http://blog.callistaenterprise.se/wp-content/uploads/Screen-Shot-2011-10-26-at-08.18.17-.png" alt="" width="510" height="310" /></a></p>
<p><a href="http://blog.callistaenterprise.se/wp-content/uploads/Screen-Shot-2011-10-26-at-08.18.22-.png"><img class="alignnone size-full wp-image-1241" title="Screen Shot 2011-10-26 at 08.18.22" src="http://blog.callistaenterprise.se/wp-content/uploads/Screen-Shot-2011-10-26-at-08.18.22-.png" alt="" width="422" height="314" /></a></p>
<p>In conclusion getting started with git is easy. Mastering all (or much) of the git functionality and different distributed repository topologies will probably take much longer.</p>
<p>Martin Fowler makes an interesting comparison between different products</p>
<p><a href="http://blog.callistaenterprise.se/wp-content/uploads/vcs-plane.png"><img class="alignnone size-full wp-image-1242" title="vcs-plane" src="http://blog.callistaenterprise.se/wp-content/uploads/vcs-plane.png" alt="" width="503" height="386" /></a></p>
<p><a href="http://blog.callistaenterprise.se/wp-content/uploads/vcs-plane.png"></a>From this you can see that git and mercurial are useful but more complex to learn.</p>
<p>When it comes to topologies I think that <a href="http://github.com/schacon">Scott Chacon</a> has some nice pictures, how about this one :</p>
<p><a href="http://blog.callistaenterprise.se/wp-content/uploads/workflow-c.png"><img class="alignnone size-full wp-image-1243" title="workflow-c" src="http://blog.callistaenterprise.se/wp-content/uploads/workflow-c.png" alt="" width="562" height="303" /></a></p>
<p>Some useful resorces</p>
<p><a href="http://help.github.com/git-cheat-sheets/">http://help.github.com/git-cheat-sheets/</a></p>
<p><a href="http://book.git-scm.com/index.html">http://book.git-scm.com/index.html</a></p>
<p><a href="http://ndpsoftware.com/git-cheatsheet.html#loc=remote_repo;">http://ndpsoftware.com/git-cheatsheet.html#loc=remote_repo;</a></p>
<p><a href="http://whygitisbetterthanx.com/#">http://whygitisbetterthanx.com/#</a></p>
<p><a href="http://martinfowler.com/bliki/VersionControlTools.html">http://martinfowler.com/bliki/VersionControlTools.html</a></p>
<p>And .. this video is a must</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/CDeG4S-mJts" frameborder="0" allowfullscreen></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.callistaenterprise.se/2011/10/26/getting-started-with-git/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>From the MuleForge: Working on the SFTP Transport and the Smooks Module</title>
		<link>http://blog.callistaenterprise.se/2011/09/29/from-the-muleforge-working-on-the-sftp-transport-and-the-smooks-module/</link>
		<comments>http://blog.callistaenterprise.se/2011/09/29/from-the-muleforge-working-on-the-sftp-transport-and-the-smooks-module/#comments</comments>
		<pubDate>Thu, 29 Sep 2011 05:19:24 +0000</pubDate>
		<dc:creator>Magnus Larsson</dc:creator>
				<category><![CDATA[ESB]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[large files]]></category>
		<category><![CDATA[mule]]></category>
		<category><![CDATA[SFTP]]></category>
		<category><![CDATA[Smooks]]></category>

		<guid isPermaLink="false">http://blog.callistaenterprise.se/?p=1208</guid>
		<description><![CDATA[How to transfer and transform very large files (&#62; 1 GB) without headaches…
While Web Services (SOAP or REST based) gets all the attention in the press, there are many companies still struggling with file transfers and transformation of very large files (for the scope of this blog defined as files of size &#62; 1 GB). [...]]]></description>
			<content:encoded><![CDATA[<h1><em><span style="color: #888888;">How to transfer and transform very large files (&gt; 1 GB) without headaches…</span></em></h1>
<p>While Web Services (SOAP or REST based) gets all the attention in the press, there are many companies still struggling with file transfers and transformation of very large files (for the scope of this blog defined as files of size &gt; 1 GB). Typically, these companies, can’t get a file of that size through their integration platform and messaging backbone without having to do all sort of tricks such as <a href="http://www.enterpriseintegrationpatterns.com/Sequencer.html">splitting</a> files into smaller one and later on both <a href="http://www.enterpriseintegrationpatterns.com/Resequencer.html">re-sequence</a> and <a href="http://www.enterpriseintegrationpatterns.com/Aggregator.html">aggregate</a> them back again and/or setting up huge memory heaps on their servers and so on…</p>
<div id="_mcePaste">On top of that, many companies still use FTP for sending files unencrypted and resulting in a lot of usernames/passwords cluttered all over the system landscape, where instead SFTP can provide a secure transport and more easy managed authentication through its use of SSH and PKI.</div>
<p>In this blog I will describe how I have been working with some of our customers to help them find inexpensive and simple (removing unnecessary complexity) but still robust solutions, using open source products such as <a href="http://www.mulesoft.org/">Mule ESB</a> and the transformation framework <a href="http://www.smooks.org/">Smooks</a>, to achieve large file transfer and transformation.</p>
<p>It turned out during this work that the current status of some of the open source components we decided to use did not meet all our requirements. But since we are talking about open source there is a very good solution to that, add the missing pieces yourself (in the way you want it) and bring it back to the open source project!</p>
<p>The open source projects mentioned below lives in the <a href="http://www.mulesoft.org/muleforge">MuleForge</a>, a hosting site and community for development and sharing of open source extensions to Mule ESB and that is where my contributions ended up.</p>
<h1>SFTP</h1>
<p>In late 2009, I was involved in a customer project using Mule ESB. In this project we needed to transfer large files but we didn’t want to use FTP. In fact we strived to replace FTP with SFTP.</p>
<p>We started to evaluate the SFPT transport in Mule ESB (that lived in the MuleForge at that time). We found out that the SFTP transport, thanks to its streaming capabilities, could handle large files very well but there were a number of other features required by the customer that were missing in the transport, such as archive functionality, handling of duplicate file names, file-size checks to determine if a file is completely created before consuming it and so on.</p>
<p>To address these shortcomings I decided to join the SFTP-transport project. A couple months later the project released a new version of the transport that solved the mentioned concerns. Since then, our customer has been using the SFTP-transport in production.</p>
<p>Below is a very basic example of a file transfer from one SFTP-server to another SFTP-server applying a Java based transformation of the content. If you download the source code of the transport and take a look in the integration tests and their <a href="http://svn.codehaus.org/mule/branches/mule-3.x/transports/sftp/src/test/resources/">mule-config-files</a>, you can find many other examples of its use.</p>
<p><a href="http://blog.callistaenterprise.se/wp-content/uploads/Skärmavbild-2011-09-27-kl.-23.47.24.png"><img title="Skärmavbild 2011-09-27 kl. 23.47.24" src="http://blog.callistaenterprise.se/wp-content/uploads/Skärmavbild-2011-09-27-kl.-23.47.24.png" alt="" width="463" height="346" /></a></p>
<p><strong>Note #1:</strong> The example assumes usage of PKI-keys and not old style username/password.</p>
<p><strong>Note #2:</strong> In a real-world case attributes such as address would not be hardcoded but instead be provided as a configurable property.</p>
<p>Over time the SFTP-transport has been used more and more widely and in early 2011, MuleSoft decided to add the SFTP-transport as a core transport of the Mule ESB product. Since Mule ESB v3.1.2 the SFTP-transport is part of the Mule ESB distribution.</p>
<p>…and my work as a MuleForge committer was over for the time being…</p>
<h1>Smooks</h1>
<p>Earlier this year (2011) I started to look at the <a href="http://www.smooks.org/">Smooks project</a>, specifically regarding its capabilities to transform between many different formats using a declarative and template driven approach. Added to that Smooks also have support for stream based transformation opening up for transforming very large files without any hassle (as described above). Very compelling when combined with the streaming capabilities of Mule ESB’s file transports (file, FTP and of course SFTP)!</p>
<p>The way to integrate Smooks in Mule ESB is to use the <a href="http://www.mulesoft.org/documentation/display/SMOOKS/Home">Smooks Module for Mule</a> at the MuleForge, i.e. Smooks support in Mule is not a core part of the Mule ESB product.</p>
<p>Using the Smooks Module you can for example easily replace the Java based transformer in the SFTP-transport example above with a much more versatile Smooks based transformer by replacing the line:</p>
<pre>    &lt;<span style="text-decoration: underline;">custom-transformer</span> class="...MyTransformer"/&gt;</pre>
<p>with:</p>
<pre>    &lt;smooks:transformer configFile="my-smooks-transformer.xml"/&gt;</pre>
<p>A problem I found out working with Smooks and Mule was that the Smooks Module for Mule was not yet released for Mule 3, only for Mule 1.x and Mule 2.x. However, all changes required for Mule 3 was already developed and committed but no one have had time to do the final testing and release management for a Mule 3 compatible release.</p>
<p>…so I decided to join in again, this time with the goal to release a Mule 3 compatible version of the Smooks Module!</p>
<p>Last weekend we released a release candidate for the next version, v1.3-RC1, which brings in compatibility with Mule 3.1.x. See <a href="http://www.mulesoft.org/documentation/display/SMOOKS/Smooks+for+Mule+1.3-RC1+released">Smooks for Mule v1.3-RC1 released</a> for details!</p>
<p>A very good example of what the Smooks framework is capable of doing for you is the example in the Smooks distribution called “<em><strong>freemarker-huge-transform</strong></em>”. It demonstrates a setup where Smooks transforms very large XML-files containing order heads and order lines. An outer streaming SAX-parser is setup to stream through the order head elements and delegates the processing of the order lines to a DOM-parser. This means that the memory intensive DOM models only exist for one order line at the time resulting in a very small memory footprint even for transforming very large files. Freemarker is used as the templating language to declare what the actual transformation should do with each order head and order line.</p>
<p>Copy of the <a href="https://github.com/smooks/smooks/blob/master/smooks-examples/freemarker-huge-transform/smooks-config.xml">smooks-config – file</a> from the example, comments removed to keep the size down:</p>
<p><a href="http://blog.callistaenterprise.se/wp-content/uploads/Skärmavbild-2011-09-27-kl.-23.36.36.png"><img title="Skärmavbild 2011-09-27 kl. 23.36.36" src="http://blog.callistaenterprise.se/wp-content/uploads/Skärmavbild-2011-09-27-kl.-23.36.36.png" alt="" width="553" height="643" /></a></p>
<p><!--[if gte mso 9]><xml> <o:DocumentProperties> <o:Revision>0</o:Revision> <o:TotalTime>0</o:TotalTime> <o:Pages>1</o:Pages> <o:Words>37</o:Words> <o:Characters>211</o:Characters> <o:Company>Callista Enterprise AB</o:Company> <o:Lines>1</o:Lines> <o:Paragraphs>1</o:Paragraphs> <o:CharactersWithSpaces>247</o:CharactersWithSpaces> <o:Version>14.0</o:Version> </o:DocumentProperties> <o:OfficeDocumentSettings> <o:AllowPNG /> </o:OfficeDocumentSettings> </xml><![endif]--> <!--[if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:TrackMoves /> <w:TrackFormatting /> <w:PunctuationKerning /> <w:ValidateAgainstSchemas /> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:DoNotPromoteQF /> <w:LidThemeOther>SV</w:LidThemeOther> <w:LidThemeAsian>JA</w:LidThemeAsian> <w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript> <w:Compatibility> <w:BreakWrappedTables /> <w:SnapToGridInCell /> <w:WrapTextWithPunct /> <w:UseAsianBreakRules /> <w:DontGrowAutofit /> <w:SplitPgBreakAndParaMark /> <w:EnableOpenTypeKerning /> <w:DontFlipMirrorIndents /> <w:OverrideTableStyleHps /> <w:UseFELayout /> </w:Compatibility> <m:mathPr> <m:mathFont m:val="Cambria Math" /> <m:brkBin m:val="before" /> <m:brkBinSub m:val="&#45;-" /> <m:smallFrac m:val="off" /> <m:dispDef /> <m:lMargin m:val="0" /> <m:rMargin m:val="0" /> <m:defJc m:val="centerGroup" /> <m:wrapIndent m:val="1440" /> <m:intLim m:val="subSup" /> <m:naryLim m:val="undOvr" /> </m:mathPr></w:WordDocument> </xml><![endif]--><!--[if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="true"   DefSemiHidden="true" DefQFormat="false" DefPriority="99"   LatentStyleCount="276"> <w:LsdException Locked="false" Priority="0" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="Normal" /> <w:LsdException Locked="false" Priority="9" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="heading 1" /> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 2" /> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 3" /> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 4" /> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 5" /> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 6" /> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 7" /> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 8" /> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 9" /> <w:LsdException Locked="false" Priority="39" Name="toc 1" /> <w:LsdException Locked="false" Priority="39" Name="toc 2" /> <w:LsdException Locked="false" Priority="39" Name="toc 3" /> <w:LsdException Locked="false" Priority="39" Name="toc 4" /> <w:LsdException Locked="false" Priority="39" Name="toc 5" /> <w:LsdException Locked="false" Priority="39" Name="toc 6" /> <w:LsdException Locked="false" Priority="39" Name="toc 7" /> <w:LsdException Locked="false" Priority="39" Name="toc 8" /> <w:LsdException Locked="false" Priority="39" Name="toc 9" /> <w:LsdException Locked="false" Priority="35" QFormat="true" Name="caption" /> <w:LsdException Locked="false" Priority="10" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="Title" /> <w:LsdException Locked="false" Priority="1" Name="Default Paragraph Font" /> <w:LsdException Locked="false" Priority="11" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="Subtitle" /> <w:LsdException Locked="false" Priority="22" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="Strong" /> <w:LsdException Locked="false" Priority="20" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="Emphasis" /> <w:LsdException Locked="false" Priority="59" SemiHidden="false"    UnhideWhenUsed="false" Name="Table Grid" /> <w:LsdException Locked="false" UnhideWhenUsed="false" Name="Placeholder Text" /> <w:LsdException Locked="false" Priority="1" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="No Spacing" /> <w:LsdException Locked="false" Priority="60" SemiHidden="false"    UnhideWhenUsed="false" Name="Light Shading" /> <w:LsdException Locked="false" Priority="61" SemiHidden="false"    UnhideWhenUsed="false" Name="Light List" /> <w:LsdException Locked="false" Priority="62" SemiHidden="false"    UnhideWhenUsed="false" Name="Light Grid" /> <w:LsdException Locked="false" Priority="63" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Shading 1" /> <w:LsdException Locked="false" Priority="64" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Shading 2" /> <w:LsdException Locked="false" Priority="65" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium List 1" /> <w:LsdException Locked="false" Priority="66" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium List 2" /> <w:LsdException Locked="false" Priority="67" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 1" /> <w:LsdException Locked="false" Priority="68" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 2" /> <w:LsdException Locked="false" Priority="69" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 3" /> <w:LsdException Locked="false" Priority="70" SemiHidden="false"    UnhideWhenUsed="false" Name="Dark List" /> <w:LsdException Locked="false" Priority="71" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful Shading" /> <w:LsdException Locked="false" Priority="72" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful List" /> <w:LsdException Locked="false" Priority="73" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful Grid" /> <w:LsdException Locked="false" Priority="60" SemiHidden="false"    UnhideWhenUsed="false" Name="Light Shading Accent 1" /> <w:LsdException Locked="false" Priority="61" SemiHidden="false"    UnhideWhenUsed="false" Name="Light List Accent 1" /> <w:LsdException Locked="false" Priority="62" SemiHidden="false"    UnhideWhenUsed="false" Name="Light Grid Accent 1" /> <w:LsdException Locked="false" Priority="63" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Shading 1 Accent 1" /> <w:LsdException Locked="false" Priority="64" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Shading 2 Accent 1" /> <w:LsdException Locked="false" Priority="65" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium List 1 Accent 1" /> <w:LsdException Locked="false" UnhideWhenUsed="false" Name="Revision" /> <w:LsdException Locked="false" Priority="34" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="List Paragraph" /> <w:LsdException Locked="false" Priority="29" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="Quote" /> <w:LsdException Locked="false" Priority="30" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="Intense Quote" /> <w:LsdException Locked="false" Priority="66" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium List 2 Accent 1" /> <w:LsdException Locked="false" Priority="67" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 1 Accent 1" /> <w:LsdException Locked="false" Priority="68" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 2 Accent 1" /> <w:LsdException Locked="false" Priority="69" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 3 Accent 1" /> <w:LsdException Locked="false" Priority="70" SemiHidden="false"    UnhideWhenUsed="false" Name="Dark List Accent 1" /> <w:LsdException Locked="false" Priority="71" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful Shading Accent 1" /> <w:LsdException Locked="false" Priority="72" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful List Accent 1" /> <w:LsdException Locked="false" Priority="73" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful Grid Accent 1" /> <w:LsdException Locked="false" Priority="60" SemiHidden="false"    UnhideWhenUsed="false" Name="Light Shading Accent 2" /> <w:LsdException Locked="false" Priority="61" SemiHidden="false"    UnhideWhenUsed="false" Name="Light List Accent 2" /> <w:LsdException Locked="false" Priority="62" SemiHidden="false"    UnhideWhenUsed="false" Name="Light Grid Accent 2" /> <w:LsdException Locked="false" Priority="63" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Shading 1 Accent 2" /> <w:LsdException Locked="false" Priority="64" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Shading 2 Accent 2" /> <w:LsdException Locked="false" Priority="65" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium List 1 Accent 2" /> <w:LsdException Locked="false" Priority="66" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium List 2 Accent 2" /> <w:LsdException Locked="false" Priority="67" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 1 Accent 2" /> <w:LsdException Locked="false" Priority="68" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 2 Accent 2" /> <w:LsdException Locked="false" Priority="69" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 3 Accent 2" /> <w:LsdException Locked="false" Priority="70" SemiHidden="false"    UnhideWhenUsed="false" Name="Dark List Accent 2" /> <w:LsdException Locked="false" Priority="71" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful Shading Accent 2" /> <w:LsdException Locked="false" Priority="72" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful List Accent 2" /> <w:LsdException Locked="false" Priority="73" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful Grid Accent 2" /> <w:LsdException Locked="false" Priority="60" SemiHidden="false"    UnhideWhenUsed="false" Name="Light Shading Accent 3" /> <w:LsdException Locked="false" Priority="61" SemiHidden="false"    UnhideWhenUsed="false" Name="Light List Accent 3" /> <w:LsdException Locked="false" Priority="62" SemiHidden="false"    UnhideWhenUsed="false" Name="Light Grid Accent 3" /> <w:LsdException Locked="false" Priority="63" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Shading 1 Accent 3" /> <w:LsdException Locked="false" Priority="64" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Shading 2 Accent 3" /> <w:LsdException Locked="false" Priority="65" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium List 1 Accent 3" /> <w:LsdException Locked="false" Priority="66" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium List 2 Accent 3" /> <w:LsdException Locked="false" Priority="67" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 1 Accent 3" /> <w:LsdException Locked="false" Priority="68" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 2 Accent 3" /> <w:LsdException Locked="false" Priority="69" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 3 Accent 3" /> <w:LsdException Locked="false" Priority="70" SemiHidden="false"    UnhideWhenUsed="false" Name="Dark List Accent 3" /> <w:LsdException Locked="false" Priority="71" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful Shading Accent 3" /> <w:LsdException Locked="false" Priority="72" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful List Accent 3" /> <w:LsdException Locked="false" Priority="73" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful Grid Accent 3" /> <w:LsdException Locked="false" Priority="60" SemiHidden="false"    UnhideWhenUsed="false" Name="Light Shading Accent 4" /> <w:LsdException Locked="false" Priority="61" SemiHidden="false"    UnhideWhenUsed="false" Name="Light List Accent 4" /> <w:LsdException Locked="false" Priority="62" SemiHidden="false"    UnhideWhenUsed="false" Name="Light Grid Accent 4" /> <w:LsdException Locked="false" Priority="63" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Shading 1 Accent 4" /> <w:LsdException Locked="false" Priority="64" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Shading 2 Accent 4" /> <w:LsdException Locked="false" Priority="65" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium List 1 Accent 4" /> <w:LsdException Locked="false" Priority="66" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium List 2 Accent 4" /> <w:LsdException Locked="false" Priority="67" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 1 Accent 4" /> <w:LsdException Locked="false" Priority="68" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 2 Accent 4" /> <w:LsdException Locked="false" Priority="69" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 3 Accent 4" /> <w:LsdException Locked="false" Priority="70" SemiHidden="false"    UnhideWhenUsed="false" Name="Dark List Accent 4" /> <w:LsdException Locked="false" Priority="71" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful Shading Accent 4" /> <w:LsdException Locked="false" Priority="72" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful List Accent 4" /> <w:LsdException Locked="false" Priority="73" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful Grid Accent 4" /> <w:LsdException Locked="false" Priority="60" SemiHidden="false"    UnhideWhenUsed="false" Name="Light Shading Accent 5" /> <w:LsdException Locked="false" Priority="61" SemiHidden="false"    UnhideWhenUsed="false" Name="Light List Accent 5" /> <w:LsdException Locked="false" Priority="62" SemiHidden="false"    UnhideWhenUsed="false" Name="Light Grid Accent 5" /> <w:LsdException Locked="false" Priority="63" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Shading 1 Accent 5" /> <w:LsdException Locked="false" Priority="64" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Shading 2 Accent 5" /> <w:LsdException Locked="false" Priority="65" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium List 1 Accent 5" /> <w:LsdException Locked="false" Priority="66" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium List 2 Accent 5" /> <w:LsdException Locked="false" Priority="67" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 1 Accent 5" /> <w:LsdException Locked="false" Priority="68" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 2 Accent 5" /> <w:LsdException Locked="false" Priority="69" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 3 Accent 5" /> <w:LsdException Locked="false" Priority="70" SemiHidden="false"    UnhideWhenUsed="false" Name="Dark List Accent 5" /> <w:LsdException Locked="false" Priority="71" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful Shading Accent 5" /> <w:LsdException Locked="false" Priority="72" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful List Accent 5" /> <w:LsdException Locked="false" Priority="73" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful Grid Accent 5" /> <w:LsdException Locked="false" Priority="60" SemiHidden="false"    UnhideWhenUsed="false" Name="Light Shading Accent 6" /> <w:LsdException Locked="false" Priority="61" SemiHidden="false"    UnhideWhenUsed="false" Name="Light List Accent 6" /> <w:LsdException Locked="false" Priority="62" SemiHidden="false"    UnhideWhenUsed="false" Name="Light Grid Accent 6" /> <w:LsdException Locked="false" Priority="63" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Shading 1 Accent 6" /> <w:LsdException Locked="false" Priority="64" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Shading 2 Accent 6" /> <w:LsdException Locked="false" Priority="65" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium List 1 Accent 6" /> <w:LsdException Locked="false" Priority="66" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium List 2 Accent 6" /> <w:LsdException Locked="false" Priority="67" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 1 Accent 6" /> <w:LsdException Locked="false" Priority="68" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 2 Accent 6" /> <w:LsdException Locked="false" Priority="69" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 3 Accent 6" /> <w:LsdException Locked="false" Priority="70" SemiHidden="false"    UnhideWhenUsed="false" Name="Dark List Accent 6" /> <w:LsdException Locked="false" Priority="71" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful Shading Accent 6" /> <w:LsdException Locked="false" Priority="72" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful List Accent 6" /> <w:LsdException Locked="false" Priority="73" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful Grid Accent 6" /> <w:LsdException Locked="false" Priority="19" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="Subtle Emphasis" /> <w:LsdException Locked="false" Priority="21" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="Intense Emphasis" /> <w:LsdException Locked="false" Priority="31" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="Subtle Reference" /> <w:LsdException Locked="false" Priority="32" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="Intense Reference" /> <w:LsdException Locked="false" Priority="33" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="Book Title" /> <w:LsdException Locked="false" Priority="37" Name="Bibliography" /> <w:LsdException Locked="false" Priority="39" QFormat="true" Name="TOC Heading" /> </w:LatentStyles> </xml><![endif]--> <!--[if gte mso 10]><br />
<mce:style><!   /* Style Definitions */ table.MsoNormalTable 	{mso-style-name:"Table Normal"; 	mso-tstyle-rowband-size:0; 	mso-tstyle-colband-size:0; 	mso-style-noshow:yes; 	mso-style-priority:99; 	mso-style-parent:""; 	mso-padding-alt:0cm 5.4pt 0cm 5.4pt; 	mso-para-margin:0cm; 	mso-para-margin-bottom:.0001pt; 	mso-pagination:widow-orphan; 	font-size:12.0pt; 	font-family:Cambria; 	mso-ascii-font-family:Cambria; 	mso-ascii-theme-font:minor-latin; 	mso-hansi-font-family:Cambria; 	mso-hansi-theme-font:minor-latin;} --></p>
<p><!--[endif] --> <!--StartFragment--></p>
<p class="MsoNormal"><span lang="EN-US">Going through the example in detail is out of the scope for this blog (see <a href="http://www.smooks.org/mediawiki/index.php?title=Smooks_v1.4_Examples">Smooks v1.4 Examples</a> for details) but some interesting aspects are worth mentioning: </span></p>
<p><!--EndFragment--></p>
<ul>
<li>The outer sax-parser that read order lines with a streaming approach:<br />
&lt;core:filterSettings type=&#8221;SAX&#8221; defaultSerialization=&#8221;false&#8221; /&gt;</li>
<li>The two Freemarker based templates that work together.<br />
The outer template handling transformation of order-heads (using the streaming SAX-parser) and the inner template transforming order-lines one-by-one using a traditional DOM-parser.</li>
</ul>
<ul>
<li>The Freemarker templates declare the outline of the transformed outgoing message format and the variables ${&#8230;order&#8230;} refers to elements in the incoming message and declares where their corresponding values should be placed in the outgoing transformed message.</li>
</ul>
<h1>To summarize</h1>
<p>By combining a couple of open source products and making some contributions of your own, if required, you can construct very cost-effective, low-complex but still very robust solutions to problems that traditionally are concerned to be very hard, complex and expensive to solve.</p>
<p><strong><span style="color: #000000;">Feel the power of open source!</span></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.callistaenterprise.se/2011/09/29/from-the-muleforge-working-on-the-sftp-transport-and-the-smooks-module/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

