Thursday, January 16, 2014

A service oriented Web Server

In this post I would like to discuss how a web server should be considered in the context of a Service Oriented Architecture or a distributed system in general. Usually, the web server is used as a tool which enables the possibility to public files and applications  under the HTTP protocol. Indeed, applications are developed by using some specific technology like PHP, Ruby, Java, etc. and then deployed into a web server for making them available on the web. The same approach is adopted also in Service Oriented Architecture where web services and orchestrators are developed in a given technology and then published in a web server together with the WSDL documents.

Here I want to share one of the results we obtained by developing Jolie as service oriented programming language. In Jolie the web server is just a service which provides its operations under an HTTP protocol and it follows the same programming rules we use for simple services and orchestrators. Here you can find the code of Leonardo, which is a web server completely developed in Jolie:

http://sourceforge.net/p/leonardo/code/HEAD/tree/trunk/leonardo.ol

You can download the code here and try to execute it by simply typing the following command in a shell:

      jolie leonardo.ol www/

where  www/ is the root folder where files are retrieved by Leonardo (remember to create it if it is missing). Now try to add a simple index.html file into the www folder like the following one:

<html>
<head/>
<body>
Hello World!
</body>
</html>

Then open your browser and set the url: http://localhost:8000 and you'll see the html page displayed in it. Try also to add images, css, html pages and subfolders into the www/ folder.
You can change the port by setting the Location_Leonardo parameter of the config.iol file. 

But,
          how can I program the server side behavior of a web application?

And here comes the service oriented approach. First of all let me introduce a new operation called test into the HttpInput by modifying its interface as it follows:

interface HTTPInterface {
RequestResponse:
default(DefaultOperationHttpRequest)(undefined),
test
}

Then let me add the implementation of the test operation into the main:

main {
[ default( request )( response ) {
/* ... code of the default operation */
} ] { nullProcess }

[ test( request )( response ) {
format = "html";
response = "Test!"
}] { nullProcess }
}

Operation test executes a very simple piece of code that is:

  • setting the response format to "html" in order to make the browser able to manage the response as an html file
  • set the response message with a simple html page

Now if we relaunch Leonardo and we point the browser to  http://localhost:8000/test we will see the page generated by the test operation. 

This is a pretty standard way for programming a web application: joining a web page to each operation. You can do it but I don't like it, even if in some cases it could be useful. I prefer to completely decouple the server side from the client side. I prefer to public the operation test as a JSON API which can be used by the client using an AJAX call. In this way I can program the server side as a service and the client side as a dynamic application. In order to this I modify the interface for introducing the message types which are very useful for catching message faults:
type TestType: void {
.message: string
}

interface HTTPInterface {
RequestResponse:
default(DefaultOperationHttpRequest)(undefined),
test( TestType )( TestType )
}

Then I modify the implementation of the test operation:

[ test( request )( response ) {
response.message = request.message + " RECEIVED!"
}] { nullProcess }

Finally, I just insert a little bit of Javascript on the client side by modifying the index.html:

<html><head>
  <script type="text/javascript" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>

  <script>
 function jolieCall( request, callback ) {
     $.ajax({
          url: '/test',
          dataType: 'json',
          data: JSON.stringify( request ),
          type: 'POST',
          contentType: 'application/json',
          success: function( data ){callback( data )}
     });
 }
 
 function afterResponse( data ) {
$( "#test" ).html( data.message )
 }
  </script>
  
</head>
<body>
  <div id="test">
<button onclick="jolieCall( {'message':'Ciao'}, afterResponse )">TEST</button>
  </div>
</body>
</html>

That's all! Try to open the index.html page on the browser and click on TEST button. It is worth noting that Jolie recognize the JSON format and sends back a JSON message.

Now, try to add other operations and create a more complex web application.
Have fun!


Thursday, January 2, 2014

Programming Service Oriented Recursion

