6

We're trying to consume Azure Service Bus in a Node application. Our requirement is to fetch multiple messages from a queue.

Since Azure SDK for Node doesn't support batch retrieval, we decided to use AMQP. While we're able to fetch messages using Peek Messages as described here (https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-amqp-request-response#message-operations).

What we are noticing is that as soon as messages are fetched, they are getting removed from the queue. I am wondering if anyone has an insight into how we can fetch messages in "PeekLock" mode using AMQP and Node. For AMQP, we're using amqp10 node package (https://www.npmjs.com/package/amqp10).

Here's our code for peeking at the messages:

const AMQPClient = require('amqp10/lib').Client,
Policy = require('amqp10/lib').Policy;

const protocol = 'amqps';
const keyName = 'RootManageSharedAccessKey';
const sasKey = 'My Shared Access Key'
const serviceBusHost = 'account-name.servicebus.windows.net';
const uri = protocol + '://' + encodeURIComponent(keyName) + ':' + encodeURIComponent(sasKey) + '@' + serviceBusHost;
const queueName = 'test1';
var client = new AMQPClient(Policy.ServiceBusQueue);
client.connect(uri)
.then(function () {
    return Promise.all([
        client.createReceiver(queueName),
        client.createSender(queueName)
    ]);
})
.spread(function(receiver, sender) {
    console.log(receiver);
    console.log(sender);
    console.log('--------------------------------------------------------------------------');
    receiver.on('errorReceived', function(err) {
        // check for errors
        console.log(err);
    });
    receiver.on('message', function(message) {
        console.log('Received message');
        console.log(message);
        console.log('------------------------------------');
    });

    return sender.send([], {
        operation: 'com.microsoft:peek-message',
        'message-count': 5
    });
})
.error(function (e) {
    console.warn('connection error: ', e);
});
Jagrati Modi
  • 2,038
  • 1
  • 13
  • 26
  • did you already check this https://www.example-code.com/nodejs/azure_service_bus_peek_lock_message.asp – Aravind Apr 12 '17 at 05:56
  • Thank you Aravind. The code fetches a single message from the queue. This is also available in Azure SDK as well. What we are looking for is fetching multiple messages from a queue. – Jagrati Modi Apr 12 '17 at 06:04
  • While creating queue you have to set EnableBatchedOperations to true. But again on the queue client side you need to set prefetchcount. not sure if that property is enabled in nodejs sdk. Or you can create multiple receivers and try. – Aravind Apr 12 '17 at 10:34
  • Were you able to find a work around? – Dhiren Apr 12 '18 at 05:40
  • @Dhiren By below answer, we were able to fetch the messages but can't unlock and renew the lock on those messages. – Jagrati Modi Apr 13 '18 at 09:17

1 Answers1

1

By default receiver works in auto-settle mode, you have to change it to settle on disposition:

const { Constants } = require('amqp10')

// 
// ...create client, connect, etc...
//

// Second parameter of createReceiver method enables overwriting policy parameters
const receiver = client.createReceiver(queueName, {
  attach: {
    rcvSettleMode: Constants.receiverSettleMode.settleOnDisposition
  }
})

Do not forget to accept/reject/release a message after processing it:

receiver.on('message', msg => {
  //
  // ...do something smart with a message...
  //

  receiver.accept(msg) // <- manually settle a message
})
qzb
  • 8,163
  • 3
  • 21
  • 27
  • thanks @qzb. Creating a receiver link with rcvSettleMode as settleOnDisposition helped. Now the messages are not getting deleted but I'm not able to get the lock token associated with the messages. – Jagrati Modi Jun 12 '17 at 07:22
  • It's a little bit confusing. Apparently, in order to accept/reject a message, AMQP client has to use *delivery-tag*. In case of *amp10* library *delivery-tag* is stored in `msg._deliveryId` field. But it doesn't look like a *lock-token*, it looks like a sequence number. – qzb Jun 12 '17 at 08:33
  • yea, but to renew and unlock message, we need lock-token. And if we can't get lock-token, can't use amqp then to receive message. – Jagrati Modi Jun 13 '17 at 05:34
  • AFAIK, `receiver.release(msg)` unlocks a message. I don't know if you can renew it. – qzb Jun 13 '17 at 05:43
  • As our requirement was to fetch multiple messages, which is not possible by node.js SDK. So we were trying to fetch messages using amqp and later unlock and renew msg lock with node.js SDK . But as we are not getting lock-token we can't use amqp. – Jagrati Modi Jun 13 '17 at 06:36