OUGF - Nouveautés OSGi Core 4.3

of 32 /32
Zenika © 2011 1 Nouveautés OSGi Core 4.3 OSGi Users’ Group France Jeudi 24 novembre 2011 François Fornaciari - [email protected]

Transcript of OUGF - Nouveautés OSGi Core 4.3

Page 1: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 1

Nouveautés OSGi Core 4.3

OSGi Users’ Group France Jeudi 24 novembre 2011

François Fornaciari - [email protected]

Page 2: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 2

Historique

OSGi Specifications

Core (v4.3): plateforme minimale

Compendium (v4.2) : services additionnels

Enterprise (v4.2) : services orientés « entreprise »

OSGi Core 4.3 : mars 2011

Implémentations open-source

Eclipse Equinox 3.7 (Indigo) Première livraison stable mars 2011

C’est la RI !

Apache Felix 4 Première livraison stable fin septembre 2011

Page 3: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 3

<Generics> Introduction

Meilleure lisibilité du code

Meilleur typage des objets

Compatibilité avec le JRE 1.4

Utilisation de l’option de compilation -target jsr14

N’est pas une solution au code contenant des annotations dont la RetentionPolicy est à RUNTIME

Configuration Maven <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>jsr14</target> </configuration> </plugin>

Page 4: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 4

<Generics> Enregistrement de service

Avant OSGi 4.3

OSGi 4.3

Comptabilité

PrintService service = new PrintServiceImpl(); Properties props = new Properties(); props.put("color", "true"); bundleContext.registerService(PrintService.class.getName(), service, props);

bundleContext.registerService(PrintService.class, service, props);

Page 5: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 5

<Generics> Recherche de service

Avant OSGi 4.3

OSGi 4.3

Comptabilité

ServiceReference reference = bundleContext.getServiceReference(PrintService.class.getName()); PrintService service = (PrintService) bundleContext.getService(reference);

ServiceReference<PrintService> reference = bundleContext.getServiceReference(PrintService.class); PrintService service = bundleContext.getService(reference);

Page 6: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 6

<Generics> ServiceTracker (1/2)

Avant OSGi 4.3

ServiceTracker serviceTracker = new ServiceTracker(bundleContext, PrintService.class.getName(), null) { public Object addingService(ServiceReference ref) { // Méthode appelée lors de l'ajout au tracker d'un service satisfaisant le filtre // Avantage : appelée à l'ouverture du tracker pour chaque service déjà enregistré // Retourne un objet associé au service tracké (généralement le service détecté)

return super.addingService(reference); } public void modifiedService(ServiceReference ref, Object service) { // Méthode appelée lors de la modification des propriétés d'un service tracké

} public void removedService(ServiceReference ref, Object service) { // Méthode appelée lors du retrait d'un service tracké // Avantage : appelée à la fermeture du tracker pour chaque service tracké

} }; serviceTracker.open(); PrintService service = (PrintService) serviceTracker.getService();

Page 7: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 7

<Generics> ServiceTracker (2/2)

OSGi 4.3

ServiceTracker<PrintService, PrintService> serviceTracker = new ServiceTracker<PrintService, PrintService>(bundleContext, PrintService.class, null) { public PrintService addingService(ServiceReference<PrintService> ref) { return super.addingService(reference); } public void modifiedService(ServiceReference<PrintService> ref, PrintService s) { } public void removedService(ServiceReference<PrintService> reference, PrintService s) { } }; serviceTracker.open(); PrintService service = serviceTracker.getService();

Page 8: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 8

<Generics> ServiceFactory

Création d'un nouveau service à chaque lookup

Le service créé est associé au bundle consommateur

Un bundle récupérant deux fois le service reçoit la même instance

public class PrintServiceFactory implements ServiceFactory<PrintService> { public PrintService getService(Bundle b, ServiceRegistration<PrintService> sr) { return new PrintServiceImpl(); } public void ungetService(Bundle b, ServiceRegistration sr, PrintService ps) { } } [...] // Enregistrement du service bundleContext.registerService(PrintService.class, new PrintServiceFactory() , null); [...] // Client PrintService service = bundleContext.getService((bundleContext.getServiceReference(PrintService.class)));

Page 9: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 9

<Generics> BundleTracker (1/2)

Avant OSGi 4.3

BundleTracker bundleTracker = new BundleTracker(bundleContext, Bundle.ACTIVE, null) { public Object addingBundle(Bundle bundle, BundleEvent event) { // Méthode appelée lors de l'ajout au tracker d'un bundle satisfaisant l'état spécifié // Avantage : appelée à l'ouverture du tracker pour chaque bundle déjà installé // Retourne un objet associé au bundle tracké

[...] return object; } public void removedBundle(Bundle bundle, BundleEvent event, Object o) { // Méthode appelée lors du retrait d'un des bundles trackés // Possibilité d'effectuer des traitements sur l'objet associé au bundle // Avantage : appelée à la fermeture du tracker pour chaque bundle tracké

} }; bundleTracker.open();

