Amdatu Remote

The Amdatu Remote subproject provides implementations of the OSGi Remote Services 1.0 (OSGi Enterprise R5) and Remote Service Admin 1.1 (OSGi Enterprise R6) specifications. OSGi specifications can be downloaded via the OSGi Alliance homepage

Project Info

 

Software Design

Amdatu Remote provides component implementations along the lines of the roles and entities as defined by the Remote Service Admin specification (see Figure 122.1) . Every bundle provides a single discovery, topology manager of remote service admin service implementation. This means different components can be mixed and matched as required ( image source: Figure 122.1; OSGi Enterprise Release 5).

 

Discovery Components

Discovery components are responsible for publishing exportable as well as discovering importable service endpoints across frameworks. All specification mandated interaction between discovery components and topology manager is based on the exchange of EndpointDescription instances across EndpointListener and EndpointEventListener service interfaces.  

HTTP endpoint discovery (Configured)

Bundleorg.amdatu.remote.discovery.configured/0.1.0
Description

OSGi RSA 1.1 discovery implementation that uses (pre)configured HTTP endpoints that provide the actual service discovery based on HTTP/XML (using the extender format as defined in the RSA specification).

Capability

osgi.remoteserviceadmin.discovery; protocols:List<String>="configured"; version:Version="1.1"

Configuration

The service can both be configured using OSGi environment properties and using Configuration Admin. In case both methods are used the latter takes precedence. The service PID for this service is "org.amdatu.remote.discovery.configured". The following properties can be used:

org.amdatu.remote.discovery.configured.endpoints

One or more remote endpoint discovery URLs as a comma-separated string. The URLs should follow the following pattern: http://host:port/endpoint-path. Where host and port are the host and port of the remote configured discovery endpoint, and endpoint-path the path as configured with org.amdatu.remote.discovery.configured.path for the remote configured discovery endpoint. For example: http://endpoint1:8080/org.amdatu.remote.discovery.configured,http://endpoint2:8080/org.amdatu.remote.discovery.configured.

org.amdatu.remote.discovery.configured.host

Host name or IP Address to use for the local discovery endpoint. If not specified the service will fallback to the "org.apache.felix.http.host" environment property and otherwise to "localhost".

org.amdatu.remote.discovery.configured.portPort number to use for the local discovery endpoint. If not specified the service will fallback to the "org.osgi.service.http.port" environment property and otherwise default to "8080".
org.amdatu.remote.discovery.configured.pathServlet path to use for the local discovery endpoint. If not specified the service will default to "org.amdatu.remote.discovery.configured".
org.amdatu.remote.discovery.configured.schedule

Time period in seconds between scheduled polls to the discovery endpoints. Default is 10s.

org.amdatu.remote.discovery.configured.connecttimeout

Timeout in ms to use when connecting to a discovery endpoint. Default is 5000ms.

org.amdatu.remote.discovery.configured.readtimeout

Timeout in ms to use when reading from a discovery endpoint. Default is 5000ms.

 

HTTP endpoint discovery (ZooKeeper)

Bundleorg.amdatu.remote.discovery.zookeeper/unreleased
Description

OSGi RSA 1.1 Discovery implementation that uses a ZooKeeper backend to discover HTTP endpoints that provide the actual service discovery based on HTTP/XML (using the extender format).

Capability

osgi.remoteserviceadmin.discovery; protocols:List<String>="zookeeper"; version:Version="1.1"

Configuration

The service can both be configured using OSGi environment properties and using Configuration Admin. In case both methods are used the latter takes precedence. The service PID for this service is "org.amdatu.remote.discovery.zookeeper". The following properties can be used:

org.amdatu.remote.discovery.zookeeper.host

Host name or IP Address to use for the local discovery endpoint. If not specified the service will fallback to the "org.apache.felix.http.host" environment property and default to "localhost".

