I want to route rabbitmq messages based on headers and I have created a appropriate infrastructure including headers exchange, queues, bindings etc.
Below is the complete code for the consumer.py
import pika
# define variables
url = "amqp://rabbitmq-host/"
exchange = 'headers-exchange',
s_queue = 'StudentQueue'
t_queue = 'TeacherQueue'
# create connection
connection_parameters = pika.URLParameters(url)
connection = pika.BlockingConnection(connection_parameters)
channel = connection.channel()
# declare exchange
channel.exchange_declare(
exchange=exchange,
exchange_type='headers',
durable=True
)
# declare student queue
channel.queue_declare(
queue=s_queue,
durable=True,
)
# bind student queue
channel.queue_bind(
exchange=exchange,
queue=s_queue,
# bind arguments:
# match all the given headers
# match x-queue should be equal to student
arguments={
"x-match": "all",
"x-queue": "student"
},
)
# declare teacher queue
channel.queue_declare(
queue=t_queue,
durable=True,
)
# bind teacher queue
channel.queue_bind(
exchange=exchange,
queue=t_queue,
# bind arguments:
# match all the given headers
# match x-queue should be equal to teacher
arguments={
"x-match": "all",
"x-queue": "teacher"
},
)
and publish module(publish.py
) looks like below:
import datetime
import time
import uuid
import pika
# define variables
url = "amqp://rabbitmq-host/"
exchange = 'headers-exchange',
# create connection
connection_parameters = pika.URLParameters(url)
connection = pika.BlockingConnection(connection_parameters)
channel = connection.channel()
# declare exchange
channel.exchange_declare(
exchange=exchange,
exchange_type='headers',
durable=True
)
# define message id
id_ = uuid.uuid4()
message_id = id_.hex
timestamp = time.mktime(datetime.datetime.now().timetuple())
# define message property esp. headers
properties = pika.BasicProperties(
content_type="application/json",
# match x-queue = student header
# to the StudentQueue
headers={"x-queue": "student"}
message_id=message_id,
timestamp=timestamp,
delivery_mode=2,
)
# publish the message for student queue
channel.basic_publish(
exchange=exchange,
routing_key="",
body="for student queue only",
properties=properties,
)
published message should only be delivered to StudentQueue
because we have headers={"x-queue": "student"}
but it is getting delivered to TeacherQueue
as well which is incorrect.
the list of appication versions are:
RabbitMQ: 3.6.16
Erlang: 20.3.4
Pika: 1.2.1
Could someone point the obvious which I have missed, could it be related to mismatched versions? Any help would be really appreciated.
Cheers, DD.
From the documentation:
For "any" and "all", headers beginning with the string x- will not be used to evaluate matches.
Therefore, in your example in both binding argument and message header change "x-queue": "teacher"
to "queue": "teacher"
(but still leave binding argument "x-match": "all"
as-is).