Originally published on Fedora Project Community Blog
The Federated Message Bus, or Fedmsg, is used within the Fedora Infrastructure to easily connect services using ZeroMQ publishers and subscribers. This library is now deprecated in favour of Fedora Messaging.
Fedora Messaging provides a framework for declaring message schemas and a set of APIs to publish and consume messages to and from AMQP brokers.
In the project Fedora Happiness Packets, Fedmsg was set up to send messages to the Bus so that Fedora Badges could be awarded to the sender when they send a Happiness Packet, i.e an email worth of appreciation! My piece in this jigsaw was to migrate from Fedmsg to Fedora Messaging in this containerized project.
After going through the documentation for Fedora Messaging and understanding its use case in Fedora Happiness Packets, I realized that a publisher needs to be set up in the project. To accomplish the same, I broke down the problem into a set of steps like this:
Before starting, I followed the tutorial given in Fedora Messaging Documentation to get a better grasp of what I was doing. While doing the same, I ran into a couple of minor errors mainly related to configurations of config.toml
which are summarized here with their solutions.
Fedora Messaging needs to be added as a dependency in the project as described here. Fedora Happiness Packets is a containerized application where all the dependencies are installed from a requirements file. I simply added fedora-messaging to the above mentioned file to ensure that the library and all its dependencies are installed in the container.
Apart from the library, the message schema is also needed to be installed in the project to use while publishing messages. I included the name of the python package of the message schema in the requirements file.
A configuration file config.toml
is needed for Fedora Messaging as described here. I started with the configuration file config.toml.example
given in the docs and modified it to set up configurations needed only for publishers.
The amqp_url
also needs to be configured to connect to the RabbitMQ message broker, that is setup in its docker-container. I configured this while setting up RabbitMQ in the project as described below.
The last step I did in this section was to set the environment variable FEDORA_MESSAGING_CONF
to the path of the configuration file created as detailed above. I set this up in the Dockerfile.
This step involves a lot of things so again I divided the task into bite sized pieces as follows:
While ensuring the crux of this integration worked seamlessly, I mistakenly overlooked some of the small details that need to be edited from the sample message schema. Here is a tiny list of the little things that need to be changed in setup.py
:
This is at the crux of the format in which messages will be sent to the Bus as described here. In Fedora Happiness Packets, messages are sent to the bus to ensure the sender and receiver, receive Fedora Badges. Thus the message had to contain their usernames (if permitted by the sender) to award badges as well as the ID of the Happiness Packet send.
I made the message schema best suited to the requirements of Fedora Happiness Packets as discussed here in detail.
Its always best to have every line of code tested. The same goes here. I created multiple tests for the message class I made in the section above. The tests range from basic message format validation to specific project use cases. For inspiration, refer the test cases given in the sample message schema.
The message schema needs to be packaged as the consumers of the messages install that package and use it to validate the message and extract various bits of information. I built the distributions and uploaded the sdist and wheel to PyPI for the message schema of Fedora Happiness Packets.
To verify if messages in our Dockerized project are being sent or not in the local development environment, I set up a separate container for RabbitMQ to listen to the messages. This proved to be a challenge due to the added overhead Docker presented.
I was able to create a new container for RabbitMQ by adding this to docker-compose.yml:
rabbitmq:
image: rabbitmq:alpine
ports:
- "5672:5672"
environment:
RABBITMQ_DEFAULT_PASS: pass
RABBITMQ_DEFAULT_USER: user
RABBITMQ_DEFAULT_VHOST: vhost
I made sure to link the other related containers with this container.
As mentioned previously, I configured amqp_url in config.toml so that messages could be sent to this message broker like this:
amqp_url = "amqp://user:pass@rabbitMq:5672/vhost"
Finally, I configured how messages were published on the bus in Fedora Happiness Packet as described here. For this mainly three things need to be kept in mind:
And that’s it! This is how I was able to integrate Fedora Messaging in Fedora Happiness Packets. A big shout out to Justin W. Flory, Jeremy Cline and Aurélien Bompard for helping me out with this at every instance. Thank you so much!
Hope you find something helpful and relevant for your use case in this blog post!