org.amdatu.remote.discovery.zookeeper.portPort number to use for the local discovery endpoint. If not specified the service will fallback to the "org.osgi.service.http.port" environment property and default to "8080".
org.amdatu.remote.discovery.zookeeper.pathServlet path to use for the local discovery endpoint. If not specified the service will default to "org.amdatu.remote.discovery.zookeeper".
org.amdatu.remote.discovery.zookeeper.connectstringZooKeeper connection string that contains one or more comma-separated hostname:port combinations and an optional chroot. Example: "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002/app/a".
org.amdatu.remote.discovery.zookeeper.rootpathZooKeeper path from the (ch)root that must used as its registry. If not specified the service will default to "/".
org.amdatu.remote.discovery.zookeeper.ticktime

ZooKeeper ticktime in milliseconds that must be used for the connection. If not specified the service will default to "2000".

org.amdatu.remote.discovery.zookeeper.schedule

Time period in seconds between scheduled polls to the discovery endpoints. Default is 10s.

org.amdatu.remote.discovery.zookeeper.connecttimeout

Timeout in ms to use when connecting to a discovery endpoint. Default is 5000ms.

org.amdatu.remote.discovery.zookeeper.readtimeout

Timeout in ms to use when reading from a discovery endpoint. Default is 5000ms.

 

HTTP endpoint discovery (Etcd)

Bundleorg.amdatu.remote.discovery.etcd/unreleased
Description

OSGi RSA 1.1 Discovery implementation that uses an Etcd backend to discover HTTP endpoints that in provide the actual service discovery based on HTTP/XML (using the extender format).

Capability

osgi.remoteserviceadmin.discovery; protocols:List<String>="etcd"; version:Version="1.1"

Configuration

The service can both be configured using OSGi environment properties and using Configuration Admin. In case both methods are used the latter takes precedence. The service PID for this service is "org.amdatu.remote.discovery.etcd". The following properties can be used:

org.amdatu.remote.discovery.etcd.host

Host name or IP Address to use for the local discovery endpoint. If not specified the service will fallback to the "org.apache.felix.http.host" environment property and default to "localhost".

org.amdatu.remote.discovery.etcd.portPort number to use for the local discovery endpoint. If not specified the service will fallback to the "org.osgi.service.http.port" environment property and default to "8080".
org.amdatu.remote.discovery.etcd.pathServlet path to use for the local discovery endpoint. If not specified the service will default to "org.amdatu.remote.discovery.etcd".
org.amdatu.remote.discovery.etcd.connecturlEtcd connection url. Example: "http://127.0.0.1:4001". 
org.amdatu.remote.discovery.etcd.rootpathEtcd path from the root that must be used as its registry. If not specified the service will default to "/"
org.amdatu.remote.discovery.etcd.schedule

Time period in seconds between scheduled polls to the discovery endpoints. Default is 10s.

org.amdatu.remote.discovery.etcd.connecttimeout

Timeout in ms to use when connecting to a discovery endpoint. Default is 5000ms.

org.amdatu.remote.discovery.etcd.readtimeout

Timeout in ms to use when reading from a discovery endpoint. Default is 5000ms.

 

HTTP endpoint discovery (Bonjour)

Bundleorg.amdatu.remote.discovery.bonjour/0.1.0
Description

OSGi RSA 1.1 Discovery implementation that uses Bonjour for discovering HTTP endpoints that in turn provide the actual service discovery based on HTTP/XML (using the extender format). The Bonjour discovery uses JmDNS.

Capability

osgi.remoteserviceadmin.discovery; protocols:List<String>="bonjour"; version:Version="1.1"

Configuration

The service can both be configured using OSGi environment properties and using Configuration Admin. In case both methods are used the latter takes precedence. The service PID for this service is "org.amdatu.remote.discovery.bonjour". The following properties can be used:

org.amdatu.remote.discovery.bonjour.host

Host name or IP Address to use for the local discovery endpoint. If not specified the service will fallback to the "org.apache.felix.http.host" environment property and default to "localhost".

org.amdatu.remote.discovery.bonjour.port

Port number to use for the local discovery endpoint. If not specified the service will fallback to the "org.osgi.service.http.port" environment property and default to "8080".

