Corba - Moodle INSA Rouen
Transcription
Corba - Moodle INSA Rouen
INSA - ASI InfoRep : Corba Informatique Répartie Corba Alexandre Pauchet INSA Rouen - Département ASI BO.B.RC.18, [email protected] 1/66 INSA - ASI Plan 1 Introduction 2 Le langage IDL 3 Le bus Corba 4 Corba en Java 5 Corba en C 6 Inter-opérabilité C/Java 7 Passage de paramètre InfoRep : Corba 2/66 INSA - ASI InfoRep : Corba Introduction 3/66 (1/3) Rappels sur les objets Programmation Orientée Objet Encapsulation : état (attributs) + fonctionnalités (méthodes) Modularité : regroupement en classes (abstraction) Réutilisabilité Composition/agrégation Extensibilité OBJET Interface Méthodes États attributs Implantation corps des méthodes INSA - ASI InfoRep : Corba Introduction 4/66 (2/3) Transposition du mécanisme des RPC 1 Client 10 2 4 7 9 Processus client Invocation d'une méthode Emballage des arguments Transport de l'invocation Déballage des arguments Invocation de l'objet réel 6 Processus serveur 3 1 2 3 4 5 5 Souche serveur Souche cliente 8 Réseau 6 7 8 9 10 Retour de l'invocation locale Emballage des résultats Transport des résultats Déballage des résultats Retour de l'invocation distante INSA - ASI InfoRep : Corba Introduction 5/66 (3/3) Principe de Corba Common Object Request Broker Architecture : CORBA interface de l'objet Référence de l'objet Application cliente Code d'implantation référence + opération + arguments en entrée ORB Objet CORBA activation Implantation de l'objet exception ou résultat + arguments en sortie Application serveur INSA - ASI InfoRep : Corba Le langage IDL (1/11) Description IDL : Interface Definition Language Contrat IDL : description de la coopération entre les fournisseurs et les utilisateurs de services Masquage des problèmes liés à l’interopérabilité Séparation interface/implantation des objets Masquage de l’hétérogénéité des objets Masquage de la localisation des objets Utilisé pour générer les talons, les squelettes et pour définir les interfaces du référentiel d’interface Il supporte l’héritage et l’héritage multiple Indépendant de tout langage de programmation/compilateur ⇒ langage pivot entre applications Correspondance IDL/langage est fournie pour : C, C++, Java, Smalltalk, Ada, Cobol, etc. 6/66 INSA - ASI InfoRep : Corba Le langage IDL (2/11) Cheminement 1 Écriture d’une interface IDL 2 Écriture d’une classe implantant l’interface 3 Écriture du programme serveur 4 Écriture du programme client ≡ 1 Déclaration des services accessibles à distance 2 Définition du code des services 3 Instanciation et enregistrement de l’objet serveur 4 Interactions avec le serveur 7/66 INSA - ASI InfoRep : Corba Le langage IDL (3/11) Syntaxe Caractéristiques Similaire à la syntaxe C/C++ Commentaires : /* */ ou // Identificateurs : séquence de caractères alphanumériques ou Identificateur pour chaque paramètre d’une méthode Liste de paramètres vide : () (pas (void)) Les caractères non associés signed/unsigned Préprocesseur identique au C/C++ Substitution de macros : #define Compilation conditionnelle : #ifdef et #ifndef Inclusion de sources : #include Directives de compilation : #pragma 8/66 INSA - ASI InfoRep : Corba Le langage IDL (4/11) Structure d’un fichier IDL 3 éléments principaux module : un espace de définitions interface : un regroupement de services (un objet Corba) méthode : un service Exemple module universite { interface Etudiant { string coordonnees(); boolean bacplus(in long annee); }; }; Plusieurs modules (éventuellement emboı̂tés) possibles Éléments “secondaires” pouvant être définis dans un fichier IDL : types, constantes, exceptions, attributs 9/66 INSA - ASI InfoRep : Corba Le langage IDL 10/66 (5/11) Les modules IDL Définition Modules : espaces de définition de constantes, de types de données, d’interfaces, d’exceptions et d’autres modules Chaque définition IDL est associée à un identifiant unique paramétrable (#pragma + prefix/version/ID) Exemples module Math { const double PI = 3.14159; typedef unsigned short Positif; }; module ServiceDate { typedef unsigned short Mois; typedef unsigned short Annee; }; INSA - ASI InfoRep : Corba Le langage IDL 11/66 (6/11) Types IDL Types dynamiques TypeCode Types complexes any Enum Struct Union Array Sequence Types objets Short Ushort Long Ulong Types simples LongLong UlongLong Double Float LongDouble Char String Boolean Wchar Wstring Octet INSA - ASI InfoRep : Corba Le langage IDL (7/11) Constantes, types, etc. <declaration_constante> ::= const <type> <identificateur> = <expression>; <definition_de_type> ::= typedef <type> <identificateur>; <une_enumeration> ::= enum <identificateur> { <identificateur>{,<identificateur>}* }; <une_structure> ::= struct <identificateur> { {<un_champ>}+ }; <un_champ> ::= <type> <identificateur> ; <une_union> ::= union <identificateur> switch (<type_scalaire>) { <un_choix> {<un_choix>}*}; <type_scalaire> ::= short | unsigned short | long | unsigned long | boolean | char | <id_d_une_enumeration> <un_choix> ::= <un_label> {<un_label>}* <un_champ> <un_label> ::= case <valeur_constante> : | default : <un_tableau> ::= <type> <une_dimension> {<une_dimension>}*; <une_dimension> ::= [<une_constante_de_type_entier_positif>] <une_sequence> ::= sequence < <type> >; | sequence < <type>,<taille_maximale> >; <type_indéfini> ::= any 12/66 INSA - ASI InfoRep : Corba Le langage IDL (8/11) Interface et opérations <prédéclaration> ::= interface <identificateur>; <une_interface> ::= interface <identificateur> [ <heritage> ] { <ensemble_de_declarations> }; <heritage> ::= : <une_interface> {,<une_interface>}* <ensemble_de_declarations> ::= [<un_attribut>]* [<une_operation>]* <un_attribut> ::= [readonly] attribute <type> <idenficateur>; <une_exception> ::= exception <identificateur> { <ensemble_de_declarations> }; <une_operation> ::= [oneway] <type_retour> <identificateur> (<parametres>) [<clause_exceptions>] [<clause_contextes>]; <type_retour> ::= void | <type_idl> <un_parametre> ::= <mode> <type> <nom_formel> <mode> ::= in | out | inout <clause_exceptions> ::= raises ( <liste_d_exceptions> ) <clause_contextes> ::= context ( <liste_des_contextes> ) 13/66 INSA - ASI Le langage IDL InfoRep : Corba (9/11) Exemple module ServiceDate { typedef unsigned short Jour; enum Mois { Janvier, Fevrier, Mars, Avril, Mai, Juin, Juillet, Aout, Septembre, Octobre, Novembre, Decembre }; typedef unsigned short Annee; struct Date { Jour leJour; Mois leMois; Annee lAnnee; }; typedef sequence<Date> DesDates; interface Calendrier { attribute Annee anneeCourante; boolean verifierUneDate(in Date d); void leJourSuivant(inout Date d); exception DateErronnee { string raison; }; Date convertirChaine(in string uneChaine) raises (DateErronnee); string convertirDate(in Date uneDate) raises (DateErronnee); }; interface CalendrierFerie : Calendrier { void lesJoursFeries(in Annee deLAnnee, out DesDates dates); }; }; 14/66 INSA - ASI Le langage IDL InfoRep : Corba 15/66 (10/11) Règles de projection : types simples IDL short unsigned short long unsigned long long long unsigned long long float double long double boolean octet char wchar string wstring fixed C++ CORBA::Short CORBA::UShort CORBA::Long CORBA::ULong CORBA::LongLong CORBA::ULongLong CORBA::Float CORBA::Double CORBA::LongDouble CORBA::Boolean CORBA::Octet CORBA::Char CORBA::WChar char* et CORBA::String char* et CORBA::WString template CORBA::Fixed Java short short int int long long float double pas encore défini boolean byte char char String String java.math.BigDecimal INSA - ASI Le langage IDL InfoRep : Corba 16/66 (11/11) Règles de projection : types composés IDL module type élémentaire constante définition de type énumération structure union tableau séquence interface référence d'objet attribut opération invocation passage de paramètres exception traitement des exceptions gestion mémoire C++ namespace ou classe imbriquée définition de type constante typedef enum structure classe tableau classe classe instance 1 ou 2 fonctions virtuelles membres fonction virtuelle membre appel de fonction membre voir transparent précédent classe try {...} catch classes T_var Java package type élémentaire attribut constant classe classe classe tableau tableau interface instance 1 ou 2 méthodes méthode appel de méthode Utilisation de la classe THolder classe try {...} catch ramassemiette INSA - ASI InfoRep : Corba Le bus Corba (1/9) Caractéristiques En charge de La liaison avec les langages de programmation La transparence des invocations Locales (même processus ou même environnement) Distantes Des invocations d’opérations statiques et dynamiques L’activation automatique des objets La communication entre différents bus 17/66 INSA - ASI InfoRep : Corba Le bus Corba 18/66 (2/9) Architecture du bus Corba Client Interface d'Invocations Statiques SII Programmes Utilisateurs d'objets Interface d'Invocations Dynamiques DII Programmes Fournisseurs d'objets Interface ORB Interface de Squelettes Statiques SSI Serveur Interface de Squelettes Dynamiques DSI Interface de l'Adapteur d'Objets Adaptateur d'Objets Noyau de l'Object Request Broker Protocole InterORB Internet (IIOP) Référentiel des interfaces Référentiel des implémentations INSA - ASI InfoRep : Corba Le bus Corba (3/9) Description de l’architecture du bus Corba 1/2 ORB : Assure le transport des invocations SII : Sert à encoder les arguments et décoder les résultats Projection des descriptions IDL vers les langages DII : construction dynamique des requêtes vers les objets Le référentiel d’interfaces : accès aux métadonnées sur toutes les définitions IDL des objets du Bus Interface ORB : primitives de base pour l’initialisation, le paramètrage de l’environnement Corba, l’instanciation des références et la gestion de la mémoire 19/66 INSA - ASI InfoRep : Corba Le bus Corba (4/9) Description de l’architecture du bus Corba 2/2 SSI : Sert à décoder les arguments, invoquer l’implémentation et encoder les résultats Résultat de la projection des descriptions IDL vers les langages de programmation DSI : équivalent de la SSI pour les invocations dynamiques Adaptateur d’objets : activations et contrôle d’accès Basic Object Adapter Library Object Adapter Object-oriented Database Adapter Portable Object Adapter Référentiel des implantations : contient l’ensemble des informations décrivant l’implantation des objets 20/66 INSA - ASI InfoRep : Corba Le bus Corba (5/9) Les protocoles de transport GIOP et IIOP Corba 2.0 : intégration obligatoire du protocole générique GIOP (General Inter-Orb Protocol) GIOP spécifie : Utilisation de CDR : Common Data Representation Remarque : décodage des informations que si le format de données interne est différent de celui de l’émetteur Les Références d’Objet Intéropérables (IOR) : Numéro de version de la couche transport L’adresse de la machine destinatrice Une clef pour identifier et localiser l’objet dans le serveur IIOP (Internet Inter-Orb Protocol) : Implante GIOP sur TCP/IP Les références interopérables sont définies par : Le numéro de version du protocole IIOP (1.2) L’adresse IP ou le nom de la machine Le numéro de port TCP utilisé La clef de l’objet 21/66 INSA - ASI InfoRep : Corba Le bus Corba 22/66 (6/9) Les protocoles de transport GIOP et IIOP GIOP et IIOP imposent le format des messages pour le transport des requêtes objet la localisation des objets la gestion des canaux de communication Valeur Type de message Émetteur du message 0 Request Client 1 Reply 2 3 CancelRequest LocateRequest 4 LocateReply Serveur 5 CloseConnection Serveur Serveur Client Client INSA - ASI InfoRep : Corba Le bus Corba 23/66 (7/9) Le Portable Object Adapter L’Adaptateur d’Objet active l’objet Corba sollicité Le POA remplace le BOA depuis la version 2.2 de CORBA Hiérarchie d’adaptateur d’objets IOR → ObjectID → Servant (implantation de l’objet Corba) POA Manager Policy POA 1 Default servant Root POA Active Object Map Default servant Object Id Active Object Map Object Id Object Id Object Id POA 2 Default servant Object Id Object Id Active Object Map Object Id Policy Object Id Object Id Policy servant manager servant manager INSA - ASI InfoRep : Corba Le bus Corba 24/66 (8/9) Le POA Manager Un POA est géré par un POA Manager : Actif : accepte les requêtes Suspendu : empile les requêtes dans une file d’attente du POA cible Rejet : toutes les requêtes sont rejetées en masse destroy Inactif deactivate Inactif : état temporaire avant destruction, les requêtes sont rejetées Actif deactivate Discard_requests Rejet Hold_requests activate Suspendu discard_request Create_POA INSA - ASI InfoRep : Corba Le bus Corba (9/9) Client/Serveur en Corba Un serveur Corba Initialiser le bus CORBA (obtenir l’objet ORB) Initialiser l’adaptateur d’objets (obtenir le POA) Créer les implantations d’objets Enregistrer les implantations par l’adaptateur Diffuser les références (affichage du numéro) Attendre des requêtes venant du bus Un client Corba Initialiser le bus (objet ORB) Créer les souches des objets à utiliser (obtenir les références d’objets IOR) Réaliser les traitements (appels) 25/66 INSA - ASI InfoRep : Corba Corba en Java (1/15) Distribution utilisée Distribution fournit avec le JDK (versions > 1.2) Avantages : Possède un service de nommage Inclut dans la JVM (pas besoin de charger d’autres classes) Implante le POA (versions > 1.4) Inconvénient : Peu de services Distributions concurrentes OpenORB : http://openorb.sourceforge.net/ ORBACUS : http://www.orbacus.com/ JacORB : http://www.jacorb.org/ 26/66 INSA - ASI Corba en Java InfoRep : Corba (2/15) HelloWorld : HelloWorld.idl HelloWorld.idl module HelloWorld { interface Hello { exception ChaineVide { }; string sayHello(in string name) raises (ChaineVide); }; }; 27/66 INSA - ASI InfoRep : Corba Corba en Java 28/66 (3/15) Génération des fichiers Fichiers générés (idlj -f(all|server|client) HelloWorld.idl) server : HelloPackage (ChaineVide.java, ChaineVideHelper.java, ChaineVideHolder.java) Hello.java HelloOperations.java HelloPOA.java client : HelloPackage (ChaineVide.java, ChaineVideHelper.java, ChaineVideHolder.java) Hello.java HelloHelper.java HelloHolder.java HelloOperations.java HelloStub.java Remarque En pratique, le serveur a souvent également besoin des classes Helper et nécessite donc une compilation avec l’option -fall. INSA - ASI Corba en Java InfoRep : Corba (4/15) HelloWorld : HelloPOA.java package HelloWorld; /** * HelloWorld/HelloPOA.java . * Generated by the IDL-to-Java compiler (portable), version "3.2" * from HelloWorld.idl c * mardi 12 fA~vrier 2013 18 h 54 CET */ public abstract class HelloPOA extends org.omg.PortableServer.Servant implements HelloWorld.HelloOperations, org.omg.CORBA.portable.InvokeHandler { // Constructors private static java.util.Hashtable _methods = new java.util.Hashtable (); static { _methods.put ("sayHello", new java.lang.Integer (0)); } public org.omg.CORBA.portable.OutputStream _invoke (String $method, org.omg.CORBA.portable.InputStream in, org.omg.CORBA.portable.ResponseHandler $rh) { org.omg.CORBA.portable.OutputStream out = null; java.lang.Integer __method = (java.lang.Integer)_methods.get ($method); if (__method == null) throw new org.omg.CORBA.BAD_OPERATION (0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE); 29/66 INSA - ASI InfoRep : Corba Corba en Java (5/15) HelloWorld : HelloPOA.java switch (__method.intValue ()) { case 0: // HelloWorld/Hello/sayHello { try { String name = in.read_string (); String $result = null; $result = this.sayHello (name); out = $rh.createReply(); out.write_string ($result); } catch (HelloWorld.HelloPackage.ChaineVide $ex) { out = $rh.createExceptionReply (); HelloWorld.HelloPackage.ChaineVideHelper.write (out, $ex); } break; } default: throw new org.omg.CORBA.BAD_OPERATION (0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE); } return out; } // _invoke // Type-specific CORBA::Object operations private static String[] __ids = { "IDL:HelloWorld/Hello:1.0"}; 30/66 INSA - ASI InfoRep : Corba Corba en Java (6/15) HelloWorld : HelloPOA.java public String[] _all_interfaces (org.omg.PortableServer.POA poa, byte[] objectId) { return (String[])__ids.clone (); } public Hello _this() { return HelloHelper.narrow( super._this_object()); } public Hello _this(org.omg.CORBA.ORB orb) { return HelloHelper.narrow( super._this_object(orb)); } } // class HelloPOA Mise en place d’un servant Implantation de la méthode sayHello() Utilisation du POA par héritage et non par délégation 31/66 INSA - ASI InfoRep : Corba Corba en Java (7/15) Client et Serveur Serveur 1 Initialiser l’ORB 2 Récupèrer le RootPOA 3 Activer le POAManager 4 Créer le servant 5 Référencer le servant par le POA 6 Proposer l’IOR correspondant (en l’affichant) 7 Attendre les requêtes Client 1 Initialiser l’ORB 2 Récupèrer l’IOR → Obtenir un objet de type Hello 3 Invoquer la méthode sayHello() 32/66 INSA - ASI Corba en Java InfoRep : Corba (8/15) HelloWorld sans service de nommage : HelloServant.java import HelloWorld.*; import HelloWorld.HelloPackage.*; class HelloServant extends HelloPOA { public String sayHello(String name) throws ChaineVide { if (name.equals("")) throw new ChaineVide(); System.out.println("Request from " + name); return "Hello "+name; } } 33/66 INSA - ASI InfoRep : Corba Corba en Java (9/15) HelloWorld sans service de nommage : HelloServer.java import import import import HelloWorld.*; org.omg.CORBA.*; org.omg.PortableServer.*; org.omg.PortableServer.POA; public class HelloServer { public static void main(String args[]) { try { String orbArguments[]=new String[0]; ORB orb=ORB.init(orbArguments,null); POA rootpoa = POAHelper.narrow(orb.resolve_initial_references("RootPOA")); rootpoa.the_POAManager().activate(); HelloServant helloServant=new HelloServant(); Hello corbaHelloObject = HelloHelper.narrow(rootpoa.servant_to_reference(helloServant)); System.out.println(orb.object_to_string(corbaHelloObject)); orb.run(); } catch (Exception e) { System.err.println("Error : "+e); } } } 34/66 INSA - ASI Corba en Java InfoRep : Corba (10/15) HelloWorld sans service de nommage : HelloClient.java import HelloWorld.*; import org.omg.CORBA.*; public class HelloClient { public static void main(String args[]) { try { String orbArguments[] = new String[0]; ORB orb = ORB.init(orbArguments, null); org.omg.CORBA.Object corbaObject = orb.string_to_object(args[0]); Hello corbaHelloObject = HelloHelper.narrow(corbaObject); if (args.length==1) System.out.println(corbaHelloObject.sayHello("")); else System.out.println(corbaHelloObject.sayHello(args[1])); } catch (Exception e) { System.err.println("Error : "+e); } } } 35/66 INSA - ASI InfoRep : Corba Corba en Java (11/15) Utilisation d’un service de nommage dédié Serveur 1 Initialiser l’ORB 2 Récupèrer le RootPOA et l’activer 3 Créer un servant 4 Référencer le servant par le POA 5 Récupérer le service de nommage 6 Créer un nom (= séquence de NameComponent, chemin) 7 Enregistrer l’objet auprès du serveur de nommmage 8 Attendre les requêtes 36/66 INSA - ASI InfoRep : Corba Corba en Java (12/15) Utilisation d’un service de nommage dédié Client 1 Initialiser l’ORB 2 Récupérer l’objet Service de nommage 3 Récupérer l’objet de type Hello auprès du Service de nommage 4 Invoquer l’objet distant orbd orbd : bootstrap service + transcient naming service + persistent naming service + server manager Le client et le serveur doivent être en Java 37/66 INSA - ASI InfoRep : Corba Corba en Java (13/15) HelloWorld avec service de nommage : HelloServer.java import import import import import import HelloWorld.*; org.omg.CORBA.*; org.omg.PortableServer.*; org.omg.PortableServer.POA; org.omg.CosNaming.*; org.omg.CORBA.*; public class HelloServer { public static void main(String args[]) { try { ORB orb = ORB.init(args, null); POA rootpoa = POAHelper.narrow(orb.resolve_initial_references("RootPOA")); rootpoa.the_POAManager().activate(); HelloServant helloServant=new HelloServant(); Hello helloCorbaObject = HelloHelper.narrow(rootpoa.servant_to_reference(helloServant)); org.omg.CORBA.Object corbaNamingServiceReference = orb.resolve_initial_references("NameService"); NamingContext corbaNamingServiceObject = NamingContextHelper.narrow(corbaNamingServiceReference); NameComponent helloNameComponent = new NameComponent("Hello", ""); NameComponent helloPath[] = {helloNameComponent}; corbaNamingServiceObject.rebind(helloPath, helloCorbaObject); orb.run(); } catch (Exception e) { System.err.println("Error : "+e); } } } 38/66 INSA - ASI InfoRep : Corba Corba en Java 39/66 (14/15) HelloWorld avec service de nommage : HelloClient.java import import import import HelloWorld.*; org.omg.CORBA.*; org.omg.CosNaming.*; org.omg.CORBA.*; public class HelloClient { public static void main(String args[]) { try { ORB orb = ORB.init(args, null); NamingContext corbaNamingServiceObject = NamingContextHelper.narrow(orb.resolve_initial_references( "NameService")); NameComponent helloNameComponent = new NameComponent("Hello", ""); NameComponent helloPath[] = {helloNameComponent}; Hello helloCorbaObject = HelloHelper.narrow(corbaNamingServiceObject.resolve(helloPath)); if (args.length<3) System.out.println(helloCorbaObject.sayHello("")); else System.out.println(helloCorbaObject.sayHello(args[args.length-1])); } catch (Exception e) { System.err.println("Error : "+e); } } } INSA - ASI Corba en Java InfoRep : Corba (15/15) HelloWorld avec service de nommage : orbd Service de nommage orbd -ORBInitialPort PORT Client et Serveur L’ORB doit être initialisée avec l’option : -ORBInitialPort PORT 40/66 INSA - ASI InfoRep : Corba Corba en C 41/66 (1/15) Distribution utilisée Distribution fournie avec Gnome : Orbit2 Avantages : Fourni de fait avec Gnome : OpenSource Très rapide Utilisable depuis beaucoup de langages (C, C++, perl, python, etc.) Possède un POA Outils “Compilateur” : orbit-idl-2 Aide à la compilation et à l’édition de liens : orbit2-config Serveur de nommage : orbit-name-server-2 INSA - ASI Corba en C InfoRep : Corba (2/15) orbit-idl-2 Usage: orbit-idl-2 [OPTION...] <IDL files> Help Options: -?, --help --help-all --help-libIDL --help-cpp Show Show Show Show Application Options: -v, --version -l, --lang=LANG -d, --debug=LEVEL --idlwarnlevel=LEVEL --showcpperrors --nostubs --noskels --nocommon --noheaders --noidata -i, --imodule --add-imodule --skeleton-impl --backenddir=DIR --onlytop --pidl --nodefskels --deps=FILENAME --headerguardprefix=PREFIX --output-dir=DIR Output compiler version and serial Output language (default is C) Debug level (0 to 4) IDL warning level (0 to 4, default is 2) Show CPP errors Don’t output stubs Don’t output skels Don’t output common Don’t output headers Don’t generate Interface type data Output only an imodule file Output an imodule file Output skeleton implementation Override IDL backend library directory Inhibit includes Treat as Pseudo IDL Don’t output defs for skels in header Generate dependency info suitable for inclusion in Makefile Prefix for #ifdef header guards. Sometimes useful to avoid conflicts. Where to put generated files. This directory must exist. help options all help options libIDL options preprocessor options 42/66 INSA - ASI InfoRep : Corba Corba en C (3/15) orbit2-config Usage: orbit2-config [OPTION][OPTION]... TARGET Known values for OPTION are: --prefix=DIR change ORBit prefix [default /usr] --exec-prefix=DIR change ORBit executable prefix [default /usr] --libs print library linking information --cflags print pre-processor and compiler flags --help display this help and exit --version output version information --use-service=SRVC the service SRVC will be used Known values for SRVC are: name module CosNaming, interfaces LNameComponent, LName Known values for TARGET are: client (calls pkg-config) server (calls pkg-config) Exemple orbit2-config --cflags server orbit2-config --libs --use-service=name server 43/66 INSA - ASI InfoRep : Corba Corba en C (4/15) Génération des fichiers HelloWorld.idl module HelloWorld { interface Hello { string sayHello(in string name); }; }; Fichiers générés Automatiquement (orbit-idl-2 HelloWorld.idl) : HelloWorld.h HelloWorld-common.c HelloWorld-stubs.c HelloWorld-skels.c Avec option --skeleton-impl : HelloWorld-skelimpl.c ← Fichier à compléter (service) 44/66 INSA - ASI Corba en C InfoRep : Corba (5/15) HelloWorld : HelloWorld-skelimpl.c /* /* /* /* This is a template file generated by command */ orbit-idl-2 --skeleton-impl HelloWorld.idl */ User must edit this file, inserting servant */ specific code between markers. */ #include <stdio.h> #include <string.h> #include "HelloWorld.h" /*** App-specific servant structures ***/ #if !defined(_typedef_impl_POA_HelloWorld_Hello_) #define _typedef_impl_POA_HelloWorld_Hello_ 1 typedef struct { POA_HelloWorld_Hello servant; PortableServer_POA poa; /* ------ add private attributes here ------ */ /* ------ ---------- end ------------ ------ */ } impl_POA_HelloWorld_Hello; #endif ... ... 45/66 INSA - ASI Corba en C InfoRep : Corba (6/15) HelloWorld : HelloWorld-skelimpl.c ... /*** Stub implementations ***/ #if !defined(_impl_HelloWorld_Hello__create_) #define _impl_HelloWorld_Hello__create_ 1 static HelloWorld_Hello impl_HelloWorld_Hello__create(PortableServer_POA poa, CORBA_Environment *ev) { HelloWorld_Hello retval; impl_POA_HelloWorld_Hello *newservant; PortableServer_ObjectId *objid; newservant = g_new0(impl_POA_HelloWorld_Hello, 1); newservant->servant.vepv = &impl_HelloWorld_Hello_vepv; newservant->poa = (PortableServer_POA) CORBA_Object_duplicate((CORBA_Object)poa, ev); POA_HelloWorld_Hello__init((PortableServer_Servant)newservant, ev); /* Before servant is going to be activated all * private attributes must be initialized. */ /* ------ init private attributes here ------ */ /* ------ ---------- end ------------- ------ */ objid = PortableServer_POA_activate_object(poa, newservant, ev); CORBA_free(objid); retval = PortableServer_POA_servant_to_reference(poa, newservant, ev); return retval; } #endif ... 46/66 INSA - ASI Corba en C InfoRep : Corba (7/15) HelloWorld : HelloWorld-skelimpl.c ... #if !defined(_impl_HelloWorld_Hello__destroy_) #define _impl_HelloWorld_Hello__destroy_ 1 static void impl_HelloWorld_Hello__destroy(impl_POA_HelloWorld_Hello *servant, CORBA_Environment *ev) { CORBA_Object_release ((CORBA_Object) servant->poa, ev); /* No further remote method calls are delegated to * servant and you may free your private attributes. */ /* ------ free private attributes here ------ */ /* ------ ---------- end ------------- ------ */ POA_HelloWorld_Hello__fini((PortableServer_Servant)servant, ev); g_free (servant); } #endif ... 47/66 INSA - ASI Corba en C InfoRep : Corba (8/15) HelloWorld : HelloWorld-skelimpl.c ... #if !defined(_impl_HelloWorld_Hello_sayHello_) #define _impl_HelloWorld_Hello_sayHello_ 1 static CORBA_string impl_HelloWorld_Hello_sayHello(impl_POA_HelloWorld_Hello *servant, const CORBA_char * name, CORBA_Environment *ev) { CORBA_string retval; /* ------ insert method code here ------ */ /* ------ ---------- end ------------ ------ */ printf("Request from %s\n", name); retval = CORBA_string_alloc(6+strlen(name)+1); strcpy(retval, "Hello "); strcat(retval, name); return retval; } #endif Remarque Un Servant est implanté en Java par héritage, en C par délégation. 48/66 INSA - ASI InfoRep : Corba Corba en C (9/15) Client et Serveur Serveur 1 Initialiser l’ORB 2 Récupérer le POA 3 Créer un servant 4 Afficher l’IOR 5 Attendre les requêtes Client 1 Initialiser l’ORB 2 Récupérer l’IOR → référencer l’objet distant 3 Invoquer l’objet distant 49/66 INSA - ASI Corba en C InfoRep : Corba (10/15) HelloWorld : HelloWorldServer.c #include <stdio.h> #include "HelloWorld.h" #include "HelloWorld-skelimpl.c" int main (int argc, char *argv[]) { PortableServer_POA rootpoa; HelloWorld_Hello corbaHelloObject; CORBA_ORB orb=NULL; char *ior; CORBA_Environment ev; CORBA_exception_init(&ev); orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", &ev); rootpoa = (PortableServer_POA)CORBA_ORB_resolve_initial_references(orb, "RootPOA", &ev); PortableServer_POAManager_activate(PortableServer_POA__get_the_POAManager(rootpoa, &ev), &ev); corbaHelloObject=impl_HelloWorld_Hello__create(rootpoa,&ev); ior = CORBA_ORB_object_to_string(orb, corbaHelloObject, &ev); printf ("%s\n", ior); CORBA_free(ior); CORBA_ORB_run(orb, &ev); CORBA_Object_release(corbaHelloObject, &ev); CORBA_ORB_shutdown(orb, CORBA_FALSE, &ev); return 0; } 50/66 INSA - ASI Corba en C InfoRep : Corba (11/15) HelloWorld : HelloWorldClient.c #include <stdio.h> #include "HelloWorld.h" int main (int argc, char* argv[]) { CORBA_Environment env; HelloWorld_Hello corbaHelloObject; CORBA_ORB orb = NULL; int orbArgc = 0; char* orbArgv[0]; CORBA_char* temp; CORBA_exception_init(&env); orb = CORBA_ORB_init(&orbArgc, orbArgv, "orbit-local-orb", &env); corbaHelloObject = CORBA_ORB_string_to_object(orb, argv[1], &env); temp = HelloWorld_Hello_sayHello(corbaHelloObject, argv[2], &env); printf("%s\n",temp); CORBA_free(temp); CORBA_Object_release(corbaHelloObject, &env); CORBA_ORB_shutdown(orb, CORBA_FALSE, &env); return 0; } 51/66 INSA - ASI InfoRep : Corba Corba en C 52/66 (12/15) Utilisation d’un service de nommage orbit-name-server-2 : ORBit2 COS Naming Service Remarques : Par défaut ce service de nommage doit être appelé par son IOR, via l’option : ORBInitRef NameService=IOR Alternative : corbaloc orbit-name-server-2 est initialisé avec l’option : --key=KEY L’IOR est remplacé par : corbaloc:iiop:version@host:port/KEY Exemple : corbaloc:iiop:1.2@localhost:4444/NamingService INSA - ASI InfoRep : Corba Corba en C (13/15) Utilisation d’un service de nommage Serveur 1 Initialiser l’ORB 2 Récupérer le POA 3 Créer un servant 4 Récupérer le service de nommage 5 Enregistrer le servant sous un nom 6 Attendre les requêtes Client 1 Initialiser l’ORB 2 Récupérer le service de nommage 3 Récupérer l’objet distant via le service de nommage 4 Invoquer l’objet distant 53/66 INSA - ASI InfoRep : Corba Corba en C (14/15) HelloWorld : HelloWorldServer.c #include #include #include #include #include <stdio.h> "HelloWorld.h" <ORBitservices/CosNaming.h> <ORBitservices/CosNaming_impl.h> "HelloWorld-skelimpl.c" int main (int argc, char *argv[]) { PortableServer_POA poa; HelloWorld_Hello corbaHelloObject; CosNaming_NamingContext nameServiceObject; CORBA_ORB orb = NULL; CosNaming_NameComponent namePath[1] = {"Hello", ""}; CosNaming_Name name = {1, 1, namePath, CORBA_FALSE}; CORBA_Environment env; CORBA_exception_init(&env); orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", &env); poa = (PortableServer_POA)CORBA_ORB_resolve_initial_references(orb, "RootPOA", &env); PortableServer_POAManager_activate(PortableServer_POA__get_the_POAManager(poa, &env), &env); corbaHelloObject = impl_HelloWorld_Hello__create(poa, &env); nameServiceObject = CORBA_ORB_resolve_initial_references(orb, "NameService", &env); CosNaming_NamingContext_bind(nameServiceObject, &name, corbaHelloObject, &env); CORBA_ORB_run(orb, &env); CORBA_Object_release(corbaHelloObject, &env); CORBA_ORB_shutdown(orb, CORBA_FALSE, &env); return 0; } 54/66 INSA - ASI InfoRep : Corba Corba en C (15/15) HelloWorld : HelloWorldClient.c #include #include #include #include <stdio.h> "HelloWorld.h" <ORBitservices/CosNaming.h> <ORBitservices/CosNaming_impl.h> int main (int argc, char* argv[]) { CORBA_Environment env; HelloWorld_Hello corbaHelloObject; CosNaming_NamingContext nameServiceObject; CORBA_ORB orb = NULL; CORBA_char* temp; CosNaming_NameComponent namePath[1] = {"Hello", ""}; CosNaming_Name name = {1, 1, namePath, CORBA_FALSE}; CORBA_exception_init(&env); orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", &env); nameServiceObject = CORBA_ORB_resolve_initial_references(orb, "NameService", &env); corbaHelloObject = CosNaming_NamingContext_resolve(nameServiceObject, &name, &env); temp = HelloWorld_Hello_sayHello(corbaHelloObject, argv[argc-1], &env); printf("%s\n", temp); CORBA_free(temp); CORBA_Object_release(corbaHelloObject, &env); CORBA_ORB_shutdown(orb, CORBA_FALSE, &env); return 0; } 55/66 INSA - ASI InfoRep : Corba Inter-opérabilité C/Java Contraintes Serveur/Client en C : l’option --ORBIIOPIPv4=1 est indispensable avec un serveur ou un client Java Utilisation d’un service de nommage : orbd est incompatible avec orbit2 orbit-name-server-2 permettent l’inter-opérabilité C/Java Les IOR et corbaloc sont supportés 56/66 INSA - ASI Inter-opérabilité C/Java Fichier IDL HelloGuy.idl module HelloGuy { struct Guy { string name; long age; }; interface Hello { string sayHello(in Guy aGuy); }; }; InfoRep : Corba 57/66 INSA - ASI InfoRep : Corba Inter-opérabilité C/Java Serveur en Java : le servant Génération des fichiers idlj -fall -td Java/ HelloGuy.idl HelloGuyServant.java import HelloGuy.*; class HelloGuyServant extends HelloPOA { public String sayHello(Guy aGuy) { System.out.println("Request from " + aGuy.name + ", " + aGuy.age + " years"); return "Hello " + aGuy.name; } } 58/66 INSA - ASI InfoRep : Corba Inter-opérabilité C/Java Serveur en Java : le serveur HelloGuyServer.java import import import import import HelloGuy.*; org.omg.CosNaming.*; org.omg.CORBA.*; org.omg.PortableServer.*; org.omg.PortableServer.POA; public class HelloGuyServer { public static void main(String args[]) { try { ORB orb = ORB.init(args, null); POA rootpoa = POAHelper.narrow(orb.resolve_initial_references("RootPOA")); rootpoa.the_POAManager().activate(); HelloGuyServant helloServant = new HelloGuyServant(); Hello corbaHelloObject = HelloHelper.narrow(rootpoa.servant_to_reference(helloServant)); org.omg.CORBA.Object corbaNamingServiceReference = orb.resolve_initial_references("NameService"); NamingContext corbaNamingServiceObject = NamingContextHelper.narrow(corbaNamingServiceReference); NameComponent helloNameComponent = new NameComponent("Hello", ""); NameComponent helloPath[] = {helloNameComponent}; corbaNamingServiceObject.rebind(helloPath, corbaHelloObject); orb.run(); } catch (Exception e) { System.err.println("Error : "+e); } } } 59/66 INSA - ASI InfoRep : Corba Inter-opérabilité C/Java Client en C Génaration des fichiers orbit-idl-2 --noskels --output-dir=C/ HelloGuy.idl HelloGuyClient.c #include #include #include #include <stdio.h> "HelloGuy.h" <ORBitservices/CosNaming.h> <ORBitservices/CosNaming_impl.h> int main (int argc, char* argv[]) { CORBA_Environment env; HelloGuy_Hello corbaHelloObject; HelloGuy_Guy aGuy; int age; CosNaming_NamingContext nameServiceObject; CORBA_ORB orb = NULL; CORBA_char* temp; CosNaming_NameComponent namePath[1] = {"Hello", ""}; CosNaming_Name name = {1, 1, namePath, CORBA_FALSE}; ... 60/66 INSA - ASI InfoRep : Corba Inter-opérabilité C/Java Client en C HelloGuyClient.c ... CORBA_exception_init(&env); orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", &env); nameServiceObject = CORBA_ORB_resolve_initial_references(orb, "NameService", &env); corbaHelloObject = CosNaming_NamingContext_resolve(nameServiceObject, &name, &env); aGuy.name = (CORBA_string)argv[argc-2]; sscanf(argv[argc-1], "%d", &age); aGuy.age = (CORBA_long)age; temp = HelloGuy_Hello_sayHello(corbaHelloObject, &aGuy, &env); printf("%s\n", temp); CORBA_free(temp); CORBA_Object_release(corbaHelloObject, &env); CORBA_ORB_shutdown(orb, CORBA_FALSE, &env); return 0; } 61/66 INSA - ASI InfoRep : Corba Appel de procédure à distance (1/5) Sérialisation et callbacks (rappel) 3 types de passage d’objet : Passage simple d’information (structure) : sérialisation Passage d’objet (attributs+méthodes) : sérialisation + accessibilité au code Passage d’objet non délocalisable (références locales=callback) : stub Callback On appelle Callback (fonction en retour) une méthode appelée par le serveur (resp. le client) sur un objet transmis en paramètre par le client (resp. le serveur) et nécessitant d’être exécuté par le client (resp. le serveur). 62/66 INSA - ASI InfoRep : Corba Appel de procédure à distance Exemples de Sérialisation : Chiffrement.idl module Chiffrement { struct Objet { string chaine; long nombre; }; interface ServeurDeChiffrement { string crypteChaine(in string chaine); void crypteChaineInOut(inout string chaine); Objet crypteObjet(in Objet objet); }; }; (2/5) 63/66 INSA - ASI InfoRep : Corba Appel de procédure à distance (3/5) Exemples de Sérialisation : Servant.java import Chiffrement.*; import org.omg.CORBA.StringHolder; class Servant extends ServeurDeChiffrementPOA { public String crypteChaine(String chaine) { String chaineCryptee = chaine.toUpperCase(); System.out.println(chaine + " => " + chaineCryptee); return chaineCryptee; } public void crypteChaineInOut(StringHolder chaine) { String chaineNonCryptee = chaine.value; chaine.value = chaineNonCryptee.toUpperCase(); System.out.println(chaineNonCryptee + " => " + chaine.value); } public Objet crypteObjet(Objet objet) { objet.chaine = objet.chaine.toUpperCase(); objet.nombre++; System.out.println("=> (" + objet.chaine + ", " + objet.nombre + ")"); return objet; } } 64/66 INSA - ASI InfoRep : Corba Appel de procédure à distance 65/66 (4/5) Exemples de Sérialisation : Serveur.java ... public class Serveur { public static void main(String args[]) { String orbArguments[] = new String[2]; orbArguments[0] = "-ORBInitialPort"; orbArguments[1] = args[0]; try { ORB orb = ORB.init(orbArguments, null); POA rootpoa = POAHelper.narrow(orb.resolve_initial_references("RootPOA")); rootpoa.the_POAManager().activate(); Servant servantDeChiffrement = new Servant(); ServeurDeChiffrement serveurCorba = ServeurDeChiffrementHelper.narrow(rootpoa.servant_to_reference( servantDeChiffrement)); org.omg.CORBA.Object corbaNamingServiceReference = orb.resolve_initial_references("NameService"); NamingContext corbaNamingServiceObject = NamingContextHelper.narrow(corbaNamingServiceReference); NameComponent nameComponent = new NameComponent("ServeurDeChiffrement", ""); NameComponent path[] = {nameComponent}; corbaNamingServiceObject.rebind(path, serveurCorba); orb.run(); } catch (Exception e) { System.err.println("Error : "+e); } } } INSA - ASI InfoRep : Corba Appel de procédure à distance 66/66 (5/5) Exemples de Sérialisation : Client.java ... public class Client { public static void main(String args[]) { String orbArguments[] = new String[2]; orbArguments[0] = "-ORBInitialPort"; orbArguments[1] = args[0]; try { ORB orb = ORB.init(orbArguments, null); NamingContext corbaNamingServiceObject = NamingContextHelper.narrow(orb.resolve_initial_references( "NameService")); NameComponent nameComponent = new NameComponent("ServeurDeChiffrement", ""); NameComponent path[] = {nameComponent}; ServeurDeChiffrement serveur = ServeurDeChiffrementHelper.narrow(corbaNamingServiceObject.resolve( path)); System.out.println(serveur.crypteChaine(args[args.length-2])); StringHolder chaineLocale = new StringHolder(args[args.length-2]); System.out.print(chaineLocale.value + " => "); serveur.crypteChaineInOut(chaineLocale); System.out.println(chaineLocale.value); Objet objet = new Objet(args[args.length-2], Integer.parseInt(args[args.length-1])), objetCrypte = serveur.crypteObjet(objet); System.out.println("(" + objetCrypte.chaine + ", " + objetCrypte.nombre + ")"); } catch (Exception e) { System.err.println("Error : "+e); } } }