Dans le cas du composant fournisseur de service, le handler iPOJO dsla :provide est
intégré au conteneur. Il est configuré par des informations sur le fournisseur (nom, id,
description), l’interface du service publié et une proposition de SLOs. Ces informations lui
permettent de publier la proposition de SLOs auprès du DSLAAdmin une fois que le
service correspondant à l’interface est enregistré sur la plate-forme.
Du côté du consommateur de service la gestion des liaisons se décompose en plusieurs
activités.
1. Les phases de découverte et de sélection précèdent la création de la « liaison »
2. Ensuite, une nouvelle liaison peut être créée pour utiliser un nouveau
prestataire.
3. Enfin, une liaison est détruite lorsque le fournisseur n’est plus disponible ou
requis.
Néanmoins il faut garder à l’esprit qu’une liaison à un service peut revêtir différentes
formes selon le motif d’interaction. Nous nous sommes concentrés sur la plus courante,
qui est de type requête-réponse. Cependant, il existe dans la spécification OSGi d’autres
patrons d’interaction, notamment pour les connexions producteur-consommateur de
données et publication-souscription avec respectivement les services OSGi WireAdmin et
EventAdmin.
VII.3.1 Requête-réponse
Le modèle requête-réponse est le patron d’interaction de base des services OSGi. Il
correspond à des appels de méthodes Java sur une interface de service. Le connecteur
n’est pas explicite. La liaison est en fait représentée par un champ du consommateur
appelé dépendance de service, référençant le ou les fournisseurs de service. La valeur de
ce champ est donc une référence Java vers les objets fournissant le service requis.
Les modèles à composants tels qu’iPOJO injectent la dépendance de service dans ce
champ. Par un mécanisme de manipulation de bytecode, l’injection est faite à chaque fois
que ce champ est utilisé pour appeler une méthode du service.
Un champ vide dénote une dépendance non résolue (il n’y a pas de liaison) et provoque
l’invalidation du handler de dépendances (DependencyHandler) et donc du composant
consommateur.
iPOJO permet d’étendre la gestion des liaisons à travers une abstraction du modèle de
dépendances, le DependencyModel. Le handler que nous proposons à la place du
DependencyHandler utilise ce modèle pour définir un type de dépendance sensible aux
interruptions basée sur les accords de niveau de service, DSLADependency.
Une des principales modifications apportées se situe au niveau de la gestion du cycle de
vie. Ce dernier n’est plus conditionné par la disponibilité des fournisseurs de service mais
par les accords de niveau de service qu’un consommateur passe avec ses fournisseurs et de
l’état de ses SLAs. Ainsi notre handler dsla:require n’est plus invalidé quand un service
est indisponible mais quand un SLO sur la disponibilité n’est plus respecté.
L’autre changement majeur concerne l’injection de dépendance. Quand le
consommateur tente d’accéder à une dépendance de service, le handler intercepte l’accès
grâce au mécanisme de manipulation de bytecode d’iPOJO. Il renvoie alors la valeur
correspondant au fournisseur lié (i.e., ayant passé un accord avec le consommateur) s’il y
en a un de disponible. Cependant lorsque la liaison est en attente du retour d’interruption
(le prestataire est momentanément indisponible), le fil d’exécution est suspendu jusqu’au
retour du service. Dans le cas où le SLO n’est pas respecté, soit un autre prestataire est
retourné au POJO consommateur si un accord a pu être négocié, soit l’instance du
composant est invalidée.
VII.3.2 Producteur-consommateur de données
Le modèle producteur-consommateur est particulièrement adapté dans le cas
d’applications à base de capteurs [Marin2005]. Les capteurs produisent continuellement
des données à un rythme différent de celui auquel une application pourrait les
consommer. Pour cette raison, l’approche classique d’un service de type requête-réponse
(pull) n’est pas optimale pour modéliser un capteur (qui a plutôt un comportement de
type push).
Les producteurs et consommateurs de données s’échangent des flots de données par
l’intermédiaire de connecteurs. Le producteur transmet ses données au connecteur depuis
lequel un consommateur peut récupérer les données produites.
De plus, cette forme de service nécessite une approche différente de la notion de contrat
de service. La partie fonctionnelle du contrat (par opposition à ses propriétés
extra-fonctionnelles qui ne varient pas de l’approche plus classique) n’est plus une interface
composée de méthodes. Le pivot correspond dans ce cas au type de données.
VII.3.2.1 OSGi WireAdmin
La spécification OSGi définit un modèle d’interactions producteur-consommateur,
WireAdmin [OSGi2005], permettant de connecter des producteurs et consommateurs de
données. Dans la terminologie de WireAdmin les connecteurs sont appelés wires.
WireAdmin s’appuie lui-même sur des services OSGi « classiques », c’est-à-dire des
services de type requête-réponse, pour modéliser les comportements de producteurs et
consommateurs. Ces services identifiés de manière unique à travers leur PID sont utilisés
par WireAdmin pour la transmission de données entre un producteur et un
consommateur connectés par un wire. Un wire est lui aussi identifié de manière unique et
persistante. Il est caractérisé par les identifiants des producteurs et consommateurs qu’il
relie ainsi que par un ensemble de propriétés.
Chaque composant peut produire ou consommer des données de manière active ou
passive. Lorsqu’un producteur produit une donnée sur le wire, ce dernier appelle une
méthode de rappel (callback) du consommateur en lui passant la donnée produite
(updated). Inversement un consommateur peut demander explicitement une donnée au
wire qui appellera alors une méthode de rappel du producteur (polled). La Figure 49
décrit la transmission de données entre un producteur et un consommateur par
l’intermédiaire du wire, suivant les deux modes push et pull.
Le WireAdmin fournit un service permettant de créer, détruire, récupérer et mettre à
jour des liaisons (wires) entre producteurs et consommateurs. Lorsqu’un wire est créé ou
détruit, une troisième méthode de rappel est invoquée sur les producteurs et
consommateurs. Elle permet d’injecter les liaisons en leur passant en paramètre la liste
mise à jour des wires auxquels ils sont connectés. Lors de leur publication dans l’annuaire
d’OSGi les services Producer et Consumer doivent aussi enregistrer en tant que propriété
la liste de types de données qu’ils souhaitent produire/consommer. Cette liste appelée
« flavors » permet de vérifier la compatibilité des données échangées entre un producteur
et un consommateur. A cet effet, la spécification OSGi fournit des classes pour représenter
diverses mesures physiques et positions (org.osgi.util.measurement.Measurement et
org.osgi.util.position.Position).
Du fait de la persistance des wires, tant que ces derniers ne sont pas explicitement
détruits par le WireAdmin, consommateurs et producteurs restent connectés malgré leurs
possibles interruptions.
création / destructionData
Consumer
Data
Consumer
Data
Producer
Data
Producer
Wire
Wire
WireAdmin
WireAdmin
Push
Pull
•createWire •deleteWire •updateWire •getWires •createWire •deleteWire •updateWire •getWiresVII.3.2.2 WireAdmin Binder
Le WireAdmin s’utilise via le service qu’il publie. La gestion des liaisons doit donc se
faire de manière programmatique en utilisant ce service, ce qui détériore la lisibilité et la
maintenabilité du code métier des applications. Le WireAdminBinder permet
d’externaliser la gestion des liaisons par la définition d’un langage déclaratif de
description d’architecture (ADL) dynamique, W-ADL [Touseau2008a].
W-ADL définit la notion de WireApp pour décrire le modèle d’une application
constituée d’ensembles de wires (WireSet). Du point de vue du déploiement, une
WireApp, et donc son descripteur W-ADL, est embarquée dans un bundle représentant
l’application. Le descripteur est interprété par le WireAdminBinder qui pilote alors la
création et destruction de liaisons (wires) via le WireAdmin. Les connecteurs sont créés et
détruits dynamiquement selon les arrivées et départs des producteurs et consommateurs
de données à l’exécution conformément aux WireSets.
La Figure 50 décrit le langage W-ADL. Un ensemble de wires (WireSet) se définit par
des filtres de sélection des producteurs et consommateurs, un ensemble de propriétés, et
enfin l’élément qui nous intéresse, une politique de gestion de liaison (removePolicy) qui
indique à quel moment un wire peut être détruit.
WireApp -id: String -description: String -acyclic: boolean WireSet -id: String -description: String -producersFilter: String -consumersFilter: String -mandatory: boolean -removePolicy: RemovePolicy Property -name: String -value: String -type: String RemovePolicy <<enumeration>> +KEEP_ALIVE +WHILE_PRODUCER +WHILE_CONSUMER +IF_DISCONNECTED Wire <<persistent>> Consumer Producer composed of 1 1..* generates 1 0..* characterized by -properties 1 0..* connects 0..* 0..1 connects 0..* 0..1
Les quatre politiques proposées ont les effets suivants :
• KEEP_ALIVE : la liaison est persistante et doit être détruite par un
administrateur.
• WHILE_PRODUCER : tant qu’un producteur est connecté à un wire défini par
ce WireSet, la liaison est conservée.
• WHILE_CONSUMER : idem, si un consommateur est encore connecté au wire.
• IF_DISCONNECTED : si un producteur ou un consommateur est interrompu
alors la liaison est détruite.
La mise en œuvre de notre proposition pour les services intermittents de type
« production de données » peut donc s’appuyer sur le WireAdminBinder et définir une
cinquième politique de liaison pour le langage W-ADL. Celle-ci s’appuie alors sur les SLOs
passés dans les propriétés du WireSet, et sur les informations fournies par le DSLAAdmin.
Ainsi une liaison n’est détruite que lorsque le consommateur ou le producteur, suite à une
interruption, ne respecte pas ses obligations définies par l’accord attaché à la liaison.
Dans le cas de liaisons de type producteur-consommateur, la gestion de la liaison passe
par le WireAdmin et est ainsi indépendante des composants consommateurs. C’est ce
découplage qui permet d’exprimer des contraintes bilatérales et de faire du contrôle
d’admission au niveau des fournisseurs de service. Cette question de recherche est par
ailleurs abordée en perspective de cette thèse.
Dans le document
Politique de Liaison aux Services Intermittents dirigée par les Accords de Niveau de Service
(Page 149-154)