Applications Réparties - Partie II: approche client/serveur par objets distribués

Cours Polytech'Nice, SI4, 2015-2016

Sujet du mini projet

Un portail "générique" de partage de données ET de services, avec RMI (et un peu de JMS)

Le but de cette application répartie, écrite en RMI a pour but de généraliser ce à quoi sert un Registry RMI. En offrant plus de flexibilité, ce à plusieurs titres : Ce registre "universel" utilisera donc le principe de téléchargement dynamique de bytecode Java (de classe). Il se restreint de fait au support d'applications écrites en Java... Vous réutiliserez le programme de mise à disposition de fichier de classes, utilisé dans le TP2 (classserver.ClassFileServer). Dans ce projet, on fera abstraction des problèmes de sécurité, en supposant que tous les serveurs et les clients qui utilisent ce portail sont de confiance.

Dans ce projet, vous lancez ce registre universel (cette application RMI) et devez donc l'enregistrer dans un RMI Registry standard, qui s'exécute sur la même machine que cette application. Ce RMI Registry est accessible lui même à distance, par exemple sur machineDuRegistre:4000. Donc, ceux qui l'utiliseront ne seront pas forcément lancés sur machineDuRegistre et peuvent accéder depuis n'importe où de l'internet à machineDuRegistre:4000 pour y chercher un proxy/stub vers le registre universel. Bien sûr, pour des questions pratiques évidentes, votre projet utilisera toujours localhost plutôt que n'importe quelle autre adresse IP.

Le registre n'est rien d'autre qu'une application RMI qui offre une API ressemblant à celle de RMIRegistry, ou à n'importe quel service d'annuaire type JNDI (bind, rebind, get, list, ...). En interne, ce registre utilise une HashTable (ou une HashMap, à voir si vous avez besoin de vous soucier d'aspects d'accès concurrents). L'idée est donc d'offir aux utilisateurs de ce service de mise à disposition d'information, la possibilité d'enregistrer sous une clé (une String, choisie par ses utilisateurs) un objet sérializable. Ensuite, d'autres utilisateurs viendront interroger le registre pour récupérer de tels objets à travers leur clé d'enregistrement. En plus des spécifications d'un service de nommage standard, votre service de mise à disposition peut aussi proposer à ses clients de connaitre :

Pour commencer supportez un service de nommage "flat", et si vous avez le temps, mettez en place un service de nommage hiérarchique (ex: donnez moi les loueurs de véhicules, mais seulement ceux qui ont déclaré offrir un service de location de véhicules uniquement électriques: loue_vehicules/electrique). Le registre étant générique, cela signifie qu'il ne connait aucune des classes des objets qu'il va enregistrer. Mais, il les téléchargera automatiquement comme vu dans le TP2 (codebase adéquat !). De ce fait, il peut même être utilisé pour faire la mise en relations d'usagers dans plusieurs domaines d'application à la fois.

Par contre, les clients sauront plus ou moins quel type d'information ils cherchent dans ce registre (souvenez-vous, côté client, il faut au moins connaitre les classes pour que ce code puisse compiler, à moins que vous ne fassiez appel à l'introspection, mais c'est hors sujet): par exemple, soit

