Module CSC5002—ASR6: Middleware and software architecture for distributed applications

Portail informatique

RabbitMQ Lab — VLibTour Group communication system with authentication

Introduction to the step

This page/step is about the use cases that are presented in Section 2.3 of the micro-project. The architectural entities that are concerned are the group communication system and the tourist application that are presented in Section 4 of the same document.

In this step/page, we add authentication to the group communication system that we have developed in the previous page.

Foreword

This page does not contain a definite step by step description of how to design the group communication of the micro-project. The description is not exhaustive: We only provide essential clues for a possible architecting of the AMQP infrastructure.

Group communication system in a dedicated virtual host and with authentication

Objectives: Up to now, all the tourist applications use the same broker (and the same host). If a tourist is informed, by whatever means, about the name of a group, the name of the tour, and the identifier of the user that has created the group, there is nothing in the system that prevents that tourist application to create a binding to the exchange of the group communication system of this specific visit. This is why we propose to use the concept of virtual host with access control in order to keep communication private to the group.

Learning phase


Before starting the refactoring for adding privacy concerns to the group communication systems, read the documentation page on the AMQP concept of virtual host, and then the section User Management of the rabbitmqctl command manual.

As an example, try the following sequence of commands in a terminal:

$ docker run -itd --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:4.0.0-management 2cf6ce95d54d68aac179dec769d3001882bf0b653d12379de9770054bc8f098b $ # play with a virtual host and access control $ docker exec rabbitmq rabbitmqctl add_vhost groupId Adding vhost "groupId" ... $ docker exec rabbitmq rabbitmqctl list_vhosts Listing vhosts ... groupId / $ docker exec rabbitmq rabbitmqctl add_user userId password Adding user "userId" ... Done. Don't forget to grant the user permissions to some virtual hosts! See 'rabbitmqctl help set_permissions' to learn more. $ docker exec rabbitmq rabbitmqctl list_users Listing users ... userId [] guest [administrator] $ docker exec rabbitmq rabbitmqctl set_permissions -p groupId userId ".*" ".*" ".*" Setting permissions for user "userId" in vhost "groupId" ... $ # add permissions to user guest in order to observe and log $ docker exec rabbitmq rabbitmqctl set_permissions -p groupId guest ".*" ".*" ".*" Setting permissions for user "guest" in vhost "groupId" ... $ docker exec rabbitmq rabbitmqctl list_permissions -p groupId Listing permissions for vhost "groupId" ... guest .* .* .* userId .* .* .* $ # clean up $ docker exec rabbitmq rabbitmqctl stop_app Stopping rabbit application on node ...@... ... $ docker exec rabbitmq rabbitmqctl stop Stopping and halting node ...@... ... $ docker stop rabbitmq; docker rm rabbitmq

AMQP architecture of the system


The only difference with the previous figure of the architecture of the group communicaton system is that all the AMQP elements (exchange and queues) are in a dedicated virtual host. Since identifiers must be unique in a virtual host, we have also somewhat simplified the names of the exchange, of the queues, and of the binding keys.


AMQP infrastructure of the group communication system in a separate virtual host

This is the final architecture that we propose for a group communication system of a visit—i.e. a group of tourists in a visit. This architecture is going to be built by the lobby room server, which is going to be the subject of the next step. In the sequel of this page, we prepare class VLibTourGroupCommunicationSystemProxy with access control to an AMQP virtual host.

Additional design elements


There exist two ways to open a channel to a broker:

  1. Create a ConnectionFactory, set the host by calling ConnectionFactory::setHost, etc., open the connection by calling ConnectionFactory::newConnection, and create the channel by calling Connection::createChannel. This is the approach that we have used up to now;
  2. Create a ConnectionFactory, set a URL by calling ConnectionFactory::setUri, open the connection by calling ConnectionFactory::newConnection, and create the channel by calling Connection::createChannel. Compared to the previous approach, all the configuration parameters are set via the URI—i.e. one method call that replaces "ConnectionFactory::setHost, etc.".

In the next step, the URI that is going to be returned to the client by a call to createGroupAndJoinIt on the lobby room server will be of the form "amqp://userName:password@hostName:portNumber/virtualHost". Considering that a connection factory is created (see variable factory in the following assignment statement), the URI that is going to be returned by the lobby room to the tourist application will be of the form:

uri = "amqp://" + userId + ":" + password + "@" + factory.getHost() + ":" + factory.getPort() + "/" + vhost;

On the client side, the tourist application can use the URL for setting the configuration of the connection factory: e.g. the two instructions "ConnectionFactory factory = new ConnectionFactory();", and "factory.setHost("localhost");" will be replaced by the following instructions:

ConnectionFactory factory = new ConnectionFactory(); factory.setUri(uriToGCS);

These two instructions are the easiest way to manage access control on the client side—i.e. no calls to ConnectionFactory::setVirtualHost, ConnectionFactory::setUserName, ConnectionFactory::setPassword, etc.

Adaptation of class VLibTourGroupCommunicationSystemProxy


Adapt the code of the proxy class in order to use a virtual host and add access control: The argument for connecting to RabbitMQ is going to be a URI.

Adapt also your JUnit classes, and perhaps shell scripts. Use some rabbitmqctl commands to create the users and to set their permissions.