Page 10: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 10

<Generics> BundleTracker (2/2)

OSGi 4.3

BundleTracker<String> bundleTracker = new BundleTracker<String> (bundleContext, Bundle.ACTIVE, null) { public String addingBundle(Bundle bundle, BundleEvent event) { // Méthode appelée lors de l'ajout au tracker d'un bundle satisfaisant l'état spécifié // Avantage : appelée à l'ouverture du tracker pour chaque bundle déjà installé // Retourne un objet associé au bundle tracké

[...] return "Objet tracké de type String"; } public void removedBundle(Bundle bundle, BundleEvent event, String o) { // Méthode appelée lors du retrait d'un des bundles trackés // Possibilité d'effectuer des traitements sur l'objet associé au bundle // Avantage : appelée à la fermeture du tracker pour chaque bundle tracké

} }; bundleTracker.open();

Page 11: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 11

Capabilities & Requirements Introduction

Jusqu’à présent le framework s’occupait de la résolution des bundles en faisant correspondre des packages importés avec des packages exportés

Depuis OSGi 4.3, généralisation des concepts de dépendances

Un bundle peut offrir un Capability personnalisable

Un bundle peut exprimer une dépendance vers au travers d’un Requirement

Prise en compte lors de la résolution d’un bundle

Permet de définir des dépendances qui ne sont pas des dépendances de code

Ex : nombre minimal de cœurs CPU

Page 12: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 12

Capabilities & Requirements Définition (1/2)

Capability

Un set d’attributs (couple clé/valeur) associé à un namespace

Requirement

Un filtre sur des attributs appartenant à un namespace

Namespace réservés

osgi.wiring.package Import-Package, DynamicImport-Package et Export-Package

osgi.wiring.bundle Require-Bundle, Bundle-SymbolicName et Bundle-Version

osgi.wiring.host Fragment-Host, Bundle-SymbolicName et Bundle-Version

Page 13: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 13

Capabilities & Requirements Définition (2/2)

Déclaration de le fichier MANIFEST

Capability

Requirement (filtre LDAP)

Déclaration de l’environnement d’exécution requis

Avant OSGi 4.3 (déprécié)

OSGi 4.3

Provide-Capability: com.zenika.formation; year:Long=2011; effective:=resolve

Require-Capability: com.zenika.formation; filter:="(year=2011)"

Bundle-RequiredExecutionEnvironment: JavaSE-1.6

Require-Capability: osgi.ee;filter:="(&(osgi.ee="JavaSE")(version>=1.6))"

Page 14: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 14

Core Services

Package Admin Service

Start Level Service

Conditionnal Permission Service

Bundle Wiring API

Start Level API

Service Hook Service

Resolver Hook Service

Weaving Hook Service

URL Handler Services

Remote Services

Page 15: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 15

Package Admin Service Rappel

Service permettant d'analyser et d'agir sur les dépendances

Page 16: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 16

Start Level Service Rappel

Service permettant de gérer la séquence d'activation des bundles

Page 17: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 17

Deprecated services

« Package Admin Service » et « Start Level Service » sont dépréciés

Utilisés par les outils d’administration de plateformes OSGi

Shells OSGi

Console de management web de Felix

Servers d’applications

Etc.

Page 18: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 18

Nouveaux services OSGi 4.3

Remplacement de « Package Admin Service » par « Bundle Wiring API » et de « Start Level Service » par « Start Level API »

A l'origine, choix d'une approche orientée service (dynamique) mais ce design n'était pas suffisamment orienté objet (passage de l'objet bundle à chaque méthode)

Nouvelle représentation des « Wiring » entre bundles en se basant sur l’introduction des concepts de « Capability » et « Requirement »

Page 19: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 19

Bundle Wiring API (1/4)

A chaque résolution de bundle, un objet de type BundleWiring est créé pour une révision donnée

A noter : chaque mise à jour d'un bundle déclenche la création d'une nouvelle révision. Seule une opération de « refresh » permet de forcer la rafraichissement des liaisons entre les bundles

Permet de récupérer les informations de dépendance

Nom symbolique, version, etc.

Packages requis / fournis, fragments, etc.

Représentation des liaisons au « runtime »

Page 20: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 20

Bundle Wiring API (2/4)

Page 21: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 21

Bundle Wiring API (3/4)

Exemple de récupération des packages importés

Namespaces osgi.wiring.bundle et osgi.wiring.host

