Integration and Interoperability Facilities Framework: Client Libraries Framework

From Gcube Wiki
Revision as of 23:38, 21 May 2012 by Fabio.simeoni (Talk | contribs)

Jump to: navigation, search

gCube includes client libraries for many of its services and defines a general model for their design. The model requires that, regardless of specific service semantics and client-side technology stacks, all libraries support a common set of capabilities and adopt the same solutions to design issues that recur across their APIs.

However, the model does not specify how libraries are implemented to provide such capabilities and design solutions, nor does it mandate the low-level details of their APIs. The client library framework is a set of components that support the development of client libraries which comply with the model. Through code sharing, the framework reduces development costs and ensures the consistency and correctness of library implementations.

In this document, we assume some familiarity with design model and illustrate how the framework can be used to develop a model-compliant client library for a hypothetical foo service.

Distribution

The framework is layered across as a set of libraries, all of which are available in our Maven repositories as artifacts in the org.gcube.core group.

common-clients is the top layer of the framework, i.e. defines its general capabilities irrespective of particular service technologies. In this sense, common-clients is as general as the design model for client library. Lower layers of the framework adapt common-clients to specific service technologies. At the time of writing, gCore is the dominant technology stack for gCube services and their clients. Accordingly, common-gcore-clients is the only available specialisation of common-clients.

We thus assume that foo is a gCore service, i.e. a JAX-RPC Java service that can be deployed in one or more gCore containers on some gCube hosting nodes. We also assume that a client library for foo is developed as a Maven project, in line with the management model for client libraries. In this case, the library specifies a compile-time dependency on the framework in its POM, as follows:

<dependency>
 <groupId>org.gcube.core</groupId>
 <artifactId>common-gcore-clients</artifactId>
 <version>...</version>
 <scope>compile</version>
</dependency>

This dependency will bring common-clients and other required transitive dependencies on the compile-time classpath of the library. The version will vary over time and is 2.0.0 at the time of writing. Even though the library will depend directly on classes and interfaces defined in common-clients, the library can safely omit a direct dependency on it.

The library will also have dependency on the stub library of foo, which we assume is also available as a Maven artifact, e.g.:

<dependency>
 <groupId>org.gcube.samples</groupId>
 <artifactId>foo-stubs</artifactId>
 <version>...</version>
 <scope>compile</version>
</dependency>


Framework-dependencies.png

Overview

The main design pattern defined by the model is that of a service proxy. This requires that foo endpoints be represented in the library by an interface Foo and an implementation DefaultFoo. The former defines methods that the latter implements against the API of the foo stubs. For example, if FooPortType is the type of foo stubs and bar() one of their String-valued methods:

public interface Foo {
 
  String bar() throws ...;
 
}
 
public class DefaultFoo implements Foo {
 
  public String bar() throws ... {
 
   ...FooPortType endpoint...
 
   try {
 
     return endpoint.bar();
 
   }
   catch(...) { //fault handling
 
   }
 
}

While the pattern is straightforward, complexity arises from:

  • the requirements of particular methods. The model specifies how Foo and DefaultFoo should be designed when methods take or return given types of values (e.g. streams), handle faults with given semantics (e.g. service contingencies), or execute under a given operational semantics (e.g. asynchronously).
  • the configuration and operation of proxies. The model requires proxies to work in either one of two modes:
  • in direct mode, proxies obtain the address of given service endpoints from clients and execute all their methods against those endpoints. Clients model addresses as W3EndpointReferences or - depending on wether foo is a stateless or stateless service - as (host, port) pairs or (host, port, key) triples. Since stubs APIs for gCore services model addresses as EndpointReferenceTypes, the library must implement address conversion and address validation;
  • in discovery mode, proxies identify service endpoints from queries to gCube discovery services and are responsible for using the results in a fault-tolerant and optimised manner. Queries must be high-level value-objects and the library must implement specific binding and caching strategies for query results.

The framework offer limited support for the implementation of Foo‘s API, as there are external libraries that provide it when and where it is required (e.g. the streams library, the scope library, or the security library). However, the framework includes the common faults and callback components defined by the model. We discuss these components and their placement within the framework [#Additional Support[here]].

On the other hand, the framework can meet all proxy configuration and operation requirements on behalf of the library. We give a tour below of the support available in this area and expand on individual components in later sections.

Calls and Delegates

Plugins

Queries

Additional Support