Recursion in service oriented architectures is something unusual because it seems to be useless. So, why a post about recursion in SOA? I think the big result we can obtain from service oriented recursion is understanding service oriented programming paradigm nature and technologies. Recursion indeed, is a well known programming pattern hugely adopted by all the programmers in the world and its usage could reveal us some interesting features about a programming language. So, I want to use recursion in a SOA because I want to know more about SOA. Let's do it.

In the following example you can find the implementation of Fibonacci with Jolie.
[ You can copy it into a file and save it with name fibonacci.ol. Then run it typing the command
jolie fibonacci.ol ]


include "console.iol"
include "runtime.iol"

execution{ concurrent }

interface FibonacciInterface {
  RequestResponse:
    fibonacci( int )( int )
}

outputPort MySelf {
  Location: "socket://localhost:8000"
  Protocol: sodep
  Interfaces: FibonacciInterface
}


inputPort FibonacciService {
  Location: "socket://localhost:8000"
  Protocol: sodep
  Interfaces: FibonacciInterface
}

main
{
  fibonacci( n )( response ) {
    if ( n < 2 ) {
      response = n
    } else {
      {
fibonacci@MySelf( n - 1 )( resp1 )
|
fibonacci@MySelf( n - 2 )( resp2 )
      };
      response = resp1 + resp2
    }
  }
}




The code is very intuitive and simple. The outputPort MySelf defines the external endpoint to be invoked which corresponds to the input endpoint FibonacciService where the operation fibonacci is deployed. The invocations are performed in parallel (operator |) and they are blocking activities which wait until they receive a response from the invoked service
. You can invoke it by simply exploiting the following client which sends 10 as input parameter:

include "console.iol"

interface me {
  RequestResponse:
    fibonacci( int )( int )
}

outputPort Service {
  Location: "socket://localhost:8000"
  Protocol: sodep
  Interfaces: me
}

main
{
  fibonacci@Service( 10 )( result );
  println@Console( result )()
}

Starting from this simple example we can understand some interesting features:

server sessions represent recursive call stack layers: each invocation opens a new session on the server which represents a new layer in the recursive call stack.

loosely coupling: each invocation is separated from the others which guarantees that the value of n is not overwritten by different calls.

runtime outputPort binding: the binding of the output endpoint (MySelf)  must be achieved at runtime and not at deploy time in order to avoid frustrating programming issues like those reported here:  http://blogs.bpel-people.com/2007/02/writing-recursive-bpel-process.html.

the invocation stack could be distributed: you can imagine to deploy more than one fibonacci service and switch the invocations from one to another depending on some inner parameter such as, for example, the number of the open sessions. As an example consider the code modified as it follows:

init {
  getLocalLocation@Runtime()( global.location );
  MySelf.location = global.location;
  println@Console( MySelf.location )();
  global.count = 0
}

main
{
  fibonacci( n )( response ) {
    synchronized( lock ) {
      global.count ++;
      println@Console( "begin n="+n )();
      if ( global.count >= 100 ) {
MySelf.location  = "socket://localhost:8001"
      }
    };
    if ( n < 2 ) {
      response = n
    } else {
      {
fibonacci@MySelf( n - 1 )( resp1 ) 

fibonacci@MySelf( n - 2 )( resp2 )
      };
      response = resp1 + resp2;
      synchronized( lock ) {
global.count --;
println@Console( "end n="+n )();
if ( global.count < 100 ) {
 MySelf.location  = global.location
}
      }
    }
  }
}

Here the location of the outputPort MySelf can be changed dynamically during the execution. global.count stored the number of the current open sessions, if it is greater than 100 the location is changed into socket://localhost:8001 where the second fibonacci service is deployed. In this way you can easily create a chain of Fibonacci services whose sessions participate to a unique Fibonacci number recursive calculation.


Conclusions
Here I used service oriented recursion for programming a Fibonacci service with Jolie which can be invoked by external clients. This service could be also chained with other copies of it in order to obtain a distributed SOA for calulating the Fibonacci number recursively. Such an example could be an interesting reference point for understanding how service creation and invocations work in a SOA.