BundleWiring bundleWiring = bundleContext.getBundle().adapt(BundleWiring.class); for (BundleWire wire : bundleWiring.getRequiredWires("osgi.wiring.package")) { String packageName = (String) wire.getCapability().getAttributes().get("osgi.wiring.package"); Bundle bundle = wire.getProviderWiring().getBundle(); [...] }

List<BundleCapability> capabilities = bundleWiring.getCapabilities(null); for (BundleCapability bundleCapability : capabilities) { System.out.println(bundleCapability.toString()); } // En sortie de la console osgi.wiring.bundle; osgi.wiring.bundle="zenika-bundle"; bundle-version:Version="1.0.0" osgi.wiring.host; osgi.wiring.host="zenika-bundle"; bundle-version:Version="1.0.0"

Page 22: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 22

Bundle Wiring API (4/4)

Collection<String> resources = bundleWiring.listResources("/", "*.properties", BundleWiring.LISTRESOURCES_RECURSE); Collection<URL> resources = bundleWiring.findEntries("/", "*.class", BundleWiring.FINDENTRIES_RECURSE);

Page 23: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 23

Start Level API

Manipulation des informations de « StartLevel »

Opérations à partir du « System Bundle »

BundleStartLevel bundleStartLevel = bundleContext.getBundle().adapt(BundleStartLevel.class); int startLevel = bundleStartLevel.getStartLevel();

FrameworkStartLevel frameworkStartLevel = bundleContext.getBundle(0).adapt(FrameworkStartLevel.class); int initialBundleStartLevel = frameworkStartLevel.getInitialBundleStartLevel();

Page 24: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 24

Service Hook Rappel (1/2)

Spécification permettant d'interagir avec le « service engine » : depuis OSGi 4.2

Connaître les services requis par les bundles

Limiter la visibilité de certains services

Mettre facilement en œuvre des proxies de services

Trois types d'interactions

Event Hook : intercepte les évènements liés au cycle de vie des services (enregistrement / désenregistrement / modification) Filtrer tout ou partie des évènements reçus par les bundles

Find Hook : intercepte la recherche de références de services Manipuler les références de services demandées

Listener Hook : intercepte la création et la suppression de ServiceListener Avoir la connaissance des services potentiellement utilisés par les bundles

Page 25: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 25

Service Hook Rappel (2/2)

public interface EventHook { // contexts : contextes vers lesquels les évènements sont propagés // (peuvent être modifiés) void event(ServiceEvent event, java.util.Collection contexts); }

public interface FindHook { // allServices : filtre sur getServiceReferences() // ou getAllServiceReferences() void find(BundleContext context, java.lang.String name, java.lang.String filter, boolean allServices, java.util.Collection references); }

public interface ListenerHook { void added(java.util.Collection listeners); void removed(java.util.Collection listeners); }

Page 26: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 26

Nouvelles interceptions (1/2)

Ajout de trois nouveaux mécanismes d'interception depuis la version 4.3

Weaving Hook

Permet d'intercepter le chargement de classe des bundles et de manipuler le bytecode avant chargement

Les nouvelles classes générées peuvent dépendre de nouvelles classes, d'où la possibilité de modifier au runtime l'attribut DynamicImport-Package du fichier MANIFEST

Resolver Hook

Permet d'intercepter le mécanisme de résolution de packages et d'influencer le resolver

Exemple : limiter la visibilité de certains packages

Page 27: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 27

Nouvelles interceptions (2/2)

Bundle Hook

Permet d'intercepter les évènements du framework à propos du cycle de vie des bundles (Event Hook)

Permet de limiter la visibilité de certains bundles (Find Hook)

Le trio «Service Hook », « Resolver Hook » et « Bundle Hook » offre un mécanisme efficace pour introspecter le framework et agir sur son comportement

Cas d'utilisation : isoler plusieurs applications s'exécutant sur le même framework

Alternative aux mécanismes de sécurité offerts par la plateforme

Page 28: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 28

Resolver Hook Service Mise en œuvre

Enregistrement d'un service de type ResolverHookFactory

A chaque tentative de résolution d'un bundle par le framework, création d'une instance de ResolverHook

Possibilité de filtrer la résolution d'un bundle ou la résolution de packages spécifiques

Page 29: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 29

Bundle Hook Service Mise en œuvre

Event Hook : intercepte les évènements liés au cycle de vie des bundles (install / start / update / …) avant de les émettre aux différents listeners

Filtrer les évènements reçus par les bundles

Find Hook : intercepte les appels aux méthodes de récupération des bundles présents sur la plateforme

Manipuler la liste de bundles retournées

Page 30: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 30

Virgo regions

Eclipse Virgo 3.0 s’appuie sur les mécanismes d’interception pour créer des régions isolées

Précédemment implémentées par les « nested framework » qui ont été abandonnés

Plan de contribution des régions dans Equinox

Page 32: OUGF - Nouveautés OSGi Core  4.3

Zenika © 2011 32