3 variations on OSGi themes: part 5

Troika OSGi DS version

Target platform:
If you use Eclipse 3.5.0 or more recent, the OSGi DS bundle (version 1.1.0) is included in the basic PDE configuration. For Eclipse 3.4.x you may need to use OSGi-DS target platform that adds just one bundle –
org.eclipse.equinox.ds (org.eclipse.equinox.ds_1.0.0.v20080427-0830.jar) (download) – to the standard Eclipse PDE configuration.

As in the previous section, I start with supplemental services – Config and Login. Both the service components are pretty simple, because they just need to declare their services. As described in Neil’s blog, part.7, all I need to do for these services is creating DS XML files specifying each service and adding references to the files in corresponding MANIFEST.MF files. As recommended by the OSGi Specifications, I put DS XML files in OSGI-INF directories of each bundle and added the Service-Component manifest headers pointing to the DS XML files in each component’s MANIFEST.MF file. The DS XML file for the Config service looks like this:


<scr:component name="configService" immediate="true"
   xmlns:scr="http://www.osgi.org/xmlns/scr/v1.0.0">
   <implementation
         class="...config.TaskConfigService"/>
   <service>
      <provide
         interface="...interfaces.ConfigService"/>
   </service>
</scr:component>

This DS XML file just declares the Config component name and the service provided by this component. Note that I use the same component name for the Config service component as in the ‘native’ OSGi version. The DS XML file for the Login service looks very similar.

The TaskConfigService and UserLoginService classes extending corresponding base implementation classes contain only constructors and activate()/deactivate() method stubs:


...
   // called by DS runtime when this component
   // is activated.
   protected void activate(
               ComponentContext context ) {
   }
   // called by DS runtime when this component
   // is deactivated.
   protected void deactivate(
               ComponentContext context ) {
   }
...

The methods are called by the DS runtime and used only as placeholders logging activation/deactivation of service instances. If I decided to implement the code supporting persistent state in the Config and Login service components, I would need to call a method of the base service implementation class loading/saving the component state in the activate()/deactivate() methods.

The Login and Config service bundles should import 3 packages: Interfaces (for component service IDs), Common (for base classes) and org.osgi.service.component for activate()/deactivate() methods.

Let’s now move to the main 3 services – Coordinator, Copier and Processor. I start with the Coordinator service component first. As we already know, this component depends on 3 imported services – Copier, Processor and Login, but none of the dependencies is crucial for the Coordinator component. According to the project specifications, this service component should continue running even if one of the delegate services – Copier or Processor – is temporary unavailable. The Login service is used only for checking user authorization in the start()/stop() operations, so this service does not have direct impact on current status of the delegate services. Therefore, in terms of the OSGi Specifications, all the services imported by the Coordinatior service component are ‘optional’ and the reference policy for all of the services should be ‘dynamic’. I would like to remind you that ‘dynamic’ reference policy, unlike ’static’ policy, allows the consumer of the referenced services receiving notifications when one or more imported services become available/unavailable. The DS XML file for the Coordinator service component looks like this:


<scr:component name="coordinatorService"
   xmlns:scr="http://www.osgi.org/xmlns/scr/v1.0.0">
   <implementation
         class="....coordinator.CoordinatorService"/>
   <service>
      <provide
         interface="....interfaces.TaskService"/>
   </service>
   <reference name="CopierService"
      interface="....interfaces.TaskService"
      bind="setCopierService"
      unbind="unsetCopierService"
      target="(component.name=copierService)"
      cardinality="0..1"
      policy="dynamic"/>
   <reference name="ProcessorService"
      interface="....interfaces.TaskService"
      bind="setProcessorService"
      unbind="unsetProcessorService"
      target="(component.name=processorService)"
      cardinality="0..1"
      policy="dynamic"/>
   <reference name="LoginService"
      interface="....interfaces.LoginService"
      bind="setLoginService"
      unbind="unsetLoginService"
      cardinality="0..1"
      policy="dynamic"/>
</scr:component>

