GICOM
Application de commerce électronique

Etape 2: Sous-système bancaire minimal

Projet de M2GI thème SRR et RICM3 option SR

Année Universitaire 2007-2008

Université Joseph Fourier –Grenoble 1

 

Contributeur(s) étape : Sacha Krakowiak, David Felliot, Fabienne Boyer, Sébastien Chassande, Didier Donsez

Encadrement M2GI/SRR : Didier Donsez, Sara Bouchenak, Johann Bourcier

Encadrement RICM3/SR : Pierre-Yves Gibello, Didier Donsez

PLAN                                                                                                                                          

1      Rappel 1

2      Présentation de CORBA V2. 2

2.1       Clients et serveurs. 2

2.2       IDL. 3

2.3       Talons et squelettes. 3

2.4       Notion d'activation. 5

2.5       Exemple simplifié de serveur CORBA.. 6

2.6       IIOP. 8

2.7       .NET Remoting. 9

3      Sous-système bancaire. 9

3.1       Architecture proposée. 10

3.2       Interfaces IDL proposées. 11

3.3       Identification. 12

3.4       Serveur Générique. 12

3.5       User-Agents. 12

3.6       Intégration à eCOM... 12

3.7       Organisation logicielle proposée. 13

4      Utilisation des services supports. 13

5      Documentation. 13

5.1       Ouvrages. 14

5.2       ORBs. 14

1     Rappel

Un serveur CORBA est un support permettant de rendre accessible un ensemble d'objets (écrits dans un langage de programmation quelconque) de manière distribuée. Nous allons utiliser ce support pour programmer une application bancaire qui permet à des clients ou à des organismes distants de consulter, et selon le cas de modifier des données bancaires (comptes, clients, agences, etc). Cette note pésente tout d'abord les principes d'utilisation d'un serveur CORBA, puis propose une architecture pour réaliser une application bancaire.

