TP RabbitMQ avec Java

Frank Singhoff

Sommaire




Exercice 1 : exemple d'un programme RabbitMQ avec Java

L'objectif de cet exercice est de vous montrer comment créer une application avec RabbitMQ. Nous utiliserons des clients Java pour ce faire.

Dans un premier temps, il est nécessaire de mettre en place l'environnement pour l'utilisation de RabbitMQ avec java. Dans un terminal, lancer les commandes suivantes :

cd /home/tp/poc_rabbitmq
docker-compose up -d
Cette première commande lance le serveur RabbitMQ. Une fois lancé, le serveur est en attente sur la machine localhost et le port 8050.

Cette distribution de RabbitMQ (disponible sur GitHub depuis http://github.com/hugosinghoff/poc_rabbitmq et utilisant une image docker fournie par Bitnami) contient une interface de supervision qui permet de connaitre l'état du serveur (mémoire consommée, connexions réseaux en cours, états des queues, ...) et également d'administrer les utilisateurs du serveur.

Dans ce serveur, un seul utilisateur est défini dont les données sont les suivantes :
Pour vérifier que le serveur est correctement lancé, vous pouvez:
  1. Lancer firefox en ouvrant l'URL http://localhost:8051
  2. Vous connecter avec le login/password ci-dessous
  3. Puis inspecter les différentes informations offertes par l'interface d'administration de RabbitMQ. Notez que c'est surtout quand vous ferrez tourner vos programmes que vous constaterez évoluer les informations présentées dans cette interface.


Nous allons maintenant utiliser des clients Java pour ce serveur. Afin de pouvoir compiler les clients Java et utiliser les jar associés, récupérer le fichier rabbit.bash suivant et appliquer la commande suivante :
source rabbit.bash


Puis, récupérez les fichiers de ce premier exercice à partir du répertoire EXO1 . Sauvez tous ces fichiers dans un répertoire EXO1.





Cette application est composée d'un exchange et de deux programmes: Publisher.java et Subscriber.java ; Pour compiler ces programmes, lancer la commande:
make



Puis, lancer les clients qui lisent les messages. Pour lancer et arrêter ces processus, vous pouvez soit utiliser les scripts lance.sh et stop.sh, ou taper directement ces commandes:
java Subscriber paul 'legumes.*' &
java Subscriber jacques legumes.tomate &
java Subscriber eric legumes.radis legumes.tomate &
Puis, lancer successivement les programmes qui émettent les messages par :
java Publisher legumes.radis coucou1
java Publisher legumes.tomate coucou2 
java Publisher plouf coucou3
Ce qui devrait générer l'affichage :
Publisher : legumes.radis coucou1
Subscriber paul recoit legumes.radis : coucou1
Subscriber eric recoit legumes.radis : coucou1
Publisher : legumes.tomate coucou2
Subscriber paul recoit legumes.tomate : coucou2
Subscriber eric recoit legumes.tomate : coucou2
Subscriber jacques recoit legumes.tomate':'coucou2
Publisher : plouf coucou3


Regardez ces programmes, puis,répondez aux questions suivantes :
  1. Quels ports/machines sont utilisés par ces programmes ?
  2. Pourquoi le message coucou3 n'est pas reçu ?
  3. Le programme qui lit les messages utilise-t-il des communications en mode push ou en mode pull ?
  4. Quel est le nom de l'exchange utilisé pour ces communications ?
  5. Lancer les 2 programmes selon plusieurs scénarios et naviguer dans l'interface d'administration pour voir l'effet de l'exécution de ces programmes.



Pour vous aider, l'ensemble de l'API Client Java/RabbitMQ est disponible ici .


Exercice 2 : premier programme RabbitMQ avec Java



Pour cet exercice, récupérez les fichiers à partir du répertoire EXO2 . Sauvez tous ces fichiers dans un répertoire nommé EXO2. Compléter les programme Lecteur_Depeche.java et Redacteur_Depeche.java de sorte que :




Exercice 3 : sérialisation/désérialisation/filtrage de messages : alerte pour la gestion de ligne de bus



Pour cet exercice, récupérez les fichiers à partir du répertoire EXO3 . Sauvez tous ces fichiers dans un répertoire nommé EXO3.

On vous demande d'implanter une application composée de 3 programmes et dont le but est d'émettre, de filtrer et de transmettre des messages permettant de connaitre l'état d'un réseau de lignes de bus.





L'application a réaliser est composée de 3 programmes et de 2 exchanges (voir figure ci-dessus).

Les scripts lance.sh et stop.sh vous montrent comment lancer et arrêter ces programmes. Chaque programme fonctionne de la façon suivante:

Question 1:

Dans un premier temps, on regarde uniquement les communications entre Emetteur.java et Filtrage.java. Filtrage.java se contente de recevoir les messages de Emetteur.java et de les afficher à l'écran.

On rappelle que chaque message produit par Emetteur.java doit comporter 3 informations : le numéro de ligne de bus, l'événement qui est intervénu sur la ligne et l'impact sur la ligne. Chaque message est une chaine de caractères que doit construire Emetteur.java. Pour produire dans Emetteur.java les messages à partir des classes Statut et Evenement, vous pouvez utiliser la méthode name. Ainsi :
String s = Statut.Arret.name();
permet de sérialiser la valeur Arret de l'énuméré Statut afin de l'ajouter dans le message à transmettre.

On vous demande de séparer chacune des 3 informations concaténées dans un message par le caractère #. Grâce au caractère #, lorsque le message est reçu par Filtrage.java, les 3 informations du message peuvent être séparées avant affichage par la méthode split de cette façon:
 String [] result = Message.split("#");
 
result[0] contient la première information (ex: le numéro de ligne de bus), result[1] la 2ème information (ex: l'événement) et result[2] la 3ème information (ex : le statut). Enfin, pour désérialiser les énumérés, vous utiliserez les méthodes Evenement.valueOf et Statut.valueOf.

Travail à faire :

Modifier les programmes Emetteur.java et Filtrage.java afin d'implanter la communication entre ces 2 programmes.



Question 2:

Maintenant, on implante les règles de filtrage appliquées par le programme Filtrage.java ainsi que la communication entre Filtrage.java et Recepteur.java.

Pour chaque message reçu par Filtrage.java, ce programme doit :
  1. Transfèrer le message sans le modifier vers l'atelier.
  2. Envoyer un message vers les usagers en indiquant l'état de ligne. Chacun de ces messages doit comporter le numéro de ligne concerné ainsi que l'état de la ligne (le message peut être construit avec la classe Statut.java).
  3. Comptabiliser le nombre d'événements et envoyer cette information à l'atelier.


Concernant les règles de filtrage:

Travail à faire :

Modifier le programme Filtrage.java et écrire le programme Recepteur.java pour implanter la communication entre ces 2 programmes.





Exercice 4 : Controle sur la perte de message



Pour cet exercice, récuperer les fichiers qui sont disponibles dans ce répertoire . Sauvez tous ces fichiers dans un répertoire EXO4.

Dans cet exercice, on cherche à controler la perte de message, suite, par exemple, à l'arrêt d'un subscriber. On vous demande de réaliser une application permettant de gérer et contrôler des operations bancaires. L'application est composée des 3 programmes suivants :



Question 1 :

Dans un premier temps, écrire les programmes Web.java et Compte.java. Tester que chaque opération bancaire envoyé par Web.java est bien enregistrée par Compte.java dans le fichier texte associé.



Question 2 :

L'objectif de la question 2 est maintenant d'implanter le controleur. Implanter le Controleur.java, puis, tester qu'en cas de panne de Compte.java, les messages de Web.java sont bien ré-injectés dans le serveur RabbitMQ quand ceux-ci n'ont pas pu être traités par Compte.java.




Exercice 5 : mise en oeuvre d'un mini-broker client/serveur



Dans cet exercice, on illustre comment fonctionne un mini-broker d'objets répartis similaire à CORBA ou Java RMI. Ce mini-broker utilise RabbitMQ pour implanter les communications entre les clients et les serveurs qui hébergent les objets accessibles à distance.

Récupérer les fichiers de cet exercice à partir du répertoire EXO5 . Sauvez tous ces fichiers dans un répertoire EXO4.


Question 1:




Question 2:

Le programme donné pour la question 1 ne comporte que le code nécessaire pour transmettre la requête du client vers le serveur. Avec cette première version, les objets ne peuvent pas retourner une réponse au client.

Pour cette question, nous vous donnons une nouvelle version de certains fichiers du mini-broker, fichiers qui sont disponibles dans ce répertoire EXO5Q2 . Sauvez tous ces fichiers dans un répertoire EXO5Q2.

Modifier les autres classes Java constituant ce mini-broker afin de permettre à l'objet de transmettre une réponse au client via la souche et le squelette. Cette nouvelle version nécessite de mettre en place l'envoie d'un message constituant la réponse du serveur vers le client. Pour ce faire, vous aurez besoin d'un exchange supplémentaire entre l'ObjectAdapter et le Client.



Question 3:

Le programme précédent ne gère qu'un seul objet Calcul. On souhaite étendre ce programme afin de pouvoir manipuler plusieurs objets, c-à-dire plusieurs instances de la classe CalculImpl.java. Chaque objet est identifié par un identifiant unique. Au niveau de l'ObjectAdapter, chaque objet est associé à un thread (thread généralement appelé Servant) qui lit les requetes associées à l'objet et émet les réponses vers le client. Chaque objet doit utiliser une clef de filtrage dédiée.

Modifier les classes Java afin d'implanter cette nouvelle fonctionnalité. Pour tester, vous modifierai Server.java afin d'héberger 3 instances de CalculImpl. Pour tester, le client devra également être modifié.



©(Copyright) singhoff@univ-brest.fr