1 / 63

8. Notion d’adaptateur d’objet

8. Notion d’adaptateur d’objet. Principe. Rendre plusieurs objets (Servant) disponibles dans un serveur Chaque objet est associé à une clé unique dans le serveur Une référence inclut désormais la clé de l’objet Adaptateur d’objet Aiguillage et lien entre le réseau et les objets

leanna
Download Presentation

8. Notion d’adaptateur d’objet

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 8. Notion d’adaptateur d’objet

  2. Principe • Rendre plusieurs objets (Servant) disponibles dans un serveur • Chaque objet est associé à une clé unique dans le serveur • Une référence inclut désormais la clé de l’objet • Adaptateur d’objet • Aiguillage et lien entre le réseau et les objets • Gère les clés associées aux objets et leurs références • Raffinement du Manager • Adaptateur : lien référence / objet d’implémentation • Squelette : décodeur de requête pour un objet

  3. Architecture version 8 Servant Servant Client Squelette Squelette Contrat Proxy ObjectAdaptateur Réseau

  4. Interactions version 8

  5. Côté serveur • Adaptateur d’objet • Gestion du accept et du routage des requêtes • Connecte les objets et crée leurs références • Squelette de service • Défini par rapport au contrat de Servant • Décodeur de messages réseau pour un Servant particulier • Définition de deux squelettes • Programme serveur • Crée un adaptateur d’objet • Crée deux squelettes et servants, les enregistre • Active l’adaptateur d’objet

  6. Contrats interface ServiceA { public String hello (String msg) throws Exception ; public String lower (String msg) throws Exception ; public String upper (String msg) throws Exception ; } interface ServiceB { public boolean isprime (int a) throws Exception ; public int sqr (int a) throws Exception ; }

  7. Code Server public class Server { public void run () throws Exception { ObjectAdapter oa = ObjectAdapter.init () ; SkeletonA skel_a = new SkeletonA (new ServantA ()) ; oa.register (skel_a) ; System.out.println (oa.obj2ref (skel_a)) ; SkeletonB skel_b = new SkeletonB (new ServantB ()) ; oa.register (skel_b) ; System.out.println (oa.obj2ref (skel_b)) ; oa.start () ; } // rest is unchanged

  8. Code ObjectAdapter (i) public class ObjectAdapter extends Thread { private static ObjectAdapter ref ; private ServerSocket asock ; private Vector skeletons ; protected ObjectAdapter () throws Exception { this.skeletons = new Vector () ; this.asock = new ServerSocket (0) ; } public static ObjectAdapter init () throws Exception { if (ObjectAdapter.ref == null) ObjectAdapter.ref = new ObjectAdapter () ; return ObjectAdapter.ref ; }

  9. Code ObjectAdapter (ii) public String obj2ref (Skeleton obj) { int key = this.skeletons.indexOf (obj) ; if (key == -1) return null ; String host = null ; try { host = InetAddress.getLocalHost () .getHostAddress () ; } catch (UnknownHostException uhe) { return null ; } int port = this.asock.getLocalPort () ; return host + ":" + port + ":" + key ; }

  10. Code ObjectAdapter (iii) public void run () { try { while (true) { Socket sock = this.asock.accept () ; BufferedReader in = ... String msg = in.readLine () ; if (msg == null) { // no more to be read sock.close () ; continue ;} int key = Integer.parseInt (msg.substring (0,1)) ;

  11. Code ObjectAdapter (iv) try { Skeleton skel = (Skeleton)this.skeletons.elementAt (key) ; skel.init (sock) ; new Thread (skel) .start () ; } catch (ArrayIndexOutOfBoundsException e) { sock.close () ; } } } catch (Exception e) { return ; } } }

  12. Interface Skeleton interface Skeleton extends Runnable { void init (Socket sock) throws Exception ; }

  13. Code SkeletonA (i) public class SkeletonA implements Skeleton { private ServantA ref ; public SkeletonA (ServantA s) throws Exception { this.ref = s ; } public void init (Socket sock) throws Exception { this.in = ... this.out = ... }

  14. Code SkeletonA (ii) public void run () { try { while (true) { String msg = this.in.readLine () ; if (msg == null) // no more to be read break ; String res ; switch (msg.charAt (0)) { case ’0’: res = this.ref.hello (msg.substring (1)) + "\n" ; break ; // etc. }

  15. Côté client • Modification du proxy • Prise en compte des clés d’objets • Connexion en deux temps au squelette • Définition d’un Proxy pour chacun des services • Deux chaînes Proxy / Skeleton / Servant • Fourniture de la référence comme une propriété • Définition de deux programmes clients • Chacun utilise un proxy pour un service particulier

  16. Code ProxyA (changes) public class ProxyA implements ServiceA { private Socket sock ; private BufferedReader in ; private DataOutputStream out ; public ProxyA (String host, int port, String key) throws Exception { this.sock = new Socket (host, port) ; this.in = ... this.out = ... this.out.writeBytes (key + "\n") ; } }

  17. Code ClientA (changes i) public class ClientA { private ServiceA ref ; public ClientA () throws Exception { this.ref = (ServiceA) this.ref2proxy () ; } public void run (String msg) throws Exception { System.out.println (this.ref.hello (msg)) ; System.out.println (this.ref.lower (msg)) ; System.out.println (this.ref.upper (msg)) ; }

  18. Code ClientA (changes ii) public ProxyA ref2proxy () throws Exception { Properties props = System.getProperties () ; String ref = props.getProperty ("service.reference") ; if (ref == null) throw new Exception ("no server reference given") ; String parts[] = ref.split (":") ; if (parts.length < 3) throw new Exception ("malformed reference") ; String host = parts [0] ; int port = Integer.parseInt (parts [1]) ; String key = parts [2] ; return new ProxyA (host, port, key) ; } }

  19. Bénéfices et limitations • Bénéfices • Serveur multi-services et multi-threadé (Skeleton) • Identification complète d’un service – adresse:port:clé • Les références sont créées au niveau du serveur • Limitations • Comment définir et utiliser des exceptions applicatives ? • Comment simplifier la traduction de référence en Proxy ?

  20. 9. Exceptions et traduction référence vers Proxy

  21. Principe • Exceptions • Ajout d’un code dans les messages de retour • 0 : OK; sinon un numéro d’exception... • Traduction automatique de références en Proxy • Extension des références pour contenir le type des références • Contrôle du typage lors de la création du proxy • Instanciation et initialisation automatique du Proxy

  22. Architecture version 9 Servant Servant Client Squelette Squelette Contrat Proxy ObjectAdaptateur Réseau

  23. Interactions version 9

  24. Chargement automatique de proxy • Motivations • Transformation d’une référence de service distant en proxy • Contrôler la conformité entre le type du proxy et du service • Modifications des implémentations • Extension des références • Ajout du type du service dans la référence : adresse:port:clé:type • Règles de nommage des classes • NomDuServiceProxy, NomDuServiceSkeleton, NomDuServiceServant • Les squelettes fournissent le type du service (pour construire la référence) • Interface de base Proxy implémentée par tous les proxy (pour init )

  25. Opération ref2proxy (i) public class Util { public static Proxy ref2proxy (String ref) throws Exception { String parts[] = ref.split (":") ; if (parts.length < 4) throw new Exception ("malformed reference") ; String host = parts [0] ; int port = Integer.parseInt (parts [1]) ; String key = parts [2] ; String type = parts [3] ;

  26. Opération ref2proxy (ii) // instanciation du bon proxy (présent dans classpath : convention de nommage) Class pclass = Class.forName (type + "Proxy") ; Proxy p = (Proxy) pclass.newInstance () ; // initialisation p.init (host, port, key) ; return p ; } }

  27. Interface Proxy interface Proxy { publicvoid init (String host, int port, String key) throws Exception ; }

  28. Côté serveur • Gestion des exceptions • Définition des exceptions dans le contrat du service • Modification des squelettes pour transférer les exceptions • Ajout de try catch pour les exceptions applicatives • Ajout d’un code en début de message réponse réseau • Typage des références • Modification des squelettes : fourniture du type du servant • Modification de l’opération obj2ref dans l’adaptateur d’objet

  29. Contrat ServiceB public class DivByZero extends Exception {} interface ServiceB { public boolean isprime (int a) throws Exception; public int sqr (int a) throws Exception ; public int div (int a, int b) throws Exception, DivByZero; }

  30. Interface Skeleton interface Skeleton extends Runnable { void init (Socket sock) throws Exception ; String type () ; }

  31. Code ServiceBSkeleton (modifs) public String type () { return "step9.ServiceB" ; } public void run () { … // managing isprime method from ServiceB case ’0’: int val0 = Integer.parseInt (msg.substring (1)) ; res = "0" + this.ref.isprime (val0) + "\n" ; break ;

  32. Code ServiceBSkeleton (changes ii) // managing div method from ServiceB case ’2’: String args [] = msg.substring (1) .split (" ") ; int arg0 = Integer.parseInt (args [0]) ; int arg1 = Integer.parseInt (args [1]) ; try { res = "0" + this.ref.div (arg0,arg1) + "\n" ; } catch (DivByZero e) { res = "1\n" ; // first exception raised } break ; // etc. }

  33. Code ObjectAdapter public String obj2ref (Skeleton obj) { int key = this.skeletons.indexOf (obj) ; if (key == -1) return null ; String host = null ; try { host = InetAddress.getLocalHost () .getHostAddress () ; } catch (UnknownHostException uhe) { return null ; } int port = this.asock.getLocalPort () ; return host + ":" + port + ":" + key + ":" + obj.type () ; }

  34. Côté client • Modification des proxy • Gestion des exceptions • Si code interne supérieur à 0 alors lever l’exception équivalente • Modification des clients • Utilisation de l’opération ref2proxy • Plus besoin de préciser le nom du Proxy • Utiliser le proxy avec le type de son interface

  35. Code ServiceBProxy (changes i) public boolean isprime (int val) throws Exception { // automatic conversion of int to string out.writeBytes ("0" + val + "\n") ; String res = in.readLine () ; return Boolean.valueOf( res.substring (1)) .booleanValue () ; }

  36. Code ServiceBProxy (changes ii) public int div (int a, int b) throws Exception, DivByZero { out.writeBytes ("2" + a + " " + b + "\n") ; String res = in.readLine () ; if (res.charAt (0) == ’1’) throw new DivByZero () ; return Integer.parseInt (res.substring (1)) ; }

  37. Code ClientB (changes) public ClientB () throws Exception { Properties props = System.getProperties() ; String ref = props.getProperty("service.reference") ; this.refB = (ServiceB) Util.ref2proxy (ref) ; } Exécution avec -D"service.reference=localhost:12345:1:step9.ServiceB"

  38. Bénéfices et limitations • Bénéfices • Bénéfices des exceptions sur le code produit • Contrôle du typage à l’utilisation des références • Limitations • Partage des références compliqué et réduit au fichier • Utiliser facilement plusieurs services dans un même client ?

  39. 10. Service de désignation

  40. Principe • Désignation des objets par des noms symboliques • Association : nom symbolique / références • Les serveurs enregistrent une référence avec un nom • Les clients recherchent une référence avec un nom • Service notoire : l’annuaire

  41. Architecture version 10 Nommage Servant Service Servant Client Squelette Squelette Contrat Proxy OAdap… OAdap… Réseau

  42. Interactions version 10 (*)

  43. Annuaire • Service au même titre qu’un autre • Défini par une interface • Hébergé par un serveur • Accessible au travers d’un Proxy • Particularités • Serveur dédié initialisé sur un port prédéfini • Connaître la machine = point d’entrée du système • Proxy particulier pour simplifier l’utilisation • Patron de conception Singleton

  44. Contrat NameService interface NameService { public void export (String name, String ref) throws Exception ; public String lookup (String name) throws Exception ; }

  45. Proxy Naming (extrait) public class Naming implements NameService { private static Naming ref ; private Naming () throws Exception { Properties props = System.getProperties () ; String host = props.getProperty ("naming.host") ; // etc. } public static Naming init () throws Exception { if (Naming.ref == null) Naming.ref = new Naming () ; return Naming.ref ; // etc. } // etc. }

  46. Côté serveur • Diffusion des références • Plus d’affichage sur la ligne de commande • Export des références de services • Vers une application répartie • Le serveur est client du service de nommage • Utilisation du proxy de ce dernier • Unique point d’entrée : référence du service de nommage $ javac -Dnaming.host=localhost step9.Server

  47. Code Server (changes) public void run () throws Exception { Naming ns = Naming.init () ; ObjectAdapter oa = ObjectAdapter.init () ; ServiceASkeleton skel_a = new ServiceASkeleton (new ServiceAServant ()) ; oa.register (skel_a) ; ns.export ("ServiceA", oa.obj2ref (skel_a)) ; ServiceBSkeleton skel_b = new ServiceBSkeleton (new ServiceBServant ()) ; oa.register (skel_b) ; ns.export ("ServiceB", oa.obj2ref (skel_b)) ; oa.run () ; }

  48. Côté client • Récupération des références • Plus de lecture de fichiers texte • Lookup des références de service • Vers une application répartie • Client est client des services A, B et Nommage • Utilisation des proxy de ces trois services • Unique point d’entrée : référence du service de nommage $ javac -Dnaming.host=localhost step9.Client

  49. Code Client (changes) public class Client { public Client () throws Exception { Naming ns = Naming.init () ; String ref_a = ns.lookup ("ServiceA") ; this.refA = (ServiceA) Util.ref2proxy (ref_a) ; String ref_b = ns.lookup ("ServiceB") ; this.refB = (ServiceB) Util.ref2proxy (ref_b) ; } // merge of previous clients’ code }

  50. Bénéfices et limitations • Bénéfices • Unique point d’entrée dans le système • Partage simplifié des références de services • Limitations • On écrit un peu toujours la même chose... • On risque à chaque fois de faire des erreurs (skel/proxy)

More Related