La norme CORBA à donné lieu à diverses implémentations d’ORB dans différents langages (C++, Java, …). La plateforme Java 2 Standard Edition v1.5 fournit un ORB (Object Request Broker). Vous avez utilisez celui-ci dans le TP SAR. Cependant nous utiliserons pour le projet GICOM, un ORB de substitution JacORB (http://www.jacorb.org/) qui est plus complété et bien documenté. D’autres ORBs Java  peuvent être utilisé Mico ou ORBacus. .Remarquons que l’ORB TAO écrit en C++ permettrai de tester l’interopérabilité Java-C++.

2     Présentation de CORBA V2

CORBA est une norme proposée par l'OMG, pour permettre d'interconnecter des composants logiciels  (objets) écrits dans des langages de programmation divers et s'exécutant sur des machines distantes.

2.1  Clients et serveurs

Bien que permettant de réaliser des appels à distance sur des  objets, la norme  CORBA est basée sur un modèle client/serveur. Les objets distribués (c'est à dire, ceux que l'on souhaite rendre accessible à distance) doivent être crées et gérés par un serveur CORBA, qui a pour rôle d'exécuter les méthodes appelées par les clients sur ces objets.
N'importe quel client peut appeler une méthode sur un objet distribué, à partir du moment où il connait la référence CORBA (appelée IOR, Inter Object Reference) de cet objet. Cette référence précise à la fois quel est le serveur "chez qui" se trouve l'objet, et quel est l'objet appelé. En général, une IOR est transmise à un client soit par passage de paramètres, soit par l'utilisation d'un serveur de noms.

La figure ci-après illustre un scénario de communication entre objets distribués sur des serveurs CORBA. En (1), un client récupère l'IOR d'un objet o1 dans le serveur applicatif A. En (2), le client accède à l'objet o1. La méthode m1() qu'il appelle sur o1 crée un deuxième objet o2, dont l'IOR est renvoyée au client. Ce dernier peut alors ensuite accéder à o2 avec la méthode m2() qui prend en paramètre l’IOR de o1.

2.2  IDL

Selon la norme CORBA, les objets que l'on souhaite rendre accessible de manière répartie doivent être décrits en termes de l'interface qu'ils offrent. Le développement d'applications distribuées sur des plates-formes hétérogènes nécessite en effet une séparation stricte entre les interfaces des objets et leur implémentation. Un langage spécifique, appelé IDL (Interface Definition Language) a été défini à cet effet par l'OMG (Object Management Group). Ce langage permet de définir les interface des méthodes appelables sur un objet distribué, en termes des types des paramètres et du résultat des méthodes.

Par exemple, nous allons considérer l'interface Hello définie ci-après qui permet d'afficher un message (méthode print), ainsi que de comptabiliser le nombre d'appels effectués à la méthode print. Cette interface est définie dans le module Example. Un module IDL définit une portée pour les noms d'interfaces.

module example {

  interface Hello;

  interface Hello {

    readonly attribute long print_number;   // nombre d'affichages effectués

    void print(in string msg);              // affichage d'un message

  };

};

Exemple de fichier IDL

2.3  Talons et squelettes

Tout objet distribué possède deux représentations : une représentation client (appelée talon) et une représentation serveur (appelée squelette). Un client possède un talon par objet distant qu'il est susceptible d'appeler. Un talon associé à un objet O a pour rôle de transférer les appels de méthodes effectués par le client au serveur gérant O.

De manière symétrique, un serveur possède un squelette par objet distribué qu'il gère.Un squelette associé à un objet O réceptionne les appels de méthodes sur O, et se charge d'engendrer leur exécution.

Au moment où un client effectue un appel de méthode sur un objet, l'interconnexion entre le talon et le squelette de l'objet appelé est réalisée au travers d'une couche de communication appelée Bus CORBA, ou plus généralement ORB (Object Request Broker). Le protocole de transfert des appels de méthode (définissant le format des messages échangés entre la machine cliente et la machine serveur) est appelé IIOP (Internet InterOrb Protocol).

Remarque : l'OMG spécifie en fait un protocole de communication entre ORB appelé GIOP (General Inter-ORB Protocol). Ce protocole doit être implémenté au-dessus d'une couche transport orientée connexion. IIOP est une spécialisation de GIOP utilisant TCP/IP. La spécification de GIOP est constituée de deux parties. La première est générale ; elle spécifie une représentation commune des données (CDR), le format des messages GIOP et les caractéristiques supposées de la couche de transport sous-jacente. La seconde partie, propre à IIOP, décrit la manière dont clients et serveurs CORBA établissent des connexions TCP/IP pour transmettre des messages GIOP.

La génération des classes définissant les talons et les squelettes est prise en charge par le compilateur IDL. Cette génération s'effectue à partir de l'interface IDL décrivant un objet donné, ainsi que de l'implémentation de cet objet. Autrement dit, pour tout objet distribué, le programmeur doit décrire son interface IDL, et son implémentation dans un langage supporté par CORBA (C, C++, Java, etc).

La figure ci-après récapitule ces informations. On peut voir qu'un squelette est connecté au Bus CORBA via un adaptateur d'objets (Object Adapter). Initialement, la spécification CORBA version1 proposait un adaptateur d'objets basique (Basic Object Adaptator), qui était limité en terme de portabilité.  C'est la raison pour laquelle la norme CORBA version 2.2 définit un nouvel adaptateur, appelé Portable Object Adaptor. Dans tous les cas, un adaptateur gère différents objets distribués dans un serveur CORBA donné. C'est lui qui rend accessible ou inaccessible un objet donné, et qui invoque les méthodes appelées sur cet objet par l'intermédiaire de son squelette. Nous verrons le rôle plus précis des adaptateurs au travers de l'étape 3.

  Figure 2. Interaction entre un client et un serveur CORBA

2.4  Notion d'activation

Lorsqu'un objet distribué est créé au sein d'un serveur donné, il n'est pas immédiatement accessible à distance. Pour le rendre accessible, il faut l'activer auprès de l'un des POA du serveur courant. L'activation d'un objet distribué consiste en :

Deux modèles d'activation existent, selon que le POA auprès duquel a lieu l'activation fonctionne selon le mode implicite ou explicite. Avec le mode activation implicite, la création d'une référence distribuée (ou d'un objectId) pour un objet O auprès d'un POA entraîne automatiquement l'activation de O si celle-ci n'a pas encore été faite. Les différents moyens de créer une référence distribuée sont résumés en 1.5.