Pour supporter ce "plus ou moins", dans le code du client il suffit de capturer une ClassCastException: si ce qu'on a récupéré du registre est effectivement castable en Donnee, c'est bon, on a obtenu des informations qu'un autre usager a bien voulu partager ("gratuitement") au travers du registre ; mais si ce n'est pas de ce type là, (cad pas de type Donnee), une ClassCastException est levée et peut être attrapée, et on essaye alors de la caster en un stub vers une interface Remote nommée Service. Pour simplifier, Service n'est pas sous classée, et offre toujours les méthodes Remote prévues, et pas de méthodes en plus. En bonus, vous pourrez imaginer qu'une sous classe de Service puisse permettre de demander à un client appelant ce service d'être rappelé ultérieurement en passant en paramètre son proxy/stub implémentant une interface Remote, proposant par exemple une méthode boolean etreRappelé(AccesClient) ; le service confirmera au client par le boolean qu'il a bien pris en compte la demande de rappel qui sera effectuée ultérieurement (donc, le code du client offre aussi une méthode Remote d'une interface AccesRemote que le service utilisera pour rappeler le client). Votre service devra obligatoirement aussi offrir une méthode s'abonner aux dernières informations.

Modification apportée au sujet du fait que le TP 6 n'a pu être effectué

Le client qui l'invoque reçoit en réponse si c'est possible, une référence vers un topic JMS (cette référence est donc un nom de topic JMS auquel le client devra se brancher). En tant qu'abonné à ce topic, le client recevrac ainsi automatiquement et au fur et à mesure les informations qui seront publiées par le service. Le client qui l'invoque reçoit en réponse si c'est possible, une référence vers un topic JMS (cette référence est donc un nom de topic JMS auquel le client devra se brancher). Le client qui l'invoque reçoit en réponse si c'est possible, une référence vers une queue JMS (cette référence est donc un nom de queue JMS auquel le client devra se brancher). En tant que consommateur dans cette queue, le client sera en mesure de recevoir automatiquement et au fur et à mesure les informations qui y seront déposées par le service. Ce sera au serveur de choisir le nom de la queue qu'il aura décidé de créer et qui a priori, sera propre à chaque client. Cette queue permet donc au serveur de faire passer des informations pertinentes au client, en mode "push", plutôt que ce soit le client qui vienne interroger le serveur expressément pour recevoir des informations.

Ainsi votre client est un client JMS, en plus d'être client d'un service RMI (le registre universel, et le serveur implantant le service). En bonus, le client est aussi un serveur RMI.

Pour illustrer l'aspect générique de votre registre, vous coderez plusieurs serveurs et plusieurs clients (des méthodes main possibles) pour un domaine d'application de votre choix (après tout, votre innovation est de vendre un registre ayant des propriétés utiles pour n'importe quelle problématique de mise en relation d'usagers) : par exemple, mettant en relation des vendeurs/acheteurs de véhicules, ou de passionés de botanique qui répertorient des plantes rares (et donc, des fournisseurs de services qui permettent d'interroger ou répertorier telle ou telle espèce dans des bases de données adéquates), ou des services de petites annonces de type co-voiturage, entre particuliers ou utilisant des services payants qu'il faut donc contacter... Donc, selon les applications, ce ne seront pas forcément des classes nommées Donnee ou Service, mais tout autre nom. Encore une fois, l'aspect générique de votre registre permet de télécharger n'importe quelle classe dont il aura besoin et dont il n'a pas connaissance.

Modalités de Rendu

Ce mini projet est à rendre par binôme (par défaut, sauf si vous m'en parlez avant) pour le mercredi 25 mai 2016 minuit dernier délai, parce que vous devez être à plein temps sur le projet Innovation dès le 26 au matin . N'attendez pas la dernière minute, d'autant que le sujet de l'examen porte évidemment sur les notions mises en oeuvre dans le projet.
Dans ce zip, je veux trouver un fichier documentation pour aider à savoir quelles sont les grandes fonctionnalités auxquelles répond votre projet, quels sont les aspects qui n'ont pas été développés, quels sont les grandes lignes suivies pour organiser votre architecture logicielle et code . Quelles ont été les difficultés rencontrées. Une partie du rapport doit correspondre à une aide pour pouvoir facilement faire tourner le projet. Comme il y a besoin de configurer le lancement des JVMs avec des arguments de VM ou d'utilisateur, bien indiquer ce qu'il faut. Les fichiers source Java sont à fournir, les .class également (ça m'évitera d'avoir à tout compiler).

La notation portera sur la qualité de la conception et du code RMI ainsi dans une bien moindre part, sur la quantité de fonctionnalités offertes. Un bon projet méritant largement 15-16 fonctionnera, sans bug, compréhensible dans les fonctionnalités offertes; le code sera logiquement organisé, répondra aux spécifications demandées.

Bon travail! Et n'hésitez pas, si vous êtes bloqués, à m'envoyer un email (baude at unice.fr).



Page maintenue par Francoise Baude @2016