Vérification de conformité architecturale
La vérification de conformité architecturale (en anglais, architecture conformance checking) regroupe l'ensemble des vérifications statiques et dynamiques d'une implémentation d'un logiciel à partir de son architecture. Un humain peut détecter visuellement des violations en comparant deux modèles représentant une architecture. Ce procédé n'est pas sans faille puisqu'il peut nécessiter une grande concentration, une certaine difficulté et impliquer des erreurs en fonction de la complexité du modèle. Le modèle peut être constitué de multiples vues augmentant sa complexité. La vérification de conformité automatisée (entendre par là , une vérification informatique) est un choix préférable dans ce genre de cas.
Contexte
DĂ©finition de l'Ă©rosion logicielle
L'architecture logicielle est soumise constamment à des pressions sur les exigences et les technologies utilisées tout en continuant à délivrer un niveau de performance acceptable pour les utilisateurs finaux. L'érosion logicielle est l'écart entre l'architecture prévue et son implémentation finale qui change selon ces différentes pressions. Souvent, les modifications faites durant le développement d'un système provoquent des dommages sur l'intégralité de sa structure et violent ses principes de design[1].
Causes d'une Ă©rosion logicielle
L'Ă©rosion peut survenir Ă cause de plusieurs facteurs incluant :
- L'inconscience des développeurs logiciels puisqu'ils ne font pas toujours tous attention à respecter l'architecture établie au début du projet[2] ;
- Les exigences contradictoires qui arrivent de façon imprévues au début du développement. Cela survient souvent quand la technologie choisie n'est pas maitrisée[2] ;
- Les difficultés techniques qui peuvent survenir pendant l'implémentation lorsque les développeurs se rendent compte qu'un choix technologique ne parviendra pas à atteindre les objectifs désirés[2].
- La pression des deadlines qui sont fréquentes dans le développement logiciel[2].
RĂ©solutions
Plusieurs stratégies existent pour tenter de contrôler l'érosion : la minimiser, la prévenir et la réparer[3]. La plus utilisée est la stratégie qui tente de minimiser l'érosion. Elle peut être implémentée par plusieurs techniques incluant la documentation, l'analyse et la surveillance de la conformité de l'architecture[3]. La stratégie pour prévenir l'érosion vise à complètement l'éradiquer[4]. Quant à la réparation, elle est utilisée pour déterminer si une implémentation est conforme à son architecture en réparant les dommages causés par l'érosion et réconciliant l'implémentation avec son architecture[4].
Pour chaque stratégie, il existe un second niveau de catégories classifiant plus précisément les différentes solutions[4] :
- Minimiser
- Processus orienté conformité de l'architecture inclut le processus d'ingénierie logicielle qui assure la conformité de l'architecture pendant le développement et la maintenance du système[4].
- Gestion de l'évolution de l'architecture couvre les méthodes disponibles dans la gestion de l'évolution des spécifications logicielles en parallèle avec son implémentation[4].
- Mise en application des principes architecturales qui incorpore des méthodes et des outils pour transformer des modèles architecturaux en implémentation[4].
- Prévenir
- Liaison de l'architecture vers son implémentation inclut les mécanismes qui associent les modèles architecturaux avec le code source et supporte la capacité de gérer la conformité architecturale à l'exécution[4].
- Adaptation automatique des technologies permet aux systèmes de se reconfigurer eux-mêmes pour s'aligner avec leurs architectures après un changement sur leurs implémentations[5].
- RĂ©parer
- Restauration de l'architecture implique d'extraire l'implémentation architecturale du code source[5].
- Techniques pour découvrir les architectures sont utiles pour susciter l'architecture voulue à partir des propriétés du système[5].
- Méthodes pour réconcilier l'écart entre l'implémentation et l'architecture voulue par le système[5].
Critères importants
VĂ©rification statique ou dynamique
Les vérifications statiques sont effectuées sans exécuter le code. Elles sont faites pendant la compilation d'un système ou pendant sa phase de maintenance où l'application n'est plus connectée à son environnement de production. Elles peuvent être liées à la structure du code et les aspects de l'intégrité de la communication[6].
Il existe trois approches principales pour les vérifications statiques[7] :
- La réflexion par modèles : Cette approche compare deux modèles du logiciel entre eux. Typiquement, entre une architecture visée du logiciel et une architecture basée sur le code source. La comparaison requiert un mapping entre les deux modèles pour effectuer la comparaison. Le mapping doit se faire manuellement par un développeur[7].
- Les règles de conformité entre les éléments de l'architecture : Les règles permettent d'autoriser ou d'interdire les relations entre deux composants de l'architecture. Elles peuvent mettre en évidence les violations comme la réflexion par modèles mais par contre le mapping est fait automatiquement[7].
- Les règles d'accès des composants : L'approche met en place de simples ports pour chaque composants et spécifie les composants qui sont autorisés à y accéder[7].
Les vérifications dynamiques ont deux objectifs : vérifier l'exécution et la cohérence entre l'architecture du système et la spécification définie[8]. Elles sont utilisées comme une protection contre les fautes potentielles à l'exécution. Cette protection est implémentée par un moniteur pour pouvoir réagir aux différentes violations[9]. Les vérifications dynamiques sont effectuées pendant que le système s'exécute et nécessitent donc l'accès à l'état d'exécution des opérations. Ces opérations sont validées par des contraintes architecturales dépendantes d'une solution souvent externe[6].
Ces deux types de vérifications peuvent être utilisés de façon complémentaire pour de la vérification de conformité entre une architecture et son implémentation[10].
Rapprochement entre l’architecture et son implémentation
Les vérifications de conformité se base sur un mapping entre l'architecture et son implémentation. Ce rapprochement est nécessaire pour lancer les vérifications. Il en existe différentes catégories qui sont toutes utilisées par différentes solutions[11] :
- Les conventions de nommage à partir de l'architecture sur l'implémentation du programme. Cette technique peut être étendue par des annotations pour enrichir l'information sur l'architecture en faisant correspondre l'information avec l'implémentation correspondante[11].
- Combiner l'architecture et son implémentation dans une seule spécification. L'architecture fait partie intégrante de l'implémentation. Elle est développée dans l'application cible. Cependant, cette approche demande une plateforme d'exécution permanente[11].
- Spécifier les informations de mapping dans une spécification externe (à la fois de l'architecture et son implémentation). Elle demande un projet séparé pour avoir un mapping explicite pour toutes les fonctionnalités architecturales[11].
Principales approches / Solutions existantes
Principe
PandArch est un framework de vérifications de conformité entre l'architecture et l'implémentation d'un logiciel. Cette solution est designée pour être connectable, automatisée, personnalisable, non intrusive et extensible. Grâce à ces principes, elle vise à limiter les problèmes connus de vérifications en limitant l'impact sur les performances du logiciel cible, quand les vérifications sont actives. L'objectif principal de ce framework est de rendre la vérification de conformité dynamique d'architectures une option viable pour les développeurs[6].
La réalisation de PandArch a été motivée par plusieurs principes importants :
- Connectable : L'application cible peut s'exécuter avec ou sans le framework. Quand la solution n'est pas attachée à l'application, les fichiers compilés ne sont pas manipulés[11],
- Automatisée : La génération des règles de conformité et leurs vérifications sont automatisées[11],
- Non intrusive : Le code source de l'application cible reste inchangé[11],
- Les métriques sur la performance : L'impact sur les performances de l'application cible est minimalisé le plus possible[11],
- Extensible : Le framework peut s'accommoder des modifications sur les règles de conformité[11].
Objectifs
Vérifier la conformité des fonctionnalités dynamiques par rapport à une implémentation n'est pas toujours possible quand le système est déployé dans son environnement de production. De plus, les routines de maintenance modifient les prérequis et les opérations peuvent alors causer une déviation du comportement de l'application en production[12].
PandArch vient proposer une solution pour la détection de violations à l'exécution d'un programme avec ses motivations sur la minimalisation des impacts sur l'application cible. La conformité des fonctionnalités dynamiques inclut l'instanciation à l'exécution, l'invocation de méthodes réflectives, les liaisons dynamiques, la qualité des services, etc[12].
Fonctionnement
La vérification de conformité entre l'architecture et l'implémentation d'un logiciel nécessite l'utilisation d'un système de surveillance pour reconstruire une vue de l'architecture à l'exécution de l'application cible. L'architecture extraite est utilisée pour les vérifications de conformité[12].
L'exécution du mécanisme de vérification architecturale de conformité se base sur une spécification de l'architecture. Cette spécification contient les annotations de mapping entre l'architecture et l'implémentation du logiciel cible. Les contraintes architecturales et les informations sur ce mapping sont extraites à partir de la compilation de cette spécification, et elles sont utilisées par le générateur de règles pour créer l'ensemble des règles de conformité[11].
Parallèlement à cela, le vérificateur de conformité prendra l'ensemble des règles de conformité. Il les validera pendant les évènements d'exécution survenant à l'exécution du programme. Ce processus peut alors produire une série de violations pour notifier l'architecte des dérivations présentes dans l'implémentation à partir de l'architecture[13].
Principe
Card (de l'anglais Controlling Architectural Degradation) est un outil pour identifier l'érosion de l'architecture d'un programme Java. Cette solution a été développée pour être automatisée et accessible. Elle n'a pas besoin de spécifications, de descriptions architecturales et elle peut se suffire à elle-même, aucune dépendance n'est nécessaire. Elle utilise un langage de modélisation répandue et couramment utilisé par les développeurs, l'UML 2.0[14].
Il existe quelques fonctionnalités importantes dans Card :
- Un ensemble de règles définissant la conformité entre les diagrammes de classes et les diagrammes de séquences de l'UML 2.0 et l'implémentation Java[14].
- Le concept d'une spécification maitre, qui peut être soit le modèle soit l'implémentation[14].
- Une extension Eclipse qui implémente la vérification de conformité comme définit dans les règles de l'architecte[14].
Objectifs
L'érosion architecturale est un problème bien connu et il existe déjà plusieurs approches pour prévenir, minimiser ou réparer ces érosions, principalement basé sur la concept de conformité. Cependant, la plupart de ces approches demande une rigueur stricte sur la spécification de l'architecture du logiciel cible avec l'utilisation d'un ou plusieurs outils. Des interventions manuelles sont aussi nécessaire pour le processus de vérification qui limite sa potentielle utilisation en milieu d'entreprise[14].
Les objectifs de Card tentent de résoudre tous ces problèmes en proposant un outil pour identifier l'érosion architecturale d'un programme comme solution envisageable par les entreprises[14].
Fonctionnement
Son fonctionnement se base sur l'utilisation de deux catégories de règles de conformité : des règles structurelles et d'interaction. La première catégorie concerne la structure statique d'une architecture, comme de l'héritage entre deux éléments. La seconde catégorie concerne l'interaction entre les éléments comme l'ordre des méthodes d'invocation ou la communication des éléments. Les règles structurelles sont déduites à partir du diagramme de classes de l'architecture de l'application cible alors que les règles d'interaction sont dérivés à partir du diagramme de classes et du diagramme de séquences[10].
Principe
ArchJava est une extension du langage Java qui permet de mêler la spécification de l'architecture d'un logiciel avec son implémentation. L'architecture est décrite dans le même langage que son implémentation ce qui permet d'exprimer efficacement les contraintes architecturales[15].
Objectifs
Cette approche qui allie architecture et implémentation a pour principaux objectifs :
Fonctionnement
Pour permettre aux développeurs de décrire l'architecture du logiciel, ArchJava ajoute au langage Java de nouveaux éléments dédiés à la description de l'architecture[16]. Les éléments ajoutés sont :
- Les composants (components) qui sont un type spécial d'objet Java et communiquent entre eux de façon structurée[17],
- Les ports représentent un channel de communication entre un composant et un ou plusieurs autres composants[17],
- Les connexions (connect) qui relient deux ou plusieurs ports ensemble[17].
Avec ces éléments, le développeur spécifie le comportement de la fonctionnalité sur laquelle il travaille. Les échanges et dépendances sont spécifiés en fonction des contraintes architecturales au sein même du code[17].
Principe
SAVE (Software Architecture Visualization and Evaluation) est un outil qui permet d'extraire l'architecture d'un logiciel à partir de son code source pour ensuite la comparer à l'architecture visée initialement[18].
Objectifs
SAVE a pour objectif d'aider le développeur en lui fournissant une vision de l'architecture basée sur l'implémentation pour lui exposer les violations des contraintes architecturales. L'outil permet aussi de mettre en évidence les parties de l'application qui ont besoin de plus d'attention de la part du développeur. Elles peuvent réduire de manière significative le nombre de violations architecturales[18].
Fonctionnement
Le processus pour appliquer SAVE est constitué de six étapes [18]:
- Capturer et modéliser l'architecture visée[18].
- Extraire l'architecture basée sur l'implémentation pour abstraire la structure du code et de ses dépendances[18].
- Faire le mapping entre l'architecture visée et l'architecture d'implémentation. Le mapping est effectué manuellement par les architectes et les développeurs chargés du design[18].
- Faire la comparaison entre l'architecture visée et l'architecture d'implémentation en fonction du mapping effectué à l'étape précédente. SAVE signale chaque élément de l'architecture d'implémentation qui ne correspond pas à l'architecture visée[18].
- Analyser chaque violation pour déterminer si elle est critique ou non. Cette étape est aussi manuelle mais facilitée par la capacité de l'outil à parcourir le code source[18].
- Etablir un plan pour retirer les violations considérées critiques. La complexité de cette étape dépend du nombre de violations signalées. Un petit nombre de violations est facile à retirer d'un système, tandis qu'un grand nombre de violations peut conduire à un refactoring du code source[18].
Vérification via des séquences à l'exécution
Cette solution propose une méthode semi-automatique et dynamique de vérification de conformité[19].
Principe
L'approche principale de cette méthode est de pouvoir vérifier la conformité d'un système en retraçant son exécution par rapport à la description de son implémentation. La méthode est basée sur la combinaison de deux techniques. La première est une technique quant au respect d'une implémentation par rapport aux règles initiales de son architecture. Elle fait le lien entre une architecture et son implémentation pour en ressortir les violations. La seconde repose sur le principe d'injection, les règles architecturales sont insérées dans la technologie d'implémentation permettant une approche de développement plus orientée selon son architecture[19].
Objectifs
L'objectif final de ce procédé est d'aider l'ingénieur logiciel à s'assurer de la fiabilité du système implémenté. D'abord en démontrant que l'architecture de son implémentation a bien les propriétés désirées puis en maintenant la correspondance vis-à -vis de son architecture initiale[20].
Fonctionnement
La méthode est constituée de deux étapes[21] :
- La première consiste en l'extraction des données à l'exécution du système, pour en ressortir une séquence de messages représentant l'exécution du système sous forme de chaîne de caractères[22].
- La seconde applique un filtre sur la séquence extraite qui contient des messages non pertinents. Afin de réduire la trace d'exécution, un filtre est appliqué pour obtenir une trace plus pertinente par rapport à celle prescrite par l'architecture. Les séquences extraites consistent en des messages enregistrés lors de l'exécution d'un cas d'utilisation du système[22].
La séquence prescriptive est établie par rapport aux spécificités de l'architecture initiale. Par exemple, si le message A apparait avant le message B alors il est prescrit que le message A doit avoir eu lieu avant le message B[22].
Cette méthode est donc dynamique car elle manipule des données à l'exécution du système. Elle est aussi semi-automatique car, finalement, c'est l'ingénieur même qui juge si la séquence extraite est conforme ou non à la séquence prescriptive. En effet, même si visualiser les différences entre les deux séquences peuvent être facilitées par un outil, seul un ingénieur peut décider s'il y a une violation par rapport à l'architecture initiale[21].
Évaluations des solutions existantes
Solutions | Avantages | Inconvénients |
---|---|---|
PandArch |
|
|
Card |
|
|
ArchJava |
|
|
SAVE | ||
Vérification via des séquences à l'exécution |
|
|
Références
- De Silva 2012, p. 132
- De Dimech 2013, p. 208
- De Dimech 2013, p. 211
- De Silva 2012, p. 134
- De Silva 2012, p. 135
- De Silva 2013, p. 241
- Knodel 2007, p. 2
- Yang 2011, p. 2
- Yang 2011, p. 1
- De Dimech 2013, p. 212
- De Silva 2013, p. 242
- De Silva 2013, p. 240
- De Silva 2013, p. 243
- De Dimech 2013, p. 209
- Aldrich 2002, p. 187
- Aldrich 2002, p. 188
- Aldrich 2002, p. 189
- Lindvall 2008, p. 99
- Medvidovic 2013, p. 1
- Medvidovic 2013, p. 6
- Medvidovic 2013, p. 2
- Medvidovic 2013, p. 3
- De Silva 2013, p. 245
- De Silva 2013, p. 246
- De Silva 2013, p. 247
- De Dimech 2013, p. 218
- De Dimech 2013, p. 219
- De Dimech 2013, p. 222
- Aldrich 2002, p. 197
- Lindvall 2008, p. 100
- Lindvall 2008, p. 101
Bibliographie
- (en) Lakshitha De Silva et Dharini Balasubramaniam, « PANDArch: A Pluggable Automated Non-intrusive Dynamic Architecture Conformance Checker », Software Architecture, Springer Berlin Heidelberg, lecture Notes in Computer Science,‎ , p. 240-248 (ISBN 978-3-642-39030-2 et 978-3-642-39031-9, DOI 10.1007/978-3-642-39031-9_21)
- (en) Claire Dimech et Dharini Balasubramaniam, « Maintaining Architectural Conformance during Software Development: A Practical Approach », Software Architecture, Springer Berlin Heidelberg, lecture Notes in Computer Science,‎ , p. 208-223 (ISBN 978-3-642-39030-2 et 978-3-642-39031-9, DOI 10.1007/978-3-642-39031-9_19)
- (en) Lakshitha de Silva et Dharini Balasubramaniam, « Controlling software architecture erosion: A survey », Journal of Systems and Software, vol. 85, no 1,‎ , p. 132-151 (ISSN 0164-1212, DOI 10.1016/j.jss.2011.07.036, lire en ligne, consulté le )
- (en) Hongwei Yang, « A Runtime Model Checker for Dynamic Software Based on Aspect-Oriented Programming », Intelligent Systems and Applications (ISA), 2011 3rd International Workshop,‎ , p. 1-3 (DOI 10.1109/ISA.2011.5873401)
- (en) Nenad Medvidovic et Daniel Popescu, « Ensuring Architectural Conformance in Message-Based Systems », IEEE Concurrency,‎
- (en) Peyman Oreizy, Nenad Medvidovic et Richard N. Taylor, « Runtime software adaptation: framework, approaches, and styles », ICSE Companion '08 Companion of the 30th international, New York, NY, USA, iCSE Companion '08,‎ , p. 899–910 (ISBN 978-1-60558-079-1, DOI 10.1145/1370175.1370181, lire en ligne, consulté le )
- (en) Jonathan Aldrich, Craig Chambers et David Notkin, « ArchJava: Connecting Software Architecture to Implementation », ICSE '02 Proceedings of the 24th International Conference, New York, NY, USA, iCSE '02,‎ , p. 187–197 (ISBN 1-58113-472-X, DOI 10.1145/581339.581365, lire en ligne, consulté le )
- (en) M. Lindvall et Dirk Muthig, « Bridging the Software Architecture Gap », Computer, vol. 41, no 6,‎ , p. 98-101 (ISSN 0018-9162, DOI 10.1109/MC.2008.176)
- (en) Jens Knodel et Daniel Popescu, « A Comparison of Static Architecture Compliance Checking Approaches », Software Architecture, 2007. WICSA '07. The Working IEEE/IFIP Conference,‎ , p. 12-12 (DOI 10.1109/WICSA.2007.1)