The purpose of this post is to highlight the most common mistakes I experienced with Loopback and RabbitMQ myself.
This error can result from 4 different mistakes:
Check how the Entry for model-config.json should look like below
Check how the Entry for component-config.json should look like below
Check how the Entry for model.json should look like below
If you get [rabbit.unhandled] Message of x on queue y, connection 'default' was not procced by any registered handlers and the messages only get re-queued and redelivered, you have probably connected an api to a queue where you receive message you don´t handle.
Loopback-rabbit-mq picks the next message available on the queues if is connected to, even if you haven´t implemented handling this messages.
So make sure you connect each api only to queues where you handle all message types from. Otherwise one API will eventually block the queue because it gets messages it can´t process.
Check the function you implemented and make sure you return a Promise.resolve if your function succeeded and Promise.reject if it failed.
If the origin of your message is not loopback it might mean you need to use JSON.parse to retrieve the data in the Message. Check how the Code should look like above
This file holds the Information which mixins to load for this project.
This happens inside the "mixins": [] Block
Make sure you load the loopback-component-mq with an entry like this:
"../nodemodules/loopback-component-mq/lib/mixins"
This file holds the general configuration for components that need it.
Make sure you configure loopback-component-mq with an entry like this:
{
"loopback-component-mq":{
"path":"loopback-component-mq",
"options":{
"restPort":15672,
"acls":[
{
"accessType":"",
"principalType":"ROLE",
"principalId":"$unauthenticated",
"permission":"DENY"
}
]
}
},
"topology":{
"connection":{
"uri":"amqp://user:password@host/vhost",
"timeout": timeoutinmilliseconds
},
"exchanges":[
{
"name":"exchangename",
"type":"exchangetype",
"persistent":persistent
}
],
"queues":[
{
"name":"queuename",
"subscribe":true,
"limit":concurrentnonacknoledgedtasknumber
}
],
"bindings":[
{
"exchange":"exchangename",
"target":"queuename",
"keys":[
]
}
],
"logging":{
"adapters":{
"stdOut":{
"level":5,
"bailIfDebug":true
}
}
}
}
}
In the model.json you configure the consumers and producers that this model implements, together with which queue they operate on and which type the message has.
Make sure you configure loopback-rabbit-mq with an entry like this:
{
"mixins":{
"MessageQueue":{
"consumers":{
"nameof_function_to_imlement":{
"queue":"queue_name_from_component_config",
"type":"name_of_message_type"
}
},
"producers":{
"name_of_function_to_imlement":{
"exchange":"exchange_name_from_component_config",
"options":{
"routingKey":"routing_key_name",
"type":"name_of_message_type",
"contentType":"content_type_you_wish"
}
}
}
}
}
}
In the model.js you implement the consumer and producer functions you declared i> the model.json file.
Make sure you implement it with an entry like this:
Model.name_of_function_to_implement = (payload) => {
// If send from Loopback
const { variable_name} = payload
// If send from another source like python
const { variable_name } = JSON.parse(payload)
}
If your queue needs acknowledgements make sure to return a Promise.resolve().
If something went wrong return a Promise.reject(). RabbitMQ redelivers the Message then.