• Aucun résultat trouvé

Dans cette section, nous ´etudions les sp´ecificit´es du domaine vis´e par notre langage d´edi´e FScript, `a savoir la manipulation de l’architecture d’applications constitu´ees de composants Fractal.

6.2.1

Fonctionnalit´es requises & pouvoir d’expression

L’objectif du langage est de permettre d’exprimer de fa¸con naturelle des transformations sur la struc- ture et l’´etat (configuration) d’un ensemble de composants Fractal, tout en offrant des garanties quant `a la consistance de ces manipulations. Notre langage doit permettre d’acc´eder `a l’ensemble de l’interface de programmation Fractal, y compris nos propres extensions. On peut distinguer parmi les services offerts par ces interfaces les domaines suivants :

– navigation et introspection de la structure des composants : d´ecouverte des interfaces (component), du contenu des composites (content-controller et super-controller), navigation le long des connexions entre interfaces (binding-controller) et du lien m´eta (metalink-controller).

– introspection d’une partie de l’´etat des composants : cycle de vie (lifecycle-controller), para- m`etres de configuration (attribute-controller) et nommage (name-controller)

– modification de la structure : modification du contenu (content-controller), des connexions (binding-controller), du lien m´eta (metalink-controller) et cr´eation de nouveaux composants (factory)1.

– modification de l’´etat : changements des param`etres de configuration (AttributeController), ma- nipulation du cycle de vie (LifeCycleController). Notons que Fractal ne permet d’acc´eder qu’`a une partie limit´ee de ce qui constitue l’´etat d’un composant : l’´etat des objets Java correspondant `a l’impl´ementation des composants primitifs n’est pas accessible. Cette limitation implique qu’il n’est pas possible avec le m´ethodes fournies par Fractal de transf´erer l’´etat d’un composant primitif `a un autre, op´eration n´ecessaire pour pouvoir remplacer des composants `a l’ex´ecution. Rien n’empˆeche d’´etendre Fractal pour y ajouter cette fonctionnalit´e (on peut imaginer une nouvelle interface de contrˆole serialization-controller par exemple), mais puisqu’aucune impl´ementation n’existe actuellement `a notre connaissance, nous ne traiterons pas explicitement de cette probl´ematique. Si une telle extension voit le jour dans le futur, son int´egration pourrait se faire tr`es simplement dans notre langage de reconfiguration sous la forme d’une ou plusieurs nouvelles primitives de reconfiguration.

Une partie des m´ethodes d´efinies dans l’interface de programmation Fractal est purement sans effet de bord et servent uniquement `a la d´ecouverte et `a la navigation (introspection). Les autres m´ethodes servent quant `a elles `a modifier les composants. Une interface de contrˆole typique m´elangent les deux types de m´ethodes. En pratique, les m´ethodes d’introspection sont celles qui renvoient une valeur, alors que toutes celles qui modifient les composants ont un type de retour void. Les deux types de m´ethodes signalent d’´eventuelles erreurs en levant des exceptions.

On peut voir les m´ethodes des diff´erentes interfaces propos´ees par Fractal comme un ensemble d’op´erations primitives, certaines ´etant purement fonctionnelles (introspection) et les autres n’existant que pour leurs effets de bord sur les composants (intercession). Cette distinction entre les deux types d’op´erations est important pour pouvoir offrir des garanties sur l’effet des scripts sur une application Fractal. Les diff´erentes interfaces de contrˆole de Fractal sont con¸cues pour ˆetre minimales et orthogonales entre elles. Si nous voulons que les utilisateurs de notre langage puissent avoir un pouvoir d’expression suffisant, ce dernier doit permettre d’invoquer la totalit´e de ces op´erations et de les combiner.

Il doit ˆetre possible d’exprimer des reconfigurations g´en´eriques, dans lesquelles certains ´el´ements sont variables et d´ecouverts dynamiquement. Ainsi, un script qui d´econnecte l’ensemble des interfaces serveur d’un composant donn´e ne doit pas d´ependre du type particulier de ce composant (nombre et types de ces interfaces). Si cela ´etait le cas, un script sp´ecifique devrait ˆetre ´ecrit pour chaque type de compo- sant diff´erent pr´esent dans l’application. Notre langage doit donc permettre d’appliquer une op´eration `

