RabbitMQ Lab — VLibTour Lobby room
Introduction to the lab
This lab is about the use cases that are presented in Section 2.2 of the micro-project. The architectural entities that are concerned are the lobby room, the group communication system, and the tourist application that are presented in Section 4 of the same document.
In the previous lab, you have built the group communication part of the project: Every group of tourists has its own group communication system. The creation of the AMQP infrastructure with the virtual hosts was handmade in the JUnit tests.
In this lab, the creation of the infrastructure for group communication systems is made by the lobby room: Every tourist application is going to contact the lobby room for creating or joining a group, that is for creating or joining a dedicated group communication system, whose virtual host is created and managed by the lobby room server.
This page does not contain a definite step by step description of how to design the lobby room system. The description is not exhaustive: We only provide essential clues for a possible architecting of the AMQP infrastructure.
Recall our first rationale of the lab during which we designed the group communication system. We propose that every visit of a tour by a group of tourists is managed using a dedicated group communication system. The role of the lobby room system is to create the infrastructure for each group communication system. Access control to the virtual host of a group communication system is only granted to the members of the same visit; and, there is no server, except the AMQP broker, that stores or manipulates messages exchanged by the members of the group.
Rationale 3: The calls to the lobby room are synchronous. When a tourist application calls for the creation of the group communication system infrastructure or for the joining of an already existing group communication system infrastructure, it waits for a unique reply. Therefore, the lobby room infrastructure comprises an AMQP exchange for sending the RPC calls to the lobby room server, and the lobby room server is responsible for setting up the infrastructure of the group communication systems—i.e. creation of the virtual hosts, creation of the AMQP users, setting of the user permissions, etc.
Rationale 4: The tourist application that calls for the creation of a group communication system is the one that provides the information for establishing the name of the group, i.e. the groupId. Then, we consider that the information groupId + userId is transmitted "out-of-band", i.e. the members of the group can talk to each other for knowing the information groupId + userId. In other words, none of the systems of our infrastructure is used to transmit the information groupId + userId. In a nutshell, we do not set up an infrastructure to securely transmit this kind of information.
Lobby room server
AMQP architecture of the system
The next figure presents an example of the AMQP infrastructure of the lobby room system with two tourist applications and the lobby room server. This architecture is specific to the RabbitMQ way of managing RPC calls. In order to get more details about this architecture, please refer to Step 6 of the tutorial lab and the RabbitMQ Direct reply-to feature.
Here are some explanations about the architecture:
- Since there is no access control to the lobby room, the virtual host is the default one and there are no logins and no passwords.
- Tourist applications are RPC clients. They send their RPC call through the exchange that is named vlib-tour-lobby. In the figure, tourist applications send their RPC call by specifying that the routing key is lobby, and that the type of the exchange is direct. If we consider that only the lobby room possesses a queue that is bound to the vlib-tour-lobby exchange, we could also use an exchange of type fanout.
- The implementation that we propose in this lab will be inspired by classes of Step 6 of the RabbitMQ tutorial. In this tutorial step, the class JsonRpcClient is used as the type of attribute jsonRpcClient in class RPCClient3. If you look at the code of class JsonRpcClient, you see that it extends class RpcClient, and then, the constructor of class RpcClient sets the queue for the reply to amq.rabbitmq.reply-to. According to the description of the Direct reply-to feature of RabbitMQ, it means that the reply of the RPC call is sent to the default exchange ("") and then directly to the client, that is without transiting through a queue. These details explain the strangest aspects of the AMQP infrastructure displayed in the picture.
Interface of the lobby room service
The interface VLibTourLobbyService is provided in Maven module vlibtour-lobby-room-api, which is a submodule of module vlibtour-lobby-room-system. It defines what the clients must know so that they can request for the creation of a new group communication system for their visit: the exchange name (e.g. "vlib-tour-lobby") and the routing key (e.g. "lobby").
We suggest the following methods for the API of the lobby room server:
String createGroupAndJoinIt(String groupId, String userId):
creates a group for a tour instance—i.e. a visit—and joins it.
- The method returns an URL, which is used to connect to the infrastructure for the group communication dedicated to the visit.
- Assumption/limitation of the operation for this proof of concept: the computation of the group identifier assumes that the user creates a group for this tour only once.
String joinAGroup(String groupId, String userId):
joins an existing group for a tour instance, that is a
- The method returns an URL, which is used to connect to the infrastructure for the dedicated group communication system.
- Recall from Rationale 4 that the information groupId is provided "out-of-band" by the tourist that has called createGroupAndJoinIt.
Implementation of the lobby room server
The implementation is prepared in class VLibTourLobbyServer of Maven module vlibtour-lobby-room-server, which is a submodule of Maven module vlibtour-lobby-room-system. This is one objective of this lab to write this class.
Reminder: Use the source code of the sixth step of the tutorial lab on RabbitMQ: See directory RabbitMQ-Tutorial-Step6, and more particularly, class RPCServer3.
For testing your code, we propose to wait for the implementation of the client/proxy (next implementation step).
Here follows some hints for the implementation; these hints are listed for helping purpose:
- First of all, let us note that class VLibTourLobbyServer implements two interfaces: Runnable, and VLibTourLobbyService. The class is runnable in order to be integrated into another process as a thread, i.e. in the main method of the same class. Of course, class VLibTourLobbyServer implements the API of the lobby room system.
- Constructor VLibTourLobbyServer() opens the connection to the RabbitMQ broker, creates the exchange for receiving RPC calls, creates the queue and bind the queue to the exchange. Then, the constructor creates the stub for receiving the RPC calls, i.e. an instance of JsonRpcServer that represents a VLibTourLobbyService and that delegates the calls to an instance of class VLibTourLobbyServer. Since the stub is created in the constructor of our class that implements the interface, we provide the instance this. If we wanted to better manage concurrency (because giving the reference this in the constructor is dangerous), we would add another method for the creation of the stub object (instance of JsonRpcServer).
- Method createGroupAndJoinIt uses command rabbitmqctl with sub-commands add_vhosts, add_user, etc., to set the RabbitMQ infrastructure for the new group communication system. The sequence of calls is obtained by mimicking what has been done at the end of previous lab.
- Method JoinAGroup is implemented by following the pattern as for method createGroupAndJoinIt.
- Method main is used in shell script start_lobby_room_server.sh. It instanciates the class, creates a thread with this instance, and starts the thread. The lobby room server is then ready to receive RPC calls. Method mainloop() of JsonRpcServer is running. It will be stopped by killing the corresponding process (we do not implement a more elaborate solution).
Implementation of the AMQP part of the tourist application
As for the group communication system, the tourist application delegates the call to the lobby room server to a client/proxy. This client/proxy is prepared in Class VLibTourLobbyRoomProxy, which is in Maven module vlibtour-lobby-room-proxy, which is a sub-module of Maven module vlibtour-lobby-room-system. This is one objective of this lab to write this class.
Reminder: Use the source code of the sixth step of the tutorial lab on RabbitMQ: See directory RabbitMQ-Tutorial-Step6, and more particularly, class RPCClient3.
Here follows some hints for the implementation; these hints are listed for helping purpose:
Class VLibTourLobbyRoomProxy has two
constructors: one for the client that asks for the
creation of a group and one for the clients that want to
join a group. None of the constructors performs the RPC
call—i.e. the RPC call is done in
- Constructor VLibTourLobbyRoomProxy(String tourId, String userId): creates a client application of the lobby room server. The group identifier may be computed as the concatenation of the tour identifier, the delimiter VLibTourLobbyService::GROUP_TOUR_USER_DELIMITER, and the user identifier.
- Constructor VLibTourLobbyRoomProxy(String groupId, String tourId, String userId): creates a client application of the lobby room server when the group has already been created by another user—i.e. the group identifier is provided as the first argument.
- Method createGroupAndJoinIt: uses a JsonRpcClient object to call the lobby room server for the creation of the group. In the method, a new AMQP connection and a new AMQP channel are created before the RPC call, and are closed after the receipt of the reply. In this proof of concept, let us consider that the RPC call throws no exception—i.e. if an exception is thrown, there is no recovery but the treatment of the exception is "exiting the application". The returned string is the URL to the group communication system (with the specification of a dedicated virtual host, a login and a password).
- Method joinGroup: also uses a JsonRpcClient object, but to call for joining an existing group. The implementation is similar to the previous method. In this proof of concept, let us again consider that the call throws no exception—i.e. the treatment of the exceptions is "exiting the application". The returned string is the URL to the group communication system (with the specification of a dedicated virtual host, a login and a password).
For testing your code, you can choose to:
- create a JUnit test (by mimicking the JUnit test class RabbitMQ-Tutorial-Step6/src/test/java/eu/telecomsudparis/rabbitmq/tutorial/TestScenario3.java in the examples);
- create shell scripts (by mimicking Scripts/start_lobby_room_server.sh). This latter method is much more time consuming since you would have to add a main method to class VLibTourLobbyRoomProxy.
$Date: 2020-10-12 13:27:31 +0200 (lun. 12 oct. 2020) $