Monday, July 18, 2011

Restlet for OSGi Remote Services

The ECF project released a new version of it's implementation of the OSGi 4.2 Remote Services Admin (RSA) standard.

ECF's provider architecture allows new distribution modules (known as providers) to easily be created and inserted underneath the ECF RSA implementation. The remote service consumer can now use the OSGi services model for accessing remote services...without regard to the underlying transport. If desired, one can create a service using one transport (e.g. r-osgi), test it using another (e.g. ecf generic) and deploy it using yet a third (e.g. your custom protocol)...even changing the distribution protocol for a remote service at runtime. The application requires no code changes to change providers. This is the beauty of standardization (no lockin) for distribution systems.

What does this have to do with Restlet?

Now that Restlet has been well integrated with OSGi it's now easy to use Restlet as a distribution provider module...and that's what I've just finished implementing. So now, one can use standard remote services API (i.e. OSGi remote services spec)...along with standardized enterprise remote services management (i.e. OSGi RSA spec)...and use Restlet/http+rest as the underlying distribution mechanism for exposing and accessing the remote service.

Here's a simple Restlet example

public class HelloResource extends ServerResource {
@Get("txt")
public String sayHello() {
return "Hello RESTful World";
}
}

Note the @Get("txt") annotation...this is Restlet annotation that defines that http access to this method.

To turn this into an OSGi remote service, all that's necessary is to expose the desired service as a service interface

public interface IHello {
@Get("txt")
public String sayHello();
}

and then add '...implements IHello' to the HelloResource class...e.g.

public class HelloResource extends ServerResource implements IHello
...

And that's it. Now (with the Restlet provider and ECF 3.5.1 remote service admin) when the HelloResource is exposed via Restlet, a IHello service is exported...and published for remote discovery (via Zookeeper, Zeroconf, DNSSD, SLP, file-based discovery, or some custom discovery). Then, as per the OSGi RSA specification, remote service consumers will discover the remote service and import the remote service as a IHello proxy (with RSA's support for versioning, etc). For the client/service consumer, all of the mechanics of import is handled by RSA...the programmer does not have to be concerned with it if they don't wish to be.

As an example, here's the code for a java-based client (assuming DS injection/binding):

void bindHelloService(IHello hello) {
// Now that we have discovered the service
// We'll use it. The implementation of sayHello
// remoting is provided by Restlet
String response = hello.sayHello();
System.out.println("Response to our hello was: '"+response+"'");
}

When run with the HelloResource server, the response is:

Response to our hello was: 'Hello RESTful World'

Of course, other clients (e.g. browser/javascript-based, php-based, etc) can also be used to access the same RESTful service.

Another nice aspect of this use of the ECF provider architecture is that other REST frameworks...e.g. JAX-RS, etc...can be used similarly...and even run concurrently in the same server, if desired.