a un ensemble d’´el´ements (composants, interfaces. . .) d´ecouverts dynamiquement grˆace aux fonctions d’introspection.

La possibilit´e d’´ecrire des reconfigurations g´en´eriques est importante en tant que telle, mais devient beaucoup plus int´eressante lorsqu’il est possible de r´eutiliser ce code, c’est-`a-dire des (parties de) scripts de reconfigurations entre applications. Il devient alors possible de cr´eer des biblioth`eques de scripts plus ou moins g´en´eriques et r´eutilisables dans plusieurs applications. ´Etant donn´e notre objectif final qui consiste `a utiliser ces scripts de reconfiguration dans des strat´egies d’adaptation, cette fonctionnalit´e est particuli`erement importante si l’on veut pouvoir ´ecrire facilement des strat´egies g´en´erales (par exemple une strat´egie de r´epartition de charge).

1

Tout comme Java, Fractal ne d´efinit pas d’op´eration explicite de destruction de composants. La seule fa¸con de retirer un composant d’une application est de supprimer toutes ses relations (connexions, composition, lien m´eta. . .) de tous les composants de l’application et de l’arrˆeter. Rien dans Fractal ne garantit qu’il sera alors d´etruit, seulement qu’il n’aura plus d’impact sur l’application.

6.2.2

Concepts sp´ecifiques `a la manipulation de composants Fractal

Le mod`ele de composants Fractal introduit un ensemble de concepts qui lui sont sp´ecifiques et qui n’existent habituellement pas dans les langages de programmation objet. Notre langage de script doit nous permettre de manipuler de fa¸con la plus naturelle possible ces concepts, ou au moins un partie d’entre eux.

Une premi`ere analyse de la sp´ecification du mod`ele Fractal permet d’identifier les concepts suivants : – interfaces de composants ;

– types d’interface ; – types de composants.

´

Etrangement, la notion de composant elle-mˆeme n’apparaˆıt pas explicitement au niveau du mod`ele – au sens o`u elle n’est pas r´eifi´ee – puisqu’un composant y est d´esign´e que par une interface particuli`ere (Component). La notion de connexion n’est pas non plus r´eifi´ee (contrairement `a certains autres mod`eles de composants [Medvidovic and Taylor, 2000]), mais toutes les informations n´ecessaires sont disponibles `

a travers l’interface BindingController.

Bien qu’elles soient pour leur part explicit´ees, nous consid´erons que les deux notions de types suppor- t´ees par Fractal (InterfaceType et ComponentType) ne sont pas v´eritablement des concepts du mod`ele `

a part enti`ere :

– Le type d’un composant est seulement l’ensemble de ses interfaces externes, et n’apporte donc aucune information suppl´ementaire dans le mod`ele.

– Le type d’une interface ajoute effectivement des informations qui d´ecrivent les sp´ecificit´es d’une interface, mais il s’agit plus de « m´eta-donn´ees » la concernant que d’un concept s´epar´e. En r´ealit´e, la seule raison pour s´eparer ces informations de l’interface elle-mˆeme est de permettre l’utilisation de syst`emes de types diff´erents tout en conservant la g´en´eralit´e du noyau du mod`ele. Dans notre cas, nous utiliserons le syst`eme de type standard ; il n’y a donc aucune raison de consid´erer le type d’une interface comme un concept `a part enti`ere.

En plus des aspects purement structurels, notre langage de reconfiguration doit pouvoir manipuler une partie de l’´etat des composants, `a savoir leur cycle de vie et leurs param`etres de configuration. Le cycle de vie que nous utilisons se limite `a deux ´etats, d´emarr´e ou stopp´e, et peut donc ˆetre repr´esent´e par un simple bool´een. Le cas des param`etres de configuration est plus complexe car bien qu’ils ne soient pas r´eifi´es dans le mod`ele Fractal, on peut les consid´erer comme des « objets » sp´ecifiques constitu´es d’un nom et d’une valeur associ´es `a un composant.

Pour conclure, les concepts sp´ecifiques que nous choisissons comme devant ˆetre repr´esent´es explicite- ment dans notre langage sont donc :

1. Les composants, identifi´es en tant que tels (correspond en pratique `a l’interface Component). 2. Les interfaces de composants, y compris toutes les m´eta-donn´ees les d´ecrivant sous la forme des

