• Aucun résultat trouvé

Mise en œuvre : le service d’interactions

Exemple

Application de la configuration : c = ({(a, DocAgenda), (display, T eamDisplay)}, notification) Elle s’applique seulement sur l’opération addMeetingDocqui devient :

addM eetingDoc = (DocAgenda, addM eeting, {intitule}, {result}, caddM eetingDoc) où caddM eetingDoc= ({ca1}, {}, {}) avec ca1= ({id1

1, id2

2}, {}, {}) où {id1

1, id2

2} sont simplement des copies des activités initiales.

6.4 Mise en œuvre : le service d’interactions

Il existe à ce jour, une mise en œuvre du service d’interactions nommée NOAH14, qui permet de faire interagir des composants Java locaux, RMI et/ou composants EJBs. Le service d’interactions présente les composantes suivantes :

- les interactions et les schémas sont des entités de première classe (cf.6.4.1) ;

- des composants "interagissants" ; c’est-à-dire des objets ou composants qui ont été pré-parés à interagir ; leur comportement peut être modifié dynamiquement (cf.6.4.2) ; - un serveur d’interactions qui permet (i) de définir dynamiquement de nouveaux " sché-mas d’interactions " qui constituent ainsi une bibliothèque, (ii) de lier et de délier des composants par la création et la destruction d’interactions, (iii) de naviguer dans le graphe d’interactions (cf.6.4.3) ;

- un langage de définition des schémas d’interactions (ISL : Interaction Specification Language) (cf.6.4.4) ;

- un environnement de programmation qui sert d’interface avec le serveur d’interactions (cf.6.4.5).

6.4.1 Interactions à l’exécution

Ces entités vérifient les caractéristiques suivantes :

- la cohérence des interactions est maintenue en contrôlant la réception de messages adressés aux composants,

- la définition d’un schéma d’interactions ne dépend pas des implémentations ; une inter-action peut lier des objets ou composants définis sur différentes plates-formes,

- un schéma d’interactions est décrit en se basant seulement sur les services fournis par l’interface des classes de composants,

- un schéma d’interactions et une interaction peuvent être créés et détruits en cours d’exécution,

- une interaction ne peut pas contrôler des propriétés n’appartenant pas à l’interface du composant ; l’interface d’un composant lié par des interactions n’est pas modifiée même si son comportement est modifié par l’interaction,

- la composition des interactions sur un composant est basée sur la composition telle que définie en6.2et en6.3.

Le serveur d’interactions stocke ainsi les schémas qui peuvent être récupérés pour modi-fication ou analyse. Les schémas peuvent être décrits en spécialisant un schéma existant, ce type d’héritage permet d’ajouter de nouvelles règles d’interactions plus spécifiques. Il est aussi possible d’associer à un schéma une classe d’implémentation afin d’ajouter des

attributs et des méthodes aux interactions. Notons que nous ne rencontrons pas de pro-blèmes de fusion à ce niveau, puisque les interactions sont des objets et que les données ainsi ajoutées ne sont pas accessibles directement par les composants. Ces particulari-tés ne sont pas développées ce mémoire car elles ne sont pas en liaison direct avec la composition sur laquelle nous avons choisi de nous focaliser.

6.4.2 Composant interagissant

Seuls les composants "interagissants " peuvent être liés par des interactions compor-tant des règles où leurs opérations apparaissent comme un pattern d’invocations. Tout composant peut cependant apparaître dans la partie action d’une règle. Un composant interagissant doit pouvoir remplir les tâches suivantes :

- composer ou (décomposer) dynamiquement des interactions,

- donner la main à un contrôle local lors de la réception de messages correspondant à une opération contrôlée. Nous nommons ces messages comme notifiants. Lorsqu’un com-posant interagissant reçoit un message qui se révèle être notifiant, l’activité composite qui lui est associée, est évaluée localement. Les appels entre les composants lors de cette évaluation sont alors directs et ne passent pas par le serveur d’interactions. Ce point est important pour mettre en place une communication directe entre composants et éviter ainsi que le serveur d’interactions devienne un goulot d’étranglement.

6.4.2.1 Interopérabilité et interactions

Un des défis auquel nous avons été confrontés était de permettre à des composants si-tués sur des plates-formes différentes d’interagir. Les objets interagissants peuvent être des objets locaux, des objets RMI, des composants EJB,... Il s’agit de pouvoir les mani-puler de la même façon tant au niveau du serveur que dans les communications directes inter-composants. Pour cela, il faut donc à la fois les désigner de façon uniforme et égale-ment minimiser les différences entre les différentes impléégale-mentations. En effet, l’analyse syntaxique, la gestion de l’arbre, la fusion sont autant d’éléments communs à toutes les versions réalisées jusqu’à présent. Pour cela, nous avons encapsulé les références dans des objets " interactingObject " qui gèrent les envois de message et présentent une même interface. Ces manipulations sont bien sûr transparentes du point de vue de l’utilisateur. Une modification du protocole de communication pour passer à RMI-IIOP devrait nous permettre de proposer l’interopérabilité avec les objets C++ que nous avions initialement dans le monde CORBA [Ber01].

6.4.2.2 Mises en œuvre

