Laboratoire d’Informatique du Littoral Le middleware CORBA (1) N. Melab melab@lil.univ-littoral.fr
Références R. Orfali, D. Haskey et J. Edwards. Objets Répartis Guide de Service. Intl. Thomson Publishing France, Paris, 1996. J-M. Geib, C. Gransart et P. Merle. Corba, Des concepts à la pratique. InterEditions, 1997. ORBacus for C++ and Java, Document technique version 4.0.3. Object Management Group. The Common Object Request Broker: Architecture and Specification. OMG TC Document 95-7-X, Juillet 1995. www.omg.org
Problèmes de communication et Motivations (1) Décentralisation Répartition des ressources matérielles & logicielles matérielles : processeurs, mémoires et périphériques logicielles : données (fichiers) et applications Partage de ressources Evolution technologique et croissance du ratio performance/coût des réseaux. Problèmes de communication et d’hétérogénéité
Problèmes d’interopérabilité Motivations (2) Coopération Coopération des applications «patrimoines» Nouvelles technologies Mise à jour des applications «patrimoines» Problèmes d’interopérabilité et d’intégration
Communication Applications réparties sur des sites distants Différents paradigmes de communication ? Passage de messages : PVM, MPI, ... RPC : OSF/DCE-IDL, Sun/RPCL, ... Mémoire virtuellement partagée : LINDA, ... Paradigmes non accessibles directement via les langages de programmation
Hétérogénéité Trouver la meilleure combinaison des technologies A différents niveaux : Modèles et langages de programmation Systèmes d’exploitation Matériel : PCs, Stations, Clusters, MPP, etc. Protocoles de communication En général, résolu par les mécanismes de communication par utilisation du format de données XDR
Intégration Intégration à deux niveaux Intégration des nouvelles technologies «Perpendiculaire» au problème d’intégration Intégration des applications «patrimoines» avec les nouvelles technologies
Interopérabilité Communication entre systèmes (applications) développé(e)s par des tiers Définition de normes pour l’échange des données et de services (formats universels, protocoles, …)
L’approche objet Différents environnements basés sur les 3 paradigmes cités résolvent les problèmes de communication et d’hétérogénéité L’approche objet : solution aux problèmes d’intégration et d’interopérabilité Propriété d’encapsulation IDL : Interface Definition Language Informatique répartie & approche objet : cadre conceptuel unique allant de l’analyse jusqu’au déploiement des applications distribuées Middleware (CORBA)
Objets distribués Spécification en utilisant IDL Déploiement en objets répartis sur sites distants Infrastructure de communication (ORB) Communication par RMI : Remote Method Invocation RMI : version étendue de RPC Utilisation de souches de communication Souche : représentant local d’un objet distant
Plan L’Object Management Group (OMG) IDL : Langage de spécification ORB : Bus de communication entre objets Méthodologie de développement et application
L’Object Management Group Consortium créé en 1989 actuellement plus de 850 membres Objectif: faire émerger des standards pour l’intégration d’applications distribuées hétérogènes et la réutilisation de composants logiciels
OMG : Objectifs Interopérabilité entre plusieurs langages Transparence des invocations Invocation statique et dynamique Système auto-descriptif Activation automatique Interopérabilité entre bus (GIOP, IIOP, etc)
OMA : l’architecture globale Objets applicatifs Spécifiques Finance Télécoms Santé Interfaces de domaine Gestion des tâches Gestion de l’information IHM Administration Utilitaires communs Bus d’objets répartis Licences Transactions Persistance Propriétés Changements Events Nommage Vendeur Sécurité Relations Collections Temps Externalisation Interrogations Cycle de vie Concurrence Services objet communs
Plan L’Object Management Group (OMG) IDL : Langage de spécification ORB : Bus de communication entre objets Méthodologie de développement et application
Le langage OMG-IDL Coopération entre fournisseurs et utilisateurs de services Expression sous forme de contrats Séparation de l’interface de l’implémentation Contrat : ensemble d’interfaces spécifiées avec IDL Projection en souche (côté client) et squelette (côté serveur) Précompilateur IDL
Caractéristiques Langage «objet» de spécification d’interfaces (et non pas d’implantation) : partie de C++ étendue Indépendant de tout langage de programmation Fortement typé (passage de paramètres) Héritage multiple et répété Projection automatique dans plusieurs langages de programmation : C, Smalltalk, Cobol, AdaObjet, C++, Java, etc.
Eléments du langage (1) Commentaires Identificateurs Même chose qu’en C++ Exemples : // Ceci est un commentaire court /* Ceci est un commentaire pluuuuuuuuuuuuuuuuuuuu uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuus long */ Identificateurs Séquences de caractères alphabétiques, chiffres et du caractère « _ » Premier caractère : lettre Pas de différence entre majuscules et minuscules
Eléments du langage (2) Espaces de définition Module : contient tout type de définition Exemple : module Banque { const double TAUX = 5.25; typedef unsigned sequence<string> DesAgences; // Autres définitions };
Eléments du langage (3) : Types de données Valeur Type simple Type d’objet ... Type dynamique Type composé array sequence struct union enum TypeCode any short long longlong ushort ulong ulonglong float double longdouble char string wchar wstring boolean octet
Eléments du langage (4) Constantes Définition de types Mot-clé const comme en C++ Exemples : const double PI = 3.14159; const string UneConstante = ``une chaîne de caractères``; const short TAILLE1 = 10; const long TAILLE2 = TAILLE1 * 2; Définition de types Mot-clé typedef comme en C++ typedef unsigned short Jour; typedef unsigned short Mois; typedef unsigned short Annee;
Eléments du langage (5) Enumérations Structures Mot-clé enum comme en C++ Exemple : enum JoursOuvrables { Lundi, Mardi, Mercredi, Jeudi, Vendredi }; Structures Mot-clé struct comme en C++ Exemple struct Date { Jour le_jour; Mois le_mois; Annee l_annee; };
Eléments du langage (6) Unions Mot-clé union comme en C++ Exemple union DateVariee switch (long) { case 1: Date format_date; case 2: string format_chaine; Default: Jour nb_jours; };
Eléments du langage (7) Tableaux Tableaux dynamiques : séquences : Exemples typedef Date[10] tab_dates; typedef float[TAILLE1] [TAILLE2] matrice; Tableaux dynamiques : séquences : Mot-clé sequence Exemple typedef sequence<long> DesNombresPremiers; typedef sequence<Jour> DesJours; typedef sequence<Date> DesDates;
Eléments du langage (8) Interfaces Une interface contient des définitions de types et constantes, des attributs et des opérations Exemple interface Compte { attribute float valeur; void deposer (in float somme); void retirer (in float somme); // Autres opérations }; typedef sequence<Compte> DesComptes;
Eléments du langage (9) Opérations Caractéristiques Exemple Nom : identificateur unique Paramètres : mode de passage (in, out, inout), type et nom Type du résultat : void si pas de retour Mode d’invocation : oneway si opération asynchrone Liste des exceptions : à la C++ Exemple exception problem { string raison; } oneway void retirer (in float somme) raises problem; Pas de surdéfinition d’opérations
Eléments du langage (10) Attributs Mot-clé : attribute Caractéristiques Mode Par défaut, les attributs peuvent être consultés et modifiés readonly : accessibles en lecture seulement Nom de l’attribut Exemple readonly attribute Annee annee_courante;
Eléments du langage (11) Héritage Exemple interface Compte { attribute float valeur; void deposer (in float somme); void retirer (in float somme); // Autres opérations }; interface CompteLivret : Compte { readonly attribute float Taux; } L’héritage peut être multiple et répété
Constructions du langage (résumé) Modules module NAME { ... } ; Interfaces interface NAME { ... } ; Constantes const TYPE NAME = VALEUR Types énumérés enum NAME { V1, ..., Vn } ; Nouveaux types typedef DECL NAME ; Structures struct NAME { DECL } ; Unions union NAME switch (TYPE){} ; Attributs readonly attribute TYPE NAME ; Opérations TYPE NAME (ARGs) raises ( ... ) ; [ in | inout | out] TYPE NAME Exceptions exception NAME { ... } ;
Exemple module GestionBancaire { struct FicheClient { string nom ; string adresse; }; interface compte { attribute FicheClient client; readonly attribute float balance; void faireDepot (in float f); oneway float faireRetrait (in float f); }; interface livret : compte { readonly attribute float taux; // D’autres définitions et interfaces
Projection d’IDL (1) Deux types de projection : squelette & souche Fichier IDL Précompilateur IDL C++ Précompilateur IDL Java Souche IDL C++ Squelette IDL Java Client C++ Serveur Java IIOP ORB A B
Projection d’IDL (2) Liaison vers un langage donné conformément aux règles définies par l’OMG pour ce langage Ces règles de traduction concernent Les types de base IDL Les constructeurs de type : enum, typedef, sequence, etc. Les références vers les objets L’invocation des opérations La manipulation des exceptions L’accès aux attributs L’API de l’ORB.
Types de base
Autres règles de projection (1)
Autres règles de projection (2)
Exemple : PerfectNumbers.idl interface PerfectNumbers { typedef sequence<long> PERFECTS; boolean is_perfect_number (in long number); PERFECTS all_perfects (in long number); };
Exemple : PerfectNumbers.java public interface PerfectNumbers extends org.omg.CORBA.Object { public boolean is_perfect_number (int number); public int[] all_perfects (int number); };
Exemple : PerfectNumbers.h class PerfectNumbers : virtual public CORBA_Object { // … typedef OBFixSeq<CORBA_Long> PERFECTS; virtual CORBA_boolean is_perfect_number (CORBA_Long number); virtual PERFECTS* all_perfects (CORBA_Long number); };
Passage de références en C++
Exemple interface PerfectNumbers { typedef sequence<long> PERFECTS; boolean is_perfect_number (in long number); PERFECTS all_perfects (in long number); };
Plan L’Object Management Group (OMG) IDL : Langage de spécification ORB : Bus de communication entre objets Méthodologie de développement et application
OMG : le modèle client/serveur objet Application Cliente ORB Application Serveur Interface d’objet Etat Code d’implantation Référence d’objet Requête Objet CORBA Activation
Le module CORBA Le module CORBA contient Deux interfaces de base les définitions des API des composantes du bus les définitions IDL des protocoles d’interopérabilité entre bus CORBA (IIOP, GIOP, etc.) Deux interfaces de base Object ORB
L’interface Object (1) Encapsulation des références d’objets CORBA Héritée par les interfaces IDL définies dans tout contrat Opérations d’obtention des méta-données caractérisant un objet Opérations de base de manipulation de ces références Opérations relatives à l’invocation dynamique
L’interface Object (2) interface Object { // Non standardisée : dépend de l’implantation du bus ImplementationDef get_implementation(); InterfaceDef get_interface(); boolean is_nil(); Object duplicate(); void release(); boolean is_a(in string logical_type_id); boolean non_existent(); boolean is_equivalent(in Object other_object); unsigned long hash(in unsigned long maximum); };
L’interface ORB C’est un «fourre-tout» Elle permet d’obtenir les références des objets notoires de convertir les références d ’objets en chaînes de caractères et vice versa d’obtenir les références des adaptateurs d’objets d’instancier des méta-données nécessaires à l’invocation dynamique des objets manipuler les requêtes invoquées dynamiquement
Initialisation du bus module CORBA { typedef string ORBid; typedef sequence<string> arg_list; ORB ORB_init(inout arg_list argv, in ORBid orb_identifier); }; public static void main (String args[]) { try { // initialisation du bus CORBA pour un processus client org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init (args,null); ... }
Les objets notoires (1) Objets primordiaux permettant de découvrir les objets disponibles sur le bus Trois objets notoires Référentiel des interfaces (Interface Repository) Services Nommage et Vendeur : annuaires permettant de retrouver les références de tout objet sur le bus CORBA
Les objets notoires (2) interface ORB { typedef string ObjectId; typedef sequence<ObjectId> ObjectIdList; ObjectIdList list_initial_services(); exception InvalidName {}; Object resolve_initial_references(in ObjectId identifier) raises (InvalidName); };
Les objets notoires (3) ... // Obtenir toute la liste des objets notoires ObjectIdList liste = orb.list_initial_services(); // Obtenir un seul objet notoire try { Object obj2 = resolve_initial_references(``NameService’’); } catch (org.omg.CORBA.ORBPackage.InvalidNmae ex) { System.err.println(``Can not resolve NameService’’); return; }; InterfaceRepository TradingService
Conversion d’objets // Le serveur fait … // Le client fait … HelloImpl hello = new HelloImpl (); // Diffusion de la référence de l ’objet String chaineIOR = orb.object_to_string (hello); System.out.println ("IOR de l ’objet " + chaineIOR); // Le client fait … org.omg.CORBA.Object obj = orb.string_to_object (args[0]); Hello hello = HelloHelper.narrow(obj); // Invocation de l ’objet distant hello.hello();
Plan L’Object Management Group (OMG) IDL : Langage de spécification ORB : Bus de communication entre objets Méthodologie de développement et application
Méthodologie de développement Ecrire le contrat IDL (appli.idl) : ensembles d’interfaces en IDL Générer les souches/squelettes de communication et les interfaces (compilateur IDL/langage d’implantation) Ecrire les implantations des interfaces Ecrire les codes du serveur et du client
Compilation et exécution (Java) Quelques variables d’environnement setenv CLASSPATH <RépertoireORB>/lib/OB.jar: … : classes setenv PATH <RépertoireORB>/bin/<JDK>/bin:$PATH Génération des souches/squelettes mkdir <nomPackage> jidl <nomPackage>.idl --package <nomPackage> Compilation des sources et souches/squelettes mkdir classes javac -d classes *.java <nomPackage>/*.java Exécution du serveur et du client java Server java Client [IOR: …]
Le bus ORBacus Conçu par la société Object-oriented Concepts, Inc. gratuit pour utilisation non commerciale les sources sont entièrement disponibles Environnement CORBA 2.x ouvert langages : C++ et Java OS : Solaris, Linux, Windows 95/NT, AIX, SGI et HP-UX Services Sécurité, Vendeur, Nommage, Evénement et Propriétés Disponibilité : http://www.ooc.com
Le cas du bus ORBacus ORBacus intègre 4 générateurs de code idl : IDL à C++ jidl : IDL à java hidl : IDL à HTML ridl : IDL à RTF irgen : IDL au Référentiel d’interfaces (IR) C++ Synopsis (-h, --h : option d’aide) idl [options] fichiers_idl jidl [options] fichiers_idl hidl [options] fichiers_idl ridl [options] fichiers_idl irgen nom
L’application « Hello World » Client Traitement Serveur // OMG-IDL interface Hello { void Hello(); }; HelloImpl Souche Hello Squelette Hello Bus d’objets répartis CORBA
Génération des souches et interfaces Java pour le fichier Hello.idl Compilateur OMG-IDL/Java _HelloImplBase.java StubForHello.java Hello.java HelloHelper.java HelloHolder.java HelloClient HelloServeur
L’interface et les classes Hello Hello.java : interface pour le type Hello public interface Hello extends org.omg.CORBA.object { public void hello(); } HelloHelper.java : classe utilitaire pour le type Hello final public class HelloHelper { public static Hello narrow(org.omg.CORBA.object obj) { … } … méthodes insert, extract, type, id, read, write ... HelloHolder.java : pour le passage out et inout final public class HelloHolder implements … { public Hello value; … méthodes constructeurs, _ read, _write, _type ...
Les classes souche et squelette StubForHello.java : implantation de la souche sert à envoyer les requêtes invisible pour les programmeurs instanciée automatiquement par HelloHelper (narrow) _HelloImplBase.java : implantation du squelette recoit et décode les requêtes doit être héritée par l’implantation
L’implantation Java de Hello // HelloImpl implante l’interface IDL Hello et hérite donc du squelette _HelloImplBase généré par le compilateur jidl public class HelloImpl extends HelloImplBase { public void hello() System.out.println ("JAVA HelloImpl.hello() : Hello World !"); }
Le programme HelloServer import org.omg.CORBA.*; import java.io.*; import hello.*; public class HelloServer { // Fonction principale implantant un processeur serveur CORBA public static void main (String args[]) { try { // initialisation du bus CORBA pour un processus serveur org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init (args,null); org.omg.CORBA.BOA boa = orb.BOA_init (args,null); // Création de l’objet d’implantation Hello. HelloImpl hello = new HelloImpl (); // Diffusion de la référence de l’objet String chaineIOR = orb.object_to_string (hello); System.out.println ("IOR de l’objet " + chaineIOR);
Le programme HelloServer (suite) // Mettre le serveur en attente des requêtes CORBA boa.impl_is_ready (null); System.exit(0); // En cas de problème lié à l’utilisation de CORBA } catch (org.omg.CORBA.SystemException ex) { System.err.println(ex.getMessage()); ex.printStackTrace(); System.exit(1); }
Le programme HelloClient public class HelloClient { public static void main (String args[]) try { // initialisation du bus CORBA pour un processus client org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init (args,null); // Création de la souche Java référençant l’objet Hello. org.omg.CORBA.Object obj = orb.string_to_object (args[0]); Hello hello = HelloHelper.narrow(obj); // Invocation de l’objet distant hello.hello();
Le programme HelloClient (suite) System.exit(0); // En cas de problème lié à l’utilisation de CORBA } catch (org.omg.CORBA.SystemException ex) { System.err.println(ex.getMessage()); ex.printStackTrace(); System.exit(1); }