Avec le mode activation explicite, le programmeur doit explicitement activer un objet distribué auprès d'un POA. Les méthodes fournies par la classe PortableServer.POA sont :

Dans la terminologie CORBA, l'objet qui implante une interface IDL est appelé un servant. Le type ObjectId correspont au type byte[] de Java, et son contenu n'a pas de signification particulière pour un POA. La contrainte à respecter est que deux objets distincts doivent posséder des objectId différents s'ils sont actifs au sein du même POA. Un exemple de génération d'objectId à partir d'une chaîne de caractères est donné ci-après :

String anObjectId = "myObjectId";

byte[] id = anObjectId.getBytes();

2.4.1   Identification d'un objet distribué et accès à cet objet

Pour accéder à un objet situé dans un serveur distant, un client doit posséder une référence distribuée vers cet objet. Une référence distribuée contient :

Une référence distribuée (type org.omg.Object) peut être construite au travers des méthodes suivantes qui peuvent être appelées autant de fois que nécessaire dans un programme. Si le POA auprès duquel est appelé l'une de ces méthodes fonctionne selon le mode implicite, et que l'objet n'a pas encore été activé, alors l'appel de la méthode provoque son activation.

Méthodes fournies par le servant (classe org.omg.Servant) :

Object _this(ORB)  //l'objet est actif ou activé auprès du POA par défaut

Object _this() //l'objet est actif ou activé auprès du POA par défaut

 

Méthodes fournies par le POA auprès duquel l'objet est (ou doit être) activé (classe org.omg.PortablePOA) :

Object servant_to_reference(in Servant)

Object id_to_reference(in ObjectId)

 

Si l'on souhaite simplement connaître l'identificateur unique d'un objet sans forger une référence distribuée complète, alors la méthode suivante est disponible. Comme précédemment, si le POA auprès duquel est appelé cette méthodes fonctionne selon le mode implicite, et que l'objet n'a pas encore été activé, alors l'appel de la méthode provoque son activation.

 

ObjectId servant_to_id(in Servant)

 

Inversement, depuis une référence distribuée, il est possible d'obtenir l'identification unique de l'objet (objectId), ainsi que la référence Java locale de l'objet servant.

Méthodes fournies par le POA auprès duquel l'objet est activé (classe org.omg.PortablePOA) :

 

Servant reference_to_servant(in Object)

ObjectId reference_to_id (in Object)

Servant id_to_servant(in ObjectId)

 

2.5  Exemple simplifié de serveur CORBA

Cette section décrit la mise en oeuvre d'un serveur CORBA très simple, donnant accès à un objet distribué implémentant l'interface IDL Hello. Il existe deux modèles de programmation de l’implémentation du service :

Selon le modèle de programmation, un servant peut donc hériter de son squelette, ou bien utiliser un délégué pour l'implémentation des méthodes. Les deux modèles sont décrits respectivement en 2.5.1 et 2.5.3. Enfin, le 2.5.5 explique comment écrire le programme du serveur qui va créer et héberger l'objet distribué, et nous donnons un exemple de client qui accède cet objet à distance.

Nous supposons dans la suite que l'organisation logicielle est la suivante :

2.5.1   Compilation des interfaces IDL selon le modèle par héritage

Pour compiler cette interface, nous utilisons le compilateur IDL/Java (au travers de la commande idlj example.idl) qui va générer les classes talon et squelette Java associées à l'interface Hello. Toutes les classes générées appartiennent au package example (nom du module). Ces classes sont les suivantes :

2.5.2   Ecriture d'une implémentation selon le modèle par héritage