org.amdatu.remote.discovery.bonjour.pathServlet path to use for the local discovery endpoint. If not specified the service will default to "org.amdatu.remote.discovery.bonjour".
org.amdatu.remote.discovery.bonjour.schedule

Time period in seconds between scheduled polls to the discovery endpoints. Default is 10s.

org.amdatu.remote.discovery.bonjour.connecttimeout

Timeout in ms to use when connecting to a discovery endpoint. Default is 5000ms.

org.amdatu.remote.discovery.bonjour.readtimeout

Timeout in ms to use when reading from a discovery endpoint. Default is 5000ms.

HTTP endpoint discovery (SLP)

Bundleorg.amdatu.remote.discovery.slp/0.1.0
Description

OSGi RSA 1.1 Discovery implementation that uses SLP for discovering HTTP endpoints that in turn provide the actual service discovery based on HTTP/XML (using the extender format). The SLP discovery uses LiveTribe-SLP.

Notes:

  • The LiveTribe-SLP library does not support SLP over IPv6. This causes problems on some dual-stack machines (we know of OSX). Starting the JVM with -Djava.net.preferIPv4Stack=true solves this.
Capability

osgi.remoteserviceadmin.discovery; protocols:List<String>="slp"; version:Version="1.1"

Configuration

The service can both be configured using OSGi environment properties and using Configuration Admin. In case both methods are used the latter takes precedence. The service PID for this service is "org.amdatu.remote.discovery.slp". The following properties can be used:

org.amdatu.remote.discovery.slp.host

Host name or IP Address to use for the local discovery endpoint. If not specified the service will fallback to the "org.apache.felix.http.host" environment property and default to "localhost".

org.amdatu.remote.discovery.slp.port

Port number to use for the local discovery endpoint. If not specified the service will fallback to the "org.osgi.service.http.port" environment property and default to "8080".

org.amdatu.remote.discovery.slp.pathServlet path to use for the local discovery endpoint. If not specified the service will default to "org.amdatu.remote.discovery.slp".
org.amdatu.remote.discovery.slp.schedule

Time period in seconds between scheduled polls to the discovery endpoints. Default is 10s.

org.amdatu.remote.discovery.slp.connecttimeout

Timeout in ms to use when connecting to a discovery endpoint. Default is 5000ms.

org.amdatu.remote.discovery.slp.readtimeout

Timeout in ms to use when reading from a discovery endpoint. Default is 5000ms.

Local Discovery Extender

Bundleorg.amdatu.remote.discovery.extender/0.1.0
Description

OSGi RSA 1.1 Discovery implementation that provides the osgi.extender capability that allows bundles to provide endpoint descriptions through XML files.

Capability

osgi.extender; osgi.extender=osgi.remoteserviceadmin; version:Version="1.1"; uses:="org.osgi.service.remoteserviceadmin",
osgi.remoteserviceadmin.discovery; protocols:List<String>="local"; version:Version="1.1"

Configuration

The service does not provide or need any configuration.

Topology Manager Components

Topology Managers are, based on locally registered services and remotely discovered services, responsible for controlling the imports and exports of services using registered RemoteServiceAdmin services to do so. All interaction with discovery components is based on the exchange of EndpointDescription instances across EndpointListener and EndpointEventListener service interfaces.

Promiscuous Topology 

Bundleorg.amdatu.remote.topology.promiscuous/0.1.0
Description

OSGi RSA 1.1 Topology Manager implementation of a that implements a promiscuous policy. This policy basically exports any exportable service that matches an exports filter and imports any importable service that matches another imports filter.

Capability

osgi.remoteserviceadmin.topology; policy:String="promiscuous"; version:Version="1.1"

Configuration

The service can both be configured using OSGi environment properties and using Configuration Admin. In case both methods are used the latter takes precedence. The service PID for this service is "org.amdatu.remote.topology.promiscuous". The following properties can be used:

org.amdatu.remote.topology.promiscuous.imports

Filter that determines whether a discovered endpoint will be imported. By default only remote endpoints are matched and the configured filter will be augmented to do the same.

