Upload
hoangcong
View
213
Download
0
Embed Size (px)
Citation preview
Common Object Request Broker ArchitectureDéveloppement Java
Jonathan Lejeune
Sorbonne Université/LIP6-INRIA
SRCS � Master 1 SAR 2017/2018
sources :
Présentation de Corba, Marc-Olivier Killijian
Au c÷ur de Corba avec Java, Jérome Daniel
Développer avec CORBA en Java et C++, D. Acreman, G. Moujeard, L. Rousset
Cours de Gaël Thomas et Lionel Seinturier
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 1 / 62
Rappels cours précédent : Architecture CORBA
Object Request Broker
ClientServeur
Servant
Servant
squelette squelettesouche souche
Portable Object AdapterIOR IOR
DSI
DII
Protocole GIOPORB ORB
Réseau
Mandataire Mandataire
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 2 / 62
Rappels cours précédent : Conception d'application
Etape 1 – Interface IDL
Souche ClientSérialisation + mandataire
Implémente
Etape 3 – Classe X(classe du Servant)
Implémente
Squelette de XCode de désérialisation/réceptionCode d’enregistrement de l’objet serveurCode du POA
Etape 2 -Compilation IDL
ObjetMandataire X
Instance deObjet type X
Instance de
Etape 5 - Code Client
Construit et appel
Délègue l’appel
Référence et délègue
Etape 4 – InitialisationAllocation serveurEnregistrement serveur
construit
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 3 / 62
Rappels cours précédent : classes Java d'un service
<<interface>>FooOperations/* interface java
traduisant l’IDL */
<<interface>>Foo
/* interface de l’Objet Corba
traduisant l’IDL */
FooPOA
/* squelette du Serveur (implem par héritage) */
FooPOATie
/* squelette du Serveur (implem par délégation) */
_FooStub
/* souche cliente */
org.omg.PortableServer.Servant
<<interface>>org.omg.CORBA.portable.InvokeHandler
<<abstract>>FooHelper
/* utilitaire pour gérer les Foo*/
org.omg.CORBA.portable.ObjectImplFooHolder
/* utilitaire pour gérer les out et inout sur type Foo*/
<<interface>>org.omg.CORBA.portable.Streamable
<<interface>>org.omg.CORBA.Object
<<interface>>org.omg.CORBA.portable.IDLEntity
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 4 / 62
Rappels cours précédent : étape 4 et 5
Schéma de serveur
1) Initialiser l'ORB
2) Initialiser et activer le POA
3) Créer une instance de l'objet servant
4) Enregistrer le servant dans le POA + création d'une référence CORBA(IOR)
5) Lier la référence CORBA à un nom
6) Signaler à l'ORB que le serveur est prêt et se mettre en attente dedemandes provenant des clients
Schéma de client
1) Initialiser l'ORB
2) Trouver une référence CORBA et construire le mandataire
3) Appeler les services souhaités
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 5 / 62
Code minimal du serveur (étape 4)
public class Serveur {
public static void main( String [] args ) throws Exception {
//1) Initialiser l'ORB
ORB orb = ORB.init( args , null );
//2) Initialiser et activer le POA
CORBA.Object rootobj = orb.resolve_initial_references("RootPOA");
POA rootpoa = POAHelper.narrow(rootobj );
rootpoa.the_POAManager (). activate ();
//3)Créer une instance de l'objet servant
Servant servant=new MonObjetServeur ();
//4) Enregistrer servant dans POA + création d'une réf CORBA
CORBA.Object obj = rootpoa.servant_to_reference(servant );
//5) Lier la référence CORBA à un nom
//cf annuaire CORBA
//6) se mettre en attente de demandes provenant des clients
orb.run();
}
}
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 6 / 62
API de l'ORB
Création d'un ORBorg.omg.CORBA.ORB.init(String[] args, Properties props);
Méthode statique créant un nouvel ORB
args correspond aux arguments de la fonction main
props permet de con�gurer l'ORB avec des properties Java⇒ Association entre un nom de paramètre et une valeur⇒ si null, utilisation des paramètres par défaut
public static void main(String args []){
Properties props = new Properties ();
props.setProperty("paramX", "val du param X");
props.setProperty("paramY", "val du param Y");
ORB orb = org.omg.CORBA.ORB.init(args ,props);
}
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 7 / 62
API de l'ORB
Méthodes d'instance
String[] list_initial_services() : liste les noms des objets CORBAinitialement disponibles
CORBA.Object resolve_initial_references(String object_name) :obtention d'une référence CORBA sur un service initial
String object_to_string(CORBA.Object obj) : convertir une référenced'objet CORBA en une chaîne de caractères
CORBA.Object string_to_object(String str) : construire une référenced'objet CORBA à partir d'une chaîne de caractère ou d'une URL
Any create_any() : création d'un Any
void destroy( ) : détruire l'instance
void run() : mise en attente des requête clientes (appel bloquant)
shutdown(boolean wait_for_completion) : désactiver l'ORB avec attenteou pas des requêtes en cours sur les servants hébergés
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 8 / 62
Les objets CORBA
Rappel sur les objets CORBA
Tout objet CORBA :
implante org.omg.CORBA.Object
sous-classe de org.omg.CORBA.portable.ObjectImpl
référence un servant grâce à une référence distante CORBA (= IOR)⇒ Objet CORBA = IOR sur un servant⇒ Objet CORBA 6= un objet servant
Obtenir l'IOR d'un objet au format String
org.omg.CORBA.Object objet = ......;
String ior = orb.object_to_string(objet );
Obtenir l'IOR d'un objet à partir d'une String
String ior = ......;
org.omg.CORBA.Object obj = orb.string_to_object(ior);
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 9 / 62
Quelques méthodes o�ertes par org.omg.CORBA.Object
// tester le type d'une référence CORBA
boolean _is_a(String repositoryIdentifier );
// tester si deux ref CORBA sont équivalentes (même objet distant)
boolean _is_equivalent(org.omg.CORBA.Object other );
// tester si l'objet distant existe toujours
boolean _non_existent ();
// dupliquer une référence
org.omg.CORBA.Object _duplicate ();
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 10 / 62
Objet CORBA et mandataire
<<interface>>FooOperations/* interface java
traduisant l’IDL */
<<interface>>Foo
/* interface de l’Objet Corba
traduisant l’IDL */
FooPOA
/* squelette du Serveur (implem par héritage) */
FooPOATie
/* squelette du Serveur (implem par délégation) */
_FooStub
/* souche cliente */
org.omg.PortableServer.Servant
<<interface>>org.omg.CORBA.portable.InvokeHandler
<<abstract>>FooHelper
/* utilitaire pour gérer les Foo*/
org.omg.CORBA.portable.ObjectImplFooHolder
/* utilitaire pour gérer les out et inout sur type Foo*/
<<interface>>org.omg.CORBA.portable.Streamable
<<interface>>org.omg.CORBA.Object
<<interface>>org.omg.CORBA.portable.IDLEntity
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 11 / 62
Transtypage CORBA
Problème !
Comment construire un objet mandataire à partir d'un CORBA.Object ?
Mauvaise solution
Utilisation du cast Java :org.omg.CORBA.Object objet = orb.string_to_object(ior) ;
Foo foo = (Foo) objet; // => PLANTAGE
Le type réel d'un objet Java de référence de type CORBA.Objectn'est pas forcément le type du mandataire.
Solution : Instancier un mandataire à partir de la référence CORBA
Utilisation de la fonction statique narrow du Helper :org.omg.CORBA.Object objet = orb.string_to_object(ior) ;
Foo foo = FooHelper.narrow(obj);
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 12 / 62
Transtypage CORBA : Code du narrow du Helper
public static Foo narrow (org.omg.CORBA.Object obj){
if (obj == null)
return null;
else if(obj instanceof Foo)//est -ce deja un mandataire de Foo
return (Foo)obj;
else if (!obj._is_a (id ())){
//le typeCode de obj est different du typecode de Foo
throw new org.omg.CORBA.BAD_PARAM ();
}else{
org.omg.CORBA.portable.Delegate delegate =
((org.omg.CORBA.portable.ObjectImpl)obj). _get_delegate ();
_FooStub stub = new _FooStub ();
stub._set_delegate(delegate );
return stub;
}
}
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 13 / 62
Récupérer une IOR (1/2)
Problème !
Comment échanger les IOR entre le serveur et le client ?
Première solution
Créer un �chier partagé pour chaque Servant qui contiendra l'IOR associéeCoté serveur :void saveIOR(String fileName , ORB orb , CORBA.Object obj){
String ior = orb.object_to_string(obj);
FileWriter fw = new FileWriter(fileName );
fw.write(ior);
fw.close ();
}
Coté client :CORBA.Object restoreIOR(String f, ORB orb){
BufferedReader br = new BufferedREader(new FileReader(f));
String ior = br.readline ();
br.close ();
return orb.string_to_object(ior);
}
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 14 / 62
Récupérer une IOR (2/2)
Inconvénients des �chiers
Inadapté au passage à l'échelle :
⇒ Si N clients et M serveur alors création de N ∗M �chiers
⇒ IRRÉALISABLE
Autres solutions proposées par CORBA
Utilisation des références initiales
Utilisation d'un service d'annuaire
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 15 / 62
Les références initiales (1/2)
Dé�nition
Une référence initiale est une référence initialement connue de l'ORB. Elleassocie un nom à une référence CORBA.
Ajout de références initiales
L'ajout de références initiales dépend de l'implémentation de l'ORB⇒ peut se faire via les properties avant la construction de l'ORB
Fonctionnalité non autorisée dans l'ORB du Jdk.
Opérations de recherche via une instance d'ORB
String[] ids = orb.list_initial_services() : renvoie la liste des nomsassociés aux références initiales
CORBA.Object obj = orb.resolve_initial_references("exemple") :renvoie la référence associée à un identi�ant (Exception levée sinon).
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 16 / 62
Les références initiales (2/2)
Méthode de résolution des références initiales
1) Recherche dans un ensemble de références locales :
objets créés à l'initialisation de l'ORB mais inaccessibles del'extérieur
ex : POACurrent, RootPOA, CodecFactory, PICurrent, DynAnyFactory
2) Si 1) échoue alors recherche sur un serveur bootstrap distant :
"mini-annuaire" des services basiques (ex : Annuaire du système).adresse de connexion par défaut du bootstrap : localhost sur le port 900possibilité de changer l'adresse du bootstrap via les properties
P r o p e r t i e s p rops = new P r o p e r t i e s ( ) ;p rops . put ( " org . omg .CORBA. ORBIn i t i a lHo s t " , "<host_boots t rap>" ) ;p rops . put ( " org . omg .CORBA. ORB In i t i a l Po r t " , "<por t_boots t rap>" ) ;ORB orb = ORB. i n i t ( a rgs , p rops ) ;
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 17 / 62
Le démon orbd
Caractéristiques
ORB du Jdk :
Fournissant un serveur bootstrap :
à l'écoute sur le port 900 par défautIOR référencés :
NameService, TNameService, ServerRepository, ServerActivator, ServerLocator
Héberge des services (Servant) notamment le service d'annuaire⇒ socket d'écoute du orb.run() sur le port 1049 par défaut.
Lancement sur les ports par défaut
root@machine:~# orbd
Utilisation d'autres port
~$ orbd -ORBInitialPort <port_bootstrap> -port <port_services>
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 18 / 62
Le service d'annuaire (1/2)
Caractéristiques
Répertorie l'ensemble des références des objets du système enassociant un (ou plusieurs) nom à une IOR.
Hiérarchisé sous la forme d'un graphe de désignation⇒ Permet de classi�er les entrées en catégories, sous-catégories, etc.
interface NamingContext{
// service principaux sans les raises
void bind(in Name n, in Object obj);
void rebind(in Name n, in Object obj);
void unbind(in Name n);
Object resolve(in Name n);
NamingContext bind_new_context(in Name n);
void bind_context(in Name n, in NamingContext nc);
void destroy ();// precond : doit etre vide
};c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 19 / 62
Le service d'annuaire (2/2)
Servant de NamingContext (racine)
CORBA.Object o1
CORBA.Object o2
NamingContext fils1
Name n1
Name n2
Name n3
Name n4 NamingContext fils2
Servant de NamingContext
CORBA.Object o1
CORBA.Object o2
Name n1
Name n2
Servant de NamingContext
CORBA.Object o1Name n2
Name n1 NamingContext fils1
Servant de NamingContext
CORBA.Object o1Name n1
Servant du nom /n2
Servant du nom /n1Ref CORBA
Ref CORBA
Ref CORBA
Ref CORBA
Servant du nom /n3/n1
Servant du nom /n3/n2Ref CORBA
Servant du nom /n4/n1/n1
Servant du nom /n4/n2Ref CORBA
Ref CORBA
Ref CORBA
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 20 / 62
Le service d'annuaire étendu
Caractéristiques
Extension du service NamingContext en ajoutant des méthodes utilitaires
Allège la programmation en utilisant directement des String au lieudes Name
interface NamingContextExt:NamingContext{
typedef string StringName;
typedef string Address;
typedef string URLString;
StringName to_string(in Name n);
Name to_string(in StringName sn);
URLString to_url(in Address addr , in StringName sn);
Object resolve_str(in StringName n);
};
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 21 / 62
Exemple d'utilisation de l'annuaire
Properties props = new Properties ();
props.put("org.omg.CORBA.ORBInitialPort", "???");
ORB orb = org.omg.CORBA.ORB.init(args , props);
CORBA.Object obj_nc = orb.resolve_initial_references("NameService");
NamingContextExt nc = NamingContextExtHelper.narrow(obj_nc );
Enregistrer un objet
CORBA.Object obj = ......
nc.bind_new_context(nc.to_name("bidon"));
nc.rebind(nc.to_name("bidon/Bidule"), obj);
Obtenir une référence
CORBA.Object o = nc.resolve_str("bidon/Bidule");
Foo f = FooHelper.narrow(o);
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 22 / 62
Les URL CORBA (1/2)
Dé�nition
Une URL CORBA est une chaîne de caractère permettant de localiser sansambiguïté un objet.
Les URL de type IOR
IOR au format string (obtenu avec orb.object_to_string(obj))"IOR:<suite de caractère hexa>
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 23 / 62
Les URL CORBA (2/2)
Les URL de type Corbaloc
Alias de l'IOR au format : corbaloc:<adresse_serveur>/[clef de l'objet]
adresse désigne la machine serveur hébergeant le servant
la clef de l'objet = nom d'une référence initiale hébergée sur lamachine serveur
Les URL de type Corbaname
URL étendant les capacité de corbaloc en désignant non pas une clefd'objet mais un chemin dans l'annuaire :
corbaname:<adresse_annuaire>#chemin/dans/annuaire
Deux types d'adresse
"rir:" : équivalent à l'appel resolve_initial_reference(clef_objet)
"[iiop]:[version_iiop@]machine[:port_ecoute_orb]"(Champs facultatifs entre crochets)
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 24 / 62
Exemple d'URLs
Objet de clef NameService hébergé sur la machine saturne sur le port1501 :
corbaloc:iiop:saturne:1501/NameService
ou bien corbaloc::saturne:1501/NameService
ou si local corbaloc:rir:NameService
Même objet mais sur un ORB utilisant la version 1.2 de iiop :corbaloc:iiop:1.2@saturne:1501/NameService
ou bien corbaloc::1.2@saturne:1501/NameService
Un objet désigné parle nom A/B/C dans l'annuaire situé sur la machine jupiter sur le port 2045.
corbaname:iiop:jupiter:2045#A/B/C
si l'annuaire est local corbaname:rir:#A/B/C
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 25 / 62
Équivalence URL corbaname et code java
Sans URL corbaname
CORBA.Object obj_nc =
orb.string_to_object("corbaloc :: localhost :1049/ NameService");
NamingContextExt nc = NamingContextExtHelper.narrow(obj_nc );
CORBA.Object o = nc.resolve_str("A/B/C");
Avec URL corbaname
CORBA.Object o =
orb.string_to_object("corbaname :: localhost :1049#A/B/C");
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 26 / 62
Le Portable Object Adapter (POA)
Dé�nition
Entité CORBA locale à une machine serveur pour gérer les servants :
activer/désactiver les objets
transmission des invocations provenant des clients
Caractéristiques
Une machine serveur peut avoir plusieurs POA
Un POA peut regrouper plusieurs POA �ls⇒ structure arborescente dont le POA racine est le RootPOA
Par défaut seul le RootPOA existe sur le serveur
Chaque POA a un comportement régi par un ensemble de 7 règlesappelées policies
En java un POA est de type org.omg.PortableServer.POA
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 27 / 62
Les attributs d'un POA
Interface IDL du POA
local interface POA {
...
// POA attributes
readonly attribute string the_name ;
readonly attribute POA the_parent ;
readonly attribute POAList the_children ;
readonly attribute POAManager the_POAManager ;
attribute AdapterActivator the_activator ;
...
};
Le mot clé local
Indique que les objets implantant l'interface ne sont accessibles uniquementque depuis le processus qui les héberge.
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 28 / 62
Le gestionnaire de POA
Caractéristiques
Chaque POA est associé à un gestionnaire de POA.
Un gestionnaire de POA peut gérer simultanément plusieurs POA dontil contrôle l'état de traitement des requêtes
Les états d'un gestionnaire de POA
ACTIVE : toute requête entrante pour un POA est directementtransmise à celui-ci
INACTIVE : toute requête entrante est rejetée
HOLDING : toute requête entrante est ajoutée dans une �led'attente et y restera tant que le POA reste dans cet état
DISCARDING : toute requête entrante est rejetée tant que le POAne redevient pas ACTIF
En java un Manager est de type org.omg.PortableServer.POAManager
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 29 / 62
Les états du gestionnaire de POA
DISCARDINGACTIVE
INACTIVE
HOLDING
Etat initial
activate
deactivate
deactivate
deactivate
hold_request
hold_request
discard_request
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 30 / 62
Stockage des servants actifs
Object ID
Identi�ant interne à un POA d'un servant activé :
En IDL le type est ObjectID
En java le type est byte[] (tableau de 8 octets)
À ne pas confondre avec l'IOR
La table des objets actifs (Active Object Map)
Table maintenue par chaque POA pour associer un servant activé à unObject ID.
AOM
Object Id
Object Id
Servant
Servant
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 31 / 62
Paramétrage d'un POA
Les sept règles de comportement d'un POA
Thread Quelle politique de multithreading ?
Lifespan Une référence est-elle permanente ou temporaire ?
IdUniqueness Un servant peut-il être associé à plusieurs ID ?
IdAssignement Qui attribue un ID au servant ?
ImplicitActivation Activation des servant implicite ou explicite ?
ServantRetention Le POA doit-il référencer les servants dans l'AOM?
RequestProcessing Comment la requête est acheminée jusqu'au servant ?
Bon à savoir
Chaque type de règle
est une enumeration
comporte une valeur par défaut
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 32 / 62
Paramétrage d'un POA
Thread : Quelle politique de multithreading ?
ORB_CTRL_MODEL : propre à celle dé�nie par l'ORB
SINGLE_THREAD_MODEL : un seul thread à la fois peut accéder au POA⇒ Séquentialisation des requêtes accédant au POA⇒ Valeur non supportée par l'ORB du Jdk
Lifespan : Une référence est-elle permanente ou temporaire ?
TRANSIENT : le même servant n'aura pas la même référence si onrelance l'application
PERSISTENT : la référence est persistante dans tous les cas
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 33 / 62
Paramétrage d'un POA
IdUniqueness : Un servant peut-il être associé à plusieurs ID ?
UNIQUE_ID : un seul Id par servant
MULTIPLE_ID : plusieurs Id possible par servant
IdAssignement : Qui attribue un ID au servant ?
USER_ID : C'est à l'utilisateur de choisir les ID pour les servants
SYSTEM_ID : c'est le POA qui �xe l'ID pour les servants
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 34 / 62
Paramétrage d'un POA
ImplicitActivation : Activation implicite ou explicite ?
IMPLICIT_ACTIVATION : l'activation et l'ajout dans l'AOM est faiteautomatiquement
Précondition : SYSTEM_ID
NO_IMPLICIT_ACTIVATION : l'activation des servant doit être faitemanuellement par l'appel aux fonctions activate_object ouactivate_object_with_id.
ServantRetention : référencer les servants dans l'AOM ou pas ?
RETAIN : à l'activation, le POA ajoutera l'objet dans l'AOM
NON_RETAIN : aucun servant n'est lié à l'AOM
Préconditions : USE_DEFAULT_SERVANT ou USE_SERVANT_MANAGER
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 35 / 62
Paramétrage d'un POA
RequestProcessing : Comment acheminer la requête au servant ?
USE_ACTIVE_OBJECT_MAP_ONLY :
Précondition : RETAINle servant associé à la requête sera recherché dans l'AOM.Si pas trouvé ⇒ exception
USE_DEFAULT_SERVANT :
si pas trouvé dans l'AOM ou si NON_RETAIN , utilisation d'un servantpar défautSi pas de servant par défaut ⇒ exception
USE_SERVANT_MANAGER :
si pas trouvé dans l'AOM ou si NON_RETAIN utilisation d'ungestionnaire de servantSi pas de gestionnaire ⇒ exceptionDeux types de gestionnaires (cf. + loin) :
les activateurs
les localisateurs
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 36 / 62
Récapitulatif des règles de POA
Règle Valeurs Requiert
ThreadORB_CTRL_MODEL (par def. + RootPOA) ∅SINGLE_THREAD_MODEL ∅
LifespanTRANSIENT (par def. + RootPOA) ∅PERSISTENT ∅
IdUniquenessUNIQUE_ID (par def. + RootPOA) ∅MULTIPLE_ID ∅
IdAssigmentUSER_ID ∅SYSTEM_ID (par def. + RootPOA) ∅
ImplicitActivationIMPLICIT_ACTIVATION (RootPOA) SYSTEM_ID
NO_IMPLICIT_ACTIVATION (par def.) ∅
ServantRetentionRETAIN (par def. + RootPOA) ∅NON_RETAIN
USE_DEFAULT_SERVANT ou
USE_SERVANT_MANAGER
RequestProcessing
USE_ACTIVE_OBJECT_MAP_ONLY
(par def. + RootPOA)RETAIN
USE_DEFAULT_SERVANT ∅USE_SERVANT_MANAGER ∅
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 37 / 62
Création d'un POA
La méthode create_POA de l'interface POA en IDLPOA create_POA(
in string adapter_name , //nom du POA a creer
in POAManager m, //si = null alors creation
// d'un nouveau POA manager
in CORBA :: PolicyList policies)//les regles a appliquer
// si null , regles par defaut
raises(AdapterAlreadyExist , InvalidPolicy );
⇒ le POA créé sera �ls du POA sur lequel l'opération a été appliquée
Méthode java
POA create_POA (String adapter_name ,
POAManager a_POAManager ,
Policy [] policies) throws ... ;
Attention
Toute règle non spéci�ée à la création est a�ectée via les valeurs pardéfaut et non via héritage.
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 38 / 62
Création d'un POA : exemple en Java
CORBA.Object obj_rootpoa =
orb.resolve_initial_references("RootPOA");
POA rootpoa = POAHelper.narrow(obj_rootpoa );
int num_regle_a_definir = 3; // compris entre 1 et 7
Policy [] policies = new Policy[num_regle_a_definir ];
policies [0]= rootpoa.create_request_processing_policy(
RequestProcessingPolicyValue.USE_SERVANT_MANAGER );
policies [1]= rootpoa.create_id_assignment_policy(
IdAssignmentPolicyValue.USER_ID );
policies [2]= rootpoa.create_servant_retention_policy(
ServantRetentionPolicyValue.RETAIN );
POA fils = rootpoa.create_POA("le_fils",
rootpoa.the_POAManager (),
pol);
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 39 / 62
Structure POA : récapitulatif
RootPOA
AOM
Object Id
Object Id
Servant
Servant
Policies
POA ManagerServant
Servant
POA A
AOM
Object Id
Object Id
Policies(USE_DEFAULT_SERVANT)
Servant pardéfaut
Servant Servant
Servant
POA B
AOM
Object Id
Object Id
Policies(USE_SERVANT_MANAGER)
GestionaireDe servant
the_parent
the_parent
POA B
AOM
Object Id
Object Id
Object Id
Object Id
Policies(MULTIPLE_ID)
Servant
POA Manager
the_POAManager
the_parent Servant
the_POAManager
the_POAManager the_POAManager
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 40 / 62
Désactiver/activer un servant dans l'AOM
local interface POA {. . .Ob j e c t I d a c t i v a t e_ob j e c t (in Se rvan t p_servant ) raises . . . ;
void ac t i va t e_ob j ec t_wi th_ id (in Ob j e c t I d i d , in Se rvan t p_servant ) raises . . . ;
void d e a c t i v a t e_ob j e c t (in Ob j e c t I d o i d ) raises . . . . ;. . .
}
activate_object (précond : SYSTEM_ID et RETAIN)
Ajoute un Servant à l'AOM du POA appelant en créant un nouvelObjectID.Si MULTIPLE_ID, appelable plusieurs fois pour le même Servant
activate_object_with_id (précond : RETAIN)Ajoute un Servant à l'AOM du POA appelant avec un ID spéci�é
par l'utilisateur.
deactivate_object (précond : RETAIN)Désactive un ID ⇔ le servant n'est plus accessible via cet ID
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 41 / 62
Identi�cation d'un servant
Un Servant peut être désigné de trois manières di�érentes
une référence Java
⇒ propre à une JVM⇒ type Java = org.omg.PortableServer.Servant
un Object ID
⇒ propre à un POA⇒ type IDL = ObjectID
⇒ type Java = byte[]
une référence CORBA : l'IOR
⇒ propre au système entier⇒ type IDL = Object
⇒ type Java = org.omg.CORBA.Object
Attention
On ne requête jamais directement un Servant via sa référence Java
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 42 / 62
Opérations du POA : traduction de désignation de Servant
Méthodes de traduction o�erte par un POA : du servant à l'IOR
Servant → ObjectID precond : RETAIN et (IMPLICIT_ACTIVATION ou UNIQUE_ID)
// activation implicite
byte[] servant_to_id(Servant p_servant );
Object ID → IOR precond : RETAIN
CORBA.Object id_to_reference(byte[] oid);
Servant → IOR precond : RETAIN et (IMPLICIT_ACTIVATION ou UNIQUE_ID)
// activation implicite
CORBA.Object servant_to_reference(Servant p_servant );
Méthodes de traduction o�erte par un POA : de l'IOR au Servant
IOR → Object IDbyte[] reference_to_id(CORBA.Object reference );
ObjectID → Servant precond : RETAIN
Servant id_to_servant(byte[] oid);
IOR → Servant precond : RETAIN
Servant reference_to_servant (CORBA.Object reference );
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 43 / 62
Code du serveur : objet Servant par héritage
//1) Obtenir Ref CORBA sur le rootPOA
CORBA.Object obj_rpoa;
obj_rpoa = orb.resolve_initial_references("RootPOA");
POA rpoa = POAHelper.narrow(obj_rpoa );
//2) instancier le Servant
FooImpl foo = new FooImpl (); // implique FooImpl extends FooPOA
//3) lier le servant au poa (ici le rootPOA)
byte[] serv_id = rpoa.activate_object(foo);
//4) enregistrer la reference CORBA dans l'annuaire
CORBA.Object obj = rpoa.id_to_reference(serv_id );
nc.rebind(nc.to_name("Foo1"),obj);
//5) activer le POA Manager
rpoa.the_POAManager (). activate ();
//6) mise en attente du serveur
orb.run ();
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 44 / 62
Code du serveur : objet Servant par délégation
//1) Obtenir Ref CORBA sur le rootPOA
CORBA.Object obj_rpoa;
obj_rpoa = orb.resolve_initial_references("RootPOA");
POA rpoa = POAHelper.narrow(obj_rpoa );
//2) instancier le Servant
FooImpl foo = new FooImpl();
Servant servant = new FooPOATie(foo);
//3) lier le servant au poa (ici le rootPOA)
byte[] serv_id = rpoa.activate_object(servant );
//4) enregistrer la reference CORBA dans l'annuaire
CORBA.Object obj = rpoa.id_to_reference(serv_id );
nc.rebind(nc.to_name("Foo1"),obj);
//5) activer le POA Manager
rpoa.the_POAManager (). activate ();
//6) mise en attente du serveur
orb.run ();
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 45 / 62
Mécanisme de RappelClient Serveur
interface Rappel{
void rappel ();
}
interface ObjetAppele{
oneway void appel(in Rappel o);
}
Code du client = (presque)code d'un serveur
ORB orb = ORB.init (...);
POA root_poa = ...;// reference sur rootpoa de l'orb client
ObjetAppele appele= ...;// recupere reference CORBA sur ObjetAppele
RappelImpl r = new RappelImpl ();
byte[] id = root_poa.activate_object(r);
CORBA.Object obj = root_poa.id_to_reference(id);
Rappel ref= RappelImplHelper.narrow(obj);
root_poa.the_POAManager (). activate ();
orb.run();//appel bloquant
new Thread(new Runnable(){public void run(){ orb.run();}
}).start();appele.appel(ref);// appel sur Serveur
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 46 / 62
Activation statique et dynamique de service
Activation statique de service
L'instanciation et l'activation des servants et de leur POA associé se fontavant l'appel à orb.run().⇒ Consommation inutile de ressources si le service est peu/pas utilisé
Client
ServeurServant
IOR
ORB ORB
rootPOA
POA Y
Servant
the_parent
the_parent
AOMPOA X
AOM
IOR
Client
ServeurServant
IOR
ORB ORB
rootPOA
POA Y
Servant
the_parent
the_parent
AOMPOA X
AOM
IOR
Invocation
Client
ServeurServant
IOR
ORB ORB
rootPOA
POA Y
Servant
the_parent
the_parent
AOMPOA X
AOM
IOR
Invocation
Activation dynamique de service
L'instanciation et l'activation des servants et de leur POA associé se fontau moment de recevoir une première requête⇒ Utilisation plus �exible des ressources
Client
Serveur
IOR
ORB ORB
rootPOAIOR
Client
ServeurServant
IOR
ORB ORB
rootPOA
POA Y
the_parent
the_parent
AOMPOA X
AOM
IOR
Invocation
Client
ServeurServant
IOR
ORB ORB
rootPOA
POA Y
Servant
the_parent
the_parent
AOMPOA X
AOM
IOR
Invocation
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 47 / 62
Création dynamique de servant
Principes
Création d'un POA avec la règle USE_SERVANT_MANAGER
⇒ Utilisation des gestionnaires de servantRappel : si le servant n'est pas référencé dans l'AOM, utilisation du
gestionnaire
Associer au POA une classe d'un gestionnaire (à dé�nir)
Création d'une IOR sans instancier le servant⇒ Deux types de gestionnaire de servant (rappel) :
les activateurs
les localisateurs
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 48 / 62
Création d'une IOR sans instancier le servant
Deux méthodes o�ertes par l'interface POA
local interface POA{. . .Object c r e a t e_ r e f e r e n c e ( in CORBA : : R e p o s i t o r y I d i n t f ) raises . . . ;
Object c r ea t e_re f e r ence_wi th_ id ( in Ob j e c t I d o i d ,in CORBA : : R e p o s i t o r y I d i n t f ) ;
. . .} ;
Le paramètre intf
Représente un identi�ant d'interface :
désigne sans ambiguïté le type de l'interface IDL du Servant qui seraassocié à la référence
accessible via la méthodes statique id() du Helper.
Attention
Pas d'instanciation ⇒ pas d'activation ⇒ pas d'ajout dans l'AOMc© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 49 / 62
Création dynamique de servant : le code du Serveur
Policy [] pols= ... //avec USE_SERVANT_MANAGER
POA le_poa = poaPere.create_POA("fils", null , pols);
// instanciation d'un gestionnaire de servant
ServantManager manager= new MonGestionnaire (). _this(orb);
// liaison du POA avec le gestionnaire
fils.set_servant_manager(manager );
// creation de reference CORBA d'un Foo
CORBA.Object obj1 = le_poa.create_reference_with_id(
"FooNumber1".getBytes(),
FooHelper.id());
CORBA.Object obj2 = le_poa.create_reference_with_id(
"FooNumber2".getBytes(),
FooHelper.id());
NamingContextExt nc = ..// le service d'annuaire
nc.rebind(nc.to_name("FooNumber1"), obj1);
nc.rebind(nc.to_name("FooNumber2"), obj2);
le_poa.the_POAManager (). activate ();
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 50 / 62
Les gestionnaires de type activateur 1/2
Caractéristiques
Construit/détruit une instance de servant qui sera ajouter/enlever del'AOM du POA appelant
précondition : le POA doit avoir la règle RETAIN
local interface ServantManager { };
local interface ServantActivator : ServantManager{
Servant incarnate(in ObjectId oid ,
in POA adapter)
raises (ForwardRequest );
void etherealize(in ObjectID oid ,
in POA adapter ,
in Servant serv ,
in boolean cleanup_in_progress ,
in boolean remaining_activations );
};
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 51 / 62
Les gestionnaires de type activateur 2/2
Première méthode à dé�nir
Servant incarnate(byte[] oid , POA adapter)
throws ForwardRequest;
Construction d'un servant pour un ObjectID et un POA donné
Appelée lorsque l'AOM du POA ne contient pas l'ObjectID requis
Deuxième méthode à dé�nirvoid etherealize(byte[] oid , POA adapter ,
Servant serv ,
boolean cleanup_in_progress ,
boolean remaining_activations );
Appelée lorsque POA désactive le servant serv d'Id oid
cleanup_in_progres = true ⇒ l'appel a été fait suite à une destructiondu POA ou un deactivate de son Manager
remaining_activations = true ⇒ il existe d'autres ObjectID actif dumême servant dans l'AOM.
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 52 / 62
Les gestionnaires de type activateur : exemple
public class MonGestionnaire extends ServantActivatorPOA {
public Servant incarnate(byte[] oid , POA adapter)
throws ForwardRequest {
String oid_str= new String(oid);
if(oid_str.equals("Compte")
&& adapter.the_name (). equals("fils"))
return new FooImpl ();
throw new OBJECT_NOT_EXIST ();
}
public void etherealize(byte[] oid ,
POA adapter ,
Servant serv ,
boolean cleanup_in_progress ,
boolean remaining_activations) {
// eventuellement faire une sauvegarde du servant sur disque
}
}
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 53 / 62
Les gestionnaires de type localisateur 1/2
Caractéristiques
Construit une instance de servant uniquement pour traiter la requêteen cours
précondition : le POA doit avoir la règle NON_RETAIN
local interface ServantLocator : ServantManager{
native Cookie ;
Servant preinvoke(in ObjectId oid ,
in POA adapter ,
in CORBA :: Identifier operation ,
out Cookie the_cook) raises (ForwardRequest );
void postinvoke(in ObjectId oid ,
in POA adapter ,
in CORBA :: Identifier operation ,
in Cookie the_cook ,
in Servant the_servant );
};c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 54 / 62
Les gestionnaires de type localisateur 2/2
Première méthode à dé�nir
Servant preinvoke(
byte[] oid , //l'objectID en question
POA adapter , // le POA en question
String operation , // l'operation invoquee
CookieHolder the_cookie // objet pour echanger
// des infos avec postinvoke
) throws ForwardRequest;
Deuxième méthode à dé�nirpublic void postinvoke(byte[] oid ,
POA adapter ,
String operation ,
Object the_cookie ,
Servant the_servant );
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 55 / 62
Les gestionnaires de type localisateur : exemple
public class MonGestionnaire extends ServantLocatorPOA {
private int cpt =0;
public Servant preinvoke(byte[] oid , POA adapter ,
String operation , CookieHolder the_cookie)
throws ForwardRequest {
String oid_str= new String(oid);
if(oid_str.equals("Compte")
&& adapter.the_name (). equals("fils")){
Servant cpt_ops = new CompteImpl1 ();
the_cookie.value =( Integer)cpt++;
return cpt_ops;
}
throw new OBJECT_NOT_EXIST ();
}
public void postinvoke(byte[] oid , POA adapter ,
String operation , Object the_cookie , Servant the_servant ){
System.out.print("Requiem pour requete " + the_cookie );
}
}
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 56 / 62
Détruire un POA
Méthode de l'interface POA
void destroy(boolean etherealize_objects
boolean wait_for_completion );
etherealize_objects = true ⇒ appelle la méthode etherealize pourtous les servants créé par un Activator
wait_for_completion = true ⇒ attendre la �n des traitements en cours+ l'éventuel etherealize avant la destruction
Attention
Destruction récursive de toute la descendance du POA concerné.
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 57 / 62
Création/activation dynamique de POA
Principe
Pouvoir (re-)créer/détruire toute une arborescence de POA et deservant à la demande.
Les POAs instanciés/supprimés dynamiquement doivent avoir la règlePERSISTENT
⇒ Nécessite l'ajout de 2 properties java à la création de l'ORB
Interface IDL de l'activateur de POA
interface AdapterActivator {
boolean unknown_adapter(in POA parent , in string name);
};
Invoquée par le POA parent lorsque le �ls de nom name n'existe pasmais doit traiter une requête
renvoie vrai si le POA demandé a pu être créé, sinon faux + exceptiontransmise au client
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 58 / 62
Création dynamique de POA : exemple code serveur
// properties pour PERSISTANT
props.put("com.sun.CORBA.POA.ORBServerId","4241");
props.put("com.sun.CORBA.POA.ORBPersistentServerPort","1070");
ORB orb = org.omg.CORBA.ORB.init(args , props );
POA rootpoa = ...;
rootpoa.the_activator(new MonPOAActivator(orb ));
POA fils = rootpoa.create_POA("fils",rootpoa.the_POAManager (),
....); //avec regle PERSISTENT
CORBA.Object foo = fils.
create_reference_with_id("foo".getBytes(),
FooHelper.id());
fils.destroy(true , true);
NamingContextExt nc = NamingContextExtHelper.narrow(obj_nc );
nc.rebind(nc.to_name(name), compte );
rootpoa.the_POAManager (). activate ();
orb.run ();
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 59 / 62
L'activateur de POA : exemple
public class MonPOAActivator
extends LocalObject implements AdapterActivator {
private final ORB orb;
private static final long serialVersionUID = 1L;
public MonPOAActivator(ORB orb) {
this.orb=orb;
}
@Override
public boolean unknown_adapter(POA parent , String name) {
if(name.equals("fils") && parent.the_name (). equals("RootPOA")){
POA fils = parent.create_POA("fils",
parent.the_POAManager (),
....); //avec regle PERSISTENT
fils.set_servant_manager(new FooActivator (). _this(orb));
return true;
}
return false;
}
}
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 60 / 62
Pour ou contre CORBA?
Points positifs
La première norme date de 1991⇒ solution mature
GIOP/IIOP est un protocole binaire⇒ plus performant que les protocoles textes (ex : HTTP)
Solution hétérogène⇒ possibilité d'avoir un serveur en Java et un client en C++
Points Négatifs
La dernière version (3.3) date de 2012 et reste peu implantée
Les ports de CORBA peuvent être bloqués par les pare-feu⇒ usage limité uniquement à un LAN et inadapté à Internet
des incompatibilités entre l'IDL et certains langages (ex : long double)
Programmation relativement lourde et répétitive
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 61 / 62
Bilan CORBA
Notions du premier cours
Architecture générale CORBA
Langage IDL
Traduction IDL-Java
Notions du deuxième cours
Initialisation d'ORB
Références CORBA
Annuaire, URL CORBA
Portable Object Adapter
Construction dynamique de serveur (servant + POA)
ATTENTION POUR LES TMEs
Penser à gérer les exceptions des primitives CORBA (non détaillédans ce cours)
c© Jonathan Lejeune (Sorbonne univ.) CORBA - Développement Java 62 / 62