Pour rendre une classe Java (locale ou RMI) interagissante, il suffit d’appliquer l’outil fourni avec le service d’interaction, "GENINT", qui modifie directement son byte-code. Le byte-code de l’objet est transformé par métaprogrammation en utilisant BCEL [Dah01] ; un mécanisme de capture de message (wrapper) est mis en place pour déléguer quand cela est nécessaire l’exécution du message à l’interprétation d’un arbre d’activités [Ber01,

BMO+02].

Pour rendre une classe de composants EJB interagissant, l’utilisateur doit simplement le spécifier dans le fichier de déploiement dont la grammaire XML a été étendue. Pour Jonas [Obj08], le développeur insère la ligne suivante :

6.4. Mise en œuvre : le service d’interactions 115

Dans le cas d’un composant EJB, les interactions sont prises en charge par les objets d’interposition générés, au même titre que les autres services standards. Dans JOnAS, ils sont obtenus par l’outil de génération de code GenIC que nous avons modifié pour qu’il appelle l’utilitaire "GENINT" si le composant doit être interagissant. Le code gé-néré dépend des informations décrites dans le fichier de déploiement. Le programmeur écrit donc ses composants EJB indifféremment du fait qu’ils supportent ou non les in-teractions. L’intégration aurait également pu se faire par modification du code de l’EJB au moyen de la métaprogrammation mais ceci au détriment de la composition du service d’interactions avec les autres services standards puisque la logique de composition de services est située au niveau des objets d’interposition.

6.4.3 Serveur d’interactions

6.4.3.1 Pose, composition et destruction d’interactions

En cours d’exécution, le programmeur peut lier ou délier les composants en utilisant les schémas qui sont enregistrés auprès du serveur. Pour cela, il s’adresse au serveur d’interactions qui mémorise la nouvelle configuration, renvoie son nom et demande à chacun des composants liés par l’interaction et définissant des messages notifiant de fusionner les nouvelles règles instanciées qui le concernent. La prise en compte de ces modifications a lieu à compter du prochain appel.

Le retrait d’interactions consiste à demander au serveur d’interactions la destruction d’une configuration à partir de son nom. Chacun des composants déliés comportant au moins un message notifiant est prévenu afin de retirer la ou les règle(s) qui le concerne(nt) et de recalculer l’activité composite résultante. Les opérations des composants sont exé-cutées en mutuelles exclusions avec la pose des interactions qui ne peut donc pas ’pertur-ber’ les exécutions en cours. Dans sa thèse, Audrey Occello [Occ06] a étudié la validité du retrait ou de l’ajout d’une interaction en fonction du rôle des composants.

6.4.3.2 Navigation et Analyse du graphe d’interactions

Via le serveur d’interactions, il est possible de naviguer dans le graphe d’interactions et de l’analyser. L’analyse du graphe est basée sur une représentation XML du graphe d’interactions. Le dépliage de ce graphe nous permet d’obtenir le graphe de propaga-tion correspondant à un modèle de messages donné (destinataire et signature de l’appel donnés, paramètres non instanciés). La construction et l’analyse de ce dernier graphe permettent de détecter des circuits et des points de non-déterminisme (un même compo-sant peut recevoir plusieurs messages dans un ordre indéterminé).

6.4.4 Langage de Spécifications des Interactions (ISL)

Le langage ISL présenté de façon intuitive dans les exemples précédents définit les opé-rateurs conditionnel, séquentiel et concurrentiel, l’attente, la levée d’exception, etc. A l’instar de l’OMG avec les approches CORBA, ce langage est indépendant des langages d’application. Il permet ainsi l’interopérabilité " interactive " des composants. Nous ne le décrivons pas davantage dans ce document et invitons le lecteur à se reporter à la

thèse de Laurent Berger [Ber01] pour plus d’informations. La figure 6.10 visualise la grammaire du langage15.

FIGURE6.10:GRAMMAIREISL

6.4.5 Environnement de programmation

Outre les outils de génération de code présentés au paragraphe6.4.2, plusieurs outils et interfaces graphiques ont été définis pour aider le programmeur à définir des schémas d’interactions (cf. figure 6.11, extrait de cette interface) et à contrôler son application. Ainsi la pose d’interactions peut aussi être effectuée par une interface graphique. A par-tir de la liste des schémas d’interactions enregistrés, l’utilisateur sélectionne le schéma d’interactions à instancier (security par exemple). Une fenêtre rappelle alors le type des composants à connecter (Object et SecurityManager) et les composants interagissant disponibles de ce type afin de poser une interaction. Cette liste présente les différents composants connus du serveur d’interaction pour avoir déjà fait l’objet d’une instancia-tion de schéma. Il est également possible via l’outil graphique d’étendre cette liste en définissant à l’aide d’un formulaire un autre composant qui ne serait pas déjà connu du serveur d’interaction. Dans le cas RMI par exemple ce formulaire permet de saisir l’hôte et le port d’un registre RMI ainsi que le nom du composant relativement à ce registre. L’utilisateur peut également visualiser de façon progressive le réseau d’interactions ou visualiser le graphe de propagation pour un message donné (cf. figure6.11). Afin de facili-ter la tâche du programmeur, il est également possible de visualiser la règle de réécriture associée à un composant résultat de l’ensemble des règles qui le lie.

15. Dans le cadre de ce document, nous avons travaillé sur une sous-partie de cette grammaire, en ne prenant pas en compte la gestion des exceptions, et une extension en introduisant l’opérateur absorb.