CLASSES A MODIFIER POUR OBTENIR UN MODELE PAR HERITAGE

Nous devons définir la classe HelloImpl.java comme une extension de la classe HelloPOA. Dans cette application très simple, la classe HelloServer.java crée une instance de la classe HelloImpl, puis crée une référence distribuée sur cet objet (méthode _this(orb)), et enfin enregistre cette référence auprès du serveur de noms. La méthode _this crée une référence distribuée en activant l'objet auprès du POA affecté par défaut au serveur courant. Ce POA (appelé RootPOA) fonctionne en effet selon le mode d'activation implicite. La classe HelloClient.java donne un exemple de client.
Dans le modèle par héritage, le servant d'un objet distribué d'interface XXX a pour classe XXXImpl qui étend XXXPOA. Cet objet met en oeuvre à la fois l'implémentation et le squelette de l'objet.

2.5.3   Compilation des interfaces IDL selon le modèle par délégation

Pour compiler l'interface hello.idl selon le modèle par délégation, nous utilisons le compilateur IDL/Java avec l'option -tie (au travers de la commande idlj -tie hello.idl). Les classes générées comportent un fichier supplémentaire par rapport à une compilation selon le modèle par héritage : HelloPOATie.java. Cette classe implémente le squelette associé aux objets d'interface Hello. Ce squelette, qui doit être considéré comme servant, utilise un objet de classe HelloImpl comme délégué.

Note : l'option de compilation --impl permet d'obtenir des squelettes des classes d'implémentation.

2.5.4   Ecriture d'une implémentation selon le modèle par délégation

Nous devons cette fois définir la classe HelloImpl.java  comme une implémentation de l'interface HelloOperations. Dans la classe HelloServer.java, il faut d'abord instancier la classe HelloImpl, puis créer un servant en instanciant la classe HelloPOATie et en lui passant, comme paramètre de construction, une référence vers la classe d'implémentation.

HelloImpl hello = new HelloImpl();

HelloPOATie helloTie = new HelloPOATie(hello);

L'activation de l'objet crée peut être réalisée par son créateur (classe HelloServer), ou bien par lui-même, selon les choix de programmation que l'on réalise. Dans le premier cas, le créateur n'a qu'à appeler la méthode activate_object(helloTie) sur le POA choisi. Dans le second cas, c'est dans la classe HelloImpl que l'on souhaite effectuer cette activation, et il faut alors enregistrer à un moment donné la référence du servant (helloTie) dans l'objet d'implémentation HelloImpl. La classe HelloClient.java donne un exemple de client.

Remarque : Nous utiliserons le modèle par délégation dans la suite et dans les étapes suivantes.

2.5.5   Lancement de l'application

Pour compiler l'application, vous pouvez utiliser la tache build du script ANT (en faisant les adaptations nécessaires).

Ensuite, pour exécuter, il faut :

2.6  IIOP

IIOP (Internet Inter-ORB Protocol) est un protocole permettant à des implémentations indépendantes d’ORB d’interopérer entre elles au moyen de TCP/IP.

2.7  .NET Remoting

.NET Remoting est le bus de communication générique de la plateforme .NET de MicroSoft. .NET Remoting permet de distribuer des services et d’invoquer leur opération à distance. Son architecture décrit par la présentation http://www-adele.imag.fr/~donsez/cours/dotnetremoting.pdf  est extensible car il supporte plusieurs protocoles et formats d’encodage pour le transport des messages (requête et réponse) via la notion de Channel. Les 2 Channel livrés est standard sous TcpChannel (basé sur ORPC utilisé dans DCOM)et HttpChannel (basé sous HTTP et SOAP). Cependant, il est possible d’ajouter d’autres Channel comme le IIOPChannel.

IIOPChannel utilise le protocole IIOP et permet à un client .NET d’invoquer des opérations sur des services CORBA (écrit en Java, C++, …) ou à un client CORBA (écrit en Java, C++, …) d’invoquer des méthodes sur un service écrit en C#,VB,J# sur .NET.

