2.49k likes | 2.69k Views
Jacques Augustin Nov- Jan 2012. Cours d’Architecture des Systèmes d'Information EFREI. Sommaire. Introduction Rôle de l’architecte de systèmes d’information Architecture et intégration de systèmes Cartographie du SI Considérations stratégiques Conception et modélisation Middlewares
E N D
Jacques Augustin Nov- Jan 2012 Cours d’Architecture des Systèmes d'Information EFREI
Sommaire Introduction Rôle de l’architecte de systèmes d’information Architecture et intégration de systèmes Cartographie du SI Considérations stratégiques Conception et modélisation Middlewares Les premières technologies : DCOM et CORBA Middleware transactionnel : COM+ et EJB Middleware orienté messages (MOM) Architecture orientée services Conception et mise en œuvre Orchestration et mise en œuvre Persistance et stockage de données Couche de persistance et l’outil Hibernate Interaction avec les systèmes de gestion de bases de données Problématique particulière des migrations de données
Introduction But de cette formation Vous donner les éléments de base d’architecture de systèmes d’information. Deux parties avec de fortes adhérences : architecture systèmes et réseaux. Agrégation et orchestration de connaissances diverses (technologies, conception et programmation, bases de données et réseaux) Organisation du cours 5 cours 3 cours 100% théoriques en nov-déc 2 cours 50/50 théorie / pratique
Introduction Architecture de systèmes d’information Architecture (Larousse) : "Art de concevoir et de construire un bâtiment selon des partis pris esthétiques et des règles techniques et déterminés". Ne pas confondre avec architecture des ordinateurs Rôle d’un architecte Concevoir les différentes briques du système d’information et s’assurer de leur interopérabilité. Il veille aussi à l’évolution de ces briques. Il doit s’assurer d’une bonne orchestration de ces briques en termes de qualité, performance, de flexibilité et de sécurité. Positionnement stratégique par rapport au fonctionnement de l’entreprise.
Introduction Architecture et intégration de systèmes L’intégration de systèmes est avant tout une démarche logicielle. L’architecte va plus loin que l’intégrateur en intégrant des paramètres d’urbanisation, des règles d’entreprise, des contraintes d’harmonisation et de sécurité. Les compétences de l’architecte englobent la programmation, les réseaux, les bases de données, les mainframes, les traitements batchs, les technologies Web et les règles métier de l’entreprise. Ses connaissances doivent être constamment à jour dans tous ces domaines. Il assiste efficacement le DSI et participe à toutes les décisions stratégiques concernant le système d’information. Il a une connaissance rigoureuse et exacte de la cartographie du système d’information.
Introduction Cartographie du SI Diagramme illustrant toutes les briques d’un système d’information.
Introduction Considérations stratégiques L’architecte de SI doit constamment jauger ses décisions à la lumière des questions suivantes : Quels sont les avantages et inconvénients techniques de cette approche? Cette solution est-elle flexible? Quel est le coût de mise en œuvre et de maintenance? Cette technologie a-t-elle un avenir? Approche "custom" ou "package" ? Le niveau de performances est-il acceptable? Le niveau de qualité est-il suffisant? La solution est-elle fiable et sécurisée? Quel est le retour sur investissement (ROI) de cette solution ? Cela vaut-il la peine de remplacer/faire évoluer l’existant?
Design patterns : définition Design patterns Les problèmes auxquels font face concepteurs et développeurs sont rarement exceptionnels. Ils sont en fait souvent récurrents. Et la réapparition systématique de ces problèmes a poussé la communauté des concepteurs à échafauder des solutions réutilisables. Ainsi est née une approche visant à élever la réutilisabilité au niveau de la conception et de l'architecture des systèmes orientés objets, par l’emploi de modèles capturant la sémantique et la structure de solutions utilisées de façon récurrente pour résoudre des problèmes survenant dans des contextes similaires. Un patron est donc une solution répondant à un problème récurrent, dans un contexte spécifique. Connaître les principaux patrons est très utile à tout développeur du monde objet, surtout dans le cadre de grands projets (basés sur le modèle objet). En effet, l'appréhension d'un système développé en utilisant des patterns est grandement facilitée, puisque leur identification permet de comprendre plus vite les différentes parties du système en question et d'avoir ainsi une vue de plus haut niveau plus rapidement.
Différents types de patterns Patterns architecturaux Ce sont des modèles pour des architectures logicielles concrètes et peuvent donc être vus comme des patrons à grande échelle. Ils spécifient les différents sous-systèmes et composants d'un système, leurs responsabilités, ainsi que les règles d'organisation de leurs interrelations. L'un des modèles architecturaux les plus connus est le modèle MVC (Model – View – Controller). Patterns de conception Un patron de conception fournit un schéma pour raffiner les sous-systèmes ou les composants d'un système logiciel. Il décrit une structure de composants communiquant entre eux et solutionnant un problème de conception récurrent. On peut compléter cette définition en ajoutant la notion de contexte attaché au problème et indissociable de celui-ci. Un patron de conception peut donc être vu comme la description d'un problème et de sa solution.
Classification des patterns Patterns : classification Le GoF (Gang of Four, nom donné aux auteurs de « Design Patterns – Catalogue de modèles de conceptions réutilisables) propose une classification des design patterns suivant deux critères : Le rôle du modèle, qui traduit ce qu'il fait : créateur : création des objets. Ces patrons fournissent des interfaces de création des objets, évitant ainsi l'instanciation directe des objets. Le programme gagne en flexibilité en décidant quels objets doivent être créés pour un cas donné. Exemples : fabrique (abstract factory, factory method), singleton structurel : composition des classes ou des objets. Ces patrons servent à regrouper des objets dans des structures plus grandes, comme par exemple des interfaces utilisateur complexes. Exemples : adaptateur, composite, décorateur, façade, proxy comportemental : définition des interactions entre classes et objets, et de la répartition des responsabilités. Ces patrons définissent une communication entre les objets. Exemples : commande, itérateur, observateur, stratégie Le domaine (ou la portée) du modèle, qui précise si le modèle s’applique à des classes ou à des objets : les modèles de classes traitent des relations entre les classes et leurs sous-classes les modèles d'objets traitent des relations entre les objets
Exemple de pattern Patterns : exemple Le pattern Singleton Ce modèle créateur permet de s'assurer que la classe n'aura qu'une seule instance, accessible par un point d'entrée unique (une méthode) bien déterminé. Implémentation L’instance unique est conservée comme membre de classe (protégé pour permettre l’héritage), créée par un constructeur accessible uniquement par la classe et ses dérivées (donc également en accès protégé). Le point d’entrée est une méthode publique statique (ne nécessitant heureusement la création préalable d’aucune instance de singleton).
Exercice Singleton Un singleton sert à contrôler le nombre d'instances d'une classe présent à un moment donné. C'est souvent très pratique pour les classes sans état et effectuant toujours les mêmes traitements. Un singleton est construit grâce à des méthodes de classes. Ces méthodes appartiennent à une classe et peuvent être accédées indépendamment de l'objet. Compléter le code suivant pour implémenter correctement le pattern Singleton public CanvasFactory { /** Donnée de classe contenant l'instance courante */ private ??? CanvasFactory instance = new CanvasFactory(); /** Constructeur privé interdisant l'instanciation en dehors de cette classe */ ??? CanvasFactory () {} /** Singleton de la classe courante */ public ??? CanvasFactory getInstance() { ??? ; } ... } Typiquement l'usage de la classe CanvasFactory se fera ainsi : CanvasFactory cf = CanvasFactory.getInstance();
Le pattern architectural MVC Introduction (1/2) Le concepteur d'applications interactives (avec interface homme-machine (IHM)) doit faire face à un problème fondamental qui est celui de la flexibilité de ses interfaces. D’une part, divers utilisateurs de son application doivent accéder aux mêmes données, avec des interfaces hétérogènes, pouvant dépendre de leurs préférences, de leurs besoins et de leurs environnements matériel et logiciel. Cette diversité des IHM constitue un problème de flexibilité d'apparence pour le concepteur. En outre, les fonctionnalités mêmes peuvent varier d'un type d'utilisateur à un autre ou d'une période à une autre (ajout / suppression d’une fonctionnalité). Le développeur doit pouvoir gérer ces modifications sans toucher aux fonctionnalités essentielles de l'application. Dans ce cas, le couplage interface - système est faible.
Le pattern architectural MVC Introduction (2/2) Dans le cas contraire (couplage fort), il devra implémenter des modules entiers – mélangeant fonctionnalités et interface – par type d'utilisateur. On peut alors facilement imaginer la difficulté que constitue la synchronisation de tout changement effectué sur une interface. Afin de répondre à cette problématique, un pattern architectural appelé MVC (Model View Controller) a été proposé (pour Smalltalk 80) et rapidement adopté par la communauté des développeurs d'applications ou de modules de type IHM. Il permet de faire collaborer une équipe d'infographistes et une équipe d'informaticiens.
Le pattern architectural MVC Composants Une application conforme au modèle MVC comporte trois parties distinctes : le MODELE, comprenant les fonctionnalités de base (logique métier) et les données – ou l'accès à ces dernières – (état de l'application). Il ne contient pas d’information relative à la façon d’afficher les informations qu’il contient. Le modèle est donc indépendant de la représentation des données et est facilement portable d’un environnement à un autre. la VUE, affichant des informations à l'utilisateur (représentation graphique ou textuelle des informations contenues par le modèle) le CONTROLEUR, gérant la réaction du système aux événements provoqués par l'utilisateur (dont la synchronisation entre la vue et le modèle)
Le pattern architectural MVC Interactions (I) La vue est la partie graphique de l'interface, c’est-à-dire ce que l'utilisateur voit. Elle constitue en fait le dispositif d’introduction des données dans le système. Les événements (clics de souris, sélection dans un menu, …) déclenchés par l’utilisateur sont interceptés par le contrôleur qui les transmet par la suite au modèle pour les traitements appropriés. Le contrôleur peut donc être vu comme un gestionnaire d'événements. Ainsi, à chaque intervention de l'utilisateur nécessitant l'"attention" du contrôleur, ce dernier effectue deux tâches : • l'interception de l'événement • l'envoi d'un message au modèle demandant l'activation d'un service correspondant En outre, le contrôleur intervient également pour la sélection d'une vue (une par fonctionnalité) conformément à la cinématique (cheminement) définie pour le traitement des actions.
Le pattern architectural MVC Interactions (II) Le modèle entre en scène dans l'un des deux cas de figure suivants : • envoi d'un message du contrôleur suite à une action de l'utilisateur • demande, par la vue (ou les vues), de données actualisées, lorsque l'état du système change Un message du contrôleur au modèle peut entraîner un changement au niveau des données, sans que la vue en soit avertie (perte de cohérence entre données du système et données de l'interface). Or le modèle MVC impose qu'il n'y ait pas de lien direct du modèle vers la vue : le modèle doit rester indépendant de la vue ou des vues qui en dépendent. Comment faire alors pour que cette dernière dispose toujours des informations les plus récentes afin de les afficher à l'utilisateur ? La réponse à cette question réside dans un mécanisme de diffusion de messages (ou d'événements) : une fois sa tâche exécutée, le modèle "avertit" les vues qui lui sont associées du changement. Pour cela, il maintient un registre de "dépendants" (liste de vues ou de paires vue-contrôleur), qui sont informés de tout changement par simple envoi de messages au registre (pattern comportemental Observer-Observable).
Le pattern architectural MVC Avantages De par la séparation qu'il propose, le modèle MVC offre des avantages évidents concernant l'extensibilité et la maintenance des applications développées selon ce pattern : • la dissociation de la structure logique de sa représentation visuelle permet d’associer plusieurs représentations visuelles pour un même modèle (vues de plusieurs faces d’un objet en 3D, modification du look and feel, …). On peut ainsi changer la ou les vues sans rien modifier de la structure logique (plusieurs affichages graphiques – camembert, histogramme, … – d’un même tableau de données). • l'association modèle / représentation visuelle est effectuée dynamiquement, c'est-à-dire à l'exécution, par le contrôleur (pas de liaison statique à réaliser avant le lancement de l'application).
La mise en œuvre des patterns Les frameworks Le champ d'application des patterns est volontairement le plus large possible, puisqu'ils font figures de schémas abstraits standardisés. Un développeur désireux d'utiliser des patterns doit donc bien en connaître les principes ou suivre à la lettre les directives de son concepteur. Or le développeur évolue dans un domaine particulier et s’il sait qu'il existe une solution à son problème, il s'intéressera plutôt au moyen de mettre en œuvre rapidement et de manière fiable cette solution, sans s'embarrasser de considérations abstraites. Beaucoup d'outils ont été proposés pour atteindre cet objectif. L'approche qui est la plus adoptée actuellement (et qui fait l'objet de cette partie) est celle qui consiste à utiliser une structure "préfabriquée", un moule, qui garantit au développeur que l'application qu'il va concevoir sur cette base, sera conforme à tel ou tel modèle. Cette démarche est celle concernant les frameworks. Un framework est un modèle (une base) de programme réutilisable représenté par un ensemble de classes, qui coopèrent et forment ainsi un moule pour produire des applications sur mesure, de même structure, dans une catégorie spécifique de logiciels. En contraste avec les techniques traditionnelles de réutilisation en développement orienté objet, basées principalement sur la réutilisation de classes, les frameworks sont conçus pour une activité précise. Un framework est donc utilisé pour la génération de multiples applications d'un domaine particulier.
CORBA - Principe simplifié Client Serveur Objet Objet Middleware
Qu'est ce que C.O.R.B.A. ? • CORBA ( Common Object Request Broker Architecture ) est un environnement réparti (middleware). • Défini par l'OMG • Créé en 1989 • But non lucratif • Plus de 850 membres (Sun, IBM, Microsoft, ...) • Crée et maintient les spécifications • CORBA • UML • http://www.omg.org
Objectifs de CORBA • Fournir un environnement ouvert • les membres participent aux spécifications • Fournir un environnement portable • les API sont définis pour rendre les applications portables ( quelque soit le produit CORBA utilisé ) • Fournir un environnement interopérable • Permettre aux applications CORBA de collaborer entre elles.
Le bus CORBA Le bus CORBA = ORB NT UNIX UNIX PC PC Sparc
La vue réelle du bus CORBA Réseau TCP/IP ORB PC/NT ORB PC/UNIX ORB Sparc/UNIX NT UNIX UNIX PC PC Sparc
Serveur et objets • Un serveur CORBA peut héberger plusieurs objets CORBA. • Chaque objet est accessible indépendamment des autres objets du serveur. • Chaque objet exprime son offre de services. Pour cela, on utilise un langage de description de services appelé IDL CORBA.
Composants • Stub : partie cliente • Skeleton : partie serveur • Object Adapter : enregistrement des objets • ORB : passage de message • IIOP : Internet Inter-ORB Protocol générés automatiquement
Le langage IDL CORBA • Il s'agit de décrire au sein d'une interface ( vue cliente de l'objet ) la liste des services offerts ( ensemble de fonctions ). interface Horloge { string donne_heure_a_paris(); string donne_heure_a_pekin(); };
La compilation IDL • Une description IDL est compilée pour générer les amorces nécessaires au mécanisme RPC. souche Génération de l'amorce cliente description IDL Génération de l'amorce serveur squelette
Intervention des amorces C.O.R.B.A. Client Java Objet C++ Protocole IIOP Souche Java Squelette C++ ORB Java PC/NT ORB PC/UNIX ORB C++ Sparc/UNIX NT UNIX UNIX PC PC Sparc
Souche : Coté client • Fonctions de la souche : • Prépare les paramètres d’entrée de l’invocation • Décode les paramètres de sortie et le résultat • Souche statique • Une par type d’objet serveur à invoquer • Identique aux talons clients RPC • Générée à la compilation à partir de l’interface IDL • Souche dynamique • Souche générique construisant dynamiquement tout type de requêtes • Permet d’invoquer des objets serveurs que l’on découvre à l’exécution (i.e. dont on ne connaît pas l’interface à la compilation : Référentiel d’interfaces)
Squelette : Côté serveur • Fonctions du squelette : • décode les paramètres d’entrée des invocations • prépare les paramètres de sortie et le résultat • Squelette statique • un par type d’objet serveur invocable • identique aux talons serveurs RPC • généré à la compilation à partir de l’interface IDL • Squelette dynamique • squelette générique prenant en compte dynamiquement tout type de requêtes • permet de créer à l’exécution des classes d’objets serveurs (i.e. que l’on ne connaissait pas à la compilation)
L'identité d'un objet C.O.R.B.A. • Chaque objet C.O.R.B.A. est associé à une référence d'objet qui forme son identité. • Deux objets C.O.R.B.A. du même type ( exemple deux objets Horloge ) ont deux identités différentes. Les références d'objets sont le moyen d'accès à un objet. serveur
L'adaptateur d'objets Serveur Objet A Objet B Squelette A Squelette B Client Adaptateur d'objets Souche A Le bus C.O.R.B.A. ( O.R.B. )
L'adaptateur d'objets • Fonctions • Interface entre les objets CORBA et l’ORB • Enregistrement et recherche des implantations d’objets • Génération de références pour les objets • Gestion de l’instanciation des objets serveurs • Activation des processus dans le serveur • Aiguillage des invocations de méthodes vers les objets serveurs • Différents type d’adaptateur • BOA (Basic Object Adapter) • POA (Portable Object Adapter)
Les communications avec CORBA • Les participants à un échange CORBA communiquent à l'aide d'un protocole spécifique à CORBA : IIOP ( Internet Inter-ORB Protocol ). • Le protocole IIOP est indépendant du langage de programmation, du système d'exploitation et de la machine utilisée. Un client Java pourra utiliser un serveur C++
Normalisation des communications • Protocoles d’interopérabilité entre ORBs conformes à CORBA 2 • GIOP : General Inter-ORB Protocol • Messages : request, reply, cancelrequest, … • nécessite un protocole de transport fiable, orienté connexion • IIOP (Internet IOP) : instanciation de GIOP sur TCP • Autres implantations de GIOP au-dessus de HTTP, RPC DCE, RPC Sun • Composants du protocole • CDR : Common Data Representation • Format de données d’encodage des données • IOR : Interoperable Object References (références d’objets)
L'annuaire C.O.R.B.A. • L'annuaire C.O.R.B.A. est un service. • Il s'agit d'un serveur qui enregistre des associations nom / référence d'objet. • Un serveur peut enregistrer ses objets dans l'annuaire. • Un client peut récupérer l'accès à un objet en consultant l'annuaire.
Compilation d'une description IDL • La description doit être compilée afin de générer les amorces ( souche et squelette ) requises pour l'établissement de la communication inter-processus. • A l'issu de la compilation, plusieurs fichier sont créés : • Le squelette • La souche, • L'interface • Les opérations de l'interface
Concept de « mapping » • Une description IDL est traduite vers un langage de programmation. • Les règles de traduction sont appelées « mapping » et font partie de la spécification CORBA. • Grâce au mapping, deux fournisseurs d'ORBs offriront le même modèle de programmation. portabilité des applications
Développer les objets CORBA • Pour développer un objet CORBA plusieurs critères sont à prendre à compte : • le type de l'adaptateur d'objet utilisé, • l'approche de développement. • Deux adaptateurs d'objets sont disponibles : • le B.O.A. ( Basic Object Adapter ) • le P.O.A. ( Portable Object Adapter ) • Deux approches existent : • l'approche par héritage : ici l'implantation de l'objet doit hériter du squelette ( c'est à dire de la classe Java correspondant au squelette qui à été générée par le compilateur ). • l'approche par délégation (prochaine partie).
Développement de notre premier objet CORBA public class PremierImpl extends PremierPOA { public void affiche( String message ) { System.out.println( message ); } } L'implantation hérite du squelette. La seule obligation est de ne pas oublier l'héritage du squelette. Ensuite, il faut tout simplement fournir le code des opérations décrites dans l'interface IDL. !
Développer le serveur • Les étapes à respecter sont les suivantes : • initialiser l'ORB • initialiser l'adaptateur d'objets • créer l'objet CORBA • enregistrer l'objet CORBA • exporter la référence de l'objet CORBA • attendre les invocations clientes
Initialiser l'ORB • Pour cela, on fait appel à la fonction statique « init » de la classe « org.omg.CORBA.ORB ». • Deux formes de cette fonction sont disponibles : • org.omg.CORBA.ORB.init( ) • org.omg.CORBA.ORB.init( String [] args, java.util.Properties prop ) public static void main( String [ ] args ) { org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init( args, null ); // … }
Initialiser l'adaptateur d'objets • Une application serveur contient au minimum un POA (elle peut en avoir plusieurs) appelé le RootPOA • Le(s) POA(s) sont gérés par le POA Manager • Une application serveur doit • Récupérer une référence d’objet RootPOA POA rootpoa = POAHelper.narrow(orb.resolve_initial_references («RootPOA»)); et • Activer le POA Manager rootpoa.the_POAManager().activate();