Mono2Micro-MDE : Une approche de bout en bout pour migrer une application monolithique vers une architecture orientée microservice

Illustration de l'image vedette

Retrouvez la première approche de la migration dans ces articles : article 1 & article 2

Dans cette section, nous présentons un aperçu général des différentes phases qui constituent notre flux de travail global de migration basé sur l'EDM. En bref, notre flux de travail (voir la figure 1) englobe 4 étapes importantes :

  1. Extraction d'un modèle à partir de l'application source.
  2. Identifier le MSA candidat de l'application et l'incorporer dans un modèle de pivot intermédiaire.
  3. Transformer le modèle pivot pour obtenir le modèle MSA cible, composé de plusieurs microservices et de leurs entités associées.
  4. Génération et conditionnement du code source cible à partir du modèle MSA cible pour le rendre déployable.
Processus de migration global basé sur le MDE
Figure 1 : Le processus global de migration basé sur l'EDM avec les modèles et les méta-modèles utilisés.

Ce flux de travail est principalement orienté PIM au lieu d'être orienté PSM (Platform-Specific Model), comme c'est le cas avec ses homologues ad-hoc. En particulier, chaque modèle intervenant dans le processus est décrit par un méta-modèle correspondant.
De plus, la transition d'un modèle source à un autre modèle cible nécessite un ensemble de règles de transformation de modèle, faisant correspondre un/plusieurs éléments de la source à un/plusieurs éléments de la cible. Ces transformations se produisent au niveau du domaine, et sont donc moins contraintes par les technologies et les plates-formes de leurs applications, ce qui les rend par conséquent plus réutilisables pour les applications orientées objet en général.
En outre, nos contributions s'étendent sur la phase d'incorporation du candidat MSA, la phase de transformation du modèle et la phase d'exportation du modèle du flux de travail.

Extraction de modèles

La première phase du processus de migration basé sur MDE consiste à analyser le code source du projet et à extraire son modèle de son AST (Abstract Syntax Tree) correspondant. En fonction du code source du projet, un analyseur syntaxique correspondant peut être utilisé pour extraire son AST.

Identification et incorporation du candidat MSA

La deuxième phase consiste à extraire l'architecture orientée microservices du modèle source et à l'incoporer dans un modèle pivot (Figure 2). Concrètement, nous divisons cette phase en deux étapes :

  1. L'identification d'un candidat MSA,
  2. Son incorporation dans un modèle de pivot.
Figure 2 : L'étape d'identification et d'incorporation de la migration guidée par le modèle.
Figure 2 : L'étape d'identification et d'incorporation de la migration guidée par le modèle

Identification de la ZSM candidate

L'identification des microservices est une tâche d'ingénierie logicielle qui se déroule au niveau architectural d'un monolithe et qui vise à appliquer des techniques d'ingénierie inverse sur ses artefacts logiciels afin d'identifier les candidats microservices correspondants et leur description dans un MSA. Le processus d'identification est basé sur un ensemble de modèles/stratégies, de contraintes et d'attributs de qualité qui façonnent et guident son déroulement.
Dans le cadre de ce projet, nous nous concentrons sur l'identification de microservices à partir du code source d'une application monolithique orientée objet. Une façon courante d'y parvenir est une approche basée sur les graphes qui utilise des techniques de regroupement et de visualisation des graphes pour identifier les microservices candidats à partir du code source de l'application monolithique. En particulier, nous appliquons l'approche proposée dans le document Article en première partie qui extrait l'architecture en couches avant de partitionner ses artefacts à l'aide d'un algorithme de clustering pour représenter la MSA candidate comme un ensemble de clusters LayerEntity.
L'étape initiale de rétro-ingénierie de l'architecture en couches constitue une tâche importante pour le processus global de migration. De plus, dans la transformation guidée par le modèle, elle a également pour fonction de structurer l'architecture interne de chaque microservice identifié. Une fois que la MSA candidate est obtenue à partir de l'étape d'identification, elle sera transmise à l'architecte logiciel pour validation. En conséquence, l'architecte peut également interagir avec la MSA candidate pour la modifier. Sinon, le processus d'identification se termine et la MSA candidate peut être incorporée dans un nouveau modèle. En outre, pour accompagner le processus itératif qui sous-tend la mise en œuvre de notre migration, nous avons ajouté un processus d'identification manuel pour permettre aux experts d'affiner l'architecture des microservices.