Il existe plusieurs implémentations de IIOPChannel:

·       IIOP.NET http://iiop-net.sourceforge.net/ est une autre implémentation libre complétée d’un générateur d’IDL depuis CLS et d’un compilateur d’IDL vers CLS. Deux présentations de IIOP.NET sont « Building a Distributed Object System with .NET and J2EE Using IIOP.NET”, par Patrik Reali, http://www.codeproject.com/csharp/dist_object_system.asp et “Accessing an EJB from .NET Using IIOP.NET: an Example”, By Patrik Reali http://www.codeproject.com/csharp/iiop_net_and_EJB.asp , Accessing an EJB from .NET Using IIOP.NET: an Example - The Code Project - C# Programming http://www.codeproject.com/csharp/iiop_net_and_EJB.asp

·       Remoting.Corba http://remoting-corba.sourceforge.net/ est une implémentation libre dont une présentation brève est disponible sur http://www.dotnetguru.org/articles/articlets/iiopchannel/iiopremoting.htm

·       Janeva http://www.borland.com/janeva/ est une implémentation commerciale de Borland/Inprise

Un exemple d’usage de IIOPChannel pour réaliser l’interopérabilité entre Java et .NET avec IIOP est présenté dans l’exemple de l’archive http://www-adele.imag.fr/~donsez/cours/ex_dotnet/interopcsharpjava.zip. L’exécution de cet exemple requière l’installation du framework .NET (il est installé dans plusieurs salles machines de l’UFR) téléchargeable gratuitement depuis le site http://www.microsoft.com/dotnet.

Quels liens sur .NET Remoting

·       .NET Remoting: design decisions and best practicies http://www.codeproject.com/csharp/RemotingDesignDecisions.asp

3     Sous-système bancaire

Cette section propose une architecture pour la réalisation du sous-système bancaire en terme de serveurs CORBA. Bien entendu, il est tout à fait possible d'étendre ou de modifier cette architecture.

3.1  Architecture proposée

Nous proposons qu'une application bancaire soit mise en oeuvre par trois types de serveurs CORBA:

Le schéma ci-dessous montre l'enchaînement des opérations pour obtenir la référence d'une agence.

Cette dernière opération crée automatiquement un talon correspondant à un objet Branch sur le site client. Ce dernier peut donc par la suite appeler les méthodes de l'interface Branch sur l'objet correspondant.

3.2  Interfaces IDL proposées

Les banques doivent fournir un ensemble de services spécifiés par des interfaces IDL. Nous proposons les interfaces IDL suivantes décrite dans le fichier bank.idl qui bien entendu NE DOIVENT être modifiées. REMARQUE : il représente des interfaces de services communes à toutes les banques (de toutes les équipes). Car un user-agent d’une équipe doit pouvoir interopérer avec les serveurs (bank, branch, transaction) d’une autre équipe.

L'accès initial à une banque sera réalisé à l’aide de son nom au travers du serveur de noms fourni dans le J2SDK1.4.

Les méthodes registerBranch et unregisterBranch permettent respectivement d'enregistrer et de désenregistrer une agence (branch en anglais) d'une banque donnée. La référence d'une agence rattachée à une banque peut être récupérée par la méthode getBranch. La méthode getBranches  permet de récupérer les références de toutes les agences rattachées à une banque donnée.

A partir d'un objet Branch, un UA doit pouvoir lister les objet clients (customer en anglais), en créer ou supprimer, et récupérer sa référence distribuée. Les objets Customer sont donc également accessibles au travers d'une interface IDL.

A partir d'un objet Customer, un UA peut récupérer des informations (nom, adresse, etc) sur le client, et l'on peut également créer, consulter ou détruire des comptes (account en anglais) pour ce client, ainsi que récupérer leur référence.

Les objets Account devront principalement permettre de consulter ou de modifier un solde (balance en anglais).

3.3  Identification

Les numéros de comptes sont au format IBAN (International Bank Account Numbers).

