Fabrizio Montesi's Blog2019-01-15T12:25:53+00:00https://fmontesi.github.ioFabrizio Montesihttps://fmontesi.github.io/2018/08/16/jo.htmlMicroservice-aware Web Application (MAWA)2018-08-16T00:00:00+00:002018-08-16T00:00:00+00:00Fabrizio Montesihttps://fmontesi.github.io<p><img src="https://fmontesi.github.io/assets/jo-demo-chuck/joke-workflow.png" alt="Chuck kicks" /></p>
<h1 id="introduction-and-tldr">Introduction (and TL;DR)</h1>
<p>You want to build a website based on microservices.</p>
<p><a href="https://github.com/jolie/leonardo">Leonardo</a> makes it easy to build the services and handle separation of concerns by routing messages to (sub)services exposed to the web browser.
<a href="https://github.com/fmontesi/jo">Jo</a> exposes these services as JavaScript objects to the webpage (an idea I’ve been toying with recently).
I call the result a Microservice-aware Web Application (MAWA), because the webpage accesses explicitly (is aware of) the different (micro)services made available by the server.</p>
<p>The purpose of this document is to show you how. The only software you need installed in your computer to try out what I show here is <a href="https://www.docker.com/">Docker</a>.</p>
<p>I’m going to use some <a href="https://www.jolie-lang.org/">Jolie</a> language <a href="https://doi.org/10.1007/978-1-4614-7518-7_4">[Montesi et al., 2014]</a>, in particular its web features <a href="https://doi.org/10.1016/j.scico.2016.05.002">[Montesi, 2016]</a>, because it makes things very simple for the purposes of this tutorial. You do not need to know Jolie to read what follows: the code is simple enough to be explained on the fly.</p>
<h2 id="references">References</h2>
<p>You can run the finished application with the following Docker commands.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker pull fmontesi/jo-demo-chuck
docker run -it --rm -p 8080:8080 fmontesi/jo-demo-chuck
</code></pre></div></div>
<p>Just browse to <a href="http://localhost:8080/">http://localhost:8080/</a> once the container is running.</p>
<p>You can look at the finished source code here: <a href="https://github.com/fmontesi/jo-demo-chuck">https://github.com/fmontesi/jo-demo-chuck</a>.</p>
<h1 id="get-started">Get started</h1>
<p>Create the following directory structure.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>app/
internal/
web/
</code></pre></div></div>
<p>We will use <code class="highlighter-rouge">app</code> for our services, and <code class="highlighter-rouge">web</code> for our web frontend files.</p>
<h2 id="install-the-web-server">Install the web server</h2>
<p>Go to <code class="highlighter-rouge">app/internal</code> and download the Leonardo web server in the subdirectory <code class="highlighter-rouge">leonardo</code>:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl -L https://github.com/jolie/leonardo/archive/0.2.tar.gz | tar xvz --transform 's/leonardo-0.2/leonardo/'
</code></pre></div></div>
<p>We will use Leonardo to serve static content and to route service invocations from webpages to our services.</p>
<h2 id="write-the-main-application">Write the main application</h2>
<p>Now we write our main Jolie application, in file <code class="highlighter-rouge">app/main.ol</code>.</p>
<pre><code class="language-jolie">// This includes the LeonardoAdmin output port, which we'll use to configure Leonardo
include "internal/leonardo/ports/LeonardoAdmin.iol"
// Embedding is Jolie for running a service inside of the same VM
embedded {
Jolie:
/*
Run Leonardo and link it to the output port LeonardoAdmin
Communications over embedding use local memory (they're fast)
The Standalone=false parameter means that we'll have to configure Leonardo
*/
"-C Standalone=false internal/leonardo/cmd/leonardo/main.ol" in LeonardoAdmin
}
main
{
with( config ) {
.wwwDir = "../web" // The web content directory
};
config@LeonardoAdmin( config )(); // Send the configuration to Leonardo
linkIn( Shutdown ) // Wait until somebody terminates us
}
</code></pre>
<h2 id="make-a-run-script">Make a run script</h2>
<p>First, pull Jolie.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker pull jolielang/jolie
</code></pre></div></div>
<p>Now we make a convenience script to run our website. Write this in <code class="highlighter-rouge">run.sh</code> in the root directory of your project.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/sh</span>
docker run <span class="nt">-it</span> <span class="nt">--rm</span> <span class="se">\</span>
<span class="nt">-v</span> <span class="s2">"</span><span class="k">$(</span><span class="nb">pwd</span><span class="k">)</span><span class="s2">"</span>/web:/web <span class="se">\</span>
<span class="nt">-v</span> <span class="s2">"</span><span class="k">$(</span><span class="nb">pwd</span><span class="k">)</span><span class="s2">"</span>/app:/app <span class="se">\</span>
<span class="nt">-w</span> /app <span class="se">\</span>
<span class="nt">-p</span> 8080:8080 <span class="se">\</span>
jolielang/jolie <span class="se">\</span>
jolie main.ol
</code></pre></div></div>
<p>The script mounts the <code class="highlighter-rouge">app</code> and <code class="highlighter-rouge">web</code> directories as volumes, goes in <code class="highlighter-rouge">app</code>, and runs our program in <code class="highlighter-rouge">main.ol</code>. We expose the TCP port 8080.</p>
<p>Make the script executable:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>chmod +x run.sh
</code></pre></div></div>
<p>Whenever I say “run the application” in the remainder, I mean: go to the root directory of the project and run <code class="highlighter-rouge">./run.sh</code> (<code class="highlighter-rouge">sh run.sh</code> also works, if you did not make <code class="highlighter-rouge">run.sh</code> executable).</p>
<h2 id="test-if-your-setup-works">Test if your setup works</h2>
<p>Create a file <code class="highlighter-rouge">web/index.html</code> with this content:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;html&gt;&lt;body&gt;</span>Hello, World!<span class="nt">&lt;/body&gt;&lt;/html&gt;</span>
</code></pre></div></div>
<p>Run the application (reminder: this means executing <code class="highlighter-rouge">run.sh</code>).
You should see the output:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Leonardo started
Location: socket://localhost:8080/
Web directory: /web/
</code></pre></div></div>
<p>Go to <a href="http://localhost:8080/">http://localhost:8080/</a> with your web browser. You should see the “Hello, World!” message we wrote in <code class="highlighter-rouge">web/index.html</code>.</p>
<p><img src="https://fmontesi.github.io/assets/jo-demo-chuck/hello_world.png" alt="Hello, World!" /></p>
<h1 id="adding-services">Adding services</h1>
<p>Let’s add some dynamic fun.
We can use Leonardo to proxy requests to both external and internal services. External services are services run outside of our application. Internal services are provided by our application. Other than that, their configuration in Leonardo is the same.</p>
<h2 id="external-services">External services</h2>
<p>By “dynamic fun”, I meant Chuck Norris jokes.
There’s an API for that: <a href="https://api.chucknorris.io/">https://api.chucknorris.io/</a>. (If you didn’t know about this, reading this tutorial might be worth it just for getting that link now…)
For example, to search for a joke containing the word “computer”, we just invoke <a href="https://api.chucknorris.io/jokes/search?query=computer">https://api.chucknorris.io/jokes/search?query=computer</a>.</p>
<p>To get Chuck Norris in our application, we need to update <code class="highlighter-rouge">app/main.ol</code> as follows.
I comment the new lines (the rest is as before).</p>
<pre><code class="language-jolie">include "internal/leonardo/ports/LeonardoAdmin.iol"
// Output port to contact api.chucknorris.io
outputPort Chuck {
Location: "socket://api.chucknorris.io:443/" // Use TCP/IP, port 443
Protocol: https {
.osc.search.method = "get"; // HTTP method for operation search
.osc.search.alias = "jokes/search?query=%{query}" // URI template for operation search
}
RequestResponse: search // Request-response operation declaration (search)
}
embedded {
Jolie:
"-C Standalone=false internal/leonardo/cmd/leonardo/main.ol" in LeonardoAdmin
}
main
{
with( config ) {
.wwwDir = "../web";
// Expose a service to the web application
with( .redirection[0] ) {
.name = "ChuckNorris"; // Name of the exposed service
.binding -&gt; Chuck // Binding information (from output port Chuck)
}
};
config@LeonardoAdmin( config )();
linkIn( Shutdown )
}
</code></pre>
<p>Our web server now exposes a ChuckNorris service that supports operation <code class="highlighter-rouge">search</code>.
Next, we update the <code class="highlighter-rouge">web/index.html</code> page to invoke this service.
We use <a href="https://github.com/fmontesi/jo">Jo</a> (a library to interact with Jolie web servers) to call the web server,
and jQuery to interact with the DOM (but you can use any other framework you like).</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;html&gt;</span>
<span class="nt">&lt;head&gt;</span>
<span class="nt">&lt;script </span><span class="na">type=</span><span class="s">"text/javascript"</span>
<span class="na">src=</span><span class="s">"https://raw.githubusercontent.com/fmontesi/jo/master/lib/jo.js"</span><span class="nt">&gt;&lt;/script&gt;</span>
<span class="nt">&lt;script
</span><span class="na">src=</span><span class="s">"https://code.jquery.com/jquery-3.3.1.slim.min.js"</span>
<span class="na">integrity=</span><span class="s">"sha256-3edrmyuQ0w65f8gfBsqowzjJe2iM6n0nKciPUp8y+7E="</span>
<span class="na">crossorigin=</span><span class="s">"anonymous"</span><span class="nt">&gt;&lt;/script&gt;</span>
<span class="nt">&lt;/head&gt;</span>
<span class="nt">&lt;body&gt;</span>
<span class="nt">&lt;p&gt;</span>
<span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">id=</span><span class="s">"jokeQuery"</span> <span class="na">value=</span><span class="s">"Computer"</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;button</span> <span class="na">id=</span><span class="s">"getJokeBtn"</span> <span class="na">type=</span><span class="s">"button"</span><span class="nt">&gt;</span>Get me a Chuck joke!<span class="nt">&lt;/button&gt;</span>
<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;p</span> <span class="na">id=</span><span class="s">"display"</span><span class="nt">&gt;&lt;/p&gt;</span>
<span class="nt">&lt;script </span><span class="na">type=</span><span class="s">"text/javascript"</span><span class="nt">&gt;</span>
<span class="nx">$</span><span class="p">(</span><span class="nb">document</span><span class="p">).</span><span class="nx">ready</span><span class="p">(</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="s2">"#getJokeBtn"</span><span class="p">).</span><span class="nx">click</span><span class="p">(</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="s2">"#display"</span><span class="p">).</span><span class="nx">html</span><span class="p">(</span> <span class="s2">"Work in progress..."</span> <span class="p">);</span>
<span class="c1">// Call operation search on the exposed service ChuckNorris</span>
<span class="nx">Jo</span><span class="p">(</span><span class="s2">"ChuckNorris"</span><span class="p">).</span><span class="nx">search</span><span class="p">(</span> <span class="p">{</span> <span class="na">query</span><span class="p">:</span> <span class="nx">$</span><span class="p">(</span><span class="s2">"#jokeQuery"</span><span class="p">).</span><span class="nx">val</span><span class="p">()</span> <span class="p">}</span> <span class="p">)</span>
<span class="p">.</span><span class="nx">then</span><span class="p">(</span> <span class="nx">response</span> <span class="o">=&gt;</span> <span class="p">{</span>
<span class="c1">// Pick a random joke</span>
<span class="c1">// api.chucknorris.io returns jokes in a "result" array subelement</span>
<span class="nx">$</span><span class="p">(</span><span class="s2">"#display"</span><span class="p">).</span><span class="nx">html</span><span class="p">(</span>
<span class="p">(</span> <span class="nb">Array</span><span class="p">.</span><span class="nx">isArray</span><span class="p">(</span> <span class="nx">response</span><span class="p">.</span><span class="nx">result</span> <span class="p">)</span> <span class="p">)</span>
<span class="p">?</span> <span class="nx">response</span><span class="p">.</span><span class="nx">result</span><span class="p">[</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span><span class="o">*</span><span class="nx">response</span><span class="p">.</span><span class="nx">result</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="p">].</span><span class="nx">value</span>
<span class="p">:</span> <span class="s2">"This is not a joke"</span>
<span class="p">);</span>
<span class="p">}</span> <span class="p">)</span>
<span class="p">.</span><span class="k">catch</span><span class="p">(</span> <span class="nx">JoHelp</span><span class="p">.</span><span class="nx">parseError</span> <span class="p">).</span><span class="k">catch</span><span class="p">(</span> <span class="nx">alert</span> <span class="p">);</span>
<span class="p">}</span> <span class="p">);</span>
<span class="p">}</span> <span class="p">);</span>
<span class="nt">&lt;/script&gt;</span>
<span class="nt">&lt;/body&gt;</span>
<span class="nt">&lt;/html&gt;</span>
</code></pre></div></div>
<p>Clicking the button “Get me a Chuck joke!” will fetch a Chuck Norris joke from <a href="https://api.chucknorris.io/">https://api.chucknorris.io/</a> for us. I got this joke:</p>
<p><img src="https://fmontesi.github.io/assets/jo-demo-chuck/joke1.png" alt="Chuck Norris is no joke" /></p>
<h2 id="internal-services">Internal services</h2>
<p>What good is a joke if you can’t share it?
We write a Jolie service to post our jokes to <a href="https://telegra.ph/">https://telegra.ph/</a>.
I’m going to put all the code in our <code class="highlighter-rouge">app/main.ol</code>. (In a real project, you’d probably want to start creating separate files at this point and embed them, just like we did with Leonardo.)</p>
<p>Here’s the new <code class="highlighter-rouge">app/main.ol</code>.</p>
<pre><code class="language-jolie">include "internal/leonardo/ports/LeonardoAdmin.iol"
outputPort Chuck {
Location: "socket://api.chucknorris.io:443/"
Protocol: https {
.osc.search.method = "get";
.osc.search.alias = "jokes/search?query=%{query}"
}
RequestResponse: search
}
embedded {
Jolie:
"-C Standalone=false internal/leonardo/cmd/leonardo/main.ol" in LeonardoAdmin
}
include "string_utils.iol"
// Output port to Telegraph. We're going to need it to implement our internal service.
outputPort Telegraph {
Location: "socket://api.telegra.ph:443/"
Protocol: https {
.format = "json";
// Yeah, I'm using querystrings... that's the official example in the Telegraph API documentation
.osc.createAccount.alias =
"createAccount?short_name=%{short_name}";
.osc.createPage.alias =
"createPage?access_token=%{access_token}&amp;title=%{title}&amp;content=[\"%{content}\"]"
}
RequestResponse: createAccount, createPage
}
type CreatePageRequest:void { .title:string .content:string }
interface TelegraphPosterIface {
RequestResponse: createPage(CreatePageRequest)(string) throws TelegraphError(string)
}
// Here's the internal service that we're going to expose to the webpage
service TelegraphPoster {
Interfaces: TelegraphPosterIface
main {
createPage( postRequest )( postUrl ) {
// Create a fresh account on Telegraph
short_name = new;
replaceAll@StringUtils( short_name { .regex = "-", .replacement = "" } )( short_name );
createAccount@Telegraph( { .short_name = short_name } )( response );
if ( !response.ok ) throw( TelegraphError, response.error );
// Post the joke with the account we've just created
access_token = response.result.access_token;
createPage@Telegraph( {
.access_token = access_token,
.title = postRequest.title,
.content = postRequest.content
} )( response );
if ( !response.ok ) throw( TelegraphError, response.error );
postUrl = response.result.url // Return the post's url to the webpage
}
}
}
main
{
with( config ) {
.wwwDir = "../web";
with( .redirection[0] ) {
.name = "ChuckNorris";
.binding -&gt; Chuck
};
with( .redirection[1] ) { // We add the redirection for TelegraphPoster
.name = "TelegraphPoster";
.binding.location = TelegraphPoster.location
}
};
config@LeonardoAdmin( config )();
linkIn( Shutdown )
}
</code></pre>
<p>So now we have a new service TelegraphPoster that the webpage can invoke to post content on Telegraph. Let’s use it to share our jokes.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;html&gt;</span>
<span class="nt">&lt;head&gt;</span>
<span class="nt">&lt;script </span><span class="na">type=</span><span class="s">"text/javascript"</span>
<span class="na">src=</span><span class="s">"https://raw.githubusercontent.com/fmontesi/jo/master/lib/jo.js"</span><span class="nt">&gt;&lt;/script&gt;</span>
<span class="nt">&lt;script
</span><span class="na">src=</span><span class="s">"https://code.jquery.com/jquery-3.3.1.slim.min.js"</span>
<span class="na">integrity=</span><span class="s">"sha256-3edrmyuQ0w65f8gfBsqowzjJe2iM6n0nKciPUp8y+7E="</span>
<span class="na">crossorigin=</span><span class="s">"anonymous"</span><span class="nt">&gt;&lt;/script&gt;</span>
<span class="nt">&lt;/head&gt;</span>
<span class="nt">&lt;body&gt;</span>
<span class="nt">&lt;p&gt;</span>
<span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">id=</span><span class="s">"jokeQuery"</span> <span class="na">value=</span><span class="s">"Computer"</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;button</span> <span class="na">id=</span><span class="s">"getJokeBtn"</span> <span class="na">type=</span><span class="s">"button"</span><span class="nt">&gt;</span>Get me a Chuck joke!<span class="nt">&lt;/button&gt;</span>
<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;p</span> <span class="na">id=</span><span class="s">"display"</span><span class="nt">&gt;&lt;/p&gt;</span>
<span class="nt">&lt;p&gt;</span>
<span class="nt">&lt;button</span> <span class="na">id=</span><span class="s">"postJokeBtn"</span> <span class="na">type=</span><span class="s">"button"</span><span class="nt">&gt;</span>Share this wisdom<span class="nt">&lt;/button&gt;</span>
<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;p</span> <span class="na">id=</span><span class="s">"telegraphDisplay"</span><span class="nt">&gt;&lt;/p&gt;</span>
<span class="nt">&lt;script </span><span class="na">type=</span><span class="s">"text/javascript"</span><span class="nt">&gt;</span>
<span class="nx">$</span><span class="p">(</span><span class="nb">document</span><span class="p">).</span><span class="nx">ready</span><span class="p">(</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="s2">"#getJokeBtn"</span><span class="p">).</span><span class="nx">click</span><span class="p">(</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="s2">"#display"</span><span class="p">).</span><span class="nx">html</span><span class="p">(</span> <span class="s2">"Work in progress..."</span> <span class="p">);</span>
<span class="nx">Jo</span><span class="p">(</span><span class="s2">"ChuckNorris"</span><span class="p">).</span><span class="nx">search</span><span class="p">(</span> <span class="p">{</span> <span class="na">query</span><span class="p">:</span> <span class="nx">$</span><span class="p">(</span><span class="s2">"#jokeQuery"</span><span class="p">).</span><span class="nx">val</span><span class="p">()</span> <span class="p">}</span> <span class="p">)</span>
<span class="p">.</span><span class="nx">then</span><span class="p">(</span> <span class="nx">response</span> <span class="o">=&gt;</span> <span class="p">{</span>
<span class="c1">// Pick a random joke</span>
<span class="nx">$</span><span class="p">(</span><span class="s2">"#display"</span><span class="p">).</span><span class="nx">html</span><span class="p">(</span>
<span class="p">(</span> <span class="nb">Array</span><span class="p">.</span><span class="nx">isArray</span><span class="p">(</span> <span class="nx">response</span><span class="p">.</span><span class="nx">result</span> <span class="p">)</span> <span class="p">)</span>
<span class="p">?</span> <span class="nx">response</span><span class="p">.</span><span class="nx">result</span><span class="p">[</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span><span class="o">*</span><span class="nx">response</span><span class="p">.</span><span class="nx">result</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="p">].</span><span class="nx">value</span>
<span class="p">:</span> <span class="s2">"This is not a joke"</span>
<span class="p">);</span>
<span class="p">}</span> <span class="p">).</span><span class="k">catch</span><span class="p">(</span> <span class="nx">JoHelp</span><span class="p">.</span><span class="nx">parseError</span> <span class="p">).</span><span class="k">catch</span><span class="p">(</span> <span class="nx">alert</span> <span class="p">);</span>
<span class="p">}</span> <span class="p">);</span>
<span class="c1">// Should be self-explanatory by now</span>
<span class="c1">// When the button is clicked, invoke createPage at TelegraphPoster</span>
<span class="nx">$</span><span class="p">(</span><span class="s2">"#postJokeBtn"</span><span class="p">).</span><span class="nx">click</span><span class="p">(</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="s2">"#telegraphDisplay"</span><span class="p">).</span><span class="nx">html</span><span class="p">(</span> <span class="s2">"Work in progress..."</span> <span class="p">);</span>
<span class="nx">Jo</span><span class="p">(</span><span class="s2">"TelegraphPoster"</span><span class="p">).</span><span class="nx">createPage</span><span class="p">(</span> <span class="p">{</span>
<span class="na">title</span><span class="p">:</span> <span class="s2">"Chuck Norris Wisdom"</span><span class="p">,</span>
<span class="na">content</span><span class="p">:</span> <span class="nx">$</span><span class="p">(</span><span class="s2">"#display"</span><span class="p">).</span><span class="nx">html</span><span class="p">()</span>
<span class="p">}</span> <span class="p">).</span><span class="nx">then</span><span class="p">(</span> <span class="nx">response</span> <span class="o">=&gt;</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="s2">"#telegraphDisplay"</span><span class="p">).</span><span class="nx">html</span><span class="p">(</span>
<span class="s2">`Wisdom shared at &lt;a href=\"</span><span class="p">${</span><span class="nx">response</span><span class="p">.</span><span class="nx">$</span><span class="p">}</span><span class="s2">\" target=\"_new\"&gt;</span><span class="p">${</span><span class="nx">response</span><span class="p">.</span><span class="nx">$</span><span class="p">}</span><span class="s2">&lt;/a&gt;`</span>
<span class="p">);</span>
<span class="p">}</span> <span class="p">).</span><span class="k">catch</span><span class="p">(</span> <span class="nx">JoHelp</span><span class="p">.</span><span class="nx">parseError</span> <span class="p">).</span><span class="k">catch</span><span class="p">(</span> <span class="nx">alert</span> <span class="p">);</span>
<span class="p">}</span> <span class="p">);</span>
<span class="p">}</span> <span class="p">);</span>
<span class="nt">&lt;/script&gt;</span>
<span class="nt">&lt;/body&gt;</span>
<span class="nt">&lt;/html&gt;</span>
</code></pre></div></div>
<p>Here’s a screenshot of what the final page looks like.</p>
<p><img src="https://fmontesi.github.io/assets/jo-demo-chuck/joke2.png" alt="Now everybody knows" /></p>
<h1 id="done">Done!</h1>
<p>It’s done!</p>
<p>If you’d like to containerise your application, you just need a simple Dockerfile, like the following.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>FROM jolielang/jolie
COPY app /app
COPY web /web
WORKDIR /app
EXPOSE 8080
CMD ["jolie","main.ol"]
</code></pre></div></div>
<h1 id="references-1">References</h1>
<ul>
<li>Fabrizio Montesi. (2016). Process-aware web programming with Jolie. Sci. Comput. Program., 130, 69–96. <a href="https://doi.org/10.1016/j.scico.2016.05.002">doi</a> <a href="https://arxiv.org/abs/1410.3712">arxiv</a></li>
<li>Fabrizio Montesi, Claudio Guidi, &amp; Gianluigi Zavattaro. (2014). Service-Oriented Programming with Jolie. In A. Bouguettaya, Q. Z. Sheng, &amp; F. Daniel (Eds.), Web Services Foundations (pp. 81–107). Springer. <a href="https://doi.org/10.1007/978-1-4614-7518-7_4">doi</a> <a href="https://www.fabriziomontesi.com/files/mgz14.pdf">pdf</a></li>
</ul>
https://fmontesi.github.io/2018/08/14/serve.htmlA script to serve webpages quickly with Leonardo and Docker2018-08-14T00:00:00+00:002018-08-14T00:00:00+00:00Fabrizio Montesihttps://fmontesi.github.io<h1 id="what">What</h1>
<p>You want to serve some web pages, quickly!</p>
<h1 id="installation">Installation</h1>
<p>You’ll need Docker. Pull the Docker image for Leonardo if you don’t have it already.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker pull jolielang/leonardo
</code></pre></div></div>
<p>Download the <code class="highlighter-rouge">serve</code> script and set it as executable.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wget https://rawgit.com/jolie/leonardo/master/cmd/serve/serve &amp;&amp; chmod +x serve
</code></pre></div></div>
<h1 id="use">Use</h1>
<p>Syntax: <code class="highlighter-rouge">serve [path] [-p TCP_PORT]</code> where the default <code class="highlighter-rouge">path</code> is <code class="highlighter-rouge">.</code> and the default <code class="highlighter-rouge">TCP_PORT</code> is <code class="highlighter-rouge">8080</code>.</p>
<h2 id="examples">Examples</h2>
<p>Serve the current directory: <code class="highlighter-rouge">serve</code></p>
<p>Serve directory <code class="highlighter-rouge">web</code>: <code class="highlighter-rouge">serve web</code></p>
<p>Serve directory <code class="highlighter-rouge">web</code> on port <code class="highlighter-rouge">8000</code>: <code class="highlighter-rouge">serve web 8000</code></p>
https://fmontesi.github.io/2017/12/01/jolie-duckduckgo.htmlInstant web search results from DuckDuckGo in Jolie2017-12-01T00:00:00+00:002017-12-01T00:00:00+00:00Fabrizio Montesihttps://fmontesi.github.io<p><a href="https://duckduckgo.com/">DuckDuckGo</a> has an API for instant search results.
It’s really easy to invoke and it can reply with JSON or XML data (here I use XML).</p>
<p>Here’s a snippet that uses it.</p>
<pre><code class="language-jolie">include "console.iol"
outputPort DuckDuckGo {
Location: "socket://api.duckduckgo.com:443/"
Protocol: https {
.osc.search.alias = "?q=%{q}&amp;format=xml&amp;t=jolie_example";
.osc.search.method = "get"
}
RequestResponse: search // I feel lazy, so I'm using dynamic typing
}
main
{
// Get the results
search@DuckDuckGo( { .q = args[0] } )( response );
// Print results
println@Console( "# Found " + #response.Results.Result + " result(s)" )();
for( result in response.Results.Result ) {
println@Console( "\n" + result.Text + "\n" + result.FirstURL )()
};
println@Console()();
// Print related topics
println@Console( "# Found " + #response.RelatedTopics.RelatedTopic + " related topic(s)" )();
for( topic in response.RelatedTopics.RelatedTopic ) {
println@Console( "\n" + topic.Text + "\n" + topic.FirstURL )()
}
}
</code></pre>
<p>Just save this as a file, say <code class="highlighter-rouge">search.ol</code>, and then you can use it to fetch some results. For example, try <code class="highlighter-rouge">jolie search.ol DuckDuckGo</code> or <code class="highlighter-rouge">jolie search.ol "Jolie Programming Language"</code>.</p>
<p>A note about the rules from DuckDuckGo at the time of this writing.
If you use this in some project, remember to update the <code class="highlighter-rouge">t</code> parameter in the alias of operation <code class="highlighter-rouge">search</code> from <code class="highlighter-rouge">jolie_example</code> to something that describes your own project.</p>
https://fmontesi.github.io/2017/11/28/jolie-google-analytics.htmlInvoking Google Analytics from Jolie2017-11-28T00:00:00+00:002017-11-28T00:00:00+00:00Fabrizio Montesihttps://fmontesi.github.io<p>Do you need to send events to Google Analytics from your Jolie service?
Here is a self-explanatory snippet.</p>
<pre>
<code class="language-jolie">interface GoogleAnalyticsIface {
RequestResponse: collect
}
outputPort GoogleAnalytics {
Location: "socket://www.google-analytics.com:80/"
Protocol: http { .format = "x-www-form-urlencoded" }
Interfaces: GoogleAnalyticsIface
}
main
{
collect@GoogleAnalytics( {
.v = 1,
.tid = "UA-XXXXXXXX-Y", // put your own tracking id here
.cid = 555,
.t = "event",
.ec = "Publications",
.ea = "Download",
.el = "mypaper.pdf"
} )()
}
</code></pre>
<p>To know what the fields mean, have a look at the official documentation from Google: <a href="https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters">https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters</a>.</p>
<p>I myself find it useful to send events from web servers or other microservices. That snippet is from my own website written in Jolie, to track downloads of my research papers. (Sending these events from the server has the nice consequence that you do not track extra information from the web browser.)</p>
<p>Enjoy!</p>
https://fmontesi.github.io/2016/11/12/service-decorators.htmlService Decorators2016-11-12T00:00:00+00:002016-11-12T00:00:00+00:00Fabrizio Montesihttps://fmontesi.github.io<p><em>TL;DR</em>: decorators for services are pretty easy to write in <a href="http://www.jolie-lang.org/">Jolie</a>,
thanks to a native feature called <a href="http://docs.jolie-lang.org/#!documentation/architectural_composition/aggregation.html">aggregation</a>.
Be careful in the deployment phase for managing performance hits!</p>
<h1 id="service-decorators">Service Decorators</h1>
<p>Just read <a href="https://dzone.com/articles/is-inheritance-dead">this article about using decorators</a> over inheritance in
object-oriented programs. I assume that you know decorators in the following. If
you don’t, get informed (e.g., by reading that article) before proceeding.</p>
<p>The Decorator design pattern offers a way to cleanly modify the behaviour of an
object by using composition instead of inheritance. I won’t enter in the merits
of composition against inheritance in object-orientation (both have their own,
depending on the other features of the language), because I’m interested in
microservices here. In microservices, composition is typically the only option
you have. That’s because your microservices may be written in different
languages, or even paradigms. And even if their codebases were somehow
compatible, inheritance would still be out of place: your microservices can only
depend on the communication APIs of other services, not on their implementation
details (e.g., by looking at their source code).</p>
<p>Since decorator acts through composition, this pattern is potentially
interesting for service programming. But as the author of the article linked above mentions,
using it can be frustrating since it requires a lot of boilerplate code. This makes it also
error-prone.
As a running example, let’s look at the e-mail service interface proposed in that article, rewritten in Jolie:</p>
<pre>
<code class="language-jolie">interface EmailServiceIface {
RequestResponse:
send(Email)(void),
listEmails(Range)(EmailInfoList),
downloadEmail(EmailInfo)(Email)
}</code></pre>
<h2 id="decorating-an-operation">Decorating an operation</h2>
<p>Now, suppose that this service is available to us as <code class="highlighter-rouge">EmailService</code>. Assume also
that we want to write a new service that decorates <code class="highlighter-rouge">EmailService</code> with the
following logic: whenever <code class="highlighter-rouge">send</code> is called, we check if we have sent an
“important” e-mail (e.g., the subject contains a specific keyword telling us
that the e-mail is important, or the addressee is in a special list); if an
important e-mail has been sent successfully, we backup its content by calling
another service, for indexing and safe-keeping.</p>
<p>A naive implementation is to write the decorator by re-implementing interface <code class="highlighter-rouge">EmailService</code>, like this:</p>
<pre>
<code class="language-jolie">inputPort EmailServiceImportant {
Location: MyLocation Protocol: MyProtocol
Interfaces: EmailServiceIface
}
main
{
[ send( request )( response ) {
send@EmailService( request )();
check@Important( { .subject = request.subject, .to = request.to } )( important );
if ( important ) {
backup@BackupService( request )()
}
} ]
[ listEmails( request )( response ) {
listEmails@EmailService( request )( response )
} ]
[ downloadEmail( request )( response ) {
downloadEmail@EmailService( request )( response )
} ]
}</code></pre>
<p>The code for <code class="highlighter-rouge">listEmails</code> and <code class="highlighter-rouge">downloadEmail</code> is boilerplate, since we’re just
forwarding requests and responses. The author of the <a href="https://dzone.com/articles/is-inheritance-dead">article</a>
suggests that it would be nice if languages supported a native feature that makes
writing this code unnecessary. Luckily, we have it in this case!</p>
<p>Forwarding is a native feature in Jolie, since building proxies is the bread and
butter of service composition (think of load balancers, caches, etc.).
We can rewrite our decorator like this:</p>
<pre>
<code class="language-jolie">inputPort EmailServiceImportant {
Location: MyLocation Protocol: MyProtocol
Aggregates: EmailService // Aggregates instead of Interfaces!
}
main
{
[ send( request )( response ) {
send@EmailService( request )();
check@Important( { .subject = request.subject, .to = request.to } )( important );
if ( important ) {
backup@BackupService( request )()
}
} ]
}</code></pre>
<p>No boilerplate, same behaviour as our previous decorator!</p>
<h2 id="interface-decoration">Interface Decoration</h2>
<p>What if you want to change the behaviours of <em>many</em> operations, not just one?
What if this behaviour change is always the same? For example, suppose that we want
to write a decorator that keeps track of all events: whenever an operation is called,
we write this in an external log.</p>
<p>Here’s a naive implementation:</p>
<pre>
<code class="language-jolie">inputPort EmailServiceLogger {
Location: MyLocation Protocol: MyProtocol
Interfaces: EmailServiceIface
}
main
{
[ send( request )( response ) {
send@EmailService( request )();
log@Logger( request )()
} ]
[ listEmails( request )( response ) {
listEmails@EmailService( request )( response );
log@Logger( request )()
} ]
[ downloadEmail( request )( response ) {
downloadEmail@EmailService( request )( response );
log@Logger( request )()
} ]
}</code></pre>
<p>Ouch, boilerplate again! What we need is the capability of writing that logging
code just once, and applying it to the entire API of <code class="highlighter-rouge">EmailService</code>. That’s what
<a href="http://docs.jolie-lang.org/#!documentation/architectural_composition/couriers.html">courier processes</a>
in Jolie are for. Here’s the improved code, using <code class="highlighter-rouge">courier</code>:</p>
<pre>
<code class="language-jolie">inputPort EmailServiceLogger {
Location: MyLocation Protocol: MyProtocol
Aggregates: EmailService // Aggregates again
}
courier EmailServiceLogger // courier enables primitives for whole-interface behaviour
{
[ interface EmailServiceIface( request )( response ) ] { // Apply to all operations in the interface
forward( request )( response ); // forward is a primitive: it forwards the message to the aggreated (in this case, decorated) service
log@Logger( request )()
}
}</code></pre>
<p>No boilerplate again!</p>
<h2 id="circuit-breakers">Circuit breakers</h2>
<p>What’s a cool example of a decorator? Circuit breaker! Yup. A sketch in Jolie using aggregation can be found
<a href="https://arxiv.org/abs/1609.05830">in this paper</a>.</p>
<h2 id="conclusions">Conclusions</h2>
<p>As cool as decorators are, don’t forget that you are adding a layer of
indirection. Many times, you don’t have a choice and your code benefits so much
that you should pay the price. But in microservices, be <em>very</em> careful about how
efficient your extra layer will be. If you stack too many decorators and they
are all communicating remotely via sockets, you’ll soon have a performance
problem. This is a deployment challenge: in Jolie, using a different
communication medium doesn’t alter your behavioural code. So choose your
communication media wisely when you deploy! If you have control over your stack
of decorators, consider whether it would be better to put them all in one place and
have them communicate using shared-memory (<code class="highlighter-rouge">local</code> location in Jolie).</p>
https://fmontesi.github.io/2016/05/15/provide-until.htmlProvide-until now provided in Jolie2016-05-15T00:00:00+00:002016-05-15T00:00:00+00:00Fabrizio Montesihttps://fmontesi.github.io<p>A pattern that arises often when writing a (micro)service is that of a workflow that <em>provides</em> access to a resource <em>until</em> something special happens. The new provide-until primitive in <a href="http://www.jolie-lang.org/">Jolie</a> supports exactly this pattern. It doesn’t add any expressivity to the language (we could do this before using bookkeeping variables, just like in any other language), but it makes the code more readable and pleasant in this kind of situations that come up so frequently.</p>
<p>Here is an example of a service that handles shopping carts. We can start a process in our service by invoking operation <code class="highlighter-rouge">createCart</code>. We then set a timeout (given by the constant <code class="highlighter-rouge">TIMEOUT</code>, omitted here). When the timeout expires, the <code class="highlighter-rouge">Time</code> service (from the Jolie standard library) is going to call us on operation <code class="highlighter-rouge">timeout</code>.
Now we are all set and we enter a <code class="highlighter-rouge">provide-until</code> block. Provide-until takes two input choices. The reasoning is very simple: the operations in the first input choice are provided (thus can be invoked multiple times) until any of the operations in the until block is called. Below, we can invoke the operations <code class="highlighter-rouge">add</code> and <code class="highlighter-rouge">remove</code> to add and remove, respectively, items in our shopping cart, until one of the following happens: the process timeouts (operation <code class="highlighter-rouge">timeout</code> is invoked); the user decides to delete the cart (operation <code class="highlighter-rouge">delete</code>); or, the user decide to proceed to checkout (operation <code class="highlighter-rouge">checkout</code>).</p>
<pre>
<code class="language-jolie">/* Interfaces and ports ... */
cset { id: Add.id Remove.id Timeout.id Delete.id Checkout.id }
main
{
createCart( request )( cart ) {
cart.id = csets.id = new;
cart.user = request.user
};
setNextTimeout@Time( TIMEOUT { .message.id = cart.id } );
provide
[ add( request )( cart ) {
cart.items[ #cart.items ] &lt;&lt; request.item
} ]
[ remove( request )( cart ) {
undef( cart.items[ request.which ] )
} ]
until
[ timeout() ]
[ delete()() ]
[ checkout( paymentInfo )() {
// ...
} ]
}</code></pre>
<p>Provide-until is a little thing that I enjoyed developing lately. It originally comes from the desire of handling elegantly REST processes in Jolie, but it works just as well in any similar situation. I give a longer explanation for researchers of how Jolie works with the Web in this paper: <a href="https://arxiv.org/abs/1410.3712">https://arxiv.org/abs/1410.3712</a>.</p>
https://fmontesi.github.io/2015/06/09/non-distributed-microservices.htmlNon-distributed Microservices2015-06-09T10:54:00+00:002015-06-09T10:54:00+00:00Fabrizio Montesihttps://fmontesi.github.io<div dir="ltr"><br /><a href="http://3.bp.blogspot.com/-A3lcjBFxVn8/VXaTCbX919I/AAAAAAAAGT4/sqRXwRMczJ8/s1600/puzzle-654957_1280.jpg" imageanchor="1" style="clear: left; display: inline !important; float: left; margin-bottom: 1em; margin-right: 1em; text-align: center;"><img border="0" height="150" src="http://3.bp.blogspot.com/-A3lcjBFxVn8/VXaTCbX919I/AAAAAAAAGT4/sqRXwRMczJ8/s200/puzzle-654957_1280.jpg" width="200" /></a><br />Thanks to Martin's <a href="https://github.com/jolie/jolie/pull/45" target="_blank">great</a>&nbsp;<a href="https://github.com/jolie/jolie/pull/48" target="_blank">help</a>, <a href="http://www.jolie-lang.org/" target="_blank">Jolie</a> 1.4 will have support for <a href="http://docs.jolie-lang.org/#!documentation/architectural_composition/internal_services.html" target="_blank">Internal Services</a>&nbsp;and enhanced <a href="http://docs.jolie-lang.org/#!documentation/architectural_composition/embedding_jolie.html" target="_blank">local locations</a>. If you feel like testing, you can already find it in <a href="https://github.com/jolie/jolie" target="_blank">our git repository</a>&nbsp;(see <a href="http://jolie-lang.org/downloads.html" target="_blank">compile from sources</a>).<br />While these features do not add any essential expressiveness to Jolie, they make it easier to program non-distributed microservice architectures (NMSA here for brevity). "Wait" - I hear you - "NMSAs?"<br /><br /><a name='more'></a><br /><h2>Non-distributed Microservice Architectures (NMSAs)</h2><div>When I teach somebody (students or professionals) how to program microservices, I pay attention to following a very gradual path. The fact is, there are simply too many things to worry about when you program Microservice Architectures (MSAs). If you are not an expert, you are going to get overwhelmed by the complexity. Even if you are an expert, you may be better off with the <a href="http://martinfowler.com/bliki/MonolithFirst.html" target="_blank">MonolithFirst</a> approach.<br /><br />But why are Microservices so complicated? The main reason is that an MSA is typically distributed, and distributed computing is hard (see&nbsp;<a href="http://en.wikipedia.org/wiki/Fallacies_of_distributed_computing" target="_blank">the fallacies of distributed computing</a>). So, intuitively, it is much simpler to start with a monolith, and switch to microservices later. Unfortunately intuition is not really met by reality here. Developing a monolith does not force programmers to make their components modular and loosely-coupled enough to be smoothly ported to microservices; for example, it is way too tempting to share resources and/or develop APIs that are not suitable for message passing. Most probably, your initial monolith will end up being a&nbsp;<a href="http://martinfowler.com/bliki/SacrificialArchitecture.html" target="_blank">SacrificialArchitecture</a>. This is not necessarily a bad thing: many successes were built on top of sacrificing architectures. I am more worried about the fact that this is not really a smooth learning process: develop a monolith, learn something, now change everything.<br /><br />NMSAs is a style where you program your system <i>as if it were an MSA, but without the distribution</i>. In an NMSA, Microservices are run concurrently in the same container (in our case, a Jolie-controlled JVM). It is an attempt at providing an easier setting for learners and experimenters to start with: no distributed computing means no fallacies of distributed computing. What can you learn in such an environment? A great deal, including:<br /><br /><ul><li>You can learn how to develop loosely-coupled service interfaces, and how to deal with message passing in the easier setting of a perfectly-working "network".</li><li>You can learn how to test your services, and how to automatise testing.</li><li>You can learn how to monitor service execution.</li></ul>The idea is to first approach the programming of microservices in this simpler ("fake", if you like) setting, and learn how to deal with distribution later. In the Jolie programming language, this path from NMSAs to MSAs is supported by the language itself.<br /><br /><h2>NMSAs first...</h2></div>NMSAs are created in Jolie by using <a href="http://docs.jolie-lang.org/#!documentation/architectural_composition/embedding.html" target="_blank">embedded</a> or <a href="http://docs.jolie-lang.org/#!documentation/architectural_composition/internal_services.html" target="_blank">internal services</a>, i.e., services that run locally in the same container of the main service program. I will refer to such services as "local services" here. All components that you can write in Jolie are services, therefore all the architectures that you write in Jolie are service-oriented by design. This means that components cannot share state, and must interact through service interfaces based on message passing. What happens behind the scenes depends on the deployment information that you specify for your services, which is kept separate from the application logic. If the case of a local service, messages are efficiently communicated via shared memory, but without breaking the message passing abstraction given to the programmer.<br /><br />Here is a toy example of a program using local services (you can of course split this in multiple files; oh, and I'm omitting what happens in case we do not find some records or files):<br /><br /><br /><span style="font-family: 'Courier New', Courier, monospace;">service Images {</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; Interfaces: ImagesIface</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; main {</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; &nbsp; &nbsp; get( request )( img ) {</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fetch@ImageDB( request )</span><span style="font-family: 'Courier New', Courier, monospace;">( img )</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; &nbsp; &nbsp; }</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; }</span><br /><span style="font-family: 'Courier New', Courier, monospace;">}</span><br /><span style="font-family: 'Courier New', Courier, monospace;"><br /></span><span style="font-family: 'Courier New', Courier, monospace;">service Products {</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; Interfaces: ProductsIface</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; main {</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; &nbsp; &nbsp; get( request )( response ) {</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; query@ProductDB</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ( "select name,desc,imageurl from products where id=:id"</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { .id = request.id } )</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ( response )</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; &nbsp; &nbsp; }</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; }</span><br /><span style="font-family: 'Courier New', Courier, monospace;">}</span><br /><span style="font-family: 'Courier New', Courier, monospace;"><br /></span><span style="font-family: 'Courier New', Courier, monospace;">main {</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; viewProduct( request )( product ) {</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; &nbsp; &nbsp; get@Products( { .id = request.id } )( product );</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; &nbsp; &nbsp; if ( request.embedImage ) {</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get@Images( { .url = product.imageurl } )( product.image )</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; &nbsp; &nbsp; }</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; }</span><br /><span style="font-family: 'Courier New', Courier, monospace;">}</span><br /><div><br />The program above is a simple service to access product information. It offers one operation, viewProduct, that clients can invoke with a message containing the id of the product they want to see (as a subnode of request). The service then invoke the internal service Products, which queries a database for some basic information and returns it. The product information contains an URL to an image depicting the product. Then, the main program checks whether the original client requested the image to be embedded in the response (useful, e.g., for mobile applications that want to minimize the number of message exchanges); if positive, the image is added to the response by fetching it from the Images service.<br /><br />The main service, Images, and Products communicate using shared memory in the Jolie implementation of internal services. Communications are therefore always going to succeed, but each service has its own interface and state and the style is still message passing. Hence, internal services can be used to teach how to design a loosely-coupled architecture.<br /><br /></div><h2>...and MSAs later</h2><div>NMSAs are expressive enough to teach, e.g., how to deal with concurrency issues (each service has its own processes), message passing interfaces, and good API design. They are also fairly easy to achieve, relieving beginners from the frustrations of service deployment.<br /><br />After a while, however, an NMSA that needs to scale has to evolve into an MSA, by taking some internal services and making them distributed. Distributing an internal service in Jolie is easy. Simply put, take the code of the internal service you want to distribute and execute it with a separate interpreter in another machine (<a href="http://www.italianasoftware.com/products.html" target="_blank">Jolie Enterprise</a> automatises this job for you in a cloud environment, but you can use the tools of your choice).<br /><br />The main service now needs to be updated to refer to Images and Products as external distributed services:<br /><br /><span style="font-family: 'Courier New', Courier, monospace;">outputPort Images {</span><br /><span style="font-family: 'Courier New', Courier, monospace;">Location: "socket://images.example:8080"</span><br /><span style="font-family: 'Courier New', Courier, monospace;">Protocol: sodep</span><br /><span style="font-family: 'Courier New', Courier, monospace;">Interfaces: ImagesIface</span><br /><span style="font-family: 'Courier New', Courier, monospace;">}</span><br /><span style="font-family: 'Courier New', Courier, monospace;"><br /></span><span style="font-family: 'Courier New', Courier, monospace;">outputPort Products {</span><br /><span style="font-family: 'Courier New', Courier, monospace;">Location: "socket://products.example:8080"</span><br /><span style="font-family: 'Courier New', Courier, monospace;">Protocol: sodep</span><br /><span style="font-family: 'Courier New', Courier, monospace;">Interfaces: ProductsIface</span><br /><span style="font-family: 'Courier New', Courier, monospace;">}</span><br /><span style="font-family: 'Courier New', Courier, monospace;"><br /></span><span style="font-family: 'Courier New', Courier, monospace;">main {</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; viewProduct( request )( product ) {</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; &nbsp; &nbsp; get@Products( { .id = request.id } )( product );</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; &nbsp; &nbsp; if ( request.embedImage ) {</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get@Images( { .url = product.imageurl } )( product.image )</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; &nbsp; &nbsp; }</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; }</span><br /><span style="font-family: 'Courier New', Courier, monospace;">}</span><br /><br />Basically, we have replaced the code for each internal service with a respective <a href="http://docs.jolie-lang.org/#!documentation/basics/communication_ports.html" target="_blank">output port</a>. The rest of the code does not change (again, a key aspect of developing services with Jolie is that deployment is kept as separate as possible from behaviour). However, now the system is distributed. Among other consequences of this, communications with services Products and Images may now fail! In practice, this means that the invocations get@Products and get@Images can throw network-related faults now, and we must account for that. If we leave the code like this, such faults are going to be automatically propagated to clients. This may be undesirable. A better strategy could be:<br /><br /><ul><li>If we fail to get the product information, we immediately return an informative fault to the client.</li><li>If we manage to get the product information but fail to get its image, we should return at least the product information with a placeholder blank image.</li></ul><div>We update the code accordingly, using <a href="http://docs.jolie-lang.org/#!documentation/fault_handling/basics.html" target="_blank">dynamic fault handlers</a>:</div><br /><br /><br /><span style="font-family: 'Courier New', Courier, monospace;">main {</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; viewProduct( request )( product ) {</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; &nbsp; &nbsp; scope( s ) {</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; install( default =&gt; throw( ProductsCurrentlyUnavailable ) );</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get@Products( { .id = request.id } )( product )</span><span style="font-family: 'Courier New', Courier, monospace;">;</span><br /><span style="font-family: 'Courier New', Courier, monospace;"><br /></span><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; install( default =&gt; product.image = BLANK_IMAGE );</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ( request.embedImage ) {</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get@Images( { .url = product.imageurl } )( product.image )</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; &nbsp; &nbsp; }</span><br /><span style="font-family: 'Courier New', Courier, monospace;">&nbsp; &nbsp; }</span><br /><span style="font-family: 'Courier New', Courier, monospace;">}</span><br /><br />There we go. Now our code accounts for network errors (actually any error, since I used the default handler, which catches any fault). There are, of course, many other things to watch out for, e.g., distributed monitoring, crash recovery, and performance. However, this small example gives already an idea of the overall methodology.</div><h2>Gotcha</h2><div>Although Jolie does its best in not allowing resource sharing among services (they simply cannot be shared, by the language syntax), this can always be circumvented via external side-effects. For example, two internal service may share access to the same file system. However, this can also be abstracted from: in Jolie all accesses to the file system happen through the File service from the standard library which, being a service, can also be distributed.<br /><br /><h2>Conclusions</h2><div>The microservices style arises out of practical needs, and although it should be used only when necessary, sometimes it is appropriate. I believe that we should find ways to guide a smoother transition from monoliths to microservices, and that finding such ways is possible. This is a rough attempt at giving a first piece of the puzzle towards building such a transition model.</div><div><br /></div><br />PS: I should really try to come up with better acronyms.<br />PPS: If you have interesting examples to share in other languages, please feel free to do so!</div></div>https://fmontesi.github.io/2015/05/04/evaluating-design-of-microservice.htmlEvaluating the Design of a Microservice2015-05-04T12:47:00+00:002015-05-04T12:47:00+00:00Fabrizio Montesihttps://fmontesi.github.io<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-myKK6dZLLv8/VUdxKVaE3vI/AAAAAAAAFnM/0heNkj021EA/s1600/stock_task.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-myKK6dZLLv8/VUdxKVaE3vI/AAAAAAAAFnM/0heNkj021EA/s1600/stock_task.png" /></a></div><br />I made a little rubric for evaluating the design of Microservices. Keep in mind that it is still very preliminary. If you have comments, I would be more than happy to discuss them with you.<br /><br />Find it here:<br /><br /><div style="text-align: center;"><a href="https://github.com/microservices-course/material/blob/master/rubrics/design.md">https://github.com/microservices-course/material/blob/master/rubrics/design.md</a></div>https://fmontesi.github.io/2015/02/06/programming-microservices-with-jolie.htmlProgramming Microservices with Jolie - Part 1: Data formats, Proxies, and Workflows.2015-02-06T14:44:00+00:002015-02-06T14:44:00+00:00Fabrizio Montesihttps://fmontesi.github.ioIn&nbsp;<a href="http://en.wikipedia.org/wiki/Microservices" target="_blank">Microservice</a>&nbsp;architectures, software components are built as reusable and scalable services that interact with each other. While this introduces many advantages, it also brings all the issues of distributed computing to the internals of software applications and developers <a href="http://martinfowler.com/articles/microservices.html" target="_blank">need to be careful about this</a>. Luckily, we are standing on the shoulders of all the knowledge that we accumulated by using <a href="http://en.wikipedia.org/wiki/Service-oriented_architecture" target="_blank">Service-oriented Architectures</a>&nbsp;(SOAs), so we are more aware of these issues and we have more technologies and methodologies to deal with them. Microservices could (and I believe they will) fly after all, in one form or the other, and we at the <a href="http://www.jolie-lang.org/" target="_blank">Jolie</a> team are surely not the only ones sharing this <a href="http://www.infoworld.com/article/2864453/application-development/why-2015-will-be-the-year-of-microservices.html" target="_blank">optimism</a>.<br /><br />But like SOAs were, Microservices are also at risk of exposing programmers to too much complexity to deal with when they take their first steps in this world. And we are at risk again of making arbitrary technology choices that we may regret later, just like <a href="http://en.wikipedia.org/wiki/SOAP" target="_blank">SOAP</a> was in many cases.<br /><br />In developing <a href="http://www.jolie-lang.org/" target="_blank">Jolie</a>, a microservice-oriented programming language, we are trying to make microservice programming simple and productive. A major challenge in this is <b>how we can map design ideas for a microservice architecture to code as fast as possible</b>, without committing to specific implementation details on communications and service deployment/distribution.<br /><br />The problem of focusing on design issues and not getting locked inside of interoperability problems is particularly dear to me. Jolie helps in this, e.g., by abstracting application logic from the underlying data formats that you will use for communications.<br /><br />Another problem that is dear to the team in general and I will talk about below is that of making composition of microservices easy. This does not simply mean composition of the operations offered by microservices, but also dealing with how we can deploy new systems based on previously developed systems.<br /><br />But talk is cheap. Let's do code and see an example.<br /><br /><br /><h2>Get Jolie</h2>You don't need to have Jolie installed to read this article, but if you want to try what I will show, <a href="http://jolie-lang.org/downloads.html" target="_blank">go install Jolie</a>.<br />Ready? Let's proceed.<br /><br /><br /><h2>A calculator microservice</h2>We are going to program a little toy calculator microservice for making additions. Feeling lazy? Download the code <a href="http://fabriziomontesi.com/files/blog/jolie_microservices_part1.zip" target="_blank">here</a>.<br />Open a file and call it <span style="font-family: Courier New, Courier, monospace;">calculator.ol</span><span style="font-family: inherit;">.</span><br /><span style="font-family: inherit;">Then we write:</span><br /><span style="font-family: inherit;"><br /></span><span style="font-family: Courier New, Courier, monospace;">include "calculator.iol"</span><br /><span style="font-family: Courier New, Courier, monospace;"><br /></span><span style="font-family: Courier New, Courier, monospace;">execution { concurrent }</span><br /><span style="font-family: Courier New, Courier, monospace;"><br /></span><span style="font-family: Courier New, Courier, monospace;">inputPort CalcInput {</span><br /><span style="font-family: Courier New, Courier, monospace;">Location: "socket://localhost:8000"</span><br /><span style="font-family: Courier New, Courier, monospace;">Protocol: sodep</span><br /><span style="font-family: Courier New, Courier, monospace;">Interfaces: CalcIface</span><br /><span style="font-family: Courier New, Courier, monospace;">}</span><br /><span style="font-family: Courier New, Courier, monospace;"><br /></span><span style="font-family: Courier New, Courier, monospace;">main</span><br /><span style="font-family: Courier New, Courier, monospace;">{</span><br /><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>sum( req )( resp ) {</span><br /><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>resp = req.x + req.y</span><br /><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span><br /><br /><span style="font-family: Courier New, Courier, monospace;">}</span><br /><span style="font-family: Courier New, Courier, monospace;"><br /></span>Above, we are telling Jolie that this microservice is concurrent, i.e., each request is handled in parallel by a lightweight process (Jolie processes are implemented as threads with a local state).<br />The input port CalcInput states that the service can be accessed using TCP/IP sockets on port 8000, using the <a href="http://docs.jolie-lang.org/#!documentation/protocols/sodep.html" target="_blank">SODEP</a> protocol. CalcIface is the exposed interface, which we define in &nbsp;the included file <span style="font-family: Courier New, Courier, monospace;">calculator.iol</span><span style="font-family: inherit;">:</span><br /><span style="font-family: inherit;"><br /></span><span style="font-family: Courier New, Courier, monospace;">type SumT:void {</span><br /><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>.x:int</span><br /><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>.y:int</span><br /><span style="font-family: Courier New, Courier, monospace;">}</span><br /><span style="font-family: Courier New, Courier, monospace;"><br /></span><span style="font-family: Courier New, Courier, monospace;">interface CalcIface {</span><br /><span style="font-family: Courier New, Courier, monospace;">RequestResponse: s</span><span style="font-family: 'Courier New', Courier, monospace;">um( SumT )( int )</span><br /><br /><span style="font-family: Courier New, Courier, monospace;">}</span><br /><div><br /></div><div><span style="font-family: inherit;">CalcIface is an interface with only one Request-Response operation called sum, which receives a tree with two nodes (x and y, both integers) and returns an integer.</span></div><div>The sum operation is implemented in the main procedure of the calculator microservice: it simply receives the message on variable req and replies with the sum of the two subnodes x and y to the invoker.</div><div><br /></div><div><br /></div><h2><span style="font-family: inherit;">Using the calculator</span></h2><div><span style="font-family: inherit;">Using the calculator service from Jolie is easy. We create a </span><span style="font-family: Courier New, Courier, monospace;">client.ol </span><span style="font-family: inherit;">program, include the interface and off we go:</span></div><div><span style="font-family: inherit;"><br /></span></div><div><div><span style="font-family: Courier New, Courier, monospace;">include "calculator.iol"</span></div><div><span style="font-family: Courier New, Courier, monospace;">include "console.iol"</span></div><div><span style="font-family: Courier New, Courier, monospace;"><br /></span></div><div><span style="font-family: Courier New, Courier, monospace;">outputPort Calculator {</span></div><div><span style="font-family: Courier New, Courier, monospace;">Location: "socket://localhost:8000"</span></div><div><span style="font-family: Courier New, Courier, monospace;">Protocol: sodep</span></div><div><span style="font-family: Courier New, Courier, monospace;">Interfaces: CalcIface</span></div><div><span style="font-family: Courier New, Courier, monospace;">}</span></div><div><span style="font-family: Courier New, Courier, monospace;"><br /></span></div><div><span style="font-family: Courier New, Courier, monospace;">main</span></div><div><span style="font-family: Courier New, Courier, monospace;">{</span></div><div><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>with( req ) {</span></div><div><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>.x = 3;</span></div><div><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>.y = 2</span></div><div><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>};</span></div><div><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>sum@Calculator( req )( resp );</span></div><div><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>println@Console( resp )()</span></div><div><span style="font-family: Courier New, Courier, monospace;">}</span></div><div style="font-family: inherit;"><br /></div></div><div><span style="font-family: inherit;">Running this client program will reach the calculator service and print the number 5 on screen. SODEP is a binary protocol, so you don't need to worry about overhead as much as you have to in, e.g., SOAP.</span></div><div><span style="font-family: inherit;"><br /></span></div><div>The attentive reader may have noticed that in our client code we are calling the println operation of the Console service, just like we are calling the sum operation of calculator. That's right, even our Console library is a microservice that you can relocate as you like.</div><div><span style="font-family: inherit;"><br /></span></div><h2><span style="font-family: inherit;">OK, but what if the rest of my system is not in Jolie?</span></h2><div><span style="font-family: inherit;">Jolie is interoperable with many other technologies, both server- and client-side. Let's see what happens if our client is not written in Jolie and does not support SODEP. Let's say instead that it's a web browser and that it consequently uses HTTP.</span></div><div>Take the calculator program again and add the following before the main procedure:</div><div><br /></div><div><span style="font-family: Courier New, Courier, monospace;">inputPort CalcWebInput {</span><br /><span style="font-family: Courier New, Courier, monospace;">Location: "socket://localhost:8080"</span><br /><span style="font-family: Courier New, Courier, monospace;">Protocol: http</span><br /><span style="font-family: Courier New, Courier, monospace;">Interfaces: CalcIface</span><br /><span style="font-family: Courier New, Courier, monospace;">}</span><br /><span style="font-family: Courier New, Courier, monospace;"><br /></span><span style="font-family: inherit;">Et voil</span>à, now calculator is not only exposed on TCP port 8000 with SODEP but <b>also</b> on TCP port 8080 with the HTTP protocol. Run calculator and you can now point your browser to:<br /><br /><div style="text-align: center;"><a href="http://localhost:8080/sum?x=3&amp;y=5" target="_blank">http://localhost:8080/sum?x=3&amp;y=5</a></div><br />You will see calculator crunching the numbers and reply with:<br /><br /><div style="text-align: center;"><span style="font-family: Courier New, Courier, monospace;"><span class="html-tag" style="font-size: 14px;">&lt;sumResponse&gt;</span><span class="text" style="font-size: 14px;">8</span><span class="html-tag" style="font-size: 14px;">&lt;/sumResponse&gt;</span></span></div><span style="font-family: Courier New, Courier, monospace;"><span class="html-tag" style="font-size: 14px;"><br /></span></span>You can use many other protocols (HTTP/JSON, SOAP, local memory, ...) and communication mediums (Bluetooth, UNIX sockets, ...), depending on your needs. See <a href="http://docs.jolie-lang.org/#!documentation/protocols/introduction.html" target="_blank">here</a>.<br /><br /><br /><h2>What if I cannot change the code of my microservices?</h2></div><div><span style="font-family: inherit;">If your calculator is a black box that you cannot or do not want to touch, then you cannot just edit its code to add an HTTP input port. This is the typical case in which you would like to compositionally evolve your system without touching what has already been deployed.</span></div><div><span style="font-family: inherit;"><br /></span></div><div>The standard solution is to use a proxy. In our example, we wish to make a proxy that enables web browsers to communicate with the calculator service:</div><div><br /></div><div style="text-align: center;">Web browser <-> Proxy <-> Calculator<!-----><!-----><!-----><!-----></-></-></div><div style="text-align: left;"><br /></div><div style="text-align: left;">Proxies (and variants) are very useful in general as intermediate glue components in service systems, but managing them may require you getting to know yet another technology. In Jolie, instead, proxies are powered by a native language primitive for forwarding messages and integrate well with our communication ports, so you can take advantage of the data abstraction layer provided by Jolie.</div><div style="text-align: left;"><br /></div><div style="text-align: left;">Open a file <span style="font-family: Courier New, Courier, monospace;">proxy.ol</span><span style="font-family: inherit;">&nbsp;and write:</span></div><div style="text-align: left;"><span style="font-family: inherit;"><br /></span></div><div style="text-align: left;"><div><span style="font-family: Courier New, Courier, monospace;">include "calculator.iol"</span></div><div><span style="font-family: Courier New, Courier, monospace;">include "console.iol"</span></div><div><span style="font-family: Courier New, Courier, monospace;"><br /></span></div><div><span style="font-family: Courier New, Courier, monospace;">execution { concurrent }</span></div><div><span style="font-family: Courier New, Courier, monospace;"><br /></span></div><div><span style="font-family: Courier New, Courier, monospace;">outputPort Calculator {</span></div><div><span style="font-family: Courier New, Courier, monospace;">Location: "socket://localhost:8000"</span></div><div><span style="font-family: Courier New, Courier, monospace;">Protocol: sodep</span></div><div><span style="font-family: Courier New, Courier, monospace;">Interfaces: CalcIface</span></div><div><span style="font-family: Courier New, Courier, monospace;">}</span></div><div><span style="font-family: Courier New, Courier, monospace;"><br /></span></div><div><span style="font-family: Courier New, Courier, monospace;">inputPort ProxyInput {</span></div><div><span style="font-family: Courier New, Courier, monospace;">Location: "socket://localhost:9000"</span></div><div><span style="font-family: Courier New, Courier, monospace;">Protocol: http</span></div><div><span style="font-family: Courier New, Courier, monospace;">Aggregates: Calculator</span></div><div><span style="font-family: Courier New, Courier, monospace;">}</span></div><div><span style="font-family: Courier New, Courier, monospace;"><br /></span></div><div><span style="font-family: Courier New, Courier, monospace;">main</span></div><div><span style="font-family: Courier New, Courier, monospace;">{</span></div><div><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>in()</span></div><div><span style="font-family: Courier New, Courier, monospace;">}</span></div><div><span style="font-family: Courier New, Courier, monospace;"><br /></span></div><div><span style="font-family: inherit;">The important part here is that we have an input port on TCP port 9000 that <a href="http://docs.jolie-lang.org/#!documentation/architectural_composition/aggregation.html" target="_blank">aggregates</a> the output port towards the Calculator. This means that all messages on port ProxyInput for an operation provided by Calculator will be forwarded to that service. So now we have our proxy and we can navigate to:</span></div></div><div style="text-align: left;"><span style="font-family: inherit;"><br /></span></div><div style="text-align: center;"><a href="http://localhost:9000/sum?x=3&amp;y=5">http://localhost:9000/sum?x=3&amp;y=5</a></div><div style="text-align: center;"><br /></div><div style="text-align: left;">The proxy service will now receive your HTTP message on port ProxyInput, see that it is for the sum operation of calculator. The message is therefore converted to the SODEP format, as specified by the output port towards the calculator. The response from calculator will finally be converted again from SODEP to HTTP and sent to the initial client.</div><div style="text-align: left;"><br /></div><div style="text-align: left;">Aggregation is really useful. You can also add hooks (called <a href="http://docs.jolie-lang.org/#!documentation/architectural_composition/couriers.html" target="_blank">couriers</a>) for intercepting messages and, e.g, log operations or check for authentication credentials.</div><div style="text-align: left;"><br /></div><div style="text-align: left;"><h2></h2><h2>Workflows</h2><div>Alright, now we have our toy microservice system. Let's say that after a while, you want to add the requirement that a user must log in before calling the sum operation on the calculator. This is a workflow, the magic keyword being <b>before</b>&nbsp;in the previous sentence. Jolie inherits native workflow primitives from business process languages (e.g., <a href="http://en.wikipedia.org/wiki/Business_Process_Execution_Language" target="_blank">BPEL</a>), making handling flows of communications among services a breeze!</div><div><br /></div><div>Open <span style="font-family: Courier New, Courier, monospace;">calculator.ol</span><span style="font-family: inherit;">&nbsp;and change the main definition as follows:</span></div><div><span style="font-family: inherit;"><br /></span></div><div><div><span style="font-family: Courier New, Courier, monospace;">cset {</span></div><div><span style="font-family: Courier New, Courier, monospace;">sid : SumT.sid</span></div><div><span style="font-family: Courier New, Courier, monospace;">}</span></div><div><span style="font-family: Courier New, Courier, monospace;"><br /></span></div><div><span style="font-family: Courier New, Courier, monospace;">main</span></div><div><span style="font-family: Courier New, Courier, monospace;">{</span></div><div><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>login( creds )( csets.sid ) {</span></div><div><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>if ( creds.pwd != "jolie" ) {</span></div><div><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>throw( InvalidPwd, "The password is jolie" )</span></div><div><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>};</span></div><div><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>csets.sid = new</span></div><div><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>};</span></div><div><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>sum( req )( resp ) {</span></div><div><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>resp = req.x + req.y</span></div><div><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div><div><span style="font-family: Courier New, Courier, monospace;">}</span></div></div><div><span style="font-family: Courier New, Courier, monospace;"><br /></span></div><div><span style="font-family: inherit;">The cset block above declares a session identifier sid, which we will use to track invocations coming from a same client (that's a <a href="http://docs.jolie-lang.org/#!documentation/basics/sessions.html" target="_blank">correlation set</a>). We also introduced a new operation, login, which simply checks if the password sent by the client is jolie and otherwise throws a fault to the invoker. Observe now that we use the semicolon operator to tell Jolie that sum becomes available only after login has successfully completed.</span></div><div><span style="font-family: inherit;"><br /></span></div><div><span style="font-family: inherit;">This is a fundamental difference with respect to, say, object-oriented computing, where if you want to enforce order in how different methods are called, you have to implement it yourself with bookkeeping variables and concurrent lock mechanisms. Here instead, you just write a semicolon.</span></div><div><span style="font-family: inherit;"><br /></span></div><div><span style="font-family: inherit;">We also need to update the interface of the calculator, in </span><span style="font-family: Courier New, Courier, monospace;">calculator.iol</span><span style="font-family: inherit;">, to account for our modifications:</span></div><div><span style="font-family: inherit;"><br /></span></div><div><div><span style="font-family: Courier New, Courier, monospace;">type SumT:void {</span></div><div><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>.x:int</span></div><div><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>.y:int</span></div><div><span class="Apple-tab-span" style="white-space: pre;"><span style="font-family: Courier New, Courier, monospace;"> </span></span></div><div><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>.sid:string</span></div><div><span style="font-family: Courier New, Courier, monospace;">}</span></div><div><span style="font-family: Courier New, Courier, monospace;"><br /></span></div><div><span style="font-family: Courier New, Courier, monospace;">type LoginT:void {</span></div><div><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>.pwd:string</span></div><div><span style="font-family: Courier New, Courier, monospace;">}</span></div><div><span style="font-family: Courier New, Courier, monospace;"><br /></span></div><div><span style="font-family: Courier New, Courier, monospace;">interface CalcIface {</span></div><div><span style="font-family: Courier New, Courier, monospace;">RequestResponse:</span></div><div><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>login( LoginT )( string ) throws InvalidPwd( string ),</span></div><div><span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>sum( SumT )( int )</span></div><div><span style="font-family: Courier New, Courier, monospace;">}</span></div><div style="font-family: inherit;"><br /></div></div><div><span style="font-family: inherit;">We are done! No need to update the code of the proxy, as the aggregation primitive is parametric on the interface and the protocols used by the aggregated services. Jolie will do that lifting for us. So now we can browse to:&nbsp;</span></div><div><span style="font-family: inherit;"><br /></span></div><div style="text-align: center;"><a href="http://localhost:9000/login?pwd=jolie">http://localhost:9000/login?pwd=jolie</a></div><div><span style="font-family: inherit;"><br /></span></div><div>You will get a random session identifier. I got:</div><div><br /></div><div style="text-align: center;"><span class="html-tag" style="font-family: monospace; font-size: 14px;">&lt;loginResponse&gt;</span><span class="text" style="font-family: monospace; font-size: 14px;">193e6a7a-895c-4ff6-b32a-5bbab0eea7f3</span><span class="html-tag" style="font-family: monospace; font-size: 14px;">&lt;/loginResponse</span><span style="font-family: monospace; font-size: 14px;">&gt;</span></div><div><span style="font-family: inherit;"><br /></span></div><div><span style="font-family: inherit;">So now I can go to (remember to replace sid with what you got in the previous call if you try this yourself):</span></div><div><span style="font-family: inherit;"><br /></span></div><div style="text-align: center;"><a href="http://localhost:9000/sum?x=3&amp;y=5&amp;sid=193e6a7a-895c-4ff6-b32a-5bbab0eea7f3">http://localhost:9000/sum?x=3&amp;y=5&amp;sid=193e6a7a-895c-4ff6-b32a-5bbab0eea7f3</a></div><div style="text-align: left;"><br /></div><div style="text-align: left;">And receive my good old 8 as result.</div><div style="text-align: left;"><br /></div><div style="text-align: left;">Have a look at the Jolie documentation if you are interested in using cookies and theming your responses with nice HTML. You can put that in a separate microservice, to keep calculator clean!</div><div style="text-align: left;"><br /></div><h2 style="text-align: left;">Conclusions</h2><div>This is just the tip of the iceberg of what you may have to do with microservices and what Jolie can do for you.</div><div><br /></div><div>But we can already see some of the underlying concepts that Jolie is based on:</div><div><br /></div><div><ul><li>You should not commit to any particular communication technology. Microservices are born to be lean and reusable, and should be kept decoupled from the implementation details of how data is exchanged.</li><li>Building proxies and <a href="http://docs.jolie-lang.org/#!documentation/architectural_composition/introduction.html" target="_blank">other kinds of architectural composers</a>&nbsp;is very handy in microservice architectures just like it is in any other distributed system. However, with microservices you can end up having a lot of them. Jolie helps in creating and managing these composers by making them programmable with native primitives that make it clear what is happening.</li><li>Workflows can help in making the structure of communications followed by a service explicit. They should be easy to write and Jolie strives in doing so. See <a href="http://docs.jolie-lang.org/#!documentation/basics/composing_statements.html" target="_blank">here</a> for our other workflow primitives.</li></ul><div><br /></div></div><div><br /></div><div>Stay tuned for the next chapters. :-)</div><div><br /></div><div>Meanwhile, you may want to have a look at some more material <a href="http://docs.jolie-lang.org/" target="_blank">here</a> and&nbsp;<a href="http://fabriziomontesi.com/teaching/imds-f2014/index.html" target="_blank">here</a>.</div></div>https://fmontesi.github.io/2015/01/30/running-jolie-inside-of-java.htmlRunning Jolie inside of Java2015-01-30T12:25:00+00:002015-01-30T12:25:00+00:00Fabrizio Montesihttps://fmontesi.github.ioLately I have been asked a lot how to run a Jolie program from inside of a Java program.<br />The opposite, running Java from Jolie, is <a href="http://docs.jolie-lang.org/#!documentation/architectural_composition/embedding_java.html" target="_blank">well documented</a> in our documentation site.<br /><br />Running Java code from inside a Jolie program is also a very simple process.<br />First, you need to add to your classpath (import in your project, if you are using an IDE) the jolie.jar and libjolie.jar libraries that you can find in your Jolie installation directory (JOLIE_HOME).<br />Now, from Java, you can create an Interpreter object. Interpreter is the class that implements the Jolie language interpreter. It will need two parameters for the constructor. The first is the command line arguments that you want to pass to the interpreter. The second is the parent class loader to use for loading the resources that the interpreter will need. Here is an example based on the Linux launcher script (but it should work on any OS), where we assume that the Jolie program that we want to run is called main.ol:<br /><br /><br /><pre class="brush: java">String jh = System.getenv( "JOLIE_HOME" );<br />String args[] = "-l ./lib/*:$JOLIE_HOME/lib:$JOLIE_HOME/javaServices/*:$JOLIE_HOME/extensions/* -i $JOLIE_HOME/include main.ol".replaceAll( "\\$JOLIE_HOME", jh ).split( " " );<br />final Interpreter interpreter = new Interpreter( args, this.class.getClassLoader() );<br /></pre><br />Now you just need to use the run method of the interpreter object you have just created. Here I do it in a separate thread, as that method will return only when the Jolie program terminates. This is a toy example so I am disregarding exceptions here, but you should obviously care about them in real-world code:<br /><br /><pre class="brush: java">Thread t = new Thread( () -&gt; {<br /> try { interpreter.run(); }<br /> catch( Exception e ) { /* Handle e.. */ }<br />} );<br />t.setContextClassLoader( interpreter.getClassLoader() );<br />t.start();<br /></pre><br />If you need to stop the interpreter manually, you can use the exit method it comes with. It takes a hard timeout if you need one. Enjoy your Jolie interpreter inside of Java!https://fmontesi.github.io/2015/01/26/faster-websites-with-jolie-http.htmlFaster websites with Jolie - HTTP Compression enabled by default2015-01-26T15:18:00+00:002015-01-26T15:18:00+00:00Fabrizio Montesihttps://fmontesi.github.ioThanks to Matthias Dieter Wallnöfer, Jolie now supports the negotiation of HTTP compression and this is activated by default. This means that all your Jolie-powered websites will benefit from this, along with your Jolie programs which access remote HTTP content.<br /><br /> We have just uploaded the patch to the web server on the Jolie website: <a href="http://www.jolie-lang.org/">http://www.jolie-lang.org</a><br /><br />We have also added caching, with the good old <a href="http://docs.jolie-lang.org/#!documentation/protocols/http.html">.cacheControl HTTP configuration parameter</a> that I introduced a while ago (<a href="http://arxiv.org/abs/1410.3712">http://arxiv.org/abs/1410.3712</a>).<br /><br />Two minutes later, the loading speed of the main webpage doubled. We went from ~140ms down to ~70ms ! You should feel the difference navigating from one page to the other (aside from those pages using slideshare plugins, which take time to load from slideshare.net).<br /><br />Enjoy a faster Jolie website and faster $all_your_Jolie_programs.<br /><br />PS: Yes, this will be released with Jolie 1.1.1https://fmontesi.github.io/2014/12/19/the-first-full-course-on-jolie-has-ended.htmlThe first full course on Jolie has ended2014-12-19T23:03:00+00:002014-12-19T23:03:00+00:00Fabrizio Montesihttps://fmontesi.github.ioThe first university course almost entirely on Jolie (and choreographies!) ended today, with cakes and final discussion on the exam procedure. :-)<br />I had a lot of fun teaching it. I look forward to the next edition, I got lots of good ideas from this one.<br /><br />It was also a lot of work, as I had to prepare a lot of material from scratch. There is still lots of room for improvement, but I got a decent set of lectures and exercises out of it. Here is the material from this year:<br /><a href="http://fabriziomontesi.com/teaching/imds-f2014/index.html">http://fabriziomontesi.com/teaching/imds-f2014/index.html</a><br /><br />Feel free to use it, as long as you put a reference to the origin please. Or, just contact me.<br /><br />This year I also experimented with teaching students how to prepare and give a presentation on a scientific paper, and how to read scientific articles. I think it really paid off, they gave excellent presentations. But it's hard to tell, I had really clever students.. so maybe it's all them. ;-)<br />Here are some of their carefully crafted presentations:<br /><iframe src="http://www.slideshare.net/IMDS2014/slideshelf" width="760px" height="570px" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:none;" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe>I still have to get the final feedback on the course, but an initial probing tells me that most of them would use Jolie for their future software projects. This alone makes all the effort worth it. I can't wait to see what they build with it. Some of them have already started.<br /><br />As the students were so happy, I am going to try carrying out an educational project on research-led teaching next year and see how to push its limits a little more every year! Doing live demos on Jolie during lectures is so much fun (you should see the faces of people when I hack a multiparty web chat server or a prototype cloud computing solution in Jolie in about 10 minutes), but I think that I can transform some of them into videos and apply some more flipped classroom techniques along with other videos from the research community on session programming. We'll see.. and suggestions are welcome!<br /><br />PS: something that baffled me. I could not find a good tutorial for master students on CCS and the pi-calculus. I had to prepare introductory lectures by myself, which was also quite a bit of work. But maybe they are out there and I just could not find them? https://fmontesi.github.io/2010/11/02/plasma-crashing-upon-login-after.htmlPlasma crashing upon login after updating the system clock2010-11-02T08:52:00+00:002010-11-02T08:52:00+00:00Fabrizio Montesihttps://fmontesi.github.ioMany people have just recently switched from DST to standard time, putting their clocks an hour back. This can possibly cause a nasty behaviour in Plasma, due to a bug in KSharedDataCache: the application simply crashes just after logging in.<br />The bug has already been <a href="https://bugs.kde.org/show_bug.cgi?id=253795">reported</a> and corrected at the speed of light (kudos to Michael Pyne for the instantaneous reaction), so it will be fixed in KDE SC 4.5.3 and 4.6. If you are running KDE SC 4.5.2 and you do not want to apply the patch in the bug report, you can simply empty your user's cache directory.<br />Simply go in the directory pointed by cache-$HOSTNAME inside your user's kde configuration directory and remove every file that is located inside.<br />In openSUSE such directory is /var/tmp/kdecache-$USER, and your kde configuration directory is $HOME/.kde4.<br /><br />Happy Plasmaing! (or would that word be Plasming? ;-) )https://fmontesi.github.io/2010/05/13/web-services-for-human-beings.htmlWeb Services for human beings2010-05-13T13:37:00+00:002010-05-13T13:37:00+00:00Fabrizio Montesihttps://fmontesi.github.io<span style="font-size: xx-small;"><i>No, this is not related to *buntu. But this is looong... and now I've got your attention. :-)</i></span><br /><span style="font-size: xx-small;"><i><br /></i></span><br />Interacting with Web Services usually implies reading some <a href="http://www.w3.org/TR/wsdl">WSDL (Web Service Description Language) document</a>. Unfortunately, WSDL documents are written in XML and can be pretty complicated, leaving the user with no other choice than to use some graphical development tool in order to understand them.<br /><br />Lately at italianaSoftware we had to handle a lot of Web Services stuff, equipped with long WSDL documents and complex data types. <a href="http://www.jolie-lang.org/">Jolie</a> already had support for the SOAP protocol, but one had to code the interface and data types of the Web Service to invoke by hand. So we started a new project aiming to enable Jolie for the automatic usage of WSDL documents, mainly composed by two parts: a tool and an improvement to the Jolie SOAP protocol. Of course both things are open source and available in the trunk branch in the Jolie svn repository!<br /><br /><b>wsdl2jolie </b>(whose executable is now installed by default if you install Jolie from trunk) is the newly developed tool in question. It simply takes a URL to a WSDL document and automatically downloads all the related files (e.g., referred XML schemas), parses them and outputs the corresponding Jolie port/interface/data type definitions.<br />Let us see an example. See this WSDL document for a service that calculates prime numbers: <a href="http://www50.brinkster.com/vbfacileinpt/np.asmx?wsdl">http://www50.brinkster.com/vbfacileinpt/np.asmx?wsdl</a>. Reading the raw XML is not so easy, or at least requires some time.<br />Let us see what we get if we execute <span style="font-family: &quot;Courier New&quot;,Courier,monospace;">wsdl2jolie http://www50.brinkster.com/vbfacileinpt/np.asmx?wsdl</span> <span style="font-family: inherit;">:</span><br /><br /><pre>Retrieving document at 'http://www50.brinkster.com/vbfacileinpt/np.asmx?wsdl'.<br />type GetPrimeNumbersResponse:void {<br /> .GetPrimeNumbersResult?:string<br />}<br /><br />type GetPrimeNumbers:void {<br /> .max:int<br />}<br /><br />interface PrimeNumbersHttpPost {<br />RequestResponse:<br /> GetPrimeNumbers(string)(string)<br />}<br /><br />interface PrimeNumbersHttpGet {<br />RequestResponse:<br /> GetPrimeNumbers(string)(string)<br />}<br /><br />interface PrimeNumbersSoap {<br />RequestResponse:<br /> GetPrimeNumbers(GetPrimeNumbers)(GetPrimeNumbersResponse)<br />}<br /><br />outputPort PrimeNumbersHttpPost {<br />Location: "socket://www50.brinkster.com:80/vbfacileinpt/np.asmx"<br />Protocol: http<br />Interfaces: PrimeNumbersHttpPost<br />}<br /><br />outputPort PrimeNumbersHttpGet {<br />Location: "socket://www50.brinkster.com:80/vbfacileinpt/np.asmx"<br />Protocol: http<br />Interfaces: PrimeNumbersHttpGet<br />}<br /><br />outputPort PrimeNumbersSoap {<br />Location: "socket://www50.brinkster.com:80/vbfacileinpt/np.asmx"<br />Protocol: soap {<br /> .wsdl = "http://www50.brinkster.com/vbfacileinpt/np.asmx?wsdl";<br /> .wsdl.port = "PrimeNumbersSoap"<br />}<br />Interfaces: PrimeNumbersSoap<br />}<br /></pre><br /><span style="font-family: &quot;Courier New&quot;,Courier,monospace;"><span style="font-family: Arial,Helvetica,sans-serif;">which is the Jolie equivalent of the WSDL document. Those ".wsdl" and ".wsdl.port" parameters are the aforementioned improvement to the SOAP protocol: when the output port is used for the first time, Jolie will read the WSDL document for processing information about the correct configuration for interacting with the service instead of forcing the user to insert it by hand.</span></span><br /><span style="font-family: &quot;Courier New&quot;,Courier,monospace;"><span style="font-family: Arial,Helvetica,sans-serif;">Now we can just put this into a file, say "PrimeNumbers.iol"<span style="font-family: inherit;">, and use the output ports we discovered from Jolie code. As in the following:</span></span></span><br /><br /><pre>include "PrimeNumbers.iol"<br />include "console.iol"<br /><br />main<br />{<br /> request.max = 27;<br /> GetPrimeNumbers@PrimeNumbersSoap( request )( response );<br /> println@Console( response.GetPrimeNumbersResult )()<br />}<br /></pre><br /><div style="font-family: inherit;"><span style="font-size: small;">That little program will output "1,3,5,7,11,13,17,19,23</span><span style="font-size: small;">"</span><span style="font-size: small;">. The example can be downloaded from <a href="http://www.jolie-lang.org/examples/unsorted/prime_numbers_wsdl.zip">this link</a> (remember, it requires Jolie from trunk).</span></div><div style="font-family: inherit;"><span style="font-size: small;"><br /></span></div><div style="font-family: inherit;"><span style="font-size: small;">wsdl2jolie acts as a nice tool for being able to use the typed interface of a Web Service from Jolie and for getting a more human-readable form of a WSDL document (its Jolie form).</span></div><div style="font-family: inherit;"><br /></div><span style="font-family: &quot;Courier New&quot;,Courier,monospace;"><span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-family: inherit;"><span style="font-family: &quot;Courier New&quot;,Courier,monospace;"><span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-family: inherit;">Another nice feature we get for free from the SOAP protocol improvement is that <b>now MetaService can act as a transparent bridge towards Web Services</b>. Simply call the addRedirection operation with the right protocol configuration (in this case, the ".wsdl" and ".wsdl.port" parameters) and MetaService will automatically download the WSDL document (we also have a cache system for them already in trunk!) and make it callable by clients.</span></span></span></span></span></span><br /><span style="font-family: &quot;Courier New&quot;,Courier,monospace;"><span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-family: inherit;"><span style="font-family: &quot;Courier New&quot;,Courier,monospace;"><span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-family: inherit;">This is a huge step forward for client libraries such as QtJolie: just tell where the WSDL document is and you can already place calls to the Web Service of interest.</span></span></span></span></span></span><br /><span style="font-family: &quot;Courier New&quot;,Courier,monospace;"><span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-family: inherit;"><span style="font-family: &quot;Courier New&quot;,Courier,monospace;"><span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-family: inherit;">Also, by using <b>wsdl2jolie</b> first and then tools such as <b>jolie2plasma</b> one could use the Jolie intermediate representation for transforming a Web Service interface definition into a (<a href="http://www.kde.org/">KDE</a>) Plasma::Service XML one. With the same trick, one could also write C++ generators for QtJolie and introduce ease and type-safeness to Web Services invocations. I and Kévin sure have things to think about now. ;-)</span></span></span></span></span></span><br /><br /><span style="font-family: &quot;Courier New&quot;,Courier,monospace;"><span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-family: inherit;"><span style="font-family: &quot;Courier New&quot;,Courier,monospace;"><span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-family: inherit;">Beware that the code is still in its early stages. It already works with a lot of Web Services, but we're still improving it. For instance, we currently support only the SOAP document format (which is the one people advise to use, anyway). Patches, comments and reports are welcome in jolie-devel @ lists.sourceforge.net!</span></span></span></span></span></span>https://fmontesi.github.io/2009/11/24/discovering-jolie-in-italian.htmlDiscovering Jolie... in italian!2009-11-24T16:00:00+00:002009-11-24T16:00:00+00:00Fabrizio Montesihttps://fmontesi.github.ioI have just discovered that Simone (Demo) Gentili is documenting his journey about the <a href="http://www.jolie-lang.org/">Jolie language</a>&nbsp;on his blog! As a matter of fact, he's practically translating the Jolie language tutorials in italian!<br />See <a href="http://www.unodeitanti.com/wordpress/jolie/">his blog here</a> if you are interested in some Jolie lessons in italian.<br /><br />This is obviously a very nice surprise for us and an important form of contribution, so thank you Simone for your work!https://fmontesi.github.io/2009/10/20/service-oriented-computing-new.htmlService-Oriented Computing: a new programming paradigm?2009-10-20T16:19:00+00:002009-10-20T16:19:00+00:00Fabrizio Montesihttps://fmontesi.github.io<span style="font-style: italic;">The point of this post is to introduce a paper that explains service-oriented computing that can be read by anyone, without requiring too much previous knowledge. The link is in the last paragraph of the post. If you were interested in knowing more about what service-oriented computing is, it could be a good starting point.</span><br /><br />The concepts of online service and distributed programming exist since quite some time now, to the point that they evolved into a huge research topic both for academia and the industry. Huge as it is, a lot of different results from different research areas appeared; conferences on Service-Oriented Computing (SOC) were opened; a lot of investments were made.<br />In the last decade or so it became apparent that new foundations were need in order to build truly inter-operable distributed applications and that ad-hoc technologies were not good enough for the job. Moreover, it was clear how much SOC could benefit from theoretical research for handling its complex inherent problems. New concepts were forged and new languages were made, the most notable result being the set of languages, specifications and technologies that falls under the name of "Web Services".<br /><br />Today, we reached the point in which we can look back and see that "services" follow common principles (e.g. public interface, protocol descriptions...) and must necessarily address certain problems (e.g. session handling, structured data description and manipulation, interoperability...). The whole thing grew up so much in detail that we may be looking at a new programming paradigm: the service-oriented one. A paradigm that has the concept of "service" as a native element, much like object-oriented programming has the native concept of "object" or functional programming of "function".<br />This is not something that we just imagined. We see this every day at <a href="http://www.italianasoftware.com">italianaSoftware</a>, programming solutions for our customers with the <a href="http://www.jolie-lang.org">JOLIE language</a>. Having a language that allows you to make lightweight services in a matter of minutes and to exploit local communications between them in order to maintain performance can change your point of view: services are not mere bridges between different applications anymore, they can be used (and reused) as the building blocks of a single application.<br /><br />We tried to express our definition and experience on this new paradigm on a concept paper at YR-SOC'09, which is publicly available online. Here is the <a href="http://arxiv.org/abs/0906.3920">link</a> (on the upper right area of the linked page you can find links for the pdf or postscript versions). It is an introduction to service-oriented computing that considers what has been made so far, so you will find links to a lot of existing works inside it. Some concepts may be pretty new to some readers (after all, it was originally meant for an academic audience and contains references to theoretical works), but we are currently interested in enhancing the paper to make it more readable by the casual developer (probably with less references to theoretical works and more comparisons with existing languages and technologies) and put the new version online in the JOLIE website. So, if you read the paper and find some concepts too obscure or you have some doubts or comments (apart what I have already said) or some arguments that you wish would be addressed, please let us know!https://fmontesi.github.io/2009/09/29/jolie-and-arm.htmlJolie and ARM2009-09-29T07:48:00+00:002009-09-29T07:48:00+00:00Fabrizio Montesihttps://fmontesi.github.ioLast year (yeah, this is one of those "I should have posted this long ago" posts, but better late than never) I received a precious delivery:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_I6cBVk6ZngU/STlF0zRUZ9I/AAAAAAAAABc/0PsvHrAHV0U/s1600-h/05-12-08_1451.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 256px; height: 320px;" src="http://3.bp.blogspot.com/_I6cBVk6ZngU/STlF0zRUZ9I/AAAAAAAAABc/0PsvHrAHV0U/s320/05-12-08_1451.jpg" alt="" id="BLOGGER_PHOTO_ID_5276325211859609554" border="0" /></a>Oh, yes! KDE sent me bubble wrap, woohoo! I played with it until its exhaustion, so thank you KDE (and Claudia for handling the delivery, and Nokia for providing the materials)!<br /><br />After playing with the bubble wrap I discovered that there was something inside it: a shining Nokia N810. My very first ARM device to experiment with. The ARM world is indeed very interesting not only for <a href="http://www.kde.org/">KDE</a>, but also for the <a href="http://www.jolie-lang.org/">Jolie</a> language; so I started to try installing a working execution environment for Jolie in this little device.<br /><br />The first try wasn't easy. I needed a working Java environment before trying to install Jolie. Fortunately, the <a href="https://wiki.evolvis.org/jalimo/index.php/Main_Page">Jalimo project</a> out there has already made all the important steps. So I made contact with them in IRC and I've found people willing to help. Many thanks in particular to <a href="http://www.ohloh.net/accounts/xranby">xranby</a>, who provided me an almost-ready binary package for getting me started. The result?<br />Jolie has been tested on ARM, and it just works! The whole process has produced some patches for Jolie too, in terms of performance improvements (loading protocol extensions is now faster than before) and memory consumption.https://fmontesi.github.io/2009/09/09/random-thoughts-getting-ready-for-jolie.htmlRandom thoughts: getting ready for Jolie 1.0 and remote services inclusion in KDE2009-09-09T14:26:00+00:002009-09-09T14:26:00+00:00Fabrizio Montesihttps://fmontesi.github.io<a href="http://www.jolie-lang.org/">Jolie</a> is getting into shape for the 1.0 release. This is requiring a lot of work, and whenever we reach our current objectives we feel like improving things even further (every developer likes perfection, the problem is it requires too much time)! Nevertheless, the line for a good 1.0 release has been placed and is getting very near. The two major points we need to address are SSL support (both in SODEP an HTTP) and documentation. By documentation I'm not just referring to the language documentation but also to the source code documentation of the interpreter; the aim is to make the Jolie interpreter more approachable by hackers who want to improve it or want to write an extension (protocols, specifications, hardware support, ...). The 1.0 release will also contain experimental support for XML-RPC.<br /><br />SSL support is already working and waiting for inclusion (rough edges need to be investigated) in the main source tree. SSL support will particularly benefit B2B applications, which until<br />now had to get security by wrapping Jolie in SSL containers, and <a href="http://www.kde.org/">the KDE project</a>, which has just <a href="http://pindablog.wordpress.com/2009/09/08/tokamak-3-wrap-up/">included support for remote services</a> in trunk using Jolie and MetaService as backend technologies. SSL support in Jolie would allow KDE remote Plasma services to encrypt their data exchanges, an essential feature when dealing with sensitive data (though the initial handshake part is already made secure by using Qt).<br />I must say that the KDE inclusion was pretty quick: it was just one year ago when the Jolie and the Plasma teams met at the first Tokamak and now we already have a first functioning version in trunk. This process required quite a lot of work and skill, from writing a service orchestrator that could dynamically create bridges from Plasma to services using different protocols and technologies onward to the QtJolie gluing layer and the final implementation in the Plasma library. Now we have the basis for constructing even more complex frameworks and applications, and all of this will benefit from the future Jolie static analysis tools that we (the Jolie team) are planning to implement. All of this to say that it really is a pleasure to work with the KDE team: I will be sure to keep in touch as much as possible.<br /><br />I'm now focusing heavily on source code documentation and polishing (for which I've just made some pretty big commits). Regarding code polishing, I got some help from the <a href="http://findbugs.sourceforge.net/">FindBugs</a> static analysis tool; you can just ask it to read some Java bytecode and it comes up with a lot of good hints for performance improvements and bug removals. It is really easy to use and it even considers correct resource locking and releasing. Pretty useful if you have old code to maintain or for checking new extensions before merging them.<br /><br /><br />Ah yes, I should also blog about a lot of other features and the porting of Jolie to ARM-based devices thanks to the <a href="https://wiki.evolvis.org/jalimo/index.php/Main_Page">Jalimo project</a>... but that's for other blog posts!https://fmontesi.github.io/2009/02/24/rfc-service-oriented-training-hacking.htmlRFC: Service-oriented Training & Hacking session at Akademy 20092009-02-24T12:20:00+00:002009-02-24T12:20:00+00:00Fabrizio Montesihttps://fmontesi.github.ioIt is some time that I'm thinking about Akademy 2009, and how to make people aware of the potential the integration of Plasma and <a href="http://www.jolie-lang.org">Jolie</a> are going to bring. The following is what I came up with, and from some early discussions it really looks like something worth doing. Please share your thoughts and comments on this.<br /><br />The idea is to make a (workshop-like) session about the service-oriented world, with pragmatism in mind. aseigo and ervin have been coerced into helping. It'd be composed by two parts, training and hacking.<br /><br /><h2>Training</h2><br />The training part would touch these topics (not necessarily in order):<br />- the Service-Oriented Computing paradigm: what is it, and how can we use it?<br />- how to exploit the service-oriented paradigm through the Jolie language.<br />- bridging Jolie and Qt with kevin's latest cool library<br />- the Plasma::Service+MetaService API explained. Service-oriented plasmoids!<br />- how to make powerful service compositors/orchestrators in Jolie, and use them as backends for plasmoids or $insert_your_app_here.<br />- use cases and surprises (?)<br />- questions and answers<br /><br /><h2>Hacking</h2><br />Everyone starts his editor of choice and starts hacking on some service-oriented UI/Plasmoid/etc, getting help and sharing ideas.<br />It will be an excellent occasion to improve the framework too (not only the C++ libraries but even the Jolie framework itself, as I'll be there), as there will probably be necessities that could be implemented as a Jolie protocol or some other extension.<br /><br /><br /><br />What I'd like to have are ideas and comments about this. Is there any topic you'd like to be covered in particular? Questions to be answered?<br /><br />Of course it would be nice to have plasma developers attending, along with any other people interested in integrating jolie/service-oriented computing in their application or framework.<br />It'<br /><br />So, dear reader, would *you* attend? =)
https://fmontesi.github.io/2009/02/20/solid-upnp-and-jolie.htmlSolid, UPnP and Jolie2009-02-20T08:15:00+00:002009-02-20T08:15:00+00:00Fabrizio Montesihttps://fmontesi.github.ioLately there's been a lot of interest about UPnP and its application in KDE.<br />These days I'm speaking a lot about these things with <a href="http://ervin.ipsquad.net/">Kévin "ervin" Ottens</a> w.r.t. the <a href="http://solid.kde.org">Solid</a> project. Even at Akademy 2008, Kévin suggested to me that it would be nice to have a UPnP protocol implementation in <a href="http://www.jolie-lang.org">Jolie</a>. There's been some discussion since there, but we just couldn't afford to implement it because of lack of resources (people/time). GSOC is approaching and this item is among the ideas for KDE, so some explanation is probably a good thing to offer. The aim of this post is to offer such an explanation, but given that I'm so familiar with Jolie I could miss some points of interest... so please *ask* if *you*'ve got doubts about this (like "I didn't understand why that point would be better than doing this other thing...", or "Did you think about using this and/or this?..").<br /><br /><a href="http://www.jolie-lang.org">Jolie</a> is currently being integrated in KDE and will become a runtime dependency for activating Plasma on the network (making plasmoids in different machines communicating with each other, or with external services, etc.). Enabling Jolie to use UPnP would mean to re-use this dependency and all the technology developed until now (QtSodep, service composition, easy data manipulation etc.) for giving Solid (capital S) a solid backend (lower-case s ... yes, it's a pun! ha ha... *cough cough*) to exploit all the UPnP devices out there. Add to this the service-oriented programming capabilities of Jolie and you obtain a complete framework for making powerful orchestrators out of your UPnP network and even making Solid itself a UPnP service provider.<br /><br />A note about the implementation: nowadays Jolie offers two ways for implementing a new protocol: you can write it in Java or write it in Jolie itself. We offer these two possibilities because it's useful to distinguish between low-level and high-level protocols, and to use the right tool for the right job.<br />The first kind deals with low-level byte streams manipulations, e.g. binary protocols, and Jolie is not suited to do that; good examples are any binary protocol, or even HTTP.<br />The second kind is more about manipulating data structures in an abstract manner; for example, suppose that you need to implement a new protocol on top of XML: being able to exploit Jolie's syntax for XML manipulation is usually a winner.https://fmontesi.github.io/2009/02/11/opensuse-package-for-jolie.htmlopenSUSE package for Jolie2009-02-11T13:08:00+00:002009-02-11T13:08:00+00:00Fabrizio Montesihttps://fmontesi.github.ioThe title of this blog post really leaves a trail of mistery.<br /><br />Today, under a not-so-excellent-but-still-not-too-bad weather, I've decided to enter the dark school of packaging. The results can be found here: <a href="http://download.opensuse.org/repositories/home:/fmontesi/openSUSE_11.1/">http://download.opensuse.org/repositories/home:/fmontesi/openSUSE_11.1/</a><br /><br />This means that now we've got a <a href="http://download.opensuse.org/repositories/home:/fmontesi/openSUSE_11.1/jolie.ymp">one-click installer</a> for <a href="http://www.jolie-lang.org/">Jolie</a> in openSUSE 11.1. Enjoy!<br /><br />P.S.: in the <a href="http://www.jolie-lang.org/download.php">website official download page</a> there's a better looking button ;)<br /><br /><strong>Update:</strong> andred in #plasma made me notice that many people are still using openSUSE 11.0. Jolie should work flawlessly even there, but I've got no mean to test it. Anyway, <a href="http://download.opensuse.org/repositories/home:/fmontesi/">my repository</a> now contains packages for openSUSE 11.0 and openSUSE factory, too. I must say that openSUSE build service is one fantastic piece of software!https://fmontesi.github.io/2009/01/23/major-distribution-bug-in-java-support.htmlMajor distribution bug in Java support for unix sockets?2009-01-23T10:28:00+00:002009-01-23T10:28:00+00:00Fabrizio Montesihttps://fmontesi.github.ioIf you're trying to use local unix sockets using libmatthew with a Java program (as it's the case for JOLIE and thus MetaService), you might get a similar error:<br /><br />Exception in thread "main" java.lang.UnsatisfiedLinkError: /usr/lib/libunix-java.so: /usr/lib/libunix-java.so: undefined symbol: __stack_chk_fail_local<br /><br />I get it using the libmatthew-java package from openSUSE 11.1. It looks like <a href="https://bugs.launchpad.net/ubuntu/+source/dbus-java/+bug/218658">Ubuntu users are suffering of the same problem</a> (there causing a bug in dbus-java). If you read their bug thread, you'll find that they appoint the problem to a compilation flag. I've tried to simply download libmatthew sources from <a href="http://www.matthew.ath.cx/projects/java/libmatthew-java-0.7.1.tar.gz">here</a> and compiling them: they just work (except that you have to fix the Makefile by substituting the java compiler flag -source 5.0 with -source 1.5).<br /><br />This problem really looks worth going into some official update repository for each bugged distro. I have already filed a <a href="https://bugzilla.novell.com/show_bug.cgi?id=468886">bug for openSUSE</a>, but I cannot confirm it for other distros. Could *you* (dear reader) check for it and send an appropriate bug report? =)<br /><br /><strong>UPDATE:</strong> the bug has been fixed! Thanks to all the people involved! =) If you're using openSUSE 11.1, you can fetch a backport from the Java repository (http://download.opensuse.org/repositories/Java:/packages/openSUSE_11.1/).https://fmontesi.github.io/2009/01/21/metaservice-enters-main-source-tree.htmlMetaService enters the main source tree2009-01-21T11:21:00+00:002009-01-21T11:21:00+00:00Fabrizio Montesihttps://fmontesi.github.ioToday I have moved MetaService from <a href="http://www.jolie-lang.org/">JOLIE</a>'s playground source tree to the main source tree, the one that gets installed when you type <i>ant install</i>.<br /><br />A short description for people that do not know what MetaService is: MetaService is a JOLIE service that allows you to dynamically bridge applications that speak different protocols (sodep, soap, http, etc.) or use different communication transports/mechanisms (sockets, local sockets, Java RMI, etc.). It has been developed as an answer to the <a href="http://plasma.kde.org/">Plasma project</a>'s needs to have a transparent means to introduce Plasma to the Service-oriented world. The project turned out to be so useful that I have built a Java library for interacting with and dynamically loading it (metaservice-java, to be found in trunk/support/metaservice-java) which we, as <a href="http://www.italianasoftware.com">italianaSoftware</a>, have already used in the scope of web application development (I can not say much more on this topic... yet ;).<br /><br />As a bonus, *nix users get a launcher script for MetaService when installing JOLIE with <i>ant install</i>. Just type <i>metaservice -h</i> and a help screen will welcome you.<br /><br />The script supports passing MetaService's input port location and protocol as parameters. This means that for KDE launching MetaService just became a matter of executing something like:<br /><br /><i>metaservice localsocket:/tmp/ksocket-$USER/metaservice</i><br /><br />Hooray for simplicity!https://fmontesi.github.io/2009/01/20/jolie-jobs-now-with-plasma.htmlJolie Jobs (now with Plasma)2009-01-20T11:05:00+00:002009-01-20T11:05:00+00:00Fabrizio Montesihttps://fmontesi.github.ioThe Jolie web site now sponsors a "Jobs List", which can be found from the <a href="http://www.jolie-lang.org/contribute.php">Contribute page</a>, also known as "What we lack for world domination". The list features some Junior Jobs, so it's a good starting point for people that are looking for ways to start contributing to Jolie. We are continuously filling in new jobs (there's *always* something to do, as in every project ;), so be sure to refresh it if you're interested. If you don't find anything that interests you, remember that you can always post to the <a href="mailto:jolie-devel@lists.sourceforge.net">mailing list</a>. =)<br /><br />Now that JOLIE supports message types, it is feasible (and not too hard) to make automatic generators for Plasma::Service description files. These jobs are listed, so if someone wants some cool tool for automatic type-safe code generation between Plasma and JOLIE sooner rather than later and to learn something more about how Plasma and JOLIE communicate, this is a good occasion to jump on the JOLIE<->Plasma revolution train. ;)https://fmontesi.github.io/2009/01/19/compiling-jolie-from-sources-in-windows.htmlCompiling JOLIE from sources in Windows now easier2009-01-19T14:33:00+00:002009-01-19T14:33:00+00:00Fabrizio Montesihttps://fmontesi.github.ioFor everyone using Windows out there: <span style="font-weight:bold;">compiling JOLIE from sources in Windows is not a pain anymore</span>!<br /><br />I've patched the build system so that it recognizes the running operating system and installs the appropriate launcher script (a shell script in *nix and a .bat script in Windows), so now having a working environment is far less "manual" than before. You can find the updated guide <a href="http://www.jolie-lang.org/download.php">here</a> (Windows -> From sources).https://fmontesi.github.io/2009/01/14/jolie-meets-message-typing.htmlJOLIE meets Message Typing!2009-01-14T18:00:00+00:002009-01-14T18:00:00+00:00Fabrizio Montesihttps://fmontesi.github.ioI've just finished to adapt and merge into <a href="http://www.jolie-lang.org/">Jolie</a>'s SVN the awesome work derived from <a href="http://www.elvisciotti.it/blog/2008/12/tesi-sistema-di-tipi-per-jolie/">Elvis Ciotti's thesis</a>. The job required some time, but we are definitely improving our development process with people that decide to make a thesis on JOLIE (it required much more than a day in the past); I think that we can improve even more, but that's another story. Elvis made some testing scripts, too, so I'm pretty sure that my refactoring did not introduce any regression and testing the result was a painless process. Way to go, Elvis. =)<br /><br />So, message typing: what's that? Let's have a preface and then look at an example!<br /><br /><h2>The problem</h2><br />In a service-oriented world applications communicate with each other. An application (say, A) can communicate with another one (say, B) by using the interface exposed by the latter. An example of an interface is "I accept messages for an operation called <span style="font-weight: bold;">sum</span>. You shall send me two numbers and I will return their sum to you.".<br />The problem here is that A and B are completely separated applications. They could even have been made with different programming languages. What does assure us that A is gonna respect the interface specs of B? Unfortunately, nothing does. We do not have any means to do that, as A is a black box to our eyes: we can not peek inside. We can only hope A has been statically checked against our interface before being run, or that A hasn't been purposefully made wrong to mess B up.<br /><br />So what can we do?<br /><br />When B receives a message, it could check at run-time that it conforms to the interface. If not, it should discard it immediately. That way we are sure to be safe, and that B's internal program doesn't get unexpected data.<br /><br /><h2>Example</h2><br />Let us implement B with Jolie's syntax for message types. The code would look as the following:<br /><br /><pre><br />type SumRequest:void {<br /> .x:int<br /> .y:int<br />}<br /><br />inputPort B {<br />Location: "socket://localhost:8000"<br />Protocol: sodep<br />RequestResponse:<br /> sum(SumRequest)(int)<br />}<br /><br />main {<br /> sum( request )( result ) {<br /> result = request.x + request.y<br /> }<br />}<br /></pre><br /><br />In the example B accepts messages containing two sub-nodes, x and y. An XML representation of a valid message is the following:<br /><br /><pre><br />&lt;request&gt;<br /> &lt;x&gt;5&lt;/x&gt;<br /> &lt;y&gt;10&lt;/y&gt;<br />&lt;/request&gt;<br /></pre><br /><br />Jolie will take care that B doesn't receive anything that doesn't conform to SumRequestType. Clients sending a malformed message would receive a "TypeMismatch" fault in return.<br /><br />Jolie types are pretty expressive, you can also play with the number of occurrencies. An example of a more complex type:<br /><br /><pre><br />// A type describing an article<br />type Article {<br /><br />// We want at least one author, but no upper limit<br /> .author[1,*]:void {<br /> .name:string<br /> .surname:string<br /> .age:int<br /> }<br /><br />// We accept from 5 to 15 pages<br /> .page[5,15]:string<br /><br />// ? is a shortcut for [0,1], i.e. giving a summary is optional<br /> .summary?:string<br /><br />/* .metadata is left completely free,<br /> * type checking is not performed on it<br /> */<br /> .metadata:any { ? }<br />}<br /></pre><br /><br />The code has just entered so it still may have some bugs, but it works already with some advanced tests I've conducted with current SVN.<br /><br />Enjoy! =)https://fmontesi.github.io/2009/01/12/jolies-new-website-is-up.htmlJolie's new website is up!2009-01-12T16:47:00+00:002009-01-12T16:47:00+00:00Fabrizio Montesihttps://fmontesi.github.ioJOLIE has a new and shiny website: <a href="http://www.jolie-lang.org/">www.jolie-lang.org</a><br /><br />The new site has a wiki which we are filling in with a lot of information, minute by minute. Some tutorials are already final and we are preparing demos and packages of source code examples.<br /><br />This step required some effort and time, but we now have a serious and stable basis to build our knowledge base upon (the backend of the website is quite powerful and allows for easy administration and data versioning).<br /><br />The mailing list and IRC channel are already active since some time, respectively jolie-devel@lists.sourceforge.net and #jolie on freenode, providing the means for asking about anything related to JOLIE and getting the attention of the JOLIE team.https://fmontesi.github.io/2008/12/15/jolie-meets-javascript.htmlJolie meets JavaScript2008-12-15T17:26:00+00:002008-12-15T17:26:00+00:00Fabrizio Montesihttps://fmontesi.github.ioStarting today, JOLIE services can exploit the JavaScript language!<br />As usual we are <span style="font-weight: bold;">not</span> speaking of mixing JOLIE code with another language, which would result in incomprehensible JOLIE programs. We are instead speaking of the insertion of another language in JOLIE's service-oriented paradigm, by means of the embedding mechanism (which we are detailing in our new, shiny tutorials, to be published really soon).<br /><br />Embedding a JavaScript service goes like this:<br /><br /><pre>// main.ol<br /><br />include "console.iol"<br /><br />// Standard JOLIE service declaration<br />outputPort Math {<br />RequestResponse: sum<br />}<br /><br />embedded {<br />// We load our JavaScript file as the JS service<br />JavaScript:<br /> "mathservice.js" in </span><span style="font-family:courier new;">Math</span><br /><span style="font-family:courier new;">}<br /><br />main<br />{<br /> // Now we can call JS as every other service type supported by JOLIE<br /> with( request ) {<br /> .addend[0] = 2;<br /> .addend[1] = 4;<br /> .addend[2] = 1;<br /> .addend[3] = 3<br /> };<br /> sum@</span><span style="font-family:courier new;">Math</span><span style="font-family:courier new;">( request )( response );<br /> println@Console( response ) // Will print 10<br />}<br /></pre><br />The JavaScript API for accessing structured JOLIE data is the same as the one for Java. Let us see how the Math service is implemented:<br /><pre><br />// mathservice.js<br /><br />function sum( request )<br />{<br /> var addends = request.getChildren( "addend" );<br /> var total = 0;<br /> for( var i = 0; i < addends.size(); i++ ) {<br /> total += addends.get( i ).intValue();<br /> }<br /> return total;<br />}<br /></pre><br /><br /><br />Voilà! Simple, isn't it?<br />Support for other scripting programming languages will be introduced in the future, stay tuned! =)https://fmontesi.github.io/2008/11/05/today-in-jolie.htmlToday, in JOLIE...2008-11-05T17:09:00+00:002008-11-05T17:09:00+00:00Fabrizio Montesihttps://fmontesi.github.io<span style="font-weight: bold;font-size:130%;" >Build system</span><br />JOLIE's SVN contains now an ant-powered build system that compiles all the protocols, extensions and libraries and then is able to install the resulting runtime environment in your computer in a painless way. Painless like "just type <span style="font-style: italic;">sudo ant install</span> in trunk/ and you're done".<br />The system is still beta-ish, but it's been tested by some people other than me. So now installing JOLIE from SVN is just:<br /><span style="font-family:courier new;"><br />svn co https://jolie.svn.sourceforge.net/svnroot/jolie/trunk</span><br /><span style="font-family:courier new;">sudo ant install</span><br /><br /><span style="font-weight: bold;">Warning</span>: I still have to implement <span style="font-style: italic;">ant uninstall</span>, so you'll have to delete /opt/jolie and /usr/local/bin/jolie by hand for uninstalling it.<br /><br />If you want to control the install directories, just edit the buildconfig/config.properties file, it's short and easy. Suggestions and reports on the build system topic are <span style="font-style: italic;">very </span>welcome, so please tell me of anything comes up to your mind / bugs you find.<br /><br />You'll notice a couple jars in the SVN, they're there because you probably don't have them in your system and they're usually not packaged by distros (e.g. Google Web Toolkit servlet jar, relaxngDatatype). It's Java, so recompiling them is useless. But if you want to use _your_ jar anyway, just change the library paths in config.properties.<br /><span style="font-size:130%;"><br /><span style="font-size:130%;"><span style="font-weight: bold;">Program checker upgrades</span></span></span><br /><span style="font-size:100%;">The JOLIE pre-execution program checker now punches you (emits an error) whenever you're trying to use the wrong communication pattern (you send a message, but you don't wait for a response when you're supposed to, or vice versa, etc.).</span><br /><br /><span style="font-weight: bold;font-size:130%;" >Concurrent request-response pattern performing in persistent channels</span><br />Whoa, this paragraph title is so long and confusing. Let's look at the problem by using an example: if you use the same, persistent socket with multiple threads (say, 2 threads) for performing a request-response pattern (i.e. you send a request and you receive a response back, like in HTTP), the messages risk to get messed up, because now when you get the first response you aren't sure which thread is expecting it.<br />HTTP pipelining solves that problem for you by sending the responses in the same order as you sent the requests. That implies that you must first send all your requests and then wait for all the responses. But in a true asynchronous system, you'd want simply to be able to send and receive things without introducing such slowing factors.<br />How does JOLIE solve that? We tag each request with an identifier and we require the response to equip the same tag. That way we can relate responses to their requesting threads. The internal handling of this is complicated, but it's all abstracted away at the language level... the programmer doesn't even need to know this mechanism.<br />In-memory communications, Java<->JOLIE channels and the SODEP protocol already support this new feature. We're currently thinking about possible solutions to introduce this on other protocols.<br /><br /><span style="font-weight: bold;font-size:130%;" >Website and documentation progress</span><br /><span style="font-size:100%;">The new website works are on schedule (i.e. we should publish it by this month or at least december, no later). We have tutorials (Claudio already made a lot of work.. my schedule fixes next week for full diving in user documentation writing), examples (I'll problably publish some of them in advance on the blog)</span> and so on.<br />A lot of in-code documentation has been polished up (especially in the support libraries for external programs interacting with JOLIE).<br /><br /><br />Mmmh I estimate a 50% rate of things I forgot to report... I should probably post more. ;)https://fmontesi.github.io/2008/10/10/opening-metaservice-to-java-metaservice.htmlOpening MetaService to Java: the MetaService-Java API layer.2008-10-10T10:57:00+00:002008-10-10T10:57:00+00:00Fabrizio Montesihttps://fmontesi.github.ioToday, MetaService-java hit Jolie's SVN. You can find it in /trunk/support/metaservice-java. Basically, MetaService-java is a Java API abstraction layer for interacting with MetaService, so that you can use it as if it were a Java object.<br /><br />This project was born for two reasons:<br />- it will be part of a solution for the integration of Java enterprise web applications with Service-Oriented Computing;<br />- it is a good example of how to implement an API abstraction layer to MetaService from an Object-oriented language, so its source code could be a useful reading for the Plasma::Service developers.<br /><br />I'll let the code (and its comments) and a simple example speak for themselves. They're in Java, but they should be pretty easy to understand even for people non-proficient with it. Example follows.<span style="font-weight: bold;"><br /><br /><br /><span style="font-family: courier new;"><span style="font-weight: bold;">MetaService metaService = new EmbeddedMetaService(); // Create a MetaService instance.<br /><br />// Set up access to a SOAP Web Service.<br />MetaServiceChannel myWebService = metaService.addRedirection(<br /> "MyWebService", // Resource name to assign<br /> "socket://www.mywebservice.com:80/", // Service location<br /> Value.create( "soap" ), // Protocol to use<br /> Value.create( "My metadata" ) // Descriptive metadata<br />);<br /><br />// Done! Let's communicate with it.<br />myWebService.send( "getNameById", Value.create( 4 ) );<br />Value response = myWebService.recv();<br />System.out.println( response.strValue() ); // Will print the name.<br /><br /><br /></span></span></span>The API is still to be refined, but pretty much usable already. =)https://fmontesi.github.io/2008/10/02/local-socket-support-in-jolie.htmlLocal socket support in JOLIE2008-10-02T13:12:00+00:002008-10-02T13:12:00+00:00Fabrizio Montesihttps://fmontesi.github.io<div xmlns='http://www.w3.org/1999/xhtml'>This fall looks good so far! A lot of JOLIE sub-projects are taking shape, and are going better than anticipated. But I'm blogging about something which has just landed on JOLIE's svn.<br/><br />JOLIE now supports local sockets (a.k.a. unix sockets). How to use them? Let's see it by comparison; a communication interface over tcp/ip sockets is exposed like the following:<br/><br /><code>inputPort MyInputPort {<br />Location: "socket://localhost:9000"<br />Protocol: soap<br />Interfaces: MyInterface<br />}</code><br/><br />Let's switch that to a local socket:<br/><br /><code>inputPort MyInputPort {<br />Location: "localsocket:/tmp/mylocalsocket"<br />Protocol: soap<br />Interfaces: MyInterface<br />}</code><br /><br />That's it! Use the localsocket scheme in the Location URI, and supply the right path to it.<br/><br /></div>https://fmontesi.github.io/2008/09/09/im-almost-back.htmlI'm (almost) back2008-09-09T13:01:00+00:002008-09-09T13:01:00+00:00Fabrizio Montesihttps://fmontesi.github.ioAfter three weeks full of time eating monsters (scary!) here and there, here I am back to posting.<br /><br />Sorry to people who mailed me in this period, some mails I could not answer to or I missed because my life kept me <span style="font-style: italic;">really</span> busy during last weeks. I'll try to reply asap.<br /><br />Fortunately, this week looks good so far, so I'll be back blogging JOLIE news soon!<br /><br />Meanwhile, if someone has ideas for cool plasmoids making use of <a href="http://www.open-collaboration-services.org/">open collaboration services</a> (apart those already listed in the specs draft of course) and/or knows something about how <a href="http://wiki.openid.net/REST/SOAP/HTTP_Bindings">this work</a> is proceeding, please let us know.https://fmontesi.github.io/2008/08/12/open-collaboration-services-have-been.htmlOpen collaboration services have been Jolied!2008-08-12T11:20:00+00:002008-08-12T11:20:00+00:00Fabrizio Montesihttps://fmontesi.github.io<a href="http://blog.karlitschek.de/2008/08/akademy-rocks.html">Frank</a>'s <a href="http://www.open-collaboration-services.org/socialdesktop.pdf">talk</a> was great: bringing the community into the KDE desktop is actually a great idea.<br />Even better, he's building up REST services for accessing the data! Of course, as we're speaking of services, my mind went directly to "Hey, these things are Joliable".<br /><br />I've already started collaborating with Frank in order to discuss the API and a set of specifications for publishing a machine-readable format for reaching said services.<br /><br />While I'm at it, someone could wonder "Just how difficult is to use these things with JOLIE?". The answer, of course, is <a href="http://jolie.sourceforge.net/videos/jolie-open-collaboration-services.mpeg">"damn easy" (screencast)</a>. ;)<br /><br />So, once we're finished with the JOLIE<->Plasma integration, expect nice graphical frontends to pop up. =)https://fmontesi.github.io/2008/08/09/are-we-converging-to-service-oriented.htmlAre we converging to a service-oriented experience?2008-08-09T09:21:00+00:002008-08-09T09:21:00+00:00Fabrizio Montesihttps://fmontesi.github.ioThe more I speak with people at Akademy, the more I'm convinced that contacting KDE to start the JOLIE<->Plasma integration thing has been the right decision.<br /><br />It looks like the whole KDE community (users and developers) is a perfect match to start "porting service-oriented computing to the masses". There is an incredible need for integration, communication, sharing and service accessibility. And when I see talks like the one given by Frank Karlitschek (KDE Community websites: The past, the present and a vision for the future) I get the feeling that we are all trying to converge to a service-oriented experience. We have the right tools, let's make that happen!<br /><br />I do really hope to clarify <span style="font-style: italic;">what</span> this means and <span style="font-style: italic;">how </span>we can do it with my presentation this afternoon, so... here I am checking that the demos are still working. Murphy's law, begone! ;)https://fmontesi.github.io/2008/08/09/going-to-akademy-with-battery-that.htmlGoing to Akademy... with a battery that lasts longer2008-08-09T09:18:00+00:002008-08-09T09:18:00+00:00Fabrizio Montesihttps://fmontesi.github.ioI'm flying to Akademy as I'm writing this post (but I'll be able to post it only when I'll be there).<br />Just turned on my laptop to have a look at my presentation, and.. surprise surprise, with KDE 4.1 my battery actually can last 20 minutes longer than with KDE 3.5. Plasma drains almost no power. Hooray for KDE 4!<br /><br />On the other side, my flight switch in Munich was not so easy... did it ever occur to you that your flying company "does not really know if your flight has been cancelled or not" ? =)https://fmontesi.github.io/2008/08/06/before-akademy.htmlBefore Akademy2008-08-06T08:22:00+00:002008-08-06T08:22:00+00:00Fabrizio Montesihttps://fmontesi.github.ioPhew, the temperature is so high here in Bologna that it's difficult even to think.<br />Nevertheless, this month is gonna be even hotter! So, here are some quickies of the current things that are happening.<br /><span style="font-size:130%;"><br /></span><span style="font-weight: bold;font-size:130%;" >Akademy, Akademy, Akademy...</span><br />I'm finishing my preparations for Akademy, and the presentation is coming out nicely. I'm trying to make it understandable even by people who does not know much about Service-oriented Computing. I will also demo a couple of service-oriented applications for KDE (of which you could have seen screencast/shots in the kde blogs), and explain how they work and how easy is to make them with JOLIE.<br />By the way, if you need/want to talk with me, I'll be at Akademy the 9th, the 10th and the 11th (the 11th only in the morning).<br /><br /><span style="font-weight: bold;font-size:130%;" >Rising interest</span><br />We, as <a href="http://www.italianasoftware.com/">italianaSoftware</a>, are receiving more and more interest in JOLIE by the business world. It looks like this could produce some open-source products. We shall see what comes up. The industry involvement has already produced some good things, like the sponsoring of the Google Web Toolkit integration in JOLIE (we are already using this in the open-source world, too: Echoes is based upon the JOLIE-GWT compatibility).<br /><br /><span style="font-weight: bold;font-size:130%;" >A lot of features to come in the next months</span><br />Some projects from the academic side are taking shape. A student from the University of Bologna, Davide Malagoli, is putting the basis for a complete bi-directional JOLIE<->XML translator. While JOLIE already supports the SOAP protocol, this is a great thing for the integration with tools designed for the Web Services technology. For instance, we will be able to generate automatically a WSDL document of a JOLIE program. As JOLIE supports more than just SOAP and TCP/IP sockets, we are already designing standard compliant WSDL elements to describe that.<br />We have got other two projects in early development, I will blog about them in the near future.<br /><br />Looks like this fall and winter I will have a lot of features to put in the source tree, and a lot of screencast/shots to make. =)<br />As for this coming week-end, see you all at Akademy!<br /><br /><br />P.S.: welcome back to the blog world, Aaron!<br /><br /><span style="font-weight: bold;">UPDATE!</span> Got the permission from the student to blog his name, so here it is. ;)https://fmontesi.github.io/2008/07/24/vision-distributed-presentation.htmlVision: a distributed presentation framework.2008-07-24T20:48:00+00:002008-07-24T20:48:00+00:00Fabrizio Montesihttps://fmontesi.github.ioVision is a proof of concept application (thanks aseigo for the initial suggestion), showing what can be easily obtained by using the service-oriented paradigm together with rich client applications.<br /><br /><span style="font-weight: bold;">What is Vision?</span><br />But, more importantly: what's a distributed presentation?<br /><br />Imagine that you are showing a presentation, and that someone wants to see what you're presenting... in his computer! To do so, he should connect in some way to your presentation. Whenever you change page (or make another relevant action, like changing document), the client should be notified and synchronized automagically.<br />That is exactly what Vision does. It forms a network between the presenter and the clients, keeping the clients synchronized with the presentation.<br />A screencast is better than a thousand words: <a href="http://jolie.sourceforge.net/videos/vision-previewer.avi">an example usage of vision with the previewer plasmoid and kpdf</a>.<br /><br />As you can see in the screencast, Vision already supports more than one viewer (there are shown kpdf and the previewer plasmoid, but we also already support okular).<br /><br />Another nice feature of Vision is that it forms a P2P network. A client acts also as a presentation server. Say that A is watching B's presentation. Now another client (C) can connect to A. Whenever A receives an event from B, it will now also send it to C.<br />This can be exploited, for example, in order to perform bandwidth load balancing.<br /><br />Note also that Vision makes use of <a href="http://jolie.sourceforge.net/?page=sodep">SODEP</a>, a binary protocol especially designed for service communications (it can, nevertheless, use all of the other JOLIE supported protocols, such as SOAP, HTTP, GWT-RPC...). Thus, the needed bandwidth is very small and the application can handle a lot of clients at the same time.<br /><br /><br /><span style="font-weight: bold;">Exposing Vision to other platforms</span><br />A great feature of JOLIE is that it separates the logical interfaces of a service from their deployment. Suppose that we want to extend Vision to support Bluetooth clients. The ideal solution would be to expose the same interface that we expose on the network via sockets to bluetooth. Luckily, doing that in JOLIE is very easy:<br /><br /><code><br />service PresenterBluetoothService<br />{<br />Location: "btl2cap://localhost:3B9FA89520078C303355AAA694238F07;name=Vision;encrypt=false;authenticate=false"<br />Protocol: sodep { .charset = "ISO8859-1"; .keepAlive = 1 }<br />Ports: PresenterInputPort<br />}<br /></code><br /><br />What do these lines mean?<br />Well, they're telling JOLIE to expose the <code>PresenterInputPort</code> interface (which is the Vision presenter interface) on the pointed bluetooth Location using the SODEP protocol to encode and decode data. You can see the whole presenter service code in the <a href="http://sourceforge.net/svn/?group_id=171960">JOLIE SVN repository</a> (/trunk/playground/vision).<br /><br />Guess what? <a href="http://jolie.sourceforge.net/videos/vision-remote.avi">It just works! (video)</a> And what's better than a mobile phone to test it?<br /><br />By the way:<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_I6cBVk6ZngU/SIjqKz3Nz_I/AAAAAAAAAAs/UmVTnVhruO4/s1600-h/goingakademy08.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp2.blogger.com/_I6cBVk6ZngU/SIjqKz3Nz_I/AAAAAAAAAAs/UmVTnVhruO4/s320/goingakademy08.png" alt="" id="BLOGGER_PHOTO_ID_5226684839004852210" border="0" /></a><br /><br />just in case you want to see more service-oriented goodness in KDE. =)https://fmontesi.github.io/2008/07/24/starting-up-another-blog-in-cauldron.htmlStarting up: another blog in the cauldron.2008-07-24T20:01:00+00:002008-07-24T20:01:00+00:00Fabrizio Montesihttps://fmontesi.github.ioHello, readers.<br />So here I am, another piece in the blogosphere. This blog will be about the development of <a href="http://jolie.sourceforge.net/">JOLIE</a>, a language for service-oriented programming, and all of its related works.<br /><br />As of this first post, this blog is on Planet KDE; the following says why.<br /><br />If you read the planet, you should have seen JOLIE cited here and there already. Basically I'm on Planet KDE because we, the JOLIE and KDE (Plasma especially) projects, are cooperating in order to bring the power of service-oriented computing (see also: service-oriented architecture, service-oriented programming, etc.) to the desktop.<br />This blog of mine is here also to explain what this means and will mean for the KDE desktop, and to show the practical results of this effort. Stay tuned with my blog if you want to know more!