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
ramasse­miette
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 Inter­ORB 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);
}
}
}

Documents pareils