1 / 53

OSGi Component Models and Frameworks. Declarative Services

Learn about OSGi component models, frameworks, and declarative services. Explore concepts, limitations, and advanced frameworks, like service-oriented models. Dive into examples showcasing component interactions and dependencies.

mishac
Download Presentation

OSGi Component Models and Frameworks. Declarative Services

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. OSGi Component Models and Frameworks.Declarative Services

  2. Ch.1: OSGi revealed Ch 2: Mastering modularity Ch 3: Learning lifecycle Ch 4: Studying services Ch 11: Component models and frameworks Reading

  3. Outline • Review of concepts: • Components, Models, Frameworks • Evaluation of OSGi as a component model: • Mapping of concepts • Limitations • Advanced component frameworks over OSGi: • General requirements and solutions • Case study: OSGi Declarative Services

  4. Component Concepts Review • Components are software building blocks which can be independently deployed and have explicit dependencies; they provide functionality via interfaces and may require functionality provided by other components via their interfaces. • A component model describes what a component looks like, how it interacts with other components, and what capabilities it has (such as lifecycle or configuration management) • A component frameworkimplements the runtime needed to support a component model and execute the components

  5. OSGi as a component model • The core OSGi specification defines a component model and the framework for executing the corresponding components • special kind of component model, called a service-oriented component model • Component = bundle, unit of deployment • Model = OSGi specification • Framework = OSGi frameworks (different implementations) • Provided and Required Interfaces ? - OSGi Services are similar with these • In OSGi, the logical bundle (the component) is equated with the physical bundle (the module) and this means there can be only one component per module and, further, only one component instance.

  6. Module Dependencies • module-level dependencies are explicitly specified (import-package and export-package in manifest file) and automatically managed and matched by the framework BundleA BundleB Import-package P1 Export-package P1

  7. Module Dependencies • Imported and exported packages cannot be assimilated with provided and required interfaces of a component GreetingImplem IGreeting Import Greeting Export Greeting

  8. Service Dependencies • Service-level dependencies are not explicitly specified (published and consumed services can be seen only in code) • Service-level dependencies could be assimilated with required and provided interfaces of a component GreetingConsumer GreetingImplem IGreeting

  9. Limitations of the OSGi Component Model • The main weakness of the OSGi component model: • Service-level dependencies are not explicit • provided and required services are seen only by inspecting all the source code • it relies on components manually managing their own service-level dependencies • A lot of boilerplate code for publishing services, locating and binding services, checking if required services are available before publishing their own provided services

  10. Example -The Limitations of the OSGi Component Model • We want to implement following simple components and composition, using raw OSGI services: • a component FooImpl depends on service Bar and should only publish its service Foo when Bar is available org.foo.foo org.foo.barimpl Foo Bar Foo Bar FooImplem BarImplem BarTracker Activator Activator

  11. Example (contd) • Interface Bar: contained in simple bundle org.foo.barapi package org.foo.barapi; publicinterface IBar { void doBar(); }

  12. Example (contd) • Bar Implementation: in bundle org.foo.barimpl package org.foo.barimpl; import org.foo.barapi.IBar; publicclass BarImpl implements IBar{ publicvoid doBar() { System.out.println("do bar"); } }

  13. Example (contd) • Bundle BarImpl contains also an Activator class • The Activator instantiates BarImpl objects and publishes them in the service registry .

  14. Example (contd) • Interface Foo: package org.foo.foo; publicinterface IFoo { void doFoo(); }

  15. Example (contd) • Foo Implementation: package org.foo.foo; import org.foo.barapi.IBar; publicclass FooImpl implements IFoo{ private IBar m_bar=null; protectedvoid setBar(IBar b) { m_bar=b; } protectedvoid unsetBar(){ m_bar=null; } publicvoid doFoo() { if (m_bar!=null) m_bar.doBar(); } }

  16. Example (contd) • Bundle Foo contains also a BarTracker that tracks Bar services. The BarTracker is opened in the start of the bundle Activator. • If one is discovered, it checks whether this is the first Bar service it has found. If so, it calls the FooImpl.setBar() method prior to registering the Foo service of FooImpl. If more than one Bar service is found, backups are stored. • If BarTracker detects that the Bar service being used has been removed, it replaces that service with one of the backups. If no backup is available, it unregisters the Foo service and calls the FooImpl.unsetBar() method.

  17. Component Frameworks over OSGi • OSGi-based component frameworks: • Allow you to explicitly describe provided and required services, acting as provided and required interfaces • Remove boilerplate code from user code (replacing with metadata files), framework manages composition • They are actually Dependency Injection Frameworks ! Foo Bar FooImplem BarImplem

  18. Component Frameworks over OSGi • All Component Frameworks over OSGi define additional, component-related metadata, which describes the components contained in the bundle JAR file. • A component’s description defines which services it provides and which it requires • Component frameworks in OSGi are generally implemented as other bundles using the extender pattern. • They listen for bundles containing components to come and go so they can start managing the contained components • If the component’s required services are satisfied, the component framework can instantiate the component and publish its provided services into the service registry. In this way they remove boilerplate code from user bundles

  19. Component Frameworks over OSGi

  20. OSGi Based Component Frameworks • There are different OSGi based component frameworks: • By the OSGi Alliance: • Declarative Services: defined by the OSGi Alliance as part of the R4 compendium specification • Blueprint Container: from the OSGi R4.2 Enterprise Specification, • Outside of the OSGi Alliance, a number of different component models have been built for or ported to the OSGi environment: • iPOJO: Apache Felix iPOJO http://felix.apache.org/documentation/subprojects/apache-felix-ipojo.html • Google Guice peaberryhttp://code.google.com/p/peaberry/

  21. OSGi Declarative Services • “Declarative Services" (DS) is a specification from the OSGi Compendium, section 112. It was introduced in Release 4.0 and had significant improvements in R4.2. • It is based on the extender model. • Like all extenders, DS performs tasks on behalf of other bundles. • The DS spec defines this extender and it is implemented by frameworks. The extender bundle itself is called the “Service Component Runtime" or SCR • In Equinox, you have to install the SCR bundle which is : org.eclipse.equinox.ds_<qualifier>.jar and its dependent bundles .

  22. Providing Services With DS • Example: The BarComponent as a DS bundle jar file that provides a Bar service Aditional component metadata file Comp.xml Manifest file with aditional header Manifest Bar The implementation – the POJO class BarImplem No need for activator, for instantiating BarImplem and registering as service !

  23. BarImpl Manifest File Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Barimpl Bundle-SymbolicName: org.foo.barimpl Bundle-Version: 1.0.0.qualifier Import-Package: org.foo.barapi, org.osgi.framework;version="1.3.0" Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Service-Component: component.xml The last line of the manifest file tells the SCR that this bundle contains a DS component, described in the file component.xml

  24. BarImpl Component Metadata File <?xml version="1.0" encoding="UTF-8"?> <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="BarComp"> <implementation class="org.foo.barimpl.BarImpl"/> <service> <provide interface="org.foo.barapi.IBar"/> </service> </scr:component> You declare that the component provides the Bar service

  25. Installing the BarImpl bundle

  26. Consuming Services with DS • Example: The Foo Component as a DS bundle that requires a Bar service (and provides a Foo service) Comp.xml Manifest Foo Bar FooImplem No need for activator and tracker !

  27. Foo Manifest File Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Foo Bundle-SymbolicName: org.foo.foo Bundle-Version: 1.0.0.qualifier Import-Package: org.foo.barapi, org.osgi.framework;version="1.3.0" Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Service-Component: component.xml

  28. Foo Component Metadata File <?xml version="1.0" encoding="UTF-8"?> <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="FooComp" immediate="true" > <implementation class="org.foo.foo.FooImpl"/> <reference interface="org.foo.barapi.IBar" bind="setBar" unbind=“unsetBar” cardinality="1..1" name="IBar" policy=“static"/> <service> <provide interface="org.foo.foo.IFoo"/> </service> </scr:component> You declare that the component requires a Bar service

  29. Installing the Foo bundle

  30. Stopping the BarImpl bundle

  31. Components and Services • The DS component framework (SCR) automatically registers services on behalf of the component bundles if it can find a registered service for its requirements (registers a Foo service if a Bar service exists) • If the service dependency cannot be fulfilled (the BarImpl bundle is not activated or it is stopped) the service is unregistered

  32. References to Services • Using lower level APIs we must write a lot of “glue" code to bind to services. • DS replaces the glue code with simple declarations. • We declare references to services. • The reference element may contain following attributes: • name – the name of the reference • interface – required interface • bind – the name of the setter method associated with the ref • unbind – the name of the unset method for the ref • cardinality • policy

  33. Cardinality of References • References may be Optional or Mandatory - whether the the component can or cannot function without the reference • References may be for a single service instance (one-to-one) or for an aggregate number of service instances (one-to-many) • The default cardinality is 1..1 meaning that we must have exactly one instance, the reference is mandatory. • A cardinality of 0..1 indicates that either zero or one instance is okay, the reference is optional. • A cardinality of 1..n : With a multiple reference the bind/unbind methods are called for each individual service instance • A cardinality of 0..n

  34. Policies for References • Policies for updating component references: • Static: the service is injected once and not changed until the component is deactivated. • Dynamic: the component is notified whenever the service comes or goes • if you use a dynamic policy, your component needs to cope with the possible issues (such as threading and synchronization) resulting from service dynamism !

  35. Multiple References • Multiple references must use the dynamic policy. Static policy makes no sense in their case. • Thread safety is therefore important and unavoidable with multiple references.

  36. Dynamic Hello World with DS GreetingImpl1 IGreeting GreetingConsumer IGreeting [0..n] GreetingImpl2 IGreeting

  37. Service Properties Bar myprop=two BarImplem2 target=(myprop=one) Foo [1..1] Bar FooImplem BarImplem myprop=one

  38. BarImpl Component Metadata File <?xml version="1.0" encoding="UTF-8"?> <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="BarComp"> <implementation class="org.foo.barimpl.BarImpl"/> <service> <provide interface="org.foo.barapi.IBar"/> </service> <property name="myprop" type="String" value="one"/> </scr:component> You declare that the component provides a Bar service with property myprop having the value one Properties may be used to configure a component but they also act as service properties and are automatically attached to services published by a component in the service registry.

  39. Foo Component Metadata File <?xml version="1.0" encoding="UTF-8"?> <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="FooComp" immediate="true" > <implementation class="org.foo.foo.FooImpl"/> <reference interface="org.foo.barapi.IBar“ target="(myprop=one)" bind="setBar" unbind=“unsetBar” cardinality="1..1" name="IBar" policy=“static"/> <service> <provide interface="org.foo.foo.IFoo"/> </service> </scr:component> You declare that the component requires a Bar service having a property myprop with value one

  40. DS component lifecycle • When are components created? • When are they destroyed? • Are there any callbacks at these stages? • How can you access the BundleContext if there is no BundleActivator?

  41. DS component lifecycle • The component lifecycle is coupled to the lifecycle of its containing bundle. • Only components in activated bundles are eligible for lifecycle management. • If a bundle is stopped, the Declarative Services framework automatically deactivates all activated components contained in it.

  42. DS component lifecycle states • Enabled—A simple Boolean flag controls whether the component is eligible for management. • Satisfied—The component is enabled, its mandatory dependencies are satisfied, any provided services are published in the service registry, but the component itself isn’t yet instantiated. • Activated—The component is enabled, its mandatory dependencies are satisfied, any provided services are published in the service registry, and the component instance has been created as a result of a request to use its service. • Modified—The configuration associated with the component has changed, and the component instance should be notified. • Deactivated—Either the component has been disabled or its mandatory dependencies are no longer satisfied, so its provided services are no longer available and its component instance, if created, is dereferenced for garbage collection.

  43. Immediate vs delayed components • Many components, such as the Bar component, exist only to provide services to other components. If no other deployed bundles consume these services, there is no need to expend resources activating the associated components. Components that provide services are delayed by default in Declarative Services. • If you look at the component declaration of the Foo component, you see that it specifies the immediate="true" attribute. This turns off the delayed behavior and forces the Declarative Services implementation to construct the Foo as soon as it’s satisfied. Otherwise, since it has no clients using it, it would not be instantiated. For components that don’t provide a service, it’s an error to set immediate to false because they would never be instantiated; instead, they’re implicitly defined as immediate components.

  44. DS lifecycle callback methods • You define an activate() callback method to be invoked by the Declarative Services framework when the component is activated, along with a corresponding deactivate() callback method to be called when the component is deactivated. • The activation and deactivation methods are optional, so if your component has no need to track its activation state, you can leave them out. • The names of callback methods (activate() and deactivate()) are defaults. If you wish to use different names you can define the names of these callback methods via attributes on the <component> XML element.

  45. Example: Foo component with lifecycle callbacks • The Foo component in the previous example assumes that there will be another component consuming its Foo service. • There could be also the case that the Foo component is the composed application’s entry-point, executing doFoo() whenever it is activated. In order to implement this scenario we need to: • Declare the Foo component as immediate (already did this) • Implement the activate lifecycle callback method, containing an invocation of doFoo(). • The Foo component metadata file is changed • The FooImpl class is changed

  46. Foo Component Metadata File <?xml version="1.0" encoding="UTF-8"?> <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="FooComp" activate="start" deactivate="stop" immediate="true"> <implementation class="org.foo.foo.FooImpl"/> <reference bind="setBar" unbind="unsetBar" cardinality="1..1" interface="org.foo.barapi.IBar" name="IBar" policy="static" target="(myprop=two)"/> <service> <provide interface="org.foo.foo.IFoo"/> </service> </scr:component> You declare the names of the lifecycle callback methods

  47. Foo Implementation publicclass FooImpl implements IFoo{ private IBar m_bar=null; protectedvoid setBar(IBar b) { m_bar=b; } protectedvoid unsetBar(){ m_bar=null; } publicvoid doFoo() { if (m_bar!=null) m_bar.doBar(); } protectedvoid start() { System.out.println(“Activate meth of comp Foo"); doFoo(); } protectedvoid stop() { System.out.println(“Dectivate meth of comp Foo"); } } Implementations of the lifecycle callback methods

  48. Summary • The OSGi framework is a component framework, where bundles are equivalent to components that interact via services. • Additional, more advanced component frameworks can be layered on top of the OSGi framework to further enhance the core component model. • Declarative Services (DS) is one of these more advanced component models over OSGi. DS manages service publication, service dependencies, and configuration dependencies on behalf of components.

  49. Other advanced OSGi component models • Declarative Services is an OSGi specification and is the simplest framework. It focuses on building lightweight components with quick startup times. • Blueprint is also an OSGi specification and provides features similar to Declarative Services, but with a richer configuration model. It’s familiar to developers who come from a Spring background. It focuses on building highly configurable enterprise-oriented applications • iPOJO is an open source solution that uses byte-code instrumentation of components to offer a sophisticated framework for building dynamic, service-based applications. • Mix-and-match: All these component frameworks are interoperable at execution time via services, so either can be used to implement a given service interface without impacting clients

  50. Comparison of OSGi component models (1)

More Related