Master 2 TI - Conception d'Applications Hétérogènes Distribuées- TP 3

Middlewares objets distribués

Objectifs pédagogiques

Comprendre et mettre en œuvre les principes fondamentaux de la communication entre objets dans des infrastructures distribuées.

Introduction

Dans ce tp, vous allez apprendre à utiliser les infrastructures middlewares réparties CORBA et RMI. Même si CORBA est conçue pour permettre de communiquer à des objets hétérogènes, nous nous limiterons à de la programmation en Java, sachant que les mêmes techniques que celles décrites ici existent dans les autres langages de programmation. Ensuite, vous réutiliserez les concepts de ces technologies pour mettre en oeuvre des objets transactionnels distribués (EJB 3.0) et les services associés.

CORBA

Mise en route

Pour vous exercer, voici un premier exemple d’application client serveur implémentant les principes de communication avec CORBA, tiré de celui proposé par SUN (http://java.sun.com/j2se/1.4.2/docs/guide/idl/GShome.html). Un fichier zippé contenant un fichier IDL et les sources du serveur/servant et du client est disponible localement sur : http://www710.univ-lyon1.fr/~lmedini/TI1/Bonjour.zip.

  1. A partir de ce fichier, générez les fichiers correspondant à l’interface exposée par le serveur à l’aide de l’outil idlj. Ce code a été testé avec les deux modèles d’implémentation du serveur : par héritage et par délégation (TIE). En d’autres termes, vous pouvez indifféremment générer les fichiers avec l’option –fall ou –fallTIE. Pour info, vous pouvez également utiliser les options –fserver / –fserverTIE pour générer les fichiers serveur et –fclient / –fclientTIE pour les fichiers client.
  2. Copiez ensuite les fichiers source Java dans le répertoire « bonjour » créé par idlj et compilez l’ensemble des sources.
  3. Lancez ensuite le serveur de noms tnameserv, le serveur et le client, dans cet ordre (voir cours 2) depuis 3 fenêtres DOS différentes :
    • tnameserv -ORBInitialPort 1050
    • java bonjour/BonjourServer -ORBInitialPort 1050  -ORBInitialHost localhost (depuis le répertoire contenant le fichier .idl et le répertoire "bonjour")
    • java bonjour/BonjourClient -ORBInitialPort 1050  -ORBInitialHost localhost (idem)

Remarques :

Conception

Vous allez maintenant intégrer la communication CORBA à l’application développée au TP précédent. Pour cela :

Remarques :

Exemples de méthodes du serveur :

public class Serveur { static RepertoireImpl adder, remover, lister; static ORB orb; static POA rootpoa; static NamingContextExt ncRef; public static void main (String[] args) { startConteneur(); //à vous de programmer startServer(args); referenceRepertoire(adder, "add"); referenceRepertoire(remover, "remove"); referenceRepertoire(lister, "list"); run(); } private static void startServer(String[] args) { try{ // initialize the ORB orb = ORB.init(args, null); System.out.println("ORB initialized..."); // get reference to rootpoa & activate the POAManager rootpoa = POAHelper.narrow(orb.resolve_initial_references("RootPOA")); Policy p[] = new Policy[7]; p[0] = rootpoa.create_thread_policy(ThreadPolicyValue.ORB_CTRL_MODEL); p[1] = rootpoa.create_lifespan_policy(LifespanPolicyValue.PERSISTENT); p[2] = rootpoa.create_id_uniqueness_policy(IdUniquenessPolicyValue.MULTIPLE_ID); p[3] = rootpoa.create_id_assignment_policy(IdAssignmentPolicyValue.USER_ID); p[4] = rootpoa.create_servant_retention_policy(ServantRetentionPolicyValue.NON_RETAIN); p[5] = rootpoa.create_request_processing_policy(RequestProcessingPolicyValue.USE_DEFAULT_SERVANT); p[6] = rootpoa.create_implicit_activation_policy(ImplicitActivationPolicyValue.NO_IMPLICIT_ACTIVATION); rootpoa.the_POAManager().activate(); System.out.println("POA initialized..."); // get the root naming context org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); // Use NamingContextExt which is part of the Interoperable // Naming Service (INS) specification. ncRef = NamingContextExtHelper.narrow(objRef); System.out.println("NamingContext found..."); } catch (Exception e) { System.err.println("ERROR: " + e); e.printStackTrace(System.out); } } private static void referenceRepertoire(RepertoireImpl repertoire, String name) { try{ // register servant with the ORB repertoire.setORB(orb); // get object reference from the servant org.omg.CORBA.Object ref = rootpoa.servant_to_reference(repertoire); repertoire.corba.Repertoire href = (repertoire.corba.Repertoire) RepertoireHelper.narrow(ref); System.out.print("Servant " + name + " initialized..."); // bind the Object Reference in Naming NameComponent path[] = ncRef.to_name( name ); ncRef.rebind(path, href); System.out.println(" and bound."); } catch (Exception e) { System.err.println("ERROR: " + e); e.printStackTrace(System.out); } } private static void run() { System.out.println("Server ready and waiting..."); // wait for invocations from clients orb.run(); System.out.println("Server Exiting ..."); }

RMI

Mise en route

Lancement du client

Pour commencer, vous allez démarrer sur une application de type "Hello World" toute simple dont vous récupérerez le client et l'interface distante ici.

TP du 24/09/2015 : remplacez l'adresse IP de l'annuaire JNDI par la suivante : 134.214.90.240. Récupérez le stub ici et collez-le dans le répertoire serveur de votre client.

Lancement du serveur

Récupérez ensuite le code du serveur et décompressez-le dans un autre répertoire de votre machine.

De la même manière, testez le client pour qu'il appelle le serveur sur votre machine locale.

Sécurisation

Utilisez les informations situées ici pour faire en sorte que seuls les fichiers situés dans vos répertoires client et serveur soient accessibles par le serveur JNDI.

Modification de l'interface

Enfin, modifiez le servant (l'interface Hello et sa classe d'implémentation) pour que la méthode sayHello prenne en entrée deux paramètres (un nom et un entier), et qu'elle dise autant de fois bonjour que l'entier le lui indique.

Utilisation dans Eclipse

Il peut arriver qu'un client ou un serveur tourne correctement dans Eclipse. Pour cela, une méthode qui a fonctionné est de créer le projet et la structure des packages à la main et de glisser-déposer les classes et interfaces dans l'explorateur de projet. Une fois que le code Java est correctement intégré dans le projet, il faut créer une Run Configuration :

Une fois la configuration créée et appliquée, testez-la. Si Eclipse est incapable de trouver votre classe Main, essayez l'une des 3 solutions ci-dessus... Remarque : vous n'aurez pas tout perdu, Eclipse est au moins capable de compiler votre code Java.

N'oubliez pas que de toutes façons, il faut compiler les classes d'implémentation du servant avec rmic.

Conception

Reprenez une version fonctionnelle de votre application de répertoire téléphonique, décomposée en 4 parties (Main, Annuaire, Serveur, Client). Par exemple, celle issue de la question 0, mais si vous avez la version de la question 2.2 (uniformisation, cela vous simplifiera la tâche).

Dans votre projet Repertoire du TP 1 :

Licence Creative Commons
Valid XHTML 1.0 Strict