II- STAGE : Un système bancaire distribué





II.1 Les objectifs

Dans le cadre de la recherche sur l'Interface Homme Machine et les Systèmes Distribués, le sujet de mon stage était de construire un noyau d'expérimentation d'un système bancaire distribué, basé sur le standard C.O.R.B.A..
Cette construction avait pour objectif de faire ressortir les difficultés liées à la conception de Systèmes Distribués et tout particulièrement celles spécifiques au rapport espace / temps.
Pour cela, je devais utiliser l'O.R.B. Orbix Web de I.O.N.A dédié au langage Java.
Cependant, mon premier objectif a été de comprendre ce qu'était C.O.R.B.A., et comment utiliser cette norme dans le développement d'applications distribuées.
Ce que j'ai retenu et compris de ce concept vous est expliqué ci-dessus dans la première partie du document.
Par la suite, ce projet a impliqué : Ainsi, je vous expose à travers ce rapport toutes ces étapes du cycle de conception, mais aussi les difficultés posées par la distribution.


II.2 Les étapes de la conception

II.2.1 Prise en main des outils

Orbix Web 3.0 de IONA Technologies

Orbix Web est un environnement logiciel qui permet de construire et d'intégrer des applications distribuées.
Orbix Web est une implantation complète de la spécification C.O.R.B.A. de l'O.M.G.
Il associe la fonctionnalité C.O.R.B.A. au langage de programmation Java.
Orbix combine : Orbix web intègre les fonctionnalités suivantes : Par ailleurs, la technologie IONA est conforme au protocole I.I.O.P. assurant ainsi l'interopérablité avec d'autres O.R.B.

Microsoft Visual J++

L'outil de développement choisi est Microsoft Visual J++, c'est non seulement un compilateur java mais aussi un I.D.E. (Integrated Developement Environement) qui comporte : Cet outil a un avantage notoire la convivialité, mais aussi comme inconvénient sa non fiabilité. En effet le langage J++ n'a pas été attribué 100 % Java compatible.

Javasoft Swing

J'ai également utilisé Swing 1.1.1 Beta (connue officiellement sous "Java Foundation Classes 1.1").
Ce pakage 100% java comporte un ensemble de classes d'objets graphiques, tout comme java.awt swing permet de créer des interfaces mais beaucoup plus ergonomiques et strictement identiques sur des plate-formes différentes.


II.2.3 Spécification du problème en O.M.T.

II.2.3.1 Définition des objets

Mme F ADREIT, Mme S EBERSOLD, Mr JC SAKDAVONG et moi même avons réfléchi sur les objets qui pourraient composer notre futur système bancaire.
Cette phase de réflexion s'est appuyée sur le fonctionnement d'une banque dans le monde réel. Nous nous sommes intéressés plus particulièrement au système bancaire français, et à ses règles de gestion.
Ainsi, nous avons pu faire ressortir les points suivants : Après avoir dépeind plus ou moins l'environnement bancaire, penchons nous maintenant sur les mécanismes internes de gestion des comptes à travers ce réseau. Maintenant que les objets et leur relation ont été convenus, comment exprimer alors clairement la répartition et les liaisons entre eux?
Une représentation graphique semble être le mieux adapté.
Nous avons donc choisi de modéliser l'application en O.M.T. (Object Model Techniques) selon les recommandations de M EBERSOLD.


II.2.3.2 Modélisation en O.M.T.

Qu'est ce que l'O.M.T.?

La notation graphique obtenue à partir des objets décrits ci-dessus est la suivante :

omt
Notations :

Cette représentation graphique symbolise parfaitement la structure de l'application.
Il nous reste maintenant à définir les classes et les opérations possibles sur celles-ci.



II.2.4 Spécification d'un sous-ensemble de classes en I.D.L.

