imago-azure-storage
Version:
An opinionated async wrapper for azure-storage for working with Azure Storage such as tables and queues.
126 lines (113 loc) • 3.69 kB
JavaScript
/* eslint no-param-reassign:0 */
const Azure = require('azure-storage');
const { base64encode, base64decode } = require('nodejs-base64');
class AzureQueueService {
constructor(storageAccount, storageAccessKey) {
try {
this.service = Azure.createQueueService(storageAccount, storageAccessKey);
this.storageAccount = storageAccount;
} catch (error) {
console.log('Error initializing Azure Table Storage: ', error);
throw error;
}
}
/**
* Creates queues if they don't exist yet.
* @param {string[]} queues
*/
async initializeQueues(queues) {
for (const queue of queues) {
/* eslint-disable-next-line no-await-in-loop */
await new Promise((resolve, reject) => {
console.log(`Initializing queue ${queue}...`);
this.service.createQueueIfNotExists(queue, (error) => {
if (error) {
reject(error);
} else {
resolve(error);
}
});
});
}
}
/**
* Places a message into the queue.
* @param {string} queue - Name of the queue.
* @param {string|object} message - A string or object up to 48 kilobytes in
* size.
*/
put(queue, message) {
let messageText;
if (typeof message === 'object') {
messageText = base64encode(JSON.stringify(message));
} else if (message === null || message === undefined) {
messageText = base64encode('');
} else {
messageText = base64encode(message);
}
return new Promise((resolve, reject) => {
this.service.createMessage(queue, messageText, (error) => {
if (error) {
reject(error);
} else {
resolve();
}
});
});
}
/**
* Fetches available items from queue.
* @param {string} queue - Name of the queue.
* @param {number} [numOfMessages] - How many items to retrieve (up to 32)
* @param {number} [visibilityTimeout] num- Timeout in seconds after which messages will
* be requeued if not committed.
*/
fetch(queue, numOfMessages, visibilityTimeout) {
const options = {};
if (numOfMessages) {
options.numOfMessages = numOfMessages;
}
if (visibilityTimeout) {
options.visibilityTimeout = visibilityTimeout;
}
return new Promise((resolve, reject) => {
this.service.getMessages(queue, options, (error, messages) => {
if (error) {
reject(error);
} else {
messages = messages || [];
const parsedMessages = messages.map((message) => {
let item = base64decode(message.messageText);
try {
item = JSON.parse(item);
} catch (e) {
// ignore - sometimes we could save plain string data
}
message.queue = queue; // will be needed when deleting
// Item is the data and message can be used to delete the message
// from queue.
return { item, message };
});
resolve(parsedMessages);
}
});
});
}
/**
* Deletes message from the queue. You should call this after you finished
* processing the message.
* @param {object} message - The message object returned from the queue.
*/
commit(message) {
return new Promise((resolve, reject) => {
this.service.deleteMessage(message.queue, message.messageId, message.popReceipt, (error) => {
if (error) {
reject(error);
} else {
resolve();
}
});
});
}
}
module.exports = AzureQueueService;