Posts tagged ‘OSGi’

Apache Felix Web Console

En este blog ya ha aparecido Apache Felix en varias de las entradas relacionadas con OSGi. Hemos visto varios de sus comandos e instalado y arrancado módulos. Siempre con su interfaz de línea de comandos que es la que se utiliza normalmente.

Pero dando una vuelta por la web de Felix, he visto el subproyecto Apache Felix Web Console, que como su nombre indica pretende ser una interfaz web para Felix. En esta entrada os cuento cómo la he hecho funcionar. Para abrir boca os muestro el resultado final.

felixwebconsole_1_640x470

En la página del subproyecto aparece casi toda la información necesaria. Se nos indica que la única dependencia obligatoria es tener un Http Service instalado y nos muestra algunas alternativas. El Http Service de Felix todavía no tiene una versión publicada por lo que yo me decidí por OPS4J Pax Web (por cierto, curioso e interesante el proyecto OPS4J en su conjunto).

Tras descargar pax-web-service-0.5.2.jar (como se explica en su sitio web, el pax-web-service incluye ya el jetty y todo lo necesario), lo instalé en Felix (install file:////d:/felix-1.4.0/bundle/pax-web-service-0.5.2.jar) y lo intenté arrancar, pero me apareció el siguiente error:

org.osgi.framework.BundleException: Unresolved constraint in bundle 22: package; (package=javax.servlet)

Esto se soluciona si descargamos e instalamos el módulo org.osgi.compendium-1.2.0.jar desde la web de Felix. Este módulo es sólo una agrupación de clases de OSGi. De hecho es casi lo mismo que contiene el módulo osgi.cmpn.jar descargable desde la web de OSGi (requiere registro). Tras instalarlo tendremos esa dependencia cumplida y podremos arrancar el OPS4J Pax Web.

Ahora podemos descargar el módulo con la consola web (org.apache.felix.webconsole-1.2.2.jar), instalarlo y arrancarlo. Un apunte respecto a la configuración del módulo. En el archivo config.properties de nuestra instalación de Felix, aparece una propiedad (org.osgi.service.http.port) que realmente es configuración del servicio de Http. En ella se indica el puerto a escuchar (el 8080 por defecto).

Yo no he dado valor a ninguna otra de las propiedades de configuración, ni de Pax Web Service ni de We Console.

Ahora apuntamos nuestro navegador a http://localhost:8080/system/console (la ruta se podría modificar mediante configuración) y entramos con admin/admin (también modificable por configuración) y ya vemos el aspecto de nuestra consola web.

En la pestaña de módulos («bundles») vemos que podemos parar, arrancar, instalar actualizar o desinstalar módulos. También podemos ver información detallada sobre cada módulo (versión, paquetes exportados e importados, etc.). En otras pestañas podemos ver el estado de la configuración («Configuration Status»), ver la licencia de los módulos instalados («Licenses»), tener acceso a una línea de comandos en la página («Shell») o ver información y controlar el sistema en sí («System Information»).

También tenemos una pestaña para la gestión de repositorios de módulos. En el mismo archivo config.properties que hemos comentado con anterioridad se añade el repositorio de Felix (propiedad obr.repository.url). Yo para que se pudiera conectar al servidor he tenido que añadir durante el arranque las propiedades del proxy tras el que estoy (-Dhttp.proxyHost=proxy -Dhttp.proxyPort=8080 -Dhttp.proxyAut=user:pass), tal como se explica en la página del OSGi Bundle Repository de Felix. Desde esta pestaña se pueden añadir nuevos repositorios o instalar módulos desde los repositorios instalados.

felixwebconsole_2_640x472

Por último, señalar que tenemos otras pestañas («Configuration», «Deployment Packages» o «Event Admin») cuya funcionalidad se ve limitada si no tenemos el servicio correspondiente instalado. Pero para hablar de esos servicios ya habrá otras entradas.

16 marzo 2009 at 9:49 pm Deja un comentario

Desarrollo OSGi en Eclipse

En todos los ejemplo de OSGi que he estado publicando en este blog he utilizado como contenedor OSGi Apache Felix. Pero también comentamos que Eclipse estaba basado en OSGi y por tanto funciona sobre su motor OSGi Equinox.

Como mi IDE actualmente es Eclipse, voy a tratar el tema de desarrollo OSGi utilizando este magnífico entorno libre. Para ello trasladaré lo hecho en el ejemplo de gestión de dependencias con OSGi y lo probaré sobre Equinox.

Para desarrollar OSGi con eclipse, lo más cómodo es utilizar el PDE (Plugin Development Extension) de Eclipse, ya que realmente los plugins de Eclipse son módulos OSGi. Si no bajamos nuestro eclipse con PDE integrado deberemos instalarlo.

Creamos un nuevo proyecto. En la ventana de selección de wizard seleccionamos dentro de «Plug-in Development» la opción «Plug-in Project». Le damos un nombre al proyecto de forma habitual y selecciono como «Target platform» un framework OSGi standar.

osgi_eclipse1

En la siguiente ventana le damos los datos que van a formar parte del MANIFEST.MF: id, nombre, proveedor, versión. Relleno los campos para que mantenga los valores que en su día teníamos. Dejamos sin marcar la casilla de generar un Activator, ya que tenemos uno ya creado. Con esto podemos dar por concluido el wizard de creación del proyecto.

osgi_eclipse2

Se nos abre el editor especial para el MANIFEST.MF en el que tenemos distintas pestañas como por ejemplo la vista general («overview») o la de ver el MANIFEST en texto:

osgi_eclipse3_640x650 osgi_eclipse4_640x650

Copio o añado los fuentes que tenía en el módulo de logs que utilizamos para ver la gestión de dependencias en OSGi. Podremos ver un error en la compilación debido a que no reconoce las clases OSGi. Sin embargo Eclipse nos sugiere la solución: Añadir como dependencia el paquete org.osgi.framework. Lo podemos añadir mediante la sugerencia de Eclipse, o en la pestaña dependencias de nuestro MANIFEST.MF, en la que podemos ver todos los paquetes exportados.

osgi_eclipse5

Ahora en la pestaña «runtime» podemos añadir los paquetes que exporta nuestro módulo. Seleccionamos el mismo paquete que exportábamos entonces (org.tcymu.osgi.log.logger) y luego en las propiedades de lo exportado ponemos la versión (1.0.1). por último en la pestaña de visión general podemos declarar el activador (LogBundle).

En la misma pestaña de visión general también tenemos un enlace para lanzar el framework. Si lo ejecutamos veremos la traza que sacaba nuestro módulo al arrancar:

osgi> 18-02-2009 18:28:16.47: Arrancando LogBundle

Podemos utilizar el comando ss (similar al ps que vimos en Felix) para ver el estado de los módulos:

osgi_eclipse6

Si tecleamos help veremos la lista completa de comandos, en la que descubrimos que el comando stop seguido por el identificador del módulo detiene ese módulo, y que el comando exit nos sirve para detener completamente la ejecución.

Por último voy a crear un nuevo proyecto de tipo plugin para el módulo de nuestra aplicación. En él copiamos el código fuente del módulo de aplicación tal como lo teníamos en los anteriores ejemplos. Nos aparecerán los errores de dependencias tanto de las clases OSGi como de las clases del módulo de logs. Y vemos que podemos importar tanto los de OSGi como los de nuestro módulo de logs. Tras definir la clase de activación ejecutamos el módulo y todo funciona correctamente, arrancándose también el módulo de logs.

osgi_eclipse7_640x243

Y esto es todo por hoy.

23 febrero 2009 at 8:39 pm 2 comentarios

Gestión de servicios en OSGi

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!.

22 diciembre 2008 at 9:47 pm Deja un comentario

Entradas anteriores


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