First, this DS XML file declares the Coordinator component name and the service provided by this component. Note again that I use the same component name as in the ‘native’ OSGi version. Second, it specifies references to the 3 imported services – Copier, Processor and Login – by using “0..1″ (optional) cardinality and dynamic reference policy. Each reference specifies ‘bind/unbind’ methods, which will be called by the DS runtime when corresponding service is bound/unbound. Another important detail is selection of target service in references to the Copier and Processor. Since both of them implement the same TaskService interface, I use filters for selecting appropriate target service. Each filter selects service component by name assigned in the component declaration (DS XML file). The component.name is standard property name, as defined in the ComponentConstants interface.

The Coordinator service implementation class – CoordinatorService – has to implement all specified bind/unbind methods, as well as activate()/deactivate() methods that are called by the DS runtime, when the component is activated/deactivated (see OSGi R4.1 Specifications, 12.5.8, 12.5.12). The latter methods should start/stop the Coordinator service thread, which runs its command queue (see ‘Shared components’ section). The CoordinatorService class code looks like this:


public class CoordinatorService
      extends CoordinatorServiceBase {
   // Copier service
   private TaskService _copierService;
   // Processor service
   private TaskService _processorService;
   // Login service
   private LoginService _loginService;

   ...
   // called by DS runtime when this component
   // is activated.
   protected void activate(
         ComponentContext context ) {
      // start component thread
      startup();
   }
   // called by DS runtime when this component
   // is deactivated.
   protected void deactivate(
         ComponentContext context ) {
      // stop component thread
      shutdown();
   }
   // called by DS runtime to set CopierService
   protected synchronized void setCopierService(
         TaskService copierService ) {
      _copierService = copierService;
   }
   // called by DS runtime to unset CopierService
   protected synchronized void unsetCopierService() {
      _copierService = null;
   }
   // called by DS runtime to set ProcessorService
   protected synchronized void setProcessorService(
         TaskService processorService ) {
      _processorService = processorService;
   }
   // called by DS runtime to unset ProcessorService
   protected synchronized void
                  unsetProcessorService() {
      _processorService = null;
   }
   // called by DS runtime to set LoginService
   protected synchronized void setLoginService(
         LoginService loginService ) {
      _loginService = loginService;
   }
   // called by DS runtime to unset LoginService
   protected synchronized void unsetLoginService() {
      _loginService = null;
   }
   @Override
   protected synchronized LoginService
         getLoginService(long timeout) {
      return _loginService;
   }
   @Override
   protected synchronized TaskService
         getCopierService(long timeout) {
      return _copierService;
   }
   @Override
   protected synchronized TaskService
         getProcessorService(long timeout) {
      return _processorService;
   }
}

The set...Service()/unset...Service() methods are called by the DS runtime when appropriate service is bound/unbound, so that the get...Service() methods may return a reference to available service or null, if the service currently is not available. Note that the CoordinatorService class is no longer a POJO, because it needs to import the org.osgi.service.component.ComponentContext class to implement the activate()/deactivate() methods.

The Coordinator service bundle should import 3 packages: Interfaces (for component service IDs), Common (for base classes) and org.osgi.service.component for activate()/deactivate() methods.

The DS XML files for the Copier and Processor services are simpler then that of the Coordinator service, because they import only one – Config – service. There is also another important difference: unlike the Coordinator service component, which has optional dependencies on imported services, the Copier and Processor service components have critical dependency on the Config service, because they need to be able to restore their task states after being updated. This issue has been discussed earlier in the ‘Shared components’ section. The DS XML file for the Config service component looks like this:


<scr:component name="copierService"
   xmlns:scr="http://www.osgi.org/xmlns/scr/v1.0.0">
   <implementation
            class="....copier.CopierService"/>
   <service>
      <provide
            interface="....interfaces.TaskService"/>
   </service>
   <reference name="ConfigService"
      interface="....interfaces.ConfigService"
      bind="setConfigService"
      unbind="unsetConfigService"
      cardinality="1..1"
      policy="dynamic"/>
</scr:component>

