Invocation de Mthode des Objets distants Exemple CORBA
Invocation de Méthode à des Objets distants Exemple : CORBA Common Object Request Broker Architecture Mise en pratique avec Orbacus en JAVA
1. 1 -histoire Consensus pour l’interopérabilité Le problème : Intégration des applications L Pas de consensus sur les langages de programmation L Pas de consensus sur les plate-formes de développement L Pas de consensus sur les systèmes d’exploitation L Pas de consensus sur les protocoles réseau L Pas de consensus sur les formats des données manipulées par les applications è Recherche d’un Consensus pour l’interopérabilité
1. 2 CORBA? CORBA Common Object Request Broker Architecture : CORBA Plate-forme client/serveur orientée objets Un standard pour l’interopérabilité entre objets – Support pour différents langages – Support pour différentes plate-formes (interopérabilité) – Communications au travers du réseau – Des services (Distributed transactions, events, . . . ) – Guides et modèles de programmation 3
I. 3. OMG Object Management Group (OMG) http: //www. omg. org ü consortium international créé en 1989 ü but non lucratif ü regroupement de plus de 460 organismes • constructeurs (SUN, HP, DEC, IBM, . . . ) • environnements systèmes (Microsoft, OSF, Novell, . . . ) • outils et langages (Iona, Object Design, Borland, . . . ) • produits et BD (Lotus, Oracle, Informix, O 2, . . . ) • industriels (Boeing, Alcatel, Thomson, . . . ) • institutions et universités (INRIA, NASA, LIFL, W 3 C)
OMG en résumé OMA : pour l ’architecture logicielle MDA (Model Driven Architecture) CORBA : pour le « middleware » technique UML pour la modélisation UML = Unified Modeling language MOF pour la méta-modélisation MOF = Meta-Object Facility 6
Processus de développement
Le langage IDL: Un « esperanto » pour les objets Client d ’objets Stub IDL contrat IDL Bus CORBA Objets Corba Fournisseur d ’objets Squelette IDL
Spécification interface IDL (1/2) Un objet grid est un tableau contenant des valeurs. Les valeurs sont accessibles grâce aux opérateurs get et set qui peuvent être invoqués à distance. objets grid Appel de get et sur l'objet grid distant Processus client Processus serveur 9
Spécification interface IDL (2/2) interface Grid { readonly attribute short height; readonly attribute short width; void set (in short n, in short m, in long value); long get(in short n, in short m); void copy. In(inout Grid g); }; 10
Le langage IDL: Interface Definition Language + langage de spécification d’interfaces, supportant l’héritage multiple; 2 indépendant de tout langage de programmation ou compilateur (langage pivot entre applications); + langage utilisé pour générer les stubs, les squelettes et pour définir les interfaces du Référentiel d’interface; 2 la correspondance IDL-langage de programmation est fournie pour les langages C, C++, Java, Smalltalk, Ada, Cobol.
Exemple interface attribut opérations exception opérations interface account { readonly attribute float balance; attribute string description; void credit (in float f); void debit (in float f); }; interface current. Account : account { readonly attribute float overdraft. Limit; }; interface bank { exception reject {string reason; }; account new. Account (in string name) raises (reject); current. Account new. Current. Account (in string name, in float limit) raises (reject); void delete. Account (in account a); };
Eléments IDL + Une spécification IDL définit un ou plusieurs types, constantes, exceptions, interfaces, modules, . . . • pragma • constantes • types de base au format binaire normalisé • nouveaux types (typedef, enum, struct, union, array, sequence) • exceptions • types de méta-données (Type. Code, any)
Eléments IDL + Un module permet de limiter la validité des identificateurs + Interface : ensemble d’opérations et de types =>classe C++ Syntaxe : Interface | [<héritage>] { <interface Body>}; • opération (synchrone ou asynchrone sans résultat) • attribut (possibilité de lecture seule) Surcharge Interdite +Réutilisation de spécifications existantes (#include)
Exemple module définitions de type module un. Service { typedef unsigned long Entier. Positif; interface Premier { interface opérations typedef sequence<Positif> des. Entiers. Positifs; boolean est_premier ( in Entier. Positif nombre); des. Entiers. Positifs nombres_premiers (in Entier. Positif nombre); }; module mon. Application { interface Mon. Service { un. Service: : Entier. Positif prochain. Premier(. . );
3. IDL Description Exemple
Attribut IDL Définition d’attribut interface account { readonly attribute float balance; attribute string description; . . . }; Equivaut à : float get_balance(); string get_description(); void set_description(in string s);
3. IDL Description Operations (1/2) + Paramètres nommés et associés à un mode void op 1 (in long input, out long output, inout long both); + Opérations bloquantes par défaut interface account; Client une. Banque new. Account retours interface bank { calcul account new. Account (in string name); void delete. Account (in account old); }; <une. Opération> : : = <mode. Invocation> <type. Retour> <identificateur> ‘ (‘ <paramètres> ‘ ) ’ <clauses. Exceptions><clauses. Contextes>
Pourquoi différents modes de passage de paramètres ? in : Données fournies par le client out : Données retournées par l ’objet inout : Données clientes modifiées par l ’objet Répartition Passage par copie 20
3. IDL Description Opérations (2/2) oneway void notify (in string message); +Opération non bloquante + Pas de paramètre de type out, inout ou d’exceptions + Valeur de retour : void Client une. Banque notify( «ok » ) + Pas d ’exceptions déclenchées. méthode finie
3. IDL Description Exceptions exception reject {string reason; }; account new. Account (in string name) raises (reject); exception Date. Erronnee { String raison; }; CORBA: : Exception CORBA: : User. Exception CORBA: : System. Exception Des exceptions CORBA standardisées UNKNOWN BAD_PARAM COM_FAILURE INV_OBJREF NO_PERMISSION NO_IMPLEMENT OBJECT_NOT_EXIST ………. Gestion explicite de la part du client 22
3. IDL Description Définitions circulaires module Circulaire { interface B; interface A { void utiliséB(in B un. B); } interface B { void utiliséA(in A un. A); }
3. IDL Description Héritage multiple interface A {. . . } interface B : A {. . . } interface C : A {. . . } interface D : B, C {. . . } A B C D
3. IDL Description Types de base et autres types Types de base • short • long • unsigned short • unsigned long • float • double • char • boolean • octet Méta. Types • …. . . • any • Type. Code Types construits • struct • union • enum Types génériques • array • sequence • string Types de données dynamiques et auto-descriptifs
3. IDL Description Type Any interface Pile. De. Chaines { readonly attribut string sommet; void poser(in string valeur); string retirer(); }; interface Pile. Générique { readonly attribut Any sommet; readonly attribut Type. Code type. Des. Valeurs; void poser(in Any valeur); Any retirer(); }; 26
1 - Exemple introductif Exemple Compilation interface IDL vers Java Grid. idl jidl … Grid. idl Client _Grid. Stub. java Client. java A écrire Compilateur IDL/Java Répertoire grid Grid. Operations. java I Grid. java Grid. Helper. java Grid. Holder. java Généré Serveur Grid. POA. java Grid_Impl. java Serveur. java 27
1 - Exemple introductif Les classes Stubs et Squelettes • implantation du stub public class _Grid. Stub ……. Grid – envoie de requêtes – invisible par le programmeur – instanciée automatiquement par Grid. Helper (narrow) – Utilise le DII pour assurer la portabilité du binaire • implantation du squelette public abstract class Grid. POA ………. Grid. Operations – reçoit et décode des requêtes – doit être héritée par l’implantation 28
1 - Exemple introductif Implémentation du serveur (1) 1. Initialiser le bus CORBA – obtenir l’objet ORB 2. Initialiser l’adaptateur d’objets – obtenir le POA 3. Créer les implantations d’objets 4. Enregistrer les implantations par l’adaptateur 5. Diffuser leurs références – afficher une chaîne codifiant l’IOR 6. Attendre des requêtes venant du bus 7. Destruction du Bus 29
1 - Exemple introductif Implémentation du client 1. Initialiser le bus (objet ORB) 2. Créer les souches des objets à utiliser 2. a. obtenir les références d’objet (IOR) 2. b. convertir vers les types nécessaires – narrow contrôle le typage à travers le réseau 3. Réaliser les traitements • Rem. : éviter l’opérateur bind (2. a + 2. b) – spécifique à chaque produit donc non portable 30
Le cycle de vie des objets • Problème – actuellement, 1 grille = 1 serveur – pas de création/destruction d’objets à distance – seulement invocation d’opérations • Solution – notion de fabrique d’objets – exprimée en OMG-IDL • C’est un canevas de conception : Design pattern – voir aussi le service Life. Cycle Autres usages de la fabrique : - gestion de droits, load-balancing, polymophisme, … 31
L’implantation de la fabrique creer. Grille Fabrique Grille 32
L’implantation de la fabrique Fabrique Grille detruire. Grille 33
Interface IDL d ’une fabrique de Grilles module grilles {. . . interface Fabrique { Grid new. Grid(in short width, in short height); }; }; 34
Scénario d ’obtention de la référence du service de nommage ORB Client ou Serveur resolve_initial_references ("Name. Service"); Cos. Naming: : Naming. Context conversion ajout, retrait, lecture, . . . 35
Enregistrer un objet • Opération pour publier un Objet – en général, opération réalisée par le serveur • Scénario Type 1. Créer un objet 2. Construire un chemin d ’accès (Name) 3. Appeler l ’opération « bind » ou « rebind » avec le chemin et la référence de l ’objet void bind (in Name n, in Object obj) raises (Not. Found, Cannot. Proceed, Invalid. Name, Already. Bound); 37
Retrouver un objet • Opération réalisée par un client ou un serveur • Scénario type : – construire un chemin d ’accès (Name) – appeler l ’opération « resolve » avec le chemin – convertir la référence obtenue dans le bon type Object resolve (in Name n) raises (Not. Found, Cannot. Proceed, Invalid. Name) 38
Une application d’administration de la fabrique • Création d’une nouvelle grille et mise à disposition par le service Nommage – – – 1. Initialiser le bus CORBA 2. Obtenir le service Nommage (NS) 3. Obtenir la fabrique depuis le NS 4. Créer un répertoire 5. Enregistrer le répertoire dans le NS 39
Annuaire : service de nommage java. rmi. Naming bind rebind unbind lookup Client rmi URL java. rmi. naming RMI Registry RMI Remote Object 40
RMI URL • • Même syntaxe que http mais préfixe rmi: //mymachine. com/mon. Objet Inconvénient : perte de la transparence => utilisation de JNDI (Java Naming Directory Interface) 41
JNDI : Nommage et directory • C: /mon. Répertoire/mon. Fichier Lien (bind) Nom Contexte Attributs Créé le 12 mars 2002 Taille : 12 M 42
Conventions de nommage • LDAP (Light Directory Access Protocol) : "cn=Todd Sundsted, o=Com. Frame, c=US" nomme la personne "cn=Todd Sundsted" Note : c = country, o = organization • DNS : carabosse. essi. fr • => Abstraction JNDI 43
Naming/Directory • Un service de Naming permet de retrouver des objets à partir d'un nom ("pages blanches") • Un service de Directory rajoute des fonctionnalités permettant d'associer des attributs aux points d'entrée, et de faire une recherche sur ces attributs ("pages jaunes") 44
Usage • Les services de nommage sont utilisés : – Pour stocker des objets – Pour offrir un point d'accès aux applications réparties (RMI, Corba , EJB…) Ils servent également de référentiel d'entreprise pour accéder à des applications (machine/port), des bases de données, et même des informations de sécurité (gestion des accès au sein d'une entreprise) 45
Service providers 46
L'interface Context
Contexte • Le contexte permet une isolation des noms, par exemple pour plusieurs applications => évite les collisions • Structure hiérarchique comme un répertoire 48
Interface Context • void bind(String string. Name, Object object): Lie un nom à un objet. Le nom ne doit pas déjà être lié à un autre objet. Tous les contextes intermédiaires doivent exister. • void rebind(String string. Name, Object object): Lie un nom à un objet. Si le nom est déjà lié, la liaison précédente est écrasée. Tous les contextes intermédiaires doivent exister. • Object lookup(String string. Name): Renvoie l'objet pointé par le nom • void unbind(String string. Name): Délie l'objet pointé par le nom. 49
Mais aussi • void rename(String string. Old. Name, String string. New. Name): Modifie le nom auquel l'objet est lié. • Naming. Enumeration list. Bindings(String string. Name): Envoie une énumération contenant les noms liés au contexte passé en paramètre, ainsi que les objets liés à ces noms et leur classe • Naming. Enumeration list(String string. Name): Renvoie une énumération contenant les noms liés au contexte, ainsi que les noms de classes des objets liés à eux 50
Contextes • Pas de contexte racine => Initial. Context • Possibilité de créer des sous-contextes public Context create. Subcontext(String name) throws Naming. Exception 51
Un exemple : d'abord les packages import javax. naming. Context; import javax. naming. Initial. Context; import javax. naming. Binding; import javax. naming. Naming. Enumeration; import javax. naming. Naming. Exception; // Pour les paramètres d'initialisation import java. util. Hashtable; 52
Création du contexte initial L'information d'environnement spécifie le provider JNDI par le nom de la factory. Dans ce cas : répertoire sous forme URL file: //. . . Hashtable hashtable. Environment = new Hashtable(); hashtable. Environment. put( Context. INITIAL_CONTEXT_FACTORY, "com. sun. jndi. fscontext. Ref. FSContext. Factory" ); hashtable. Environment. put( Context. PROVIDER_URL, "file: //tmp" 53 );
Lien avec la sécurité private Context get. Initial. Ctx() { // Set up our JNDI environment properties. . . Hashtable env = new Hashtable(); env. put(Context. INITIAL_CONTEXT_FACTORY, INITCTX); env. put(Context. PROVIDER_URL, HOST); env. put(Context. SECURITY_AUTHENTICATION, "simple"); env. put(Context. SECURITY_PRINCIPAL, USER); env. put(Context. SECURITY_CREDENTIALS, PASSWORD); try { return new Initial. Dir. Context(env); } catch(Naming. Exception e) 54
Enumération de tous les objets Naming. Enumeration naming. Enumeration = context. list. Bindings(""); while (naming. Enumeration. has. More()) { Binding binding = (Binding)naming. Enumeration. next(); System. out. println( binding. get. Name() + " " + binding. get. Object() ); } 55
Recherche d'un objet particulier Object object = context. lookup(un. Nom); System. out. println( un. Nom + " " + object ); 56
Utilisation de l'objet On reçoit un object, il faut par conséquent faire un "cast" pour pouvoir l'utiliser (My. Class) object. my. Methode(…. ) 57
Résumé • • Comme dans RMI Initial. Context bind, lookup On peut lister un contexte, créer un souscontexte • Utilisation d'une factory pour lier à une implémentation et initialiser les paramètres • La sécurité est définie au niveau de 58
Directory Service
Directory Service • Naming + attributs 60
Les fonctions de base void bind( String string. Name, Object object, Attributes attributes ) • Même méthode que Context, mais avec un paramètre de plus : les attributs. • Idem rebind, lookup • Idem create. Subcontext • Créé à partir de Initial. Dir. Context 61
Get. Attributes • 2 formes possibles Attributes get. Attributes( String string. Name ) Attributes get. Attributes( String string. Name, String [] rgstring. Attribute. Names ) 62
modify. Attributes void modify. Attributes( String string. Name, int n. Operation, Attributes attributes ) • Avec les opérations : • ADD_ATTRIBUTE, REPLACE_ATTRIBUTE, et REMOVE_ATTRIBUTE 63
Search • La forme la plus simple passe une liste d'attributs • Il est possible d'utiliser des filtres selon la norme RFC 2254 • Les contrôles permettent la mise en forme des résultats (par exemple tri ascendant, etc…) 64
Search : pour faire des requêtes Naming. Enumeration search( String string. Name, Attributes attributes. To. Match ) On peut utiliser des filtres de recherche selon la spécification RFC 2254: (cn=Babs Jensen) (!(cn=Tim Howes)) (&(object. Class=Person)(|(sn=Jensen)(cn=Babs J*))) (o=univ*of*mich*) Naming. Enumeration search(Name string. Name, String string. RFC 2254 Filter, Search. Controls searchcontrols) 65
Search : contrôle de la recherche • On peut utiliser des contrôles permettant : – De définir les attributs à renvoyer – De définir la portée de la recherche (récursive en arbre, locale…) – Le nombre maximum de réponses – Le temps maximum d'attente – De renvoyer ou non l'objet Java associé – De déréférencer ou non les liens 66
Un exemple String filter = "(objectclass=Inetorgperson)"; Search. Controls controls = new Search. Controls(); controls. set. Search. Scope(Search. Controls. SUBTREE_SCOPE); controls. set. Returning. Obj. Flag(false); controls. set. Returning. Attributes(attr. Ids); try { Naming. Enumeration enum. Dev = init. Ctx. search("ou=people", filter, sc); 67
Classes à connaître Renvoient une Naming. Enumeration de. . . 68
Utilisation d'un Search. Result while (enum. Dev. has. More()) { Search. Result sr = (Search. Result)enum. Dev. next(); Attributes attributes = sr. get. Attributes(); Naming. Enumeration ne = attributes. get. All(); while (ne. has. More()) { Attribute attr = (Attribute) ne. next(); String attr. ID = attr. get. ID(); Naming. Enumeration values = attr. get. All(); . . . while (values. has. More()) child. add( new Default. Mutable. Tree. Node(values. next. Element())); } } 69
Résumé : Directory • • Mêmes méthodes que Context Créé à partir de Initial. Dir. Context Rajoute la gestion des attributs Rajoute les fonctions de recherche 70
Autres fonctionnalités
Noms composés Object obj 1 = ctx. lookup("cn=Ted Geisel, ou=People, o=JNDITutorial"); Composite. Name cname = new Composite. Name( "cn=Ted Geisel, ou=People, o=JNDITutorial"); Object obj 2 = ctx. lookup(cname); • L'interface lookup a 2 signatures : String ou Name 72
Stockage d'objets • On peut stocker – Des objets serialisables – Des références et des objets référençables – Des objets avec des attributs – Des Remote Objects – Des objets Corba 73
Exemple : stockage d'un objet RMI // On initialise le Contexte // ctx = new javax. naming. Initial. Dir. Context. . . Hello h = new Hello. Impl(); // Bind the object to the directory ctx. bind("cn=Remote. Hello", h); • Une fois que l'objet est stocké dans le Directory, une autre application peut l'utiliser Hello h 2 = (Hello)ctx. lookup("cn=Remote. Hello"); 74
Exemple : stockage d'une référence • public class Fruit implements Referenceable { String fruit; public Fruit(String f) { fruit = f; } public Reference get. Reference() throws Naming. Exception { return new Reference( Fruit. class. get. Name(), new String. Ref. Addr("fruit", fruit), Fruit. Factory. class. get. Name(), null); // Factory location } 75
Factory pour une référence public class Fruit. Factory implements Object. Factory { public Object get. Object. Instance(Object obj, Name name, Context ctx, Hashtable env) throws Exception { if (obj instanceof Reference) { Reference ref = (Reference)obj; if (ref. get. Class. Name(). equals(Fruit. class. get. Name())) { Ref. Addr addr = ref. get("fruit"); if (addr != null) { return new Fruit((String)addr. get. Content()); }}} return null; }} 76
URL LDAP • Ldap supporte les URLS de la forme : ldap: //host: port/dn? attributes? scope? filter? exten sions • Le nom d'hôte par défaut est localhost • Le port par défaut est 389 • Exemple : Object obj = new Initial. Context(). lookup( "ldap: //localhost: 389/cn=homedir, cn=Jon%20 Rui z, ou=People, o=jnditutorial"); 77
alias • Il est possible de définir des alias ctx. search("ou=Staff", "(cn=J*)", null); • Propriété d'environnement java. naming. ldap. deref. Aliases – – always never finding searching 78
Autres idées • Espaces de nommages • Fédérations de serveur , referrals (~alias de serveurs) • Sécurité, authentification, SSL • Liens avec JINI, EJB. . . 79
- Slides: 77