Candidat à l'incorporation de l'AMS

La deuxième étape consiste à incorporer le MSA candidat issu du processus d'identification des MSA dans un méta-modèle pivot intermédiaire, à savoir le méta-modèle pivot Monolithic-to-Microservices (M2M-Pivot-MM).
En effet, le processus d'identification de la MSA ne fournit qu'un cadre incomplet décrivant les grandes lignes du modèle de la MSA cible sous la forme d'une MSA candidate. Par conséquent, pour compléter ce processus, nous devons décrire la MSA candidate par un méta-modèle correctement dédié, suivi par l'application des transformations nécessaires sur son modèle pour refléter réellement la description de la MSA identifiée.
En outre, notre flux de travail traite des AMS candidats extraits par des processus d'identification qui utilisent des algorithmes de regroupement basés sur des graphes. Il en résulte des descriptions de MSA avec une interface spécifique qui expose les clusters de classe des MSA candidats et leurs entités associées. Par conséquent, nos règles d'incorporation sont conceptuellement dépendantes de cette interface.
Néanmoins, nous cherchons à rendre notre approche aussi réutilisable et générique que possible afin de réduire les efforts de migration. En d'autres termes, nous souhaitons rendre ces règles d'incorporation indépendantes de l'interface de la description MSA. Cela s'avère nécessaire pour les implémenter une fois et les réutiliser à travers différents flux de travail employant différents processus d'identification qui produisent des descriptions MSA avec différentes interfaces.
Par conséquent, le mécanisme d'incorporation utilise le modèle de conception Adapter. En particulier, un adaptateur de MSA candidate fait correspondre l'API d'une MSA candidate à l'API attendue par le méta-modèle pivot. (voir la figure 3). En d'autres termes, l'adaptateur de MSA candidat oblige tout MSA candidat identifié à mettre en œuvre son interface attendue, à savoir fournir des moyens d'accès au MSA, à ses microservices candidats, à leurs classes d'affaires, de données et d'utilité, ainsi qu'à leurs interfaces fournies et requises.
Une fois que la MSA candidate met en œuvre l'interface requise par l'adaptateur, ce dernier fait correspondre chaque entité extraite de la MSA candidate à son entité correspondante dans le modèle pivot.

Figure 2 : Adaptation de la MSA candidate identifiée et incorporation des iuts dans le modèle pivot
Figure 3 : Adaptation de la MSA candidate identifiée et incorporation des iuts dans le modèle pivot

Transformation du modèle

La troisième phase du processus de migration basé sur l'EDM est la transformation du modèle. (voir la figure 4). Elle consiste à transformer le modèle pivot, décrit par le M2M-Pivot- MM, pour obtenir le modèle cible, décrit par le méta-modèle de migration pilotée par le modèle de l'architecture des microservices (MMM).

Figure 4 : La phase de transformation du modèle du processus global de migration basé sur l'EDM
Figure 4 : La phase de transformation du modèle du processus global de migration basé sur l'EDM

