You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 13 Next »

Introduction

iPOJO is an extensible, service-oriented component model implemented on the top of the OSGi™ framework that aims to simplify the development of OSGi™ applications. iPOJO follows a POJO-based component approach using external metadata to describe how POJO components should be managed by the iPOJO runtime. Some of the standard features of iPOJO include automatic service dependency management, service publication, and configuration property injection.

Another standard feature of iPOJO is component factories. As stated previously, an iPOJO component is described by its metadata. In iPOJO, the metadata describes a component type. For each component type, iPOJO registers a factory service that can be used to create instances of the component type described by the metadata.

In addition to these features, iPOJO also provides a service-oriented composition model. iPOJO's composition model tries to merge:

  • Component-based structural composition and
  • Dynamic service flexibility.

This document presents iPOJO's structural service composition concepts and a simple example to illustrate them.

Motivation

Component composition occurs in two fashions:

  • Horizontal composition: A provided interface from one component instance is bound to corresponding required interface of another component instance.
  • Vertical composition: Component instances are contained inside of another component instance.

Typically, at runtime, a component composition is an unmodifiable set of connected component instances. The main motivation of iPOJO is to remove this limitation and introduce a more dynamic and flexible approach. iPOJO achieves its goals by applying service-oriented concepts to component orientation. Dynamic horizontal composition is supported by iPOJO's dependency injection mechanism described elsewhere link? and dynamic vertical composition is supported by iPOJO's structural composition mechanism described below.

iPOJO structural composition tries to merge structural component composition and dynamic service flexibility to allow:

  • Run-time/late binding.
  • Service run-time dynamics.
  • Implementation evolution.

The result is a flexible, yet easy-to-use service-oriented component model.

Structural Service Composition

iPOJO essentially provides a kind of service-oriented architecture definition language (ADL). This service-oriented ADL allows you to define composite components. The main differences between a traditional component-oriented composite and an iPOJO composite is that the iPOJO composite's constituent entities are described in terms of abstract service interfaces instead of specific component types/instances and bindings are inferred from dependency metadata data rather than explicitly declared. This approach means that composite components in iPOJO are not concrete component implementations; rather, they are abstract implementations whose precise implementation selection is deferred until run time.

Unlike a POJO component in iPOJO that has code associated with it, a composite component is completely described by its metadata. Similar to a POJO component, however, the metadata describes a component type for which iPOJO registers a factory service that can be used to create instances of the composite component.

A composite can be thought of as a service registry or a scoping mechanism of the global OSGi™ service registry. Composites can contain other composite, creating a hierarchy of service registries. The OSGi™ service registry is the root composite.

A composite can:

  • Contain services.
  • Import services from its parent composite.
  • Provide services to its parent composite.

A service contained in a composite is a sub-service, which is isomorphic to sub-components in traditional component-oriented composites. A sub-service is a service instance created from a component factory. Sub-services are not visible outside of the composite and can only see other services that reside in the composite service registry. The set of services in the composite service registry are all sub-services as well as all imported services. Sub-services are not aware of the fact that they are inside of a composite and provide and use services normally within their composite.

"Hello World" Composite

This section describes a simple composite example that imports an aggregated set of services from the parent composite, contains 3 sub-services, and provides one service to the parent composite.

The "Killer" Application

To illustrate composite we design a "Hello World" application named HelloComposition. This application offers a service for writing a "Hello" message to each person listed in a Directory service. Each person is published as a service and is used by the composition to get the name of the person in order to write the message.

The composite provides the HelloDispatcher service:

public interface HelloDispatcher {
    public void dispatch();
    public String getLanguage();
    public List<Person> getPersons();
}

Application Design

To implement this application, we can reuse existing service implementation. Indeed, we have on the shelf 3 "instantiable" services.

  • an Hello Service : returning a Hello message
  • a Directory service : aggregating Person services to create a Directory
  • a Dispatch Service : requiring an Hello Service and a Directory Service to write Hello Service to person contained in the Directory.

An "instantiable" service is a service that we can instantiate through a Factory. The following code snippets show the different service specification:

public interface Hello {
              public void hello(String name);
	      public String getLanguage();
}
public interface Directory {
                public Person getPerson(String name);
                public List<Person> getPersons();
                public void addPerson(String name, String adress);
                public void removePerson(String name);
}
public interface Person {
       public String getName();
       public String getAddress();
}
public interface Dispatch{
                public void say();
}

So to design our application we will use these services to obtain the following applications.

Application Description

To describe our application, we will use the iPOJO ADL:

<composite name="HelloComposition" factory="Hello">
                <import specification="org.apache.felix.ipojo.composition.ex1.person.Person"  aggregate="true"/>
                <provides specification="org.apache.felix.ipojo.composition.ex1.compo.HelloDispatcher"/>
                <service specification="org.apache.felix.ipojo.composition.ex1.hello.Hello"/>
                <service specification="org.apache.felix.ipojo.composition.ex1.say.Dispatcher"/>
                <service specification="org.apache.felix.ipojo.composition.ex1.directory.Directory"/>
</composite>

This application is described by a composite. This composite is expressed in term of service specification:

  • Imports all available Person service in the parent composite.
  • Provides the Hello Dispatch to the parent composite.
  • Instantiates inside the composition a Hello service, a Dispatcher Service and a Directory Service.

The providing is based on a method delagation on available specifications as depict in the following image :

Packaging

A composite is described in the metadata.xml file of an iPOJO bundle. It is possible to create an instance of the composition in this file:

<instance component="Hello" name="hello-composition"/>

 To avoid packages issues, all used "specification" are imported by the bundle containing the composition.

Runtime

Imagine that at runtime you have:

  • Two factories that can create Hello service providers
  • A factory that can create Dispatch service providers
  • A factory that can create Directory service  providers
  • Several Person services

When you deploy the composition, iPOJO will manage your application:

  • The composite will import all available services.
  • The composite will instantiate a Hello provider, one Directory provider and one SayHello provider inside the composite.
  • The composite will provides the HelloDispatcher service.
    The service providing is made by delegating service invocation on services contained in the composition. If the mapping cannot be infered, the composition is considered as invalid and cannot be started.
    If the factory which creates the Hello provider disappears, the composite will automatically used the second one to re-instantiate the service. If the second one disappears too, the composite will be invalidate (the exported service will be removed), and will wait for the apparition of a new consistent factory. Hello service implementation can be composition too.

When a person service appears this service is automatically inserted inside the composite, as well as if a person service disappear this service is automatically removed.

You can see a demo of this composition here

Composition Features

Service Import

The composite can import services from the parent composite. Each import is describe by an import element in the composite description. An import needs to specify targeted specification. Moreover, an import can be:

  • Simple / aggregate: one provider is imported / all available providers are imported
  • Mandatory /optional: if no providers are available, the composite is invalidated if the import is mandatory
  • Filtered: an import can filter providers
<import specification="...Hello" optional="true" aggregate="true" filter="(language=en)"/>

Service Providing

The composite can provide services from the composite to the parent composite. Each service providing is described by an 'provides' element in the composite description. A 'provides' needs to specify provided specification.

The service providing is realized by delegating invocation on servuces contained in the composition. If the delegating mapping cannot be discovered, the composition is invalidated.  Morevoer, if a specification used to delegate is optional (and so not necessary providied in the composition at runtime), the implicated method should be declared as optional. An optional method is a method which can be non implemented at runtime. To declare an optional method, the service specification need to declare : "throw UnsupportMethodException". If a non optional method is delegated on an optional specification, a warning message is fired.

<provides specification="...HelloDispatcher"/>

Service Instantiation

A composite can instantiate a service inside the composition. The composite will track Factories able to create targeted specification providers. The create service is accessible only inside the composite (except if the service is exported). Created instance can be composite too. Each service to instantiate is represented in the composite description by a service element.

Instantiation can be simple or aggregate. In the first case, only one provider is instantiated inside the composition. For aggregate instantiation, each consistent factory is used to instantiate one instance in the composite.

Instantiation can be mandatory or optional. If the composite cannot instantiate a mandatory service, the composite is invalidated.

The instantiation can be filtered. The filter is applied on factories. For example, it is easily possible to set which factory to use. Moreover, the instantiation can contain properties. These properties are used in the configuration to push inside the created instances.  Only factories exposing these properties are used in this case.

<composite name="composite.bar ">
   <service specification="org.apache.felix.ipojo.test.scenarios.service.Hello">
          <property name="language" value="en"/>
     </service>
</composite>

Architecture

Architecture allows a composite to publish its architecture. It allows knowing why a composite is not valid. For example, when an import cannot be fulfilled, the architecture indicates that the composite is not valid because one import is unsatisfied.

To display the architecture, use the "arch" command.

<composite name="composite.bar " architecture="true">
    <service specification="org.apache.felix.ipojo.test.scenarios.service.Hello">
        <property name="language" value="en"/>
    </service>
</composite>

Composition Model Extensibility

As the rest of iPOJO, the composition model is extensible. Indeed, composite container is composed by "composite handler". These handlers are special handler designed for composite. It is possible to create a composite handler as it is possible to create a (simple) handler without modifying the iPOJO runtime.

More documentation on this feature comes soon.

  • No labels