Getting started with R-OSGi

Quick Start

For a quick start, you can download the sample client and service distros. They contain a full configuration of Concierge, R-OSGi, and an example OSGi service that is accessed remotely. For easy evaluation of our technology, simply unpack the zips and start the client and the service on the same machine. The client is preconfigured to expect the service on localhost:9278 . If you want to run the example over a real network, you can configure the client by setting -Dch.ethz.iks.r_osgi.service.uri to the remote machine's URI (e.g., r-osgi://godot.inf.ethz.ch:9278 .

Creating your own deployment

First of all, install an OSGi framework implementation of your choice. It should be at least OSGi R3 compliant. You can use, for instance, our own R3 implementation Concierge .
Next, download the current version of R-OSGi from a sourceforge mirror .
If you want to use service discovery, you additionally have to download the current version of jSLP-OSGi from a sourceforge mirror and the service_discovery.slp bundle.
If you plan to use remote events, then you also need an EventAdmin implementation. Either your framework has one for you, or in case you are using an R3 framework (EventAdmin came out with R4), you can take the backport from Concierge. Due to its lightweight architecture, R-OSGi runs on every Java VM which implements at least J2ME CDC 1.0.

The big picture of R-OSGi

There are two very different use cases for R-OSGi. In some settings, you want to have full transparency. That means, your application is not able to distinguish between local and remote services. This is typically the case when you add distribution to an existing application.
What you do in these cases is to implement an Adapter Bundle on client side. This bundle is responsible for either starting a connection to the remote host or registering a discovery listener and decide to fetch services when they are discovered. The application itself will be able to operate on the service as if it was a local service, because it actually is a local service with the only difference that the logic resides on a remote machine and all calls to service methods are redirected through a remote method invocation scheme.
The registration of existing services for remote access through surrogate services is described in Advanced R-OSGi .

In some cases, the application is absolutely aware of distribution. In fact, the purpose of the application is to connect to remote services and operate on them. In this situation, the application wants to have full control over the connection and the access of the remote services.

Besides remote access to services, R-OSGi also features remote events. Once a remote connection is established, Events are forwarded to every connected peer that has a local registration of an EventHandler with matching topics. Thereby, the application are able to seamlessly make use of events that occurred on a remote machine. If it is required to distinguish between local and remote events, this is still possible since all forwarded events contain an additional property sender.uri which contains the URI of the peer that forwarded the event.

Registering a service for remote access (service provider side)

A registration with a proxy policy is done in the following way:
public class RobotActivator implements
	BundleActivator {

	public void start(BundleContext context) { Hashtable
		
		properties = new Hashtable();

		// this is the hint for R-OSGi that the service 
		// ought to be made available for remote access

		properties.put(RemoteOSGiService.R_OSGi_REGISTRATION,
			Boolean.TRUE);


		context.registerService(RobotDevice.class.getName(),
			new RobotDeviceImpl(), properties); 
	}

	public void stop(BundleContext context) throws
		Exception {

	}

}
				
Now, other R-OSGi enabled peers can connect to the peer and get access to the service.

Connect to a remote peer and get the service (service consumer side)

First of all, we have to get the RemoteOSGiService and establish a connection to a peer.


// get the RemoteOSGiService 
final ServiceReference sref = context.getServiceReference(RemoteOSGiService.class.getName());

if (sref == null) { 
	throw new BundleException("No R-OSGi found"); 
} 

remote = (RemoteOSGiService) context.getService(sref);

// connect 
remote.connect(new URI("r-osgi://fluidpaq1.inf.ethz.ch:9278"));

					

The connect method returns an array of RemoteServiceReference objects. These are the services which are currently available on the remote peer. One can use this array, or get a service by one of its interfaces, properties, etc. Just like it works in OSGi. Example:
final RemoteServiceReference[] srefs =
	remote.getServiceReferences(new URI("r-osgi://fluidpaq1.inf.ethz.ch:9278"),
	RobotDevice.class.getName(), null);
					

This remote reference has similar properties as a local service reference has. It can be used to access the service properties, and it is the key for getting access to a service:
RobotDevice robot = (RobotDevice) remote.getRemoteService(srefs[0]);
					

With the call of the getRemoteService method, a local proxy for the remote service is created. The service proxy is registered with the local service registry and can also be retrieved like a normal OSGi service. To get rid of a remote service, you can call ungetRemoteService .