We have a scenario where we want a node.js app to consume messages from a backend system that currently puts messages to an Websphere MQ queue (through SAP PI).
In MQ 8.0.0.3, there is a beta of AMQP support. https://www.ibm.com/developerworks/community/blogs/messaging/entry/mq_support_for_mq_light_beta_now_available?lang=en
However, I can't find a conclusive answer to how I get assured delivery. The perfect solution would be for the node.js app to register its subscription as durable, but how do I do that? We'll change the queue that SAP PI uses to an alias queue pointing to a topic. Using the mqlight client in node.js, version 1.0
You can achieve assured delivery between MQ applications and Node.js applications using the MQ Light library. MQ Light supports at-least-once messaging (not exactly-once) so you will have to bear this in mind when you design your solution. It will have to handle receiving duplicate messages.
It sounds like you might have read the article on how to bridge MQ to MQ Light which explains some of the MQ queue-to-topic options.
In order to cope with the Node.js application being offline when messages are put by the SAP application, you can create a durable destination when you issue the MQ Light subscribe call. For example:
// Destination and its messages expire 24 hours after Node.js client disconnects
var options = { qos: mqlight.QOS_AT_LEAST_ONCE, autoConfirm: false, ttl: (60 * 60 * 24 * 1000)};
client.subscribe(pattern, share, options, function(err, pattern) {
if (err) {
console.error('Problem with subscribe request: %s', err.message);
process.exit(1);
}
if (pattern) {
if (share) {
console.log('Subscribed to share: %s, pattern: %s', share, pattern);
} else {
console.log('Subscribed to pattern: %s', pattern);
}
}
});
You'll need to make sure that the messages your SAP application puts do not have an expiry time (i.e. they set MQEI_UNLIMITED
). Otherwise they could expire from the destination before the Node.js app has had a chance to consume it.
Secondly note how I've used autoConfirm: false
in the above example. That means that if the Node.js application gets a message from its destination, the message will not be deleted from the destination until you explicitly call message.confirmDelivery()
in your MQ Light app. That allows you to make sure the message has been processed completely in the Node.js app (you've written it to a file, or to a database, or done whatever you need to do with it) before removing it from MQ.
As you say, the MQ Light feature in MQ is still in beta and is not currently supported by IBM. However there is a statement of direction to say that it will be a supported feature in the future.