example: (&(!(endpoint.framework.uuid=<framework uuid>))<configured filter>)

org.amdatu.remote.topology.promiscuous.exports

Filter that determines whether a exportable service will be exported. By default only local services with exported interfaces are matched and the configured filter will be augmented to do the same.

example: (&(service.exported.interfaces=*)<configured filter>)


Remote Service Admin 
Components

Remote Service Admin components are passive components that register as RemoteServiceAdmin services and are actually capable of importing and exporting certain services as defined by configuration type and constraint by intents. Interested parties may register themselves as RemoteServiceAdminListener to be able to receive import/export events as they occur.

Admin HTTP/Json

Bundleorg.amdatu.remote.admin.http/0.1.1
Description

OSGi Remote Service Admin 1.1 implementation that implements the "org.amdatu.remote.admin.http" configuration type using HTTP transport. The remote service invocation uses a JSON representation that holds the method signature ("m") and the arguments array ("a").

Sample request
===>
POST /endpoint HTTP/1.1
Host: localhost
{
  "m":"foo(Ljava/lang/String;)I;"        # Signature is <methodname>([ <argumenttype> ])<returntype> using VM type encoding.
  "a":[ "Hello World" ]                  # Array of arguments (JSON values)
}
 
<=== return value
HTTP/1.1 200 OK
{ "r":"hello world"} # Return value (JSON value) 

<=== null return
HTTP/1.1 200 OK
{ "r":null}

<=== void return
HTTP/1.1 200 OK
{} 

<=== exception
HTTP/1.1 200 OK
{"e":{"type":"java.lang.IllegalArgumentException","msg":"Invalid value!","stacktrace":[]}}

<=== request issue
HTTP/1.1 4xx

<=== server issue
HTTP/1.1 5xx

Be aware that this implementation currently supports primitive types, most of the collection types supported by Java (Lists, Sets and Maps) as well as "simple" POJOs having a default constructor and public getters and setters. There is limited support for dealing with exceptions thrown in remote services: the exception type itself has to be available at the calling side.

Capability

osgi.remoteserviceadmin.distribution; configs:List<String>="org.amdatu.remote.admin.http"; version:Version="1.1"

Configuration

The service can both be configured using OSGi environment properties and using Configuration Admin. In case both methods are used the latter takes precedence. The service PID for this service is "org.amdatu.remote.admin.http". The following properties can be used:

org.amdatu.remote.admin.http.hostHost name or IP Address to use for service endpoints. If not specified the service will fallback to the "org.apache.felix.http.host" environment property and default to "localhost".
org.amdatu.remote.admin.http.portPort number to use for service endpoints. If not specified the service will fallback to the "org.osgi.service.http.port" environment property and default to "8080".
org.amdatu.remote.admin.http.pathServlet path to use for service endpoints. If not specified the service will default to "org.amdatu.remote.admin.http".
org.amdatu.remote.admin.http.connecttimeout
Timeout in ms to use when connecting to a remote service endpoint. If not specified the service will default to 5000ms.
org.amdatu.remote.admin.http.readtimeout
Timeout in ms to use when invoking a remote service endpoint. If not specified the service will default to 60000ms.

Admin HTTP/Avro

Bundleorg.amdatu.remote.admin.http.avro/0.1.0 (unreleased)
Description

OSGi Remote Service Admin 1.1 implementation that implements the "org.amdatu.remote.admin.http.avro" configuration type using HTTP transport. The remote service invocation uses Apache Avro based serialization

Capability

osgi.remoteserviceadmin.distribution; configs:List<String>="org.amdatu.remote.admin.http.avro"; version:Version="1.1"

Configuration

The service can both be configured using OSGi environment properties and using Configuration Admin. In case both methods are used the latter takes precedence. The service PID for this service is "org.amdatu.remote.admin.http". The following properties can be used:

org.amdatu.remote.admin.http.hostHost name or IP Address to use for service endpoints. If not specified the service will fallback to the "org.apache.felix.http.host" environment property and default to "localhost".
org.amdatu.remote.admin.http.portPort number to use for service endpoints. If not specified the service will fallback to the "org.osgi.service.http.port" environment property and default to "8080".
org.amdatu.remote.admin.http.pathServlet path to use for service endpoints. If not specified the service will default to "org.amdatu.remote.admin.http".
org.amdatu.remote.admin.http.connecttimeout
Timeout in ms to use when connecting to a remote service endpoint. If not specified the service will default to 5000ms.
org.amdatu.remote.admin.http.readtimeout
Timeout in ms to use when invoking a remote service endpoint. If not specified the service will default to 60000ms.

Component Deployment

Deployment of Amdatu Remote follows the selection of the implementing bundles of the desired components. By design (and specification) multiple components, and thus bundles, of each role may be deployed. However a minimal deployment involves at least one of each. This is shown in the deployment diagram below, that also illustrates the implicit requirement importing and exporting parties require a shared service api to be deployed.

 

Getting Started

Because OSGi Remote Service cleanly hooks into the existing service registry, developing applications that can works with Remote Services should be no problem for anyone familiar with OSGi development. As long as the service interface represent stateless contracts with pass-by-value intent there is nothing to worry about. Below a simple example taken from the demo project that can be found in the source repository

Implementing a simple chat client

A simple chat client implements two simple interfaces for message exchange. In this code there is nothing specific to Remote Services! 

public interface MessageReceiver {
	void receive(String sender, String message);
}
 
public interface MessageSender {
	void send(String message);
}


public class ChatClient implements MessageSender, MessageReceiver {
  ...
}

The activator marks the receiver interface as an exported interface. This specifies that the service may be exported using that interface.

@Override
public void init(BundleContext context, DependencyManager manager) throws Exception {
    Dictionary<String, Object> props = new Hashtable<String, Object>();
    props.put(RemoteConstants.SERVICE_EXPORTED_INTERFACES, MessageReceiver.class.getName());
    manager.add(createComponent()
        .setInterface(new String[] { MessageSender.class.getName(), MessageReceiver.class.getName() }, props)
        .setImplementation(ChatClient.class)
        .add(createServiceDependency()
            .setService(MessageReceiver.class)
            .setRequired(false)
            .setCallbacks("addReceiver", "removeReceiver")
        ));
}

 

Thats all folks! Multiple instances of the ChatClient, deployed into different containers, can now see and invoke each other's receivers. 

Deploying the simple chat client

 

Deployment is no different from any other OSGi application. Simply deploy the Amdatu Remote components and their requirements along with the remotable services. The example below is taken from the Chat Demo bnd run file found in the source repository.

START LEVEL 1
   ID|State      |Level|Name
    0|Active     |    0|System Bundle (4.2.1)
    1|Active     |    1|org.osgi.service.remoteserviceadmin (6.0.0.201403170857)
    2|Active     |    1|osgi.enterprise (5.0.0.201203141834)
    3|Active     |    1|Apache Felix Configuration Admin Service (1.8.0)
    4|Active     |    1|Apache Felix Dependency Manager (3.1.0)
    5|Active     |    1|Apache Felix Dependency Manager Shell (3.0.1)
    6|Active     |    1|Apache Felix Gogo Command (0.12.0)
    7|Active     |    1|Apache Felix Gogo Runtime (0.10.0)
    8|Active     |    1|Apache Felix Gogo Shell (0.10.0)
    9|Active     |    1|Apache Felix Http Jetty (2.2.2)
   10|Active     |    1|Apache Felix Log Service (1.0.1)
   11|Active     |    1|Apache Felix Metatype Service (1.0.6)
   12|Active     |    1|Amdatu Remote - Discovery (Bonjour) (0.1.1)
   13|Active     |    1|Amdatu Remote - Remote Service Admin (HTTP) (0.1.1)
   14|Active     |    1|Amdatu Remote - Topology Manager (Promiscuous) (0.1.1)
   15|Active     |    1|Amdatu Remote - Chat Demo api (0.1.0)
   16|Active     |    1|Amdatu Remote - Chat Demo impl (0.1.0)