This DS XML file also declares the Copier component name (same as in the ‘native’ OSGi version) and the service provided by the component. The reference policy is still dynamic, which means that the Copier component will receive notifications when the Config service is bound/unbound, but the cardinality is “1..1″ (mandatory). It means that the Copier service will be deactivated when its imported Config service becomes unavailable, and activated when its imported service comes back. The DS XML file for the Processor service is almost the same, except for the component name.

The Copier and Processor service implementation classes – CopierService, ProcessorService – essentially are the same as that of the Coordinator service. They use the activate()/deactivate() methods to start/stop the task thread, and the setConfigService()/unsetConfigService() methods to set/unset reference to the Config service. Note that the CopierService, ProcessorService classes are no longer POJOs, because they need to import the org.osgi.service.component.ComponentContext class to implement the activate()/deactivate() methods.

The Copier and Processor service bundles should import 3 packages: Interfaces (for component service IDs), Common (for base classes) and org.osgi.service.component for activate()/deactivate() methods.

The last component in our list is the Client that provides interactive control over the application in the OSGi console. Actually, the Cilent does not have any peculiarities, and its DS XML file looks similar to that of the Coordinator component:


<scr:component name="interactiveClient"
   xmlns:scr="http://www.osgi.org/xmlns/scr/v1.0.0">
   <implementation class=
            "....client.InteractiveClient"/>
   <service>
      <provide interface=
"org.eclipse.osgi.framework.console.CommandProvider"/>
   </service>
   <reference name="LoginService"
      interface="....interfaces.LoginService"
      bind="setLoginService"
      unbind="unsetLoginService"
      cardinality="0..1"
      policy="dynamic"/>
   <reference name="CoordinatorService"
      interface="....interfaces.TaskService"
      bind="setCoordinatorService"
      unbind="unsetCoordinatorService"
      target="(component.name=coordinatorService)"
      cardinality="0..1"
      policy="dynamic"/>
</scr:component>

Note that for both imported services the cardinality is “0..1″ (optional) and reference policy is dynamic. The reference to the Coordinator service specifies the target service by using a filter based on the component name declared in the Coordinator DS XML file.

Unlike the 3 main task components, the Client component does not run its own thread, so there is no need in the activate()/deactivate() methods to start/stop the component thread.

In addition to the Interfaces and Common packages, the Client component bundle needs to import the org.eclipse.osgi.framework.console package to register the org.eclipse.osgi.framework.console.CommandProvider service.

Service dependencies.

Since OSGi DS platform allows to explicitly specify service dependencies by using appropriate cardinality and policy attributes, there is no need in any additional mechanism to make sure the Copier and Processor service components are restarted whenever the Config service component is updated; the OSGi DS runtime automatically deactivates/activates them as the Config service is stopped/started. The references to all imported services are set (bound) dynamically by the OSGi DS runtime, so there is no problem of stale service references either.

 

« Native OSGi version Main Spring DM version »

10 Responses to “3 variations on OSGi themes: part 5”

  1. Kylie Batt1 says:

    Я думаю, что Вы не правы. Я уверен. Давайте обсудим….

    http://rel” rel=”nofollow”> Принт менеджер OSGi DS version Target platform: If you use Eclipse 3.5.0 or more recent, the OSGi DS bundle (version 1.1.0) is included in the basic PDE configuration…..

  2. MIKE says:

    PillSpot.org. Canadian Health&Care.No prescription online pharmacy.Special Internet Prices.Pillspot.org. Herbal-supplements@buy.online” rel=”nofollow”>.…

    Categories: Vitamins/Herbal Supplements.Anxiety/Sleep Aid.Mens Health.Weight Loss.Womens Health.Skin Care.Antibiotics.Eye Care.Antidepressants.Antidiabetic.Anti-allergic/Asthma.Mental HealthAntiviral.Stomach.Blood Pressure/Heart.Pain Relief.Stop S…

  3. JESUS says:

    buy@tadalafil.now” rel=”nofollow”>..

    Buy it now!…

  4. Alexander says:

    buy@viagra.online” rel=”nofollow”>…

    Need cheap generic VIAGRA?…

Leave a Reply