Par manque de temps et par souci de "justesse", seules les classes en relation avec le gestionnaire ont été spécifiées.
En effet, le fonctionnement d'une banque peut s'apparenter à celui du gestionnaire de comptes.
En fait, dans une banque, on retrouve toutes les opérations les plus élémentaires, décrites par le gestionnaire.
Ainsi, j'ai concentré mon travail sur la réalisation d'une mini-application (un noyau), simulant le "comportement " d'un guichet client "face" au gestionnaire de comptes d'une banque.
Plusieurs guichets clients pouront alors utiliser les fonctionnalités offertes par le gestionnaire de leur banque. Ceci grâce à la distribution de l'application cliente sur plusieurs sites (ordinateurs, plate-formes hétérogènes).
L'application serveur de gestionnaires sera lancée sur un site, attendant les requêtes des "guichets" clients.
Par ailleurs, j 'ai tenu à spécifier mes classes de la façon la plus générale possible. Ceci afin que mon travail puisse être complété par la suite, en y intégrant le reste des objets décrits dans le modèle O.M.T.ci-dessus.

II.2.4.1 Spécification des classes, opérations et attributs.

C'est une étape fondamentale qu'il ne faut pas abréger car elle évite par la suite de comettre des erreurs de conception, de revenir en arrière et de perdre du temps.
Il est donc important de bien spécifier tous nos objets et les opérations possibles sur ceux-ci avant de se lancer dans la programmation proprement dite.

Les classes retenues

Du schéma des classes ci-dessus, nous nous sommes intéressés aux classes suivantes :