La clé IBAN est composé de 2 chiffres situés après le code pays. C'est une norme de calcul internationale mais le nombre de caractères alpha-numériques dans l'identifiant IBAN dépend du pays mais ne peut dépasser 38.

En France, l'identifiant IBAN comporte 27 caractères, les 2 premiers caractères sont le code pays (FR) , les 2 chiffres suivants, la clé IBAN et les 23 caractères suivants correspondent à la clé RIB française qui comporte un numéro d’établissement (banque), un numéro d’agence (guichet), un numéro de compte. La clé IBAN vaut toujours 76 pour les comptes des banques françaises n'utilisant pas de lettre dans le numéro de compte.

Quelques liens

·       http://www.ecbs.org/iban.htm

·       http://www.smartversion.com/rib2iban.htm

·       http://www.difstream.com/rib2iban.htm

·       http://www.lencom.com/desc/indexN9645.html

3.4  Serveur Générique

Comme vous l’aviez déjà vu dans le TP SAR, le code d’un serveur ne varie que peu d’un serveur à l’autre. Il est donc recommander d’utiliser le serveur générique vu dans le TP SAR pour développer vos serveurs de banque et d’agence.

Vous pourrez le compléter à votre guise tout en maintenant son caractère générique et son caractère configurable (par un fichier au format Java properties, ou XML (en utilisant les annotations JAXB), ou bien encore au format JSON). Les fonctionnalités de ce serveur seront complétées au fur et à mesure des besoins des étapes 2, 3 et 4.

3.5  User-Agents

Deux user-agents (UA) réalisant des opérations de guichet tels que création/consultation/modification/suppression de clients et de comptes vous sont demandés :

3.6  Intégration à eCOM

L’intégration du sous-système bancaire doit être pensée dès cette étape. Celle-ci se fait par le biais du bean FundTransfer introduit dans l’étape 1.

3.7  Organisation logicielle proposée

L'organisation logicielle de chaque sous-projet recommandée pour conserver une structuration claire des programmes ainsi que des talons et des squelettes générés lors de la compilation des interfaces IDL est la suivante.

Remarque : cette organisation est celle d’un projet Maven

Vous pouvez utiliser le build.xml ANT fourni. Cependant, nous vous recommandons de définir à un projet Maven 2 (pom.xml).

4     Utilisation des services supports

Votre environnement (variables PATH, JAVA_HOME, ANT_HOME et MAVEN_HOME) doit être configuré.

La documentation des outils liés à CORBA est dans $JAVA_HOME/docs/tooldocs/tools.html#idl

5     Documentation

REMARQUE : Vous pourrez commencer par vous replonger dans le TP SAR du premier trimestre.

 

Vous pourrez lire la documentation du JDK présentant les principes d'utilisation de CORBA pour la réalisation d'applications réparties, et regarder en particulier les exemples des applications hello.

Vous pouvez aussi tester les exemples commentés du JDK "Getting Started with Java IDL"

·       http://java.sun.com/j2se/1.4.1/docs/guide/idl/GShome.html

·       http://java.sun.com/j2se/1.4.1/docs/guide/idl/idljExample.html

·       http://java.sun.com/j2se/1.4.1/docs/guide/idl/idljExample2.html

·       http://java.sun.com/j2se/1.4.1/docs/guide/idl/idljExample3.html

·       http://java.sun.com/j2se/1.4.1/docs/guide/idl/tutorial/idlj2machines.html

Le site de l'OMG donne accès à la spécification IDL entres autres : (http://www.omg.org)

5.1  Ouvrages

5.2  ORBs

La documentation et les exemples fournis avec ces ORBs est souvent riches et doit être consulté.

·       JacORB (ORB Java Open Source) http://www.jacorb.org/,

·       TAO http://www.cs.wustl.edu/~schmidt

D’autres documents de démarrage sont disponibles sur les site de Netscape et de Borland (VisiBroker):

·       http://developer.netscape.com/docs/manuals/enterprise/javapg/contents.htm

·       http://info.borland.com/techpubs/books/vbj/vbj40/programmers-guide/contents.html