Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

OSGi

1,005 views

Published on

Published in: Technology
  • Be the first to comment

  • Be the first to like this

OSGi

  1. 1. OSGi Óliver Centeno
  2. 2. Modularidad División lógica Partes independientes Oculta clases de implementación
  3. 3. Modularidad Visibilidad-Empaquetamiento Interfaces publicadas Dependencias externas entre módulos
  4. 4. Modularidad OOP Paquetes/Librerías Cohesion Acoplamiento División del trabajo Abstracción Reutilización Mantenimiento
  5. 5. Modularidad Ejemplo:  Sistema de gestión de películas
  6. 6. Ficheros JAR ¿Son módulos? Classpath compartido No restringible No admite versiones No hay dependencias Condicionado por el orden Problemas de visibilidad …
  7. 7. Inversión del Control Contenedor Control de las dependencias Classpath específico de cada JAR Gestionar las Clases compartidas
  8. 8. Bundle Fichero JAR Código Recursos Metadata Módulo META-INF/MANIFEST.MF
  9. 9. Bundle Implica modularidad física de Clases Implica unidades de despliegue Permite restringir el acceso externo a Clases
  10. 10. ¿Qué es OSGi? Open Service Gateway initiative Plataforma de Servicios  OSGi Framework  OSGi Standart Services OSGi Alliance (www.osgi.org) Versión 4
  11. 11. ¿Qué es OSGi? OSGi Framework  Entorno de ejecución Java  Portable y seguro  Gestor de servicios  Sistema de módulos  Escalable y ligero  Dinámicamente instalables y actualizables
  12. 12. ¿Qué es OSGi?
  13. 13. ¿Qué es OSGi? Implementaciones  Apache Felix (http://felix.apache.org)  Eclipse Equinox (www.eclipse.org/equinox)  Knopflerfish (www.knopflerfish.org)
  14. 14. ¿Qué es OSGi? Eclipse Equinox (www.eclipse.org/equinox)  Muy ligero  java –jar org.eclipse.osgi_3.8.0.v20120529-1548.jar –console  Integrado en Eclipse  Run Configurations > OSGi Framework
  15. 15. ¿Qué es OSGi? Apache Felix (http://felix.apache.org)  Ligero  Intérprete de Comandos Gogo  No integrado con Eclipse  Configurable con Pax Runner  http://www.ops4j.org/pax/eclipse/update/  Entorno de ejecución embebido  Run Configurations > OSGi Framework  Entorno Felix v2.0.1
  16. 16. ¿Qué es OSGi? Knopflerfish (www.knopflerfish.org)  Robusto  Interfaz gráfica  java –jar framework.jar  Plugin para Eclipse  http://www.knopflerfish.org/eclipse-update/
  17. 17. ¿Qué es OSGi? Conceptual Layers  Module  Lifecycle  Service
  18. 18. Module Layer package curso.ejemplo; public class Saludo { static Saludo instance; final String nombre; public Saludo(String nombre) { this.nombre = nombre; } public static Saludo get() { return instance; } public void saludar() { System.out.println("Hola, " + nombre + "!"); } }
  19. 19. Lifecycle Layer package curso.ejemplo; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; public class Activator implements BundleActivator { public void start(BundleContext ctx) { Saludo.instance = new Saludo("lifecycle"); } public void stop(BundleContext ctx) { Saludo.instance = null; } }
  20. 20. Service Layer package curso.ejemplo; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; public class ServicioActivator implements BundleActivator { public void start(BundleContext ctx) { ctx.registerService(Saludo.class.getName(), new Saludo("servicio"), null); } public void stop(BundleContext ctx) {} }
  21. 21. Cliente package curso.ejemplo; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; public class Cliente implements BundleActivator { public void start(BundleContext ctx) { ServiceReference ref = ctx.getServiceReference( Saludo.class. getName()); ((Saludo) ctx.getService(ref)).saludar(); } public void stop(BundleContext ctx) {} }
  22. 22. Tecnologías relacionadas RMI  Proveedor  Cliente  Registro  Multi-proceso  No modular
  23. 23. Tecnologías relacionadas Spring  Contenedor ligero  Inyección de dependencias  Sin módulos dinámicos  Portando infraestructura a OSGi
  24. 24. Tecnologías relacionadas JSR  JSR 277: Java Module System  Propuesta de Sun alternativa a OSGi  JSR 291: Dynamic Component Support for Java  Mejora apoyada en OSGi  JSR 294: Improved Modularity Support  Intento de mejorar la visibilidad de módulos
  25. 25. Tecnologías relacionadas Service Component Architecture  Modelo de componentes para SOA  Integra BPEL, SOAP, JMS, JCA,..  No define formato de módulos
  26. 26. ¿Cómo funciona? MANIFEST.MF  Formato “nombre: valor”  Admite atributos y directivas  Máximo 72 caracteres/línea  Información legible  Identificación del bundle  Visibilidad externa del código (paquetes)  Dependencias de paquetes
  27. 27. ¿Cómo funciona? MANIFEST.MF Bundle-Name: Nombre descriptivo Bundle-SymbolicName: id.del.bundle Bundle-Version: 1.0.0.build-38 Bundle-ManifestVersion: 2 Export-Package: curso.ejemplo;version=1.0.0 Import-Package: org.osgi.framework;version=[1.3,2.0) Bundle-ClassPath: .,imagenes/,embedded.jar
  28. 28. ¿Cómo funciona? Ejemplo
  29. 29. ¿Cómo funciona? Resolución de dependencias
  30. 30. ¿Cómo funciona? Resolución de dependencias  Transitiva  Restringida en importación  vendor  version  …  Prioridad a la versión  Prioridad a la instalación  Prioridad a la resolución
  31. 31. ¿Cómo funciona? Resolución de dependencias  Directiva uses  Restringe las importaciones de los clientes Export-Package: org.osgi.service.http; uses:="javax.servlet" Import-Package: javax.servlet; version=2.3.0
  32. 32. Ejercicio Desplegar un bundle public class Dao { public void sql(String message) { System.out.println(message + " v1"); } } Un cliente del bundle y su activador public class Cliente { public void listar() { new Dao().sql("SELECT * FROM Tabla"); } }
  33. 33. Ejercicio Crear una nueva versión del bundle public class Dao { public void sql(String message) { System.out.println(message + " v2"); } } Desplegar y refrescar el bundle y su cliente Modificar la interfaz del bundle Restringir la versión máxima del cliente
  34. 34. Ejercicio Crear una nueva versión del cliente Ejecutarla con la 1.0 en ejecución Restringirla al bundle 1.1 Ejecutar cliente y bundle 1.0 Ejecutar cliente y bundle 1.1 Refrescar cliente 1.0
  35. 35. Ciclo de Vida El Framework OSGi controla el ciclo de vida de los bundle  install  update  start  stop  uninstall
  36. 36. Interacción con el Lifecycle Lifecycle Layer gestiona los bundles Resolviendo dependencias Permitiendo  install  update  uninstall  start  stop
  37. 37. BundleActivator Interfaz de control del ciclo de vida Implementar y referenciar en el manifest.mf Métodos start y stop de retorno rápido Acceso al contexto del bundle  BundleContext  Instalar/desinstalar bundles  Obtener todos o uno por id  …
  38. 38. Eventos BundleListener  Recibe eventos de los bundles  bundleChanged()  BundleEvent  INSTALLED  RESOLVED  STARTED  STOPED  UPDATED  UNINSTALLED  UNRESOLVED
  39. 39. Eventos FrameworkListener  Recibe eventos de OSGi  FrameworkEvent  STARTED  INFO  WARNING  ERROR  STARTLEVEL_CHANGED  PACKAGES_REFRESHED
  40. 40. Eventos SynchronousBundleListener  Recibe eventos antes que BundleListener  bundleChanged()  BundleEvent  STARTING  STOPING
  41. 41. Eventos Se registran contra el BundleContext Método addListener() Se eliminan mediante  removeBundleListener()  removeFrameworkListener()
  42. 42. Ejercicio Crear un observador de eventos Que muestre mensajes del bundle y el evento implicados Recargar los bundles Desinstalar 1.1 Refrescar cliente 1.1
  43. 43. Servicios Interfaz  java.lang.Class Implementación Service Properties
  44. 44. Servicios Service Registry  Registrar  Desregistrar  Recuperar  Librerar
  45. 45. Servicios Service Properties  Predefinidas (Constants)  Personalizadas
  46. 46. Filtros LDAP Formato ()  & | ! Prefijos  Ejemplos  (name=John Smith)  (age>=20)  (name~=johnsmith)  (&(name=John Smith)(occupation=doctor))  (|(name~=John Smith)(name~=Smith John))  (name=Jo*n*Smith*)
  47. 47. Ejercicio Convertir en Servicio  Crear una interfaz Dao  Crear una implementación en distinto paquete  Se exportará el de la interfaz  No se exportará el de la implementación  Crear un Activador que registre la implementación  Y desregistre en el stop
  48. 48. Ejercicio Crear un consumidor  Crear un Thread implementando Runnable  Que utilice la interfaz void start() { public void run() { stop = false; while (!stop) { new Thread(this) printer.print("Hola..."); .start(); try { } Thread.sleep(TWO_SECS); } catch (InterruptedException e) { void stop(){ stop = true; stop = true; } } } }
  49. 49. Ejercicio Crear un activador del consumidor  Que instancie el cliente  Que busque el servicio  getServiceReference()  getService()  Castear a la interfaz de servicio  Arrancar el Consumidor  Detenerlo en el stop
  50. 50. ServiceFactory Instanciación de servicios Registrarla en lugar del servicio Métodos getService() y ungetService() Permite implementar patrones creacionales Y modificar el ciclo de vida
  51. 51. ServiceListener Eventos de Servicio  ServiceEvent  REGISTERED  UNREGISTERED  MODIFIED  context.addServiceListener()  Filter="(objectClass=" + IDao.class.getName() + ")"  Filtro formato LDAP
  52. 52. Consejos y trucos Mantener los paquetes privados Si SOLO se va a usar desde un bundle  Incluir la librería en éste META-INF/MANIFEST.MF lib/mylegacy.jar  Bundle-Classpath manning/osgi/MyClass.class Bundle-ClassPath: .,lib Si se va a usar desde más bundles  Crear un bundle propio y referenciarlo
  53. 53. Consejos y trucos Evitar los bundles requeridos  Ven todos los Exported-Packages del requerido  Incluso de manera transitiva Bundle-SymbolicName: B1 Require-Bundle: B2; visibility:=reexport Restringir las clases exportadas  Directivas include y exclude de Export-Package Export-Package: manning.osgi.test; include:="Foo*, Bar"; exclude:=FooImpl
  54. 54. Consejos y trucos Desacoplar Bundles mediante servicios  Importar únicamente interfaces  Publicar Bundle-implementaciones  Mediante su propio Activador  Restringir la resolución del consumidor con propiedades md4Properties.put("PERFORMANCE", "FAST");
  55. 55. Consejos y trucos Desacoplar Bundles mediante servicios  Usar filtros para restringir por propiedades String filter = "(&(objectClass=" + Servicio.class.getName() + ")" + "(PERFORMANCE=FAST))";  Usar la Propiedad de ranking para priorizar md5Properties.put(Constants.SERVICE_RANKING, 10);  Usar la Propiedad de PID para identificar servicios de manera unívoca properties.put(Constants.SERVICE_PID, "10.0.0.1");
  56. 56. Consejos y trucos Uso de fragmentos  Bundles degenerados  Se resuelven después del Bundle Host  Pero deben instalarse antes que éste  No pueden tener Activador  Permiten aumentar el manifiesto  Añadir un Import-Package propio Fragment-Host: symbolic-name-del-host-bundle
  57. 57. Consejos y trucos Carga dinámica de bundles  Por ej.: Acceso a BBDD con reflexión  DynamicImport-Package  Último recurso de resolución que admite *  Se carga en ejecución, no en resolución DynamicImport-Package: org.apache.derby.jdbc  Paquetes opcionales Import-Package: x.y.z;resolution:=optional
  58. 58. Consejos y trucos Acceso a detalles del bundle  OSGi 4.3 tiene un Wiring Framework BundleRevision revision = bundle.adapt(BundleRevision.class); List<BundleCapability> exportPackage = revision.getDeclaredCapabilities( BundleRevision.PACKAGE_NAMESPACE); List<BundleRequirement> importPackage = revision.getDeclaredRequirements( BundleRevision.PACKAGE_NAMESPACE);
  59. 59. Consejos y trucos Acceso a detalles del bundle  OSGi 4.3 tiene un Wiring Framework  Recorrer detalles de especificación for (BundleCapability capability : capabilities) { Map<String, Object> attributes = capability.getAttributes(); System.out.println( attributes.get("osgi.wiring.package") + " version " + attributes.get("version") ); }
  60. 60. Consejos y trucos Acceso a detalles del bundle  OSGi 4.3 tiene un Wiring Framework  Obtener enlaces/resoluciones en ejecución List<BundleWire> providedWires = revision.getWiring().getProvidedWires( BundleRevision.PACKAGE_NAMESPACE); for (BundleWire bundleWire : providedWires) { Bundle cliente = bundleWire.getRequirerWiring().getBundle(); Bundle proveedor = bundleWire.getProviderWiring().getBundle(); }
  61. 61. Servicios Remotos Configurar propiedades del servicio Exportar interfaces remotas Añadir Bundle de comunicación  install http://repo1.maven.org/maven2/org/osgi/org.osgi. compendium/4.2.0/org.osgi.compendium-4.2.0.jar  install http://www.apache.org/dist/cxf/dosgi/1.2/cxf-dosgi- ri-singlebundle-distribution-1.2.jar
  62. 62. Servicios Remotos Propiedades para acceso remoto  service.exported.interfaces  service.exported.configs  org.apache.cxf.ws  ws  org.apache.cxf.ws.address  SOAP.service.name  …
  63. 63. Clientes Remotos Bundle de comunicación Clase ServiceTracker  Equivalente al ServiceReference  Método open() para iniciar el tracking  Método addingService() al encontrar servicios Fichero XML de endpoints  OSGI-INF/remote-services/remote-services.xml
  64. 64. Clientes Remotos Service Tracker  Clase asociada al contexto y a la interfaz  open() y close() registran Listeners internos  Instanciarlo en un Activador  Ejecutar el open() en start()  Invocar a getService()  Admite ServiceTrackerCustomizer  Eventos del servicio  addingService() y removedService()
  65. 65. Clientes Remotos Fichero de endpoints<endpoint-descriptions xmlns="http://www.osgi.org/xmlns/rsa/v1.0.0"> <endpoint-description> <property name="objectClass"> <array> <value>servicio.wsdl.GreeterService</value> </array> </property> <property name="endpoint.id">http://localhost:9090/greeter</property> <property name="service.imported.configs">org.apache.cxf.ws</property> </endpoint-description></endpoint-descriptions>
  66. 66. Clientes Remotos Fichero de configuración  OSGI-INF/cxf/intents/intent-map.xml <beans> <bean id="intentMap" class="org.apache.cxf.dosgi.dsw.qos.IntentMap"> <property name="intents"><map> <entry key="reliability" value-ref="reliableMessaging"/> <entry key="decoupled" value-ref="decoupledAddressing"/> </map></property> </bean> <p:policies id="reliableMessaging">…</p:policies> <p:policies id="decoupledAddressing">…</p:policies> <wsp:Policy wsu:Id="ReliabilityPolicy">…</wsp:Policy> <wsp:Policy wsu:Id="DecoupledPolicy">…</wsp:Policy> <wsp:Policy wsu:Id="AddressingPolicy">…</wsp:Policy> </beans>
  67. 67. OSGi y J2EE 2 opciones  Embeber un servidor ligero en OSGi (Jetty)  Práctico en fase de desarrollo  Embeber OSGi en una aplicación Web  Eficiente en fase de despliegue
  68. 68. OSGi y J2EE Crear un bundle con su activador Crear un Servlet Crear un directorio para las páginas Web Extender ServiceTracker  Obtener el servicio HttpService de contexto  Registrar recursos y servlets  Liberarlos en removedService() Instanciarlo, abrirlo y cerrarlo en el activador
  69. 69. OSGi y J2EE Equinox tiene un bridge.war  http://www.eclipse. org/equinox/server/http_in_container.php  Plantilla de AppWeb con contexto /sp_test  Con un OSGi embebido en la consola Tomcat  BridgeServlet que hace de FrontController Desplegar los bundle web en  WEB-INFEclipseplugins Y arrancarlos desde consola
  70. 70. Depuración Arrancar el framework en modo remoto java –Xdebug -Xrunjdwp:transport= dt_socket,address=8787,server=y,suspend=n -jar framework.jar  Suspend indica que se pare en arranque Crear un Debug Configuration en Eclipse  Remote Java Application  Indicar el puerto  Poner los puntos de ruptura y ejecutar OSGi
  71. 71. Eclipse Plugins Formato de bundle especial Con un activador estandart: AbstractUIPlugin  Métodos getDefault() y getImageDescriptor() Configurado mediante plugin.xml  Extensiones de la interfaz de Eclipse  Views, ayuda contextual, menús,…
  72. 72. Eclipse Plugins Ejemplo  Plugin con Custom Templates  Seleccionar Popup Menu y View  Asociar el Popup con org.eclipse.ui.IEditorInput  Configurar la categoría de la vista  Finish  Añadir más opciones al menú  Invocarán al método run() de la clase asociada

×