InterfaceTypes.

3. Les param`etres de configuration, qui correspondent `a une paire de m´ethodes (parfois une seule dans le cas des attributs en lecture seule) d’une interface AttributeController.

6.2.3

Crit`eres de consistance

Nous avons d´ej`a indiqu´e plus haut que l’un des objectifs prioritaires de la conception et de l’impl´e- mentation du langage FScript est de garantir la consistance des reconfigurations appliqu´ees. Dans cette section, nous d´etaillons et justifions les diff´erents crit`eres de consistance retenus.

La consistance des reconfigurations dynamiques a ´et´e relativement peu ´etudi´ee comparativement aux d´eveloppement de techniques pour permettre ces reconfigurations. On retrouve encore une fois la dialec- tique entre forme (garanties) et ouverture (m´ecanismes pour la reconfiguration dynamique), mais pour l’instant les recherches se sont attach´ees `a rendre le logiciel de plus en plus flexible. Quelques travaux ont cependant essay´e de r´etablir l’´equilibre en recherchant les crit`eres de consistance n´ecessaires et suffisants pour pouvoir effectuer des reconfigurations dynamiques de fa¸con sˆure. [Wermelinger and Fiadeiro, 2002]

utilise une approche formelle `a base de transformation de graphes (repr´esentant l’architecture de l’appli- cation) pour sp´ecifier les reconfigurations et v´erifier leurs propri´et´es. [Cook and Dage, 1999] ´etudie le cas particulier de la mise-`a-jour sˆure de composants, par exemple pour installer une nouvelle version ou corri- ger un bogue. [Moazami-Goudarzi, 1999] s’int´eresse aux crit`eres de consistance qui permettent de garantir la conservation de l’int´egrit´e de l’application face `a des reconfigurations dynamiques, alors qu’[Almeida, 2001] ´etudie les caract´eristiques des algorithmes de reconfiguration (« change management ») qui per- mettent de garantir ces crit`eres. Enfin, [Tarr and Clarke, 1997] s’int´eresse au processus de gestion de la consistance `a un niveau plus global : o`u, comment et par qui sont d´efinies le contraintes, comment sont g´er´ees les erreurs, etc.

Il se d´egage de ces travaux deux types de crit`eres : d’une part ceux qui s’appliquent au processus de reconfiguration [Almeida, 2001], et d’autre part ceux qui s’appliquent aux configurations initiales et finales de l’application [Moazami-Goudarzi, 1999]. La consistance d’une reconfiguration inclut, mais n’est pas limit´e `a, la consistance des ´etats initiaux et finaux (dans notre cas, ce nouvel ´etat est cens´e ˆetre mieux adapt´e aux contexte d’ex´ecution). Le processus de reconfiguration peut ˆetre vu comme une transaction. Nous nous sommes donc en partie inspir´es des crit`eres utilis´es dans le monde des bases de donn´ees pour d´efinir l’ACIDit´e2 des transactions. Nous retenons pour le processus les crit`eres d’atomicit´e, d’isolation

et de consistance des ´etats, auquel nous ajoutons la terminaison (la durabilit´e n’a pas de sens dans notre cas). Reste `a pr´eciser le sens du crit`ere de consistance des ´etats dans le cas particulier des configurations. Certains crit`eres de consistance sont d´ej`a d´efinis au niveau du mod`ele Fractal g´en´eral (compatibilit´e entre interfaces par exemple). Cependant, une configuration Fractal valide du point de vue du mod`ele n’est pas forc´ement valide du point de vue fonctionnel. Nous consid´erons avec [Tarr and Clarke, 1997] qu’un syst`eme de reconfiguration dynamique sˆur doit ˆetre capable de prendre en compte des crit`eres sp´ecifiques `

a l’application reconfigur´ee.

Plus pr´ecis´ement, les crit`eres que nous retenons sont les suivants :