Maintenant que nous avons récupéré l'architecture et identifié le MSA qu'elle contient, nous pouvons la matérialiser par cette étape de transformation, où tous les clusters récupérés seront déployés dans leur propre microservice.
Or, les classes de bordure ont des dépendances avec des classes appartenant à un autre cluster. Ces dépendances entre les classes de différents microservices sont appelées violations de l'encapsulation des microservices. Toutes les violations doivent être traitées par des méthodes de refactoring qui convertissent les dépendances de type OO en type MS avant qu'un microservice puisse être encapsulé puis généré.
Pour encapsuler les microservices, il faut résoudre le mécanisme de partage entre les candidats microservices. La caractéristique d'un MSA d'utiliser la communication orientée message entre différents microservices (invocations de méthodes entre classes de différents clusters) doit être limitée à un ensemble d'interfaces fournies et requises qui définissent les services web qu'il fournit et ceux qu'il consomme. En outre, les appels de communication interprocessus (IPC) entre microservices sont limités à la communication basée sur les valeurs (primitives et données sérialisées). Ces dépendances OO explicites, ainsi que les dépendances implicites entre clusters doivent être traitées pour encapsuler complètement les candidats microservices. Le mécanisme d'héritage et la gestion des exceptions sont les deux principaux mécanismes OO implicites qui doivent être traités. En particulier, une violation d'héritage est définie comme une classe qui a une super-classe qui appartient à un autre cluster. La violation du traitement des exceptions est définie comme une classe lançant une exception qui est attrapée par une classe appartenant à un autre cluster.
Ces deux mécanismes OO doivent être traités et transformés en dépendances de type MS.
Enfin, les MSA générés après l'étape de transformation doivent adhérer à 2 caractéristiques opérationnelles supplémentaires : (1) les microservices doivent s'exécuter sur leurs propres
et (2) ils doivent être automatiquement déployables. Pour se conformer à ces caractéristiques opérationnelles, chaque microservice doit définir un projet indépendant qui doit être configuré pour le déploiement dans le Cloud. Ces deux caractéristiques doivent être prises en compte lors de la génération du code source de chaque microservice. (Pour en savoir plus sur la violation de l'encapsulation, consultez cet article.)

En particulier, nous distinguons deux types différents de transformations de modèles, chacun d'entre eux accomplissant un objectif bien défini au cours du processus de migration : (1) la résolution des violations de l'encapsulation des microservices et (2) la conversion Pivot2MMM.
Pour comprendre les raisons de la distinction entre ces deux types de transformations de modèles, nous devons commencer par examiner leur entrée, à savoir le modèle pivot. Comme mentionné précédemment, le modèle pivot est obtenu après les phases d'identification et d'incorporation des MSA candidats du processus de migration. En particulier, le modèle pivot incorpore le MSA candidat identifié, composé de tous les microservices candidats, de sorte que chaque microservice candidat est représenté comme un cluster de classes obtenu à partir du modèle source original.
L'acte de créer des candidats microservices à partir d'un ensemble de classes monolithiques est défini comme l'encapsulation de microservices. Dans ce contexte, chaque microservice est sa propre application.
Par conséquent, l'accès des classes résidant dans un microservice doit être limité aux classes appartenant à d'autres microservices. En d'autres termes, un microservice encapsule son propre ensemble de classes. Lorsqu'une classe encapsulée par un microservice dépend d'une classe encapsulée par un autre microservice, une violation de l'encapsulation du microservice se produit. Ces dépendances au niveau des classes comprennent les invocations de méthodes, les instanciations de classes, les accès aux attributs publics, les héritages de classes, les implémentations d'interfaces par les classes, entre autres.
Ainsi, nous observons que des dépendances au niveau des classes existent toujours entre les classes appartenant à différents candidats microservices dans le modèle pivot. (voir la figure 4)malgré l'étape d'identification des microservices. En effet, la tâche d'identification des microservices ne peut pas éliminer complètement ces dépendances, mais peut au mieux essayer de les minimiser.
Néanmoins, un MSA bien conçu devrait être exempt de telles violations. Ainsi, avant la transformation du modèle pivot en modèle cible, nous devons identifier ces violations dans le modèle pivot et les résoudre comme il se doit. Par conséquent, nous décomposons notre phase de transformation du modèle en deux étapes permettant d'atteindre respectivement les objectifs suivants :

  1. Identifier et résoudre les violations de l'encapsulation des microservices dans le modèle pivot.
  2. Convertir le modèle pivot sans violation en modèle cible.

Exportation de modèles

La quatrième et dernière phase du processus de migration basé sur les MDE consiste à générer, empaqueter et déployer le code cible du projet sur la base du modèle MSA cible correspondant. En fonction du modèle MSA cible, un exportateur de modèle peut être configuré par un expert pour choisir comment les artefacts souhaités seront générés. En bref, les configurations comprennent le choix des technologies du cadre cible, des constructeurs de projets, des gestionnaires de dépendances et d'autres technologies pertinentes pour les microservices, telles que la technologie de conteneurisation, les coupe-circuits, la découverte de services, les clients API ou les protocoles de communication.
Par exemple, si le modèle cible doit être exporté sous forme d'un ensemble de projets Spring Boot2, l'exportateur de modèle doit générer un projet Spring Boot pour chaque microservice du modèle MSA cible. En outre, il doit s'assurer que les packages des projets nouvellement générés importent correctement les dépendances Spring Boot nécessaires. Cela se fait à l'aide des constructeurs de projets et des gestionnaires de dépendances (par exemple, Maven, Gradle, etc.) utilisés avec le monolithe source. En outre, l'exportateur de modèle cible doit générer une image de conteneur pour chaque microservice du modèle MSA cible, décrivant les détails de configuration nécessaires à la création et au déploiement de son conteneur correspondant. Par exemple, si l'exportateur de modèle est configuré pour déployer chaque microservice du modèle MSA cible dans un conteneur Docker3, un Dockerfile correspondant doit être créé pour décrire son image Docker.
Enfin, un fichier de configuration de niveau MSA peut être généré pour décrire les détails de configuration de niveau MSA de ses microservices. Dans le cas de la conteneurisation Docker, par exemple, un fichier docker-compose peut être généré pour contrôler, configurer et déployer chaque microservice via son image Docker.

Pour résumer

Dans ce projet, nous présentons deux approches différentes pour migrer une architecture monolithique vers une architecture MSA.
La première méthode consiste à transformer le code source pour le faire correspondre à l'architecture (représenté en bleu dans la figure 6)tandis que dans la seconde méthode, nous passons par un modèle pour représenter l'architecture cible, puis nous générons le code qui lui correspond. (représenté en violet dans la figure 6).

Deux méthodes pour migrer une architecture monolithique vers une architecture MSA
Figure 6 : Deux méthodes pour migrer une architecture monolithique vers une architecture MSA

Références

[1] E. Barry, C. Kemerer et S. Slaughter, " Toward a detailed classification scheme for software maintenance activities ", AMCIS 1999 Proceedings, p. 251, 01 1999.
[2] J. Bisbal, D. Lawless, B. Wu, et J. Grimson, "Legacy information system migration : A brief review of problems, solutions and research issues", IEEE software, vol. 16, no. 5, pp. 103-111, 06 1999.
[3] I. Sommerville, Software Engineering, 9th ed. USA : Addison-Wesley Publishing Company, 2010.
[4] J. Bisbal, D. Lawless, B. Wu, et J. Grimson, "Legacy information systems : Issues and directions," Software, IEEE, vol. 16, pp. 103 - 111, 10 1999.
[5] C. Wagner, Model-Driven Software Migration : A Methodology : Reengineering, Recovery and Modernization of Legacy Systems. Springer Science & Business
Media, 03 2014.
[6] J. Lewis et M. Fowler, " Microservices : Une définition de ce nouveau terme architectural ", https://martinfowler.com/articles/microservices.html, 2014, consulté le 2020-06-20.
[7] X. J. Hong, H. S. Yang, et Y. H. Kim, " Performance analysis of restful api and rabbitmq for microservice web application ", in 2018 International Conference on Information and Communication Technology Convergence (ICTC). IEEE, 10 2018, p. 257-259.
[8] C. Richardson, Microservices Patterns : With Examples in Java. Manning Publications, 2018. [En ligne]. Disponible à l'adresse suivante : https://books.google.de/books?id=UeK1swEACAAJ
[9] S. Newman, Building Microservices : Designing Fine- Grained Systems. " O'Reilly Media, Inc. ", 2015.
[10] P. Zaragoza, A.-D. Seriai, A. Seriai, H.-L. Bouziane, A. Shatnawi, et M. Derras, "Refactoring monolithic object-oriented source code to materialize microserviceoriented architecture," in ICSOFT, 2021.
[11] F. Fleurey, E. Breton, B. Baudry, A. Nicolas et J.-M. J'ez'equel. J'ez'equel, "Model-driven engineering for software migration in a large industrial context," in Model Driven Engineering Languages and Systems, G. Engels, B. Opdyke, D. C. Schmidt, and F. Weil, Eds. Berlin, Heidelberg : Springer Berlin Heidelberg, 2007, pp. 482-497.
[12] D. C. Schmidt, "Guest editor's introduction : Modeldriven engineering," Computer, vol. 39, no. 2, p. 25-31, Feb. 2006. [En ligne]. Disponible : https://doi.org/10.1109/ MC.2006.58
[13] M. Waseem, P. Liang, G. M'arquez, M. Shahin, A. A. Khan, et A. Ahmad, "A decision model for selecting patterns and strategies to decompose applications into microservices," 2021.
[14] A. Selmadji, A.-D. Seriai, H. L. Bouziane, R. Oumarou Mahamane, P. Zaragoza, et C. Dony, "From monolithic architecture style to microservice
one based on a semi-automatic approach", dans 2020 IEEE International Conference on Software Architecture (ICSA), 2020, pp. 157-168.
[15] S. Demeyer, S. Tichelaar et S. Ducasse, "Famix 2.1 - le modèle d'échange d'informations Famix", Université de Berne, Tech. Rep, 01 2001.
[16] S. Demeyer, S. Ducasse, et E. Tichelaar, "Why famix and not uml ? uml shortcomings for coping with roundtrip engineering," in In Proceedings of¡¡ UML'99¿¿, Fort Collins. Citeseer, 09 1999.
[17] S. Tichelaar, S. Ducasse, et S. Demeyer, "Famix and xmi," in Proceedings Seventh Working Conference on Reverse Engineering. IEEE, 02 2000, pp. 296 - 298.
[18] S. Ducasse, M. Lanza et E. Tichelaar, "Moose : an extensible language-independent environment for reengineering object-oriented systems", in Proceedings of the Second International Symposium on Constructing Software Engineering Tools (CoSET 2000), vol. 4, Citeseer, 04 2000.
[19] S. Ducasse, N. Anquetil, M. Bhatti, A. Hora, J. Laval et T. Girba, "Mse and famix 3.0 : an interexchange format and source code model".
family", Laboratoire d'Informatique Fondamentale de Lille, Rapport de recherche, 05 2012. [En ligne]. Disponible sur : https://hal.inria.fr/hal-00646884
[20] F. Rademacher, J. Sorgalla, S. Sachweh et A. Z¨undorf, " Towards a viewpoint-specific metamodel for modeldriven development of microservice architecture ", 04 2018.
[21] A. Levcovitz, R. Terra et M. T. Valente, "Towards a Technique for Extracting Microservices from Monolithic Enterprise Systems", CoRR, vol. abs/1605.0, 2016. [En ligne]. Disponible à l'adresse suivante : http://arxiv.org/abs/1605.03175
[22] R. Chen, S. Li et Z. Li, " From Monolith to Microservices : A Dataflow-Driven Approach ", Proceedings Asia-Pacific Software Engineering Conference, APSEC, pp. 466-475, 2018.
[23] M. Gysel, L. K¨olbener, W. Giersche et O. Zimmermann, "Service cutter : A systematic approach to service decomposition ", dans European Conference on Service-Oriented and Cloud Computing, 09 2016, pp. 185-200.
[24] G. Mazlami, J. Cito et P. Leitner, " Extraction of Microservices from Monolithic Software Architectures ", dans 2017 IEEE ICWS. IEEE, juin 2017, p. 524-531.
[En ligne]. Disponible sur : http://ieeexplore.ieee.org/document/8029803/
[25] C. Pahl et P. Jamshidi, " Microservices : A systematic mapping study ", in Proceedings of the 6th International Conference on Cloud Computing and Services Science Volume 1 and 2, ser. CLOSER 2016. Setubal, PRT : SCITEPRESS - Science and Technology Publications, Lda, 2016, p. 137-146. [En ligne]. Disponible : https : //doi.org/10.5220/0005785501370146.
[26] Z. Al-Shara, " Migrating Object Oriented Applications into Component-Based ones ", Thèses, Université Montpellier, Nov. 2016. [En ligne]. Disponible : https :
//tel.archives-ouvertes.fr/tel-01816975
[27] A. Bucchiarone, K. Soysal et C. Guidi, "A modeldriven approach towards automatic migration to microservices", in Software Engineering Aspects of Continuous Development and New Paradigms of Software Production and Deployment. Springer International Publishing, 2020, pp. 15-36.

Plus ...

Retour en haut