En approfondissant notre réflexion sur les liaisons entre ces classes (qu'est ce qui circule entre le client et le compte, du compte au gestionnaire, ...), nous avons fait apparaître de nouvelles classes qui décrivent les opérations, consultations et résultat de ces transactions.
Soit :


II.2.4.2 Ecriture en I.D.L.

Toutes les spécifications ont été décrites en I.D.L. pour être ensuite exploiter dans la construction des objets (implantation de leurs méthodes) .
Comme je l'avais expliqué dans la première partie, ce sont les interfaces des objets (signature des méthodes et attributs) que l'on présente en I.D.L.
Je tenais à préciser que outre la spécification en I.D.L. des objets définis plus haut, j'ai également écrit en I.D.L. une interface MaDate qui reprend la spécification de la classe Date existant en Java.
De plus, étant donné que le type vecteur n'existe pas en I.D.L., j'ai construit une séquence d'Operation que j 'ai appelée tabop. Tabop est un tableau d'opeartions, il est nécessaire dans l'écriture de l' interface CompteRendu car il apparait comme type retour de la méthode getReleve().
typedef sequence <Operation> tabop;

Le code en I.D.L. est disponible dans les annexes de ce document.

Explications techniques

Les interfaces écrites en I.D.L. sont "tapées" dans un fichier texte puis sauvées dans mon répertoire de travail sous l'extension idl.
Ce fichier idl a ensuite été compilé (commande : idl AppBanque.idl) par le compilateur d'I.D.L. vers Java fournit par Orbix Web.
Si des erreurs sont apparues à la compilation, on les corrige dans le fichier idl et on le compile à nouveau jusqu'à ce qu'il n'y ait plus aucune erreur.
Lorsque la compilation s'est déroulée correctement, Orbix Web a généré des fichiers Java incluant le corps des squelettes et stubs utiles à la programmation de l'application. Par défaut ces fichiers sont "déposés" dans un répertoire crée par orbix Web à cet effet : java_output
Vous pouvez visualiser le contenu de ces fichiers en annexes.



II.2.5 Réalisation d'un sous-ensemble de classes

II.2.5.1 Fichiers généres par le compilateur d'Orbix Web

Le compilateur d'I.D.L. a produit plusieurs constructions Java qui correspondaient aux définitions I.D.L.. Ces constructions peuvent être scindées en deux groupes :

Première partie

Cette partie contient :

Deuxième partie

contenu :

Nous reviendrons plus tard sur ces deux approches afin de déterminer la mieux appropriée à notre application

Troisième partie

Deux types de classes générées :

II.2.5.2 Approche-Implbase ou Approche-TIE ?

Comparaison

Orbix Web fournit deux méthodes pour implanter une interface I.D.L.
Ces deux approches sont :

Le langage Java ne supporte pas l'héritage multiple.
Ainsi, utiliser l'héritage que l'approche ImplBase impose sur l'implantation des classes limite la fléxibilité de ces classes.
De plus, cela élimine la possibilité de réutiliser les implantations existantes des interfaces dérivées.
Par contre, il n'y a pas de restriction dans l'approche TIE , et c'est pour cela que nous l'avons choisie.
Etant donnée la compléxité d'héritage des classes de notre application, j'ai choisi d'implanter mes objets avec l'approche TIE.




Mécanisme d'implantation d'un objet dans l'approche TIE

Ce mécanisme n'est possible que si l'on a au préalable implementé une interface I.D.L.
Regardons le mécanisme sur le schéma suivant :

tie_approche

Le compilateur d'I.D.L. d'Orbix a génèré une classe tie java pour chaque interface I.D.L.
Le fichier généré est nommé "_tie_xxx.java".
Un objet qui implante l'interface I.D.L. est passé en paramètre au constructeur de la classe tie.
On définit ensuite une classe qui va implanter les opérations et attributs définis dans l'interface I.D.L.
exemple de classe : GestionnaireImplementation
Cette classe n'a pas besoin d'hériter de toutes les classes générées automatiquement.
Elle doit simplement implanter l'interface java : _gestionnaireOperations.
Ensuite, le programmeur instancie un objet tie : _tie_gestionnaire, en passant l'objet implanté GestionnaireImplementation au constructeur.
A la création des objets tie, il est possible de passer un second paramètre au constructeur de type String. Ce marqueur permet ainsi d'identifier de façon unique l'objet instacié sur le serveur.

GestionnaireImplementation g=new GestionnaireImplementation();
Gestionnaire gestCA= new _tie_Gestionnaire(g,"CA");

C'est une alternative au service de nommage.

Exemple implanté
[ cf sources annexes]


II.2.5.3 Classes implantées

Des classes ClassImplementation ont été écrites pour chaque interface I.D.L.
Ces classes sont composées d'un constructeur, d'attributs et de l'implantation des méthodes spécifiées dans l'I.D.L.
Chacune implante _ClassOperations : la classe générée par le compilateur en accord avec l'interface écrite en I.D.L.
C'est le principe de l'approche tie.
Tous les sources sont disponibles dans les annexes.
La prochaine étape consiste à écrire les programmes serveur et client. Puis décider d'une interface d'utilisation de l'application distribuée.


II.2.6 Classes et interfaces de test des classes implantées

Dans cette étape , j'écrits les deux classes suivantes : Je vous détaille ci-dessous l'implantation de ces classes tests.

II.2.6.1 Ecriture du programme serveur : classe ApplServeur

Mon serveur fournira deux gestionnaires de comptes : Le code de mon serveur instanciedonc deux objets Gestionnaire ga et gc avec leurs objets tie associés : gestCA et gestCL.
Ces objets sont nommés respectivement CA et CL à leur construction.
Ainsi les clients pouront invoquer l'un ou l'autre, en se "liant" avec eux sur le serveur par appel de la méthode :
bind ("nom de l'objet tie : nom du serveur d'objets",
      "adresse de la machine serveur")

Cette méthode indispensable au programme client est davantage développée dans la section suivante.
Revenons à notre programme serveur, chaque objet instancié doit être connecté au bus. Sinon, il sera impossible pour le serveur de gérer les invocations clientes arrivant pour ces objets.
Il y a deux méthodes disponibles dans Orbix Web pour connecter les objets à l'O.R.B : J'ai utilisé ORB.connect(gestCA) et ORB.connect(gestCL) pour connecter mes objets gestionnaire au bus.
Le serveur a mis ses objets à disposition puis se met en veille (blocage du processus).
Aprés un time out (delai), le processus serveur se reveille et déconnecte ses objets
est d'enregistrer Le serveur d'objets est enregistré auprés du référentiel des implantations par la commande : putit -java nom du serveur (dans une console)
Le code de la classe AppLServeur est visualisable dans les annexes


II.2.6.2 Ecriture du programme client et interface d'utilisation

Du côté client, nous pouvons utiliser et invoquer des traitements sur les gestionnaires disponibles sur le serveur : créer un compte, déposer de l'argent, consulter le solde, ...etc.
Pour tester mon application et vérifier si les méthodes que j'avais écrites étaient correctes, j'ai d'abord écrit un premier programme client : classe ApplClientDemo.
Dans ce programme de test, les opérations effectuées sont : Ce programme fait rarement intervenir l'utilisateur.
En effet,c'était avant tout une phase de test qui consistait à vérifier la cohésion et la validité des méthodes des objets que j'avais implantées auparavant.
J'ai donc élaboré cette première application cliente dans un souci de fiabilité en testant au fur et à mesure les opérations les plus élémentaires sur un compte.
Une fois cette étape de validation terminée, je me suis lancée dans l'écriture d'un autre programme client intégrant une mini-interface utilisateur. Il s'agit de la classe ApplClient
Ainsi, un client peut manipuler l'application à l'aide de l'interface graphique. La gestion des évènements dans cette interface a en partie été gérée.
De plus, contrairement au premier programme client, j'ai "éclaté" la méthode main()en plusieurs méthodes invoquées à la construction de AppClientDemo.
Cette classe implantée permet : Bien sûr, cette réalisation peut sembler minimaliste mais les bases peuvent être celles d'une réelle application distribuée.


Détails de programmation
Regardons plus précisément la méthode de connexion du client avec le serveur.
Cette méthode commune aux deux programmes clients est la méthode standard pour se lier avec les objets sur le serveur.
En effet bind() est utilisée pour créer les souches de communication pour les objets qui ont été crées sur le serveur.
La création d'un proxy dans l'espace d'adressage du client permet aux opérations d'être invoquées sur l'objet ciblé.
Lorsque l'opération est invoquée sur le proxy, Orbix web transmet automatiquement la requête à l'objet ciblé.
Bind() est une méthode statique qui est automatiquement générée par le compilateur d'I.D.L.pour chaque classe idl-java. Pour chaque interface, la forme entière de bind() est déclarée dans la classe java nom de la classe suivi de Helper.
La méthode bind() peut être utilisée pour spécifier exactement l'objet requis, ou bien en utilisant les paramètres par défaut.
Orbix web permet une certaine liberté dans le choix de l'objet.
Dans mes programmes clients, j'ai choisi de paramétrer la méthode bind() comme suit :
xxxHelper.bind(String nom de l'objet ciblé:String nom du serveur, String adresse de la machine serveur)
Exemple :
GestionnaireHelper.bind("CA:ApplServeur","mass-handicap.univ-tlse2.fr");

CA est le nom de l'objet Gestionnaire (du Crédit Agricole) disponible sur le serveur.
Applserveur est le serveur d'objets,
mass-handicap.univ-tlse2.fr : adresse de la machine où le serveur est implanté




Schéma explicatif

schema_app

Par simplicité, j'ai fait en sorte que mon client crée lui aussi des objets : Client, Operation, consultation.
Cependant, ce n'est pas la méthode qu'il faut adopter dans le cadre général, en effet l'on disposera plutôt de plusieurs serveurs d'objets : un serveur de gestionnaire, un serveur de clients, un serveur d'opérations ...ect.
Je n'ai implanté qu'un serveur de gestionnaires sur lesquels les objets crées côté client peuvent invoquer des méthodes.
Trace d'exécution sur le serveur
(cf annexe)


Difficultés posées par la distribution

Durant la réalisation de mon application distribuée, j'ai rencontré plusieurs difficultés liées à la distribution. Ces problèmes sont d'ordre spatial et temporel.
Problèmes liés à l'espace
Ma première grande difficulté a été de savoir comment répartir l'information.
Sur quel site (client ou serveur ?) les objets doivent être implantés, crées ou utilisés par les acteurs du système réparti.
En effet, dans une architecture client / serveur, le partage et la mobilité de l'information et des programmes contribuent au bon fonctionnement d'une application distribuée.
Il aurait été interessant dans mon application de créer plusieurs serveurs d'objets. Or mon application ne fonctionne pour l'instant qu'avec un unique serveur d'objets : le fournisseur de gestionnaires.
Le client sans le savoir crée lui-même les autres objets entrant dans la "composition" des requêtes.
Cette implantation ne gère donc pas au mieux l'espace de distribution, et engendre alors des problèmes temporels.
Problèmes liés au temps
Si les ressources sont mal réparties dans l'application, cela peut "alourdir" et "ralentir" le routage de l'information.
Mon application étant succinte, je ne me suis pas vraiment rendu compte de ces problèmes temporels.
Par ailleurs, il faudrait aussi vérifier un ensemble de critères théoriques tels que la fiabilité, l'intégrité, la sécurité des données et la synchronisation des processus.