Dynamic nature: they can be registered/unregistered to/from the service registry at any moment and the client must be prepared to cope with this situation, i.e. some notification. A service requester must be prepared to cope with situations where no required services are found or, on the other hand, multiple matching services are found. service requesters do not directly instantiate service instances, as is the case in object orientation, for example. As a result, service requesters do not know whether they are interacting with a common service instance or with different instances providing the same service.
Need a way to help architects to design service applications Need an easy programming model to develop applications using services
A typical view of components is that they implement one or more provided interfaces, where an interface is a contract of functional behavior. In this sense, interfaces provided by components are very similar to service interfaces. This makes components an ideal candidate for implementing services, where a service is equated with a provided interface.
Compositions are expressed in term of service specifications Applications are build by using available services
a service platform that includes a minimal component model, a small framework for managing the components, and a service registry. Services (i.e.,Java interfaces) are packaged along with their implementations and their associated resources into bundles . Services are deployed, as bundles. The OSGi framework creates a host environment for managing bundles and the services they provide; a bundle is the physical unit of deployment in OSGi and is also a logical concept used by the framework to internally represent the service implementation. The management mechanisms provided by the framework allow for the installation, activation, deactivation, update, and removal of bundles.
The activator implements activation and deactivation methods that are called to initialize and de-initialize it, respectively. In the activation/deactivation methods the activator receives a context object, which gives it access to the framework and the service registry. The context allows the activator component to register services, lookfor other services, and register itself as a listener to different types of events that the framework may fire.
The state of a bundle can change at any moment while the framework is running. When a bundle is stopped, its associated activator component must unregister its services and release the services that it is using. Clients of the activator component's services must take care to observe the departure of the services. The OSGi framework uses event notifications to signal service arrival and departure, but does not provide any additional support for service dependency management. Two classes of service dependencies exist in OSGi: component to-service and service-to-service. A component-to-service dependency occurs when a component depends on a service without itself providing any services. A service-to-service dependency occurs when a component provides services and also requires other services to provide its own. Writing the code tomanage component-to-service and service-to-service dependencies is complex and error-prone; managing service dependencies involves concurrency and synchronization issues as well as tedious code to monitor the arrival and departure of any used services. Monitoring involves the observation of changes in the service registry. This is done through the reception of notifications produced by the service registry that announce arrival, departure or changes in the servies. Reconfiguration involves acting in response to the changes in the services. Reconfiguration includes the release of a departing service but also the creation of a new binding towards a substituting or newly arriving service.
iPOJO is a service component runtime aiming to simplify OSGi application development. Based on the concept of POJO, application logic is developped easily. Non functional properties are injected in the component at runtime. iPOJO strength points are : components are developped as POJO the component model is extensible the standard component model manages service providing and service dependencies iPOJO manage the component lifecycle and the environment dynamics
A POJO is a very simple Java class containing only the business logic. A POJO has not dependencies on its execution environment. In iPOJO, a POJO is a Java class which serve of implementation to a component type. As a content of a component, non-functional requirements of this class will be injected by the container.
a component type is described by an implementation class and a container configuration. This container configuration describes non-functional requirements of the implementation / component type. For example, the container description can declare that fields are service dependencies, that it provides a service...
A handler is an object who can be plugged on an instance container. A handler manages one non-functional requirement of the instances. Handler can be created and deployed separately from the iPOJO runtime. So everybody can implement its own handler. It is possible to extend the component model by creating your own handler. Service dependency handler managing OSGi service discovery and invocation Service Providing handler managing the publication and the providing of OSGi services Lifecycle callback handler allowing the invocation of methods when the instance state changes Configuration Handler allowing the configuration and the dynamic reconfiguration of the instance Architecture Handler allowing to get information about the instance (state, handler ...) Lifecycle Invoke a method when the instance becomes valid or invalid Configuration Admin support Allow to dynamically (re-) configure an instance with the configuration admin Architecture view Allow to view instance and handlers information External handlers mechanism Allow to add non functional concerns in the component model Persistency Connectors : Event admin / Wire admin Configuration : JMX Task management : Cron, TaskScheduler Security … Easy to develop and to deploy
In fact, the container of the component contains a &quot;Dependencies Manager&quot; managing all the service dependency of the component. To do this, it registers an OSGi service event listener and listens for interesting events. When an interesting service arrives, it stores the service reference. When the service is used, it obtains the service object and returns the object to the component. If it is a multiple dependencies, it returns an array of service object. When a service goes away, the dependencies manager removes the reference from its list (and call the unget method): the manager does not keep any reference on the old service. This allows a complete unloading of the service. Two calls to a service can use two different service implementations if the used implementation has gone. iPOJO tries to return always the same service object, since the service goes away.
Field : name of the field reprensenting the dependency in the component class Interface : type of the field Optional : is the dependency an optional dependency ? Filter : filter selecting service provider Callback : allow to call a method on the component instances when a service provider (matching with the dependency) appears or disappears
POJO provides an ADL based of the notion of services. This kind of &quot;composition&quot; can be named Structural Service Composition. Generally, the application is described in terms of components or instances. iPOJO compositions are described in term of services. This composition allows more flexibility and allows service implementations to evolve without breaking the composition. As a composition can export/implement a service, a composition can be used inside another composition transparently. This brings a hierarchical composition model. Moreover, as the rest of iPOJO the composition is extensible via &quot;composite handler&quot;, which are handler participating to a composition.
During execution, every component instance is managed independently by an instance manager that takes in charge service registration and service dependency management activities based on the information present in the component descriptor. The instance manager is a container that manages the instance's life-cycle through control methods and interfaces, which are only visible to the instance manager, following the Inversion of Control pattern (see figure 1).
A component instance is in one of two states: valid or invalid . When an instance is valid, its services are registered in the service registry and it is active (i.e., executing). When an instance is invalid, its services are not registered in the service registry and it is not active. When an instance is created, it is initially invalid. After creation, the instance manager enters a configuration phase (see figure 2). At this point, it creates bindings between the instance it manages and other instances that provide services required by the managed instance. Configuration can only succeed if bindings can be created for required service interfaces that are categorized as being mandatory. After configuration, the instance manager activates the component instance, and registers its services in the service registry. At that point the instance is valid. If configuration fails, the instance manager waits for the arrival of services that can be used to configure the instance. As soon as all mandatory services become present, the instance is validated. During execution, the instance manager receives notifications from the service registry. These notifications can trigger re-configuration activities, which depend on the dependency properties associated to the component that is being managed. The behavior of the instance manager with respect to the service dependency properties is summarized .
A static binding policy indicates that dependency bindings cannot change at run time, whereas a dynamic binding policy indicates that dependency bindings can change at run time. A static dependency is simpler to program than a dynamic one. 1..1, static Instance is bound to one service, any change invalidates the instance 1..1, dynamic Instance is bound to one service, changes do not invalidate the instance as long as it can be bound to another service 1..n, static Instance is bound to at least one service, any change invalidates the instance 1..n, dynamic Instance is bound to at least one service, changes do not invalidate the instance as long as the binding count is non-zero 0..1, static Instance is bound to at most one service (i.e., optional), if it is bound, departure of the bound service invalidates the instance 0..1, dynamic Instance is bound to at most one service (i.e., optional), the instance never becomes invalid 0..n, static Instance is bound to all available services at the time of binding, any departure of a bound service invalidates the instance 0..n, dynamic Instance is bound to all available services at the time of binding, as services arrive/depart they are bound/unbound to/from the instance, the instance never becomes invalid
bind-method: The name of the method to call on the component instance to bind a service to it. unbind-method: The name of the method that to call on the component instance to unbind a service from it.
When multiple required services are declared, it may be necessary for the component instance to be notified when the configuration phase is finished. Similarly, it may be necessary to be notified when the component instance is about to be invalidated (versus a re-configuration). This is the purpose of the methods defined in the Lifecycle interface. If the component implementation class implements this interface, the following methods are called at two different moments: activate(): During configuration, after all the bindings have been created, but before the provided services are registered. deactivate(): During execution, when the instance is about to be invalidated, after its services are unregistered and before its bindings are destroyed. ServiceBinderContext When writing an the component implementation class, it may be necessary to access the OSGi's bundle context that is provided to the activator of the bundle (altough this is usually not necessary). ServiceBinderContext is a class provided to solve this issue. If the instance class constructor receives a single ServiceBinderContext parameter, a context will be passed into it during instantiation. The methods that are provided in this context allow to: Access the bundle's BundleContext. Obtain the InstanceReference object corresponding to this instance. Obtain a list of all of the instance references that belong to the bun protected Object proxyProvidedServiceObject(Object obj, InstanceMetadata metadata) protected Object proxyRequiredServiceObject(Object obj, DependencyMetadata metadata) The first parameter of both methods contains the object to which a proxy will be added. The first method is called right after the component instance is created. The InstanceMetadata passed as a parameter provides the information about the component found on the descriptor file. The second method is called right before an invocation to a bind method takes place. The DependencyMetadata passed as a parameter contains information about the dependency such as the filter and the name of the service.
Service-Oriented Component Model
Content 10/19/10 2 Service-Oriented Component Model 1 A Glance at OSGi 2 iPOJO & Service Binder 3 DS & Spring OSGi 4 Comparison 5 Summary 6
Service-Oriented Model 10/19/10 Publication Lookup Bind & Invoke
Service: Contract of defined behavior
Service Registry Service Consumer Service Provider Service Specification
History 10/19/10 Service Binder (Humberto Cervantes) GenSD Monolithic Approach close to ServiceBinder iPOJO 0.6 : Extensible component model, Hosted on APACHE iPOJO 0.7 : Refactoring, Composite … Declarative Service (OSGi™ R4) Dependency Manager (Marcel Offermans) Spring-OSGi™ (Interfaces 21) 2004 2005 2006 october june november february june september
Concepts 10/19/10 an external view for the component and are part of the application logic IOC pattern and execution environment can manage instance's lifecycle deployment dependencies or resources
Configuration: The required service interface corresponds to a single binding that must be created for the instance to be validated.
Execution: The destruction of the binding invalidates the instance
Configuration: The required service interface corresponds to a set of bindings that do not need to be created for the instance to be validated. The instance manager creates bindings with all the available service providers at the moment of configuration.
Execution: New bindings can be created and bindings can be destroyed. Instance invalidation only occurs when the instance is destroyed.
Dynamics management and component lifecycle management
Differentiation between component type / Instance
Composition, ADL, Hierarchic Model
Other non functional concerns management, extensibility, flexibility
Comparison 10/19/10 ContextClassLoader Service Mngt Life Cycle Component Factory Composite Ext. & Open Container Arch. Service Binder 1.2 N Y Y Y Y N Y Declarative Service N Y Y Y N N N Spring-OSGi Y Y y N N N N iPOJO 0.7 N
H. Cervantes and R.S. Hall. "Automating Service Dependency Management in a Service-Oriented Component Model," Proceedings of the Sixth Component-Based Software Engineering Workshop, May 2003, pp. 91-96.
Clement Escoffier. “iPOJO Yet Another Service-Oriented Component Model”.ppt