• Aucun résultat trouvé

Approche à services et disponibilité dynamique

reconfiguration dynamique

3. Approche à services et disponibilité dynamique

nouveaux composants sont susceptibles de devenir disponibles tandis que d’autres sont susceptibles de devenir indisponibles. Cette hypothèse implique qu’un système doit être capable de découvrir dynamiquement de nouveaux composants et de prendre en compte la disparition imprévisible de composants en cours d’utilisation. L’idée de disponibilité dynamique est au cœur des approches à services.

3. Approche à services et disponibilité

dynamique

La définition la plus répandue d’un service est donnée par [Bieber01] : « Un service est un comportement défini contractuellement qui peut être implémenté et fourni par un composant quelconque pour être utilisé par un autre composant ; l'interaction entre les deux composants s’appuie uniquement sur le

contrat »53. Cette approche, qui s’inscrit explicitement dans le cadre des systèmes distribués, est caractérisée par la découverte des fournisseurs de services par leurs clients au moment de l’exécution. Ainsi, les liaisons entre clients et fournisseurs de services sont établies tardivement, c’est-à-dire au moment où cette liaison devient nécessaire. Le client ne connaît ni l’adresse ni le nom d’un fournisseur de service, mais uniquement la fonctionnalité que doit offrir le service qu’il recherche. Les fonctionnalités offertes par les fournisseurs de services disponibles sont déclarées par ces fournisseurs de services dans un annuaire au moyen de descripteurs de service (voir Figure IV-10).

Figure IV-10 Approche à services : les acteurs en présence. Tiré de [Cervantes04], p.65.

Pour découvrir un fournisseur de service, un client adresse une requête à l’annuaire qui décrit la fonctionnalité attendue du fournisseur de service sous la forme, également, d’un descripteur de service. En retour, l’annuaire indique au client une référence vers le fournisseur de service capable de le satisfaire. Le client établit alors la connexion avec le fournisseur de services. Pour qu’un client puisse utiliser les fonctionnalités offertes par un fournisseur de service, peu importent les technologies utilisées pour implémenter l’un et l’autre. Seul compte le « contrat » défini dans le descripteur de service et le protocole de communication. Ainsi, chaque instanciation de l’approche à services implémente au minimum un annuaire et définit un protocole de communication permettant aux clients d’interagir avec l’annuaire, d’interpréter la référence vers un fournisseur de service retourné par l’annuaire et d’établir la liaison avec le fournisseur de service découvert.

Un exemple d’application caractéristique de ce principe de l’approche à services est donné par les Services Web. Un service Web « repose sur un système logiciel conçut pour sous-tendre une

53 « A service is a contractually defined behavior that can be implemented and provided by any component for use by any component, based solely on the contract. »

interaction entre deux machines à travers un réseau » [W3C04]. Dans cet espace technologique, les services sont décrits à l’aide du langage WSDL54, qui, comme tous langages XML, est interprétable à la fois par l’homme et par la machine. Un descripteur de service WSDL est centré sur l’interaction logicielle et la caractérise à différents niveaux de détails. Ainsi, une description WSDL embarque la définition des messages échangés et des structures de données que ceux-ci véhiculent, indique la localisation du service sur le réseau sous la forme d’une URI, donne des indications sur les patrons d’interaction logicielle en vigueur, par exemple en qualifiant les échanges de message de synchrones ou d’asynchrones, et enfin, précise les protocoles de transport et de sérialisation des données que le service utilise pour interagir avec ses clients. Le plus souvent HTTP joue le rôle du protocole de transport. Il est généralement associé au protocole SOAP, qui fixe le format des messages échangés entre les parties. Enfin, dans l’espace technologique des services Web, les annuaires de service s’appuient sur le protocole standard UDDI55, une initiative industrielle portée par le consortium OASIS. Par ailleurs, dans [W3C04], une différence est faite entre le service, notion abstraite caractérisant une fonction, de l’agent, entité logicielle ou matérielle concrète, qui l’implémente. Ainsi, dans le cadre des services Web, les protocoles et formats WSDL, SOAP, UDDI et HTTP, indépendants des plates-formes, permettent la spécification des services, laissant au concepteur le libre choix des technologies pour implémenter des agents chargés de les rendre. Les services Web proposent donc un moyen de spécifier un service indépendamment du ou des agents logiciels chargés de le rendre. À l’inverse, OSGi est un cadre technologique fondé sur Java, proposé par l’Alliance OSGi56, qui offre un modèle d’implémentation ainsi qu’un environnement de déploiement et d’exécution de services. Dans la terminologie OSGi, le terme

service correspond au terme agent de la terminologie des services Web. Ainsi, OSGi est une technologie avec laquelle il serait envisageable d’implémenter des agents de services Web. Ces agents de service sont conditionnés au sein de bundles. Un bundle se présente sous la forme d’une archive Java (JAR) qui contient des métadonnées, un activateur et l’implémentation de la logique métier. Les métadonnées associées au bundle décrivent les

54 WSDL : Web Service Description Language. Ce langage est un standard du W3C.

55 UDDI : Universal Description, Discovery, and Integration protocol. (Voir http://uddi.xml.org).

dépendances de code et les fonctions offertes par le ou par les agents de service embarqués. Quant à l’activateur, c’est un programme exécutable en charge de la gestion du cycle de vie de ces agents.

Le bundle est donc un vecteur destiné au déploiement d’un ou de plusieurs agents de service au sein d’une plate-forme d’exécution appelée passerelle dans la terminologie OSGi. Si un bundle peut embarquer un agent correspondant à un service Web, il est avant tout conçu pour le déploiement de « services OSGi ». Alors qu’un service Web est accessible à travers le réseau, un service OSGi standard n’est accessible que pour des clients situés sur la même passerelle que lui. Ainsi, chaque passerelle OSGi dispose de son propre annuaire de service. Les annuaires de service OSGi mémorisent les services disponibles sous la forme d’un nom d’interface et d’un ensemble de propriétés de type (clé, valeur). En outre, OSGi définit une API à destination l’activateur de bundle pour ajouter ou retirer des services de l’annuaire, ainsi qu’une API à destination des clients pour que ceux-ci puissent découvrir et établir des liaisons avec des services disponibles sur la passerelle. Ainsi, OSGi, qui s’inscrit dans l’approche à services, offre les mécanismes nécessaires à la disponibilité dynamique des agents de service. Cependant, ces mécanismes seuls n’étaient pas suffisants : il était difficile pour le concepteur d’un client de pouvoir tirer parti de l’arrivée dynamique d’un nouveau service ou de s’adapter à la disparition soudaine d’un service utilisé. En effet, il incombait au concepteur du client de prendre en compte ce type d’événement extérieur et d’implémenter, à chaque fois, les mécanismes propres à l’adaptation dynamique. Ainsi, pour pallier cette faiblesse, la dernière version en date de la spécification OSGi (OSGi R4) intègre les avancées issues des travaux de [Cervantes04] qui proposent Service Binder, un « modèle à composants orienté services ».

Dans le modèle de [Cervantes04], un composant est une entité logicielle disponible dynamiquement qui offre et requiert des services. L’instance d’un composant est encadrée par un « gestionnaire d’instance ». Ce gestionnaire d’instance est en charge d’enregistrer les services fournis par le composant qu’il encapsule auprès de l’annuaire. En s’appuyant sur des descriptions de services enrichies, il est également en charge de sélectionner pour le compte du composant encadré les composants nécessaires pour satisfaire les services requis, et enfin, il est en charge d’établir les connexions avec les composants sélectionnés. En cas d’apparition ou de disparition de service, c’est toujours à ce gestionnaire d’instance qu’il incombe de gérer la découverte de composants de remplacement et l’établissement de nouvelles connexions pour que le composant encapsulé puisse continuer à fonctionner. Ainsi, la prise en charge des mécanismes

d’adaptation dynamique par le gestionnaire d’instance, simplifie le travail du concepteur de composant qui peut centrer son effort sur la logique métier de celui-ci. Cependant, d’une part, il n’est pas possible d’étendre la couverture fonctionnelle du gestionnaire d’instance, et d’autre part, cette approche impose au programmeur l’utilisation d’un style de programmation et d’une API particulière [Escoffier07]. Avec iPOJO, [Escoffier07] se propose d’apporter une solution à ces deux limitations.

À l’instar de Service Binder, pour lequel il constitue l’étape suivante, iPOJO (injected Plain Old Java Object) est un modèle à composant à service développé au-dessus d’OSGi. Son objectif est de simplifier au maximum la tâche du développeur de composants en lui permettant de se focaliser sur la conception de la logique métier et non sur les aspects propres à l’approche à service et aux propriétés non-fonctionnelles. Ainsi, le développeur implémente la logique métier sous une forme très proche d’un POJO (Plain Old Java Object), et se contente de configurer le conteneur de composant iPOJO destiné à l’encapsuler. Comme dans l’approche de [Cervantes04], un composant iPOJO expose les fonctions qu’il offre sous la forme de services fournis et exprime ses dépendances sous la forme de services requis. Les liaisons entre les composants sont établies à l’exécution et sont réalisées par le conteneur du composant iPOJO. En s’appuyant sur une description détaillée des composants, le conteneur est capable de prendre en charge les aspects non-fonctionnels de l’exécution du composant, notamment les opérations de publication des services auprès de l’annuaire, de découverte et de sélection des services.

Si la fonction du conteneur de composant d’iPOJO correspond à celle du gestionnaire de services dans Service Binder, sa structure logicielle est différente. Ainsi, un conteneur de composant iPOJO rassemble un certain nombre de handlers, chacun prenant en charge la gestion d’un aspect non-fonctionnel de l’exécution d’un composant. Six handlers sont fournis par défaut. Le handler

Dependency résout les dépendances de service, Provided Service

gère l’offre de service, Lifecycle Callback permet d’appeler des méthodes de l’instance de composant lorsque son état d’exécution change, Configuration permet la configuration dynamique,

Architecture permet d’exposer l’architecture interne du composant, et enfin, Controller Lifecycle permet au code interne d’influer sur le cycle de vie de l’instance de composant. Contrairement aux gestionnaires de services de [Cervantes04], les conteneurs de composants d’iPOJO sont extensibles : il est possible de leur ajouter de nouveaux handlers afin de prendre en compte de nouvelles préoccupations non-fonctionnelles.

Contrairement à l’approche à composants, les concepts de l’approche à services semblent bien mieux définis et mieux

partagés par les différentes technologies à services. Dans leur fondement, ces technologies n’envisagent pas leur hétérogénéité : c’est-à-dire qu’un client implémenté dans une technologie à services particulière ne peut pas, tel quel, interagir avec un service implémenté dans une autre technologie. Par exemple, un service Web ne peut pas interagir directement avec un composant iPOJO. Cependant la proximité des concepts mis en œuvre dans chaque technologie permet d’envisager ce type d’interaction. C’est, par exemple, le cœur des travaux de recherche du projet européen Amigo [Amigo-D2.1].