• Aucun résultat trouvé

Chapitre 8 Introspection, reconfiguration & extensibilité

4. Support des composants composites

La gestion des composants composites est basée sur la notion de contexte de service. Lors de la création d’une instance de composite, un nouveau contexte de service (c'est-à-dire un nouveau registre de service) est créé et attaché au composite. Cependant, le conteneur du composite doit alors gérer à la fois le contexte de service interne (celui venant d’être crée) et le contexte de service parent dans lequel l’instance vit. De plus, le conteneur d’une composition est également composé de handlers. Ces handlers reprennent les concepts des handlers des composants atomiques, mais ont des spécificités liées à leur statut de handler de composite.

Cette section décrit les principes de l’implémentation des compositions structurelles de services et plus exactement comment sont gérés les sous-services et les services publiés.

4.1. Gestion des sous-services

Comme décrit auparavant dans cette thèse, iPOJO supporte deux types de sous-services, mais sont gérés par le même handler (Figure 112):

 Les services importés  Les services instanciés

Les services importés sont résolus dans le contexte de service « parent ». Ainsi, un fournisseur existant est traqué. Lorsque celui-ci est trouvé alors, le composite republie ce service dans le contexte de service interne. Les propriétés de service attaché à la publication sont également republiées. Seules les propriétés liées au contexte de service (comme l’identificateur d’enregistrement) sont modifiées. Bien qu’il s’agisse d’une republication, les instances internes auront un accès direct (et non pas derrière un proxy) au fournisseur de service. Pour les instances vivant dans le composite, l’accès à ce service n’a aucune différence avec l’accès à un service réellement existant dans le composite. De la même manière, le fournisseur ne perçoit aucune différence lorsqu’il est utilisé par une instance interne au composite. Cependant, lors de l’introspection du système, le fournisseur déclarera l’instance du composite comme consommatrice alors qu’en fait il s’agit d’une instance interne à cette composition.

Les services importés subissent les arrivées et départs des fournisseurs ciblés. Ainsi, le composite doit réagir à ces évènements. De plus, ces dépendances peuvent être reconfigurées ou être contextuelles et donc subir l’influence de sources de contexte. À chaque nouveau contexte ainsi qu’à chaque reconfiguration, l’ensemble des services importés est réévalué afin de calculer les fournisseurs qui sont toujours compatibles, ceux qu’ils ne le sont plus et ceux qu’ils le deviennent.

La gestion des services instanciés repose principalement sur les concepts de fabriques. En effet, les fabriques ont la particularité d’exposer en propriété les services fournis par les instances de cette fabrique. Le composite peut choisir les fabriques à utiliser afin d’instancier un service particulier dans le contexte de service interne. Cette instanciation s’effectue comme une instanciation normale. Cependant, le contexte de service interne à la composition est donné en paramètre à la création ce qui permet d’attacher l’instance à ce contexte de service. Une fois instanciée, l’instance réagit comme une instance « normale » et n’est pas au courant qu’elle s’exécute au sein d’un composite. Cependant, les services requis (sauf les dépendances d’implémentation qui sont résolues différemment) sont résolus dans le contexte de service du composite.

Clement Escoffier 158 Figure 112. Fonctionnement des sous-services dans les compositions

Comme les instances de services sont créées à l’aide de fabriques, le composite doit traquer la disponibilité de ces fabriques. En effet, celles-ci peuvent apparaître, disparaître ou devenir valides ou invalides. Remarquons que finalement, les instances de service sont transformées en dépendance de service. Cependant au lieu de cibler un fournisseur (comme pour les services importés), ces dépendances ciblent des implémentations, c'est-à-dire des fabriques. À chaque changement, le composite doit réagir et si nécessaire changer de fabriques. Ce changement s’effectue de la manière suivante :

 L’état de l’instance est stocké si la spécification de service définit un état  L’instance est détruite

 Une nouvelle instance est créée avec une autre fabrique (si une autre fabrique compatible est disponible)

 L’état est réinjecté (s’il a été stocké)

Ce processus peut également avoir lieu lorsque la dépendance de service est reconfigurée (lors d’un changement de contexte pour les dépendances contextuelles). Lorsqu’une instanciation est déclarée agrégée, toutes les fabriques disponibles sont utilisées. De plus, une instance de service peut elle-même être une composition, ce qui rend le modèle hiérarchique. Cependant, l’implémentation d’iPOJO prend soin d’éviter les cycles éventuels.

4.2. Gestion des services fournis

L’implémentation actuelle d’iPOJO supporte les deux types exportés présentés dans cette thèse. Ces deux types sont gérés par le même handler. Dans les deux cas, le type résultant doit être une implémentation correcte des services publiés. Le premier type de service exporté est une simple exportation. Il s’agit d’une importation inversée. Au lieu de chercher un fournisseur dans le contexte de service parent pour le publier dans le contexte de service interne, un fournisseur est recherché dans le contexte de service interne pour l’exporter dans le contexte de service parent (Figure 113). Tout comme pour l’importation, il donne accès au fournisseur et ne publie pas un proxy. Comme l’exportation cible un service présent dans le composite, celui-ci doit gérer l’apparition ou la disparition de ce service au sein du composite.

159 Figure 113. Principes de l'exportation de service

L’implémentation de service est plus complexe (Figure 114). En effet, iPOJO doit découvrir la politique de délégation permettant de fournir le service. Pour cela, iPOJO choisit, sur quelle entité (service ou instance) chaque méthode doit être déléguée. Une fois la politique de délégation décidée, une classe est générée à la volée. En fait, un composant atomique complet (classe d’implémentation et métadonnées) est généré. Une fois le type et la fabrique associés créés, une instance est créée grâce à la fabrique. Cette instance sera utilisée pour fournir les services implémentés. Les services exportés par cette instance seront exportés dans le contexte de service parent.

Figure 114. Implémentation de service par un composite

Comme l’implémentation de service repose sur un composant atomique, le dynamisme est géré par cette instance. Ainsi, les services et les instances sur lesquels les méthodes doivent être déléguées sont associés à des dépendances de service ou à des propriétés de configuration. Les propriétés de configuration permettent d’injecter des instances internes afin qu’elles puissent participer à l’implémentation de service. Ainsi, il est possible de créer des implémentations de service sophistiquées. Dès lors que cette instance est invalide, le service n’est plus exporté, et la composition devient invalide.

Lorsque cette instance dépend d’un service optionnel, certaines méthodes peuvent ne pas s’exécuter correctement. Dans ce cas, il a été choisi de lancer une UnsupportedOperationException39 lorsque la méthode est appelée tant que ce service n’est pas présent.

Lorsqu’une méthode est déléguée sur une dépendance de service agrégée, deux politiques de délégation sont supportées. La méthode peut être déléguée sur chacun des fournisseurs (seulement pour les méthodes ne retournant pas de résultat) ou peut-être délégué sur un seul (politique par défaut).

4.3. Reconfiguration de l’assemblage

Comme présentés précédemment dans cette section, de nombreux évènements peuvent déclencher une reconfiguration d’une composition. Afin de gérer correctement l’état interne, iPOJO gèle l’accès aux instances et aux services impliqués dans une reconfiguration.

39

Clement Escoffier 160 De plus, dès qu’une instance ou un service permet la gestion de l’état, celui-ci est systématiquement sauvegardé et restauré durant une reconfiguration. Cette sauvegarde s’effectue soit en mémoire, soit dans un service de persistance si un de ces services est disponible. Actuellement, ce service est recherché dans le contexte global.