Terminaison. Le premier crit`ere, qui est aussi le plus fondamental, est la terminaison des recon- figurations. Puisque les reconfigurations s’appliquent pendant l’ex´ecution de l’application, et que certaines peuvent impliquer de stopper des composants, des reconfigurations qui ne terminent pas, par exemple pour cause d’interblocage (deadlock ) ou de cycle infini, risquent de rendre l’int´egralit´e de l’application inutilisable.

Atomicit´e. Une reconfiguration doit ˆetre consid´er´ee comme un tout coh´erent, une suite d’op´erations qui font passer l’application d’un ´etat initial `a un ´etat final diff´erent. Il est important que l’ap- plication reste toujours dans un ´etat coh´erent afin de pouvoir fonctionner correctement. Or seul l’´etat initial est a priori garanti consistant, puisqu’il s’agit soit de l’´etat d’origine de l’application avant toute reconfiguration, soit du r´esultat d’une reconfiguration pr´ec´edente qui ´etait elle-mˆeme consistante. Si une reconfiguration ne r´esulte pas dans un nouvel ´etat consistant, elle ne doit pas ˆetre appliqu´ee du tout. Malheureusement, il n’est toujours possible de pr´evoir `a l’avance la consis- tante du r´esultat, et des erreurs inattendues peuvent se produire pendant la reconfiguration. Dans ce cas, le syst`eme de reconfiguration ne doit pas laisser l’application dans un ´etat interm´ediaire potentiellement inconsistant3 et doit revenir `a l’´etat initial qui est le seul garanti consistant. Une

reconfiguration doit donc ˆetre atomique, c’est-`a-dire que soit elle est appliqu´ee int´egralement et r´esulte dans un nouvel ´etat correct, soit elle n’est pas appliqu´ee du tout et le syst`eme se retrouve dans l’´etat initial (tout ou rien).

Isolation. Si plusieurs reconfigurations se produisent en mˆeme temps dans une application donn´ee, les ´etats interm´ediaires potentiellement inconsistants d’une reconfiguration ne doivent pas ˆetre visibles des autres. L’´etat de l’application du point de vue de chaque reconfiguration ne doit refl´eter que les changements explicitement effectu´es par cette reconfiguration.

Consistance des ´etats. Ce crit`ere indique que l’´etat initial et l’´etat final d’une reconfiguration sont tous les deux consistants individuellement, et que la transition elle-mˆeme est consistante.

2A

tomicit´e, Consistance, Isolation et Durabilit´e.

3

Certains ´etats interm´ediaires peuvent ˆetre consistants, mais mˆeme si c’est le cas ils ne correspondent pas au r´esultat attendu par l’initiateur de la reconfiguration. Les conserver peut alors conduire `a des probl`emes ult´erieurs ou d’autres reconfigurations ne sont plus applicables.

Dans notre cas, la consistance d’une configuration Fractal peut ˆetre vue `a deux niveaux :

1. Au niveau du mod`ele lui-mˆeme, Fractal d´efinit essentiellement une contrainte structurelle : pour qu’un composant puisse fonctionner (ˆetre dans l’´etat STARTED), toutes ses interfaces clientes obligatoires doivent ˆetre connect´ees `a des interfaces compatibles.

2. Au niveau de la s´emantique sp´ecifique de l’application, notre extension d´ecrite dans la sec- tion 4.3.2 permet d’ajouter dynamiquement de nouvelles contraintes structurelles sp´ecifiques. Quant `a la consistance de la transition, il s’agit de garantir l’int´egrit´e comportementale de l’applica- tion qui est reconfigur´ee en cours d’ex´ecution : notre syst`eme de reconfiguration doit faire en sorte d’interf´erer le moins possible avec le comportement de l’application. En particulier, il est essentiel ne pas perdre de messages pendant la reconfiguration : si un composant qui participe `a une reconfi- guration re¸coit un message pendant cette reconfiguration `a un moment o`u il ne peut pas le traiter, le message doit ˆetre mis en attente et relanc´e lorsque le composant est de nouveau prˆet.

Concernant les strat´egies de v´erification et d’application de ces crit`eres, nous choisissons dans un premier temps de nous reposer sur des techniques de v´erification dynamique, d´ecrites dans la section 6.5. Cependant, nous avons con¸cu FScript et en particulier son pouvoir d’expression limit´e afin de permettre dans le futur d’utiliser des techniques d’analyses statiques de code afin de d´etecter les reconfigurations invalides au plus tˆot.