Gestión de servicios en OSGi

22 diciembre 2008 at 9:47 pm Deja un comentario

Anteriormente hemos visto en este blog la gestión de dependencias en OSGi. En esta entrada vamos a ver OSGi desde el punto de vista de un servicio.

Un servicio lo podemos declarar como un interface que debe implementar el proveedor de ese servicio y que utilizarán los consumidores del servicio. Lógicamente, ese interface debe ser accesible tanto al proveedor como al consumidor. Aquí lo voy a poner en el módulo proveedor del servicio y dicho módulo lo exportará, pero podría estar en un módulo aparte para separarlo de la implementación.

Para esta entrada utilizaré un teórico servicio proveedor de mensajería SMS, cuyo interface será:


package org.tcymu.osgi.sms.interfaces;

public interface ISmsProvider {
    public void sendMessage(String number, String text);
}

Los servicios en OSGi se registran manualmente, es decir, no se resuelven automáticamente como las dependencias. Para registrar un servicio nos valemos del interface BundleActivator ya visto en entradas anteriores. De esta forma, al iniciarse el proveedor de un servicio lo registraremos y al pararse desharemos el registro. Vamos a ver el código:


package org.tcymu.osgi.sms;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.tcymu.osgi.sms.interfaces.ISmsProvider;

public class SmsBundleActivator implements BundleActivator {
    private SmsProvider smsProvider;
    private ServiceRegistration serviceRegistration;

    public void start(BundleContext bundleContext) throws Exception {
        System.out.println("Starting SmsProvider");
        smsProvider = new SmsProvider();
        serviceRegistration = bundleContext.registerService(ISmsProvider.class.getName(), smsProvider,null);
    }

    public void stop(BundleContext bundleContext) throws Exception {
        System.out.println("Stopping SmsProvider");
        serviceRegistration.unregister();
    }

}

La parte importante es el registro mediante el BundleContext que se nos pasa en el start de nuestro servicio. Para ello llamamos al método registerService (guardando el ServiceRegistration que nos devuelve) con los siguientes parámetros:

  1. String que representa el nombre de la clase que representa el servicio.
  2. Proveedor del servicio. En este caso una simple implementación que sólo hace un System.out (esta implementación va también en este módulo).
  3. Instancia de java.util.Dictionary (básicamente una Hashtable) que representa unas propiedades del servicio. En este caso no pasamos nada, pero se podría pasar una versión o cualquier otro dato que pudiera ser necesario.

También podemos apreciar que en el stop, deshacemos el registro mediante el método unregister del ServideRegistration que hemos guardado.

Como hemos visto en entradas anteriores, necesitamos declarar las propiedades del módulo en el MANIFEST.MF. No hay novedades respecto a lo ya visto en otras entradas. Las líneas más interesantes son:


Bundle-Activator: org.tcymu.osgi.sms.SmsBundleActivator
Export-Package: org.tcymu.osgi.sms.interfaces;version="1.0.0"

Si creamos el jar y lo instalamos en Felix (en este caso la versión 1.4.0) recibimos el mensaje esperado.

La parte interesante viene con el comando de Felix services, que nos lista los servicios disponibles en el contenedor. En su salida podemos ver entre algunos servicios propios de Felix, el nuestro:

osgiservices1_640x340

Ahora es el turno de crear el cliente para nuestro servicio.  Lo pongo todo en una sencilla clase:


package org.tcymu.osgi.smsclient;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.tcymu.osgi.sms.interfaces.ISmsProvider;

public class SmsClient implements BundleActivator {

    public void start(BundleContext bundleContext) throws Exception {
        System.out.println("Starting SmsClient");
        ServiceReference smsServiceRef = bundleContext.getServiceReference(ISmsProvider.class.getName());
        ISmsProvider smsProvider = (ISmsProvider)bundleContext.getService(smsServiceRef);
        smsProvider.sendMessage("555555555", "Tus ceros y mis unos");
    }

    public void stop(BundleContext bundleContext) throws Exception {
        System.out.println("Stopping SmsClient");
    }
}

Como podemos ver, primero se obtiene el ServiceReference a través del contexto de módulos (BundleContext). Y con esa referencia ya obtenemos la implementación del servicio también a través del contexto.

Si lo empaquetamos y arrancamos vemos que efectivamente se está utilizando el servicio.

osgiservices2_640x214

Esta no será la última entrada dedicada a OSGi en este blog, o sea que todos los interesados… ¡a suscribirse!.

Entry filed under: Java. Tags: , , .

Añadir jars de un directorio al classpath ¡¡Feliz año 2009!!

Deja una respuesta

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s

Trackback this post  |  Subscribe to the comments via RSS Feed


Mi perfil

View Miguel Orbegozo's profile on LinkedIn

Feedjit

Feeds

Otros…

BlogESfera Directorio de Blogs Hispanos - Agrega tu Blog

Bitacoras.com

Add to Technorati Favorites


A %d blogueros les gusta esto: