azurite
Version:
An open source Azure Storage API compatible server
238 lines • 9.24 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const StorageErrorFactory_1 = tslib_1.__importDefault(require("../../queue/errors/StorageErrorFactory"));
const QueueStorageContext_1 = tslib_1.__importDefault(require("../context/QueueStorageContext"));
const constants_1 = require("../utils/constants");
const BaseHandler_1 = tslib_1.__importDefault(require("./BaseHandler"));
/**
* QueueHandler handles Azure Storage queue related requests.
*
* @export
* @class QueueHandler
* @implements {IQueueHandler}
*/
class QueueHandler extends BaseHandler_1.default {
/**
* Create a queue with queueName.
*
* @param {Models.QueueCreateOptionalParams} options
* @param {Context} context
* @returns {Promise<Models.QueueCreateResponse>}
* @memberof QueueHandler
*/
async create(options, context) {
const queueCtx = new QueueStorageContext_1.default(context);
const accountName = queueCtx.account;
const queueName = queueCtx.queue;
const req = context.request;
const rawHeaders = req.req.rawHeaders;
// The same as Azure Storage, should preserve the case of metadata names with them created.
const metadata = this.parseMetadata(options.metadata, rawHeaders);
const queue = {
accountName,
name: queueName,
metadata
};
const statusCode = await this.metadataStore.createQueue(queue, context);
const response = {
date: context.startTime,
requestId: queueCtx.contextID,
statusCode,
version: constants_1.QUEUE_API_VERSION,
clientRequestId: options.requestId
};
return response;
}
/**
* Delete a queue according to its name.
*
* @param {Models.QueueDeleteMethodOptionalParams} options
* @param {Context} context
* @returns {Promise<Models.QueueDeleteResponse>}
* @memberof QueueHandler
*/
async delete(options, context) {
const queueCtx = new QueueStorageContext_1.default(context);
const accountName = queueCtx.account;
const queueName = queueCtx.queue;
await this.metadataStore.deleteQueue(accountName, queueName, context);
const response = {
date: context.startTime,
requestId: context.contextID,
statusCode: 204,
version: constants_1.QUEUE_API_VERSION,
clientRequestId: options.requestId
};
return response;
}
/**
* Get queue metadata.
*
* @param {Models.QueueGetPropertiesOptionalParams} options
* @param {Context} context
* @returns {Promise<Models.QueueGetPropertiesResponse>}
* @memberof QueueHandler
*/
async getProperties(options, context) {
const queueCtx = new QueueStorageContext_1.default(context);
const accountName = queueCtx.account;
const queueName = queueCtx.queue;
const queue = await this.metadataStore.getQueue(accountName, queueName, context);
const response = {
approximateMessagesCount: await this.metadataStore.getMessagesCount(queue.accountName, queue.name),
metadata: queue.metadata,
date: context.startTime,
requestId: context.contextID,
statusCode: 200,
version: constants_1.QUEUE_API_VERSION,
clientRequestId: options.requestId
};
return response;
}
/**
* Get queue metadata with Head.
*
* @param {Models.QueueGetPropertiesWithHeadOptionalParams} options
* @param {Context} context
* @returns {Promise<Models.QueueGetPropertiesWithHeadResponse>}
* @memberof QueueHandler
*/
async getPropertiesWithHead(options, context) {
return this.getProperties(options, context);
}
/**
* Set queue metadata.
*
* @param {Models.QueueSetMetadataOptionalParams} options
* @param {Context} context
* @returns {Promise<Models.QueueSetMetadataResponse>}
* @memberof QueueHandler
*/
async setMetadata(options, context) {
const queueCtx = new QueueStorageContext_1.default(context);
const accountName = queueCtx.account;
const queueName = queueCtx.queue;
const req = context.request;
const rawHeaders = req.req.rawHeaders;
const metadata = this.parseMetadata(options.metadata, rawHeaders);
await this.metadataStore.setQueueMetadata(accountName, queueName, metadata, context);
const response = {
date: context.startTime,
requestId: context.contextID,
statusCode: 204,
version: constants_1.QUEUE_API_VERSION,
clientRequestId: options.requestId
};
return response;
}
/**
* Get queue access policies.
*
* @param {Models.QueueGetAccessPolicyOptionalParams} options
* @param {Context} context
* @returns {Promise<Models.QueueGetAccessPolicyResponse>}
* @memberof ContainerHandler
*/
async getAccessPolicy(options, context) {
const queueCtx = new QueueStorageContext_1.default(context);
const accountName = queueCtx.account;
const queueName = queueCtx.queue;
const queue = await this.metadataStore.getQueue(accountName, queueName, context);
const response = [];
const responseArray = response;
const responseObject = response;
if (queue.queueAcl !== undefined) {
responseArray.push(...queue.queueAcl);
}
responseObject.date = context.startTime;
responseObject.requestId = context.contextID;
responseObject.version = constants_1.QUEUE_API_VERSION;
responseObject.statusCode = 200;
responseObject.clientRequestId = options.requestId;
return response;
}
/**
* Get queue access policies with Head.
*
* @param {Models.QueueGetAccessPolicyWithHeadOptionalParams} options
* @param {Context} context
* @returns {Promise<Models.QueueGetAccessPolicyWithHeadResponse>}
* @memberof QueueHandler
*/
async getAccessPolicyWithHead(options, context) {
return this.getAccessPolicy(options, context);
}
/**
* Set queue access policies.
*
* @param {Models.QueueSetAccessPolicyOptionalParams} options
* @param {Context} context
* @returns {Promise<Models.QueueSetAccessPolicyResponse>}
* @memberof ContainerHandler
*/
async setAccessPolicy(options, context) {
const queueCtx = new QueueStorageContext_1.default(context);
const accountName = queueCtx.account;
const queueName = queueCtx.queue;
// The policy number should be within 5, the permission should follow the Queue permission.
// See as https://docs.microsoft.com/en-us/rest/api/storageservices/create-service-sas.
if (options.queueAcl !== undefined) {
if (options.queueAcl.length > 5) {
throw StorageErrorFactory_1.default.getInvalidXmlDocument(context.contextID);
}
for (const acl of options.queueAcl) {
const permission = acl.accessPolicy.permission;
if (permission !== undefined) {
for (const item of permission) {
if (!constants_1.QUEUE_SERVICE_PERMISSION.includes(item)) {
throw StorageErrorFactory_1.default.getInvalidXmlDocument(context.contextID);
}
}
}
}
}
await this.metadataStore.setQueueACL(accountName, queueName, options.queueAcl, context);
const response = {
date: context.startTime,
requestId: context.contextID,
version: constants_1.QUEUE_API_VERSION,
statusCode: 204,
clientRequestId: options.requestId
};
return response;
}
/**
* Parse and retrieve the original metadata name headers array to preserve its case.
*
* @private
* @param {({ [propertyName: string]: string } | undefined)} reqMetadata
* @param {{ [id: string]: string }} headers
* @returns
* @memberof QueueHandler
*/
parseMetadata(reqMetadata, headers) {
if (reqMetadata === undefined) {
return undefined;
}
// TODO: Should take care about the robustness.
const metaPrefix = constants_1.HeaderConstants.X_MS_META;
const metadata = {};
for (const item in reqMetadata) {
if (reqMetadata.hasOwnProperty(item)) {
for (const id in headers) {
if (headers.hasOwnProperty(id)) {
const name = headers[id];
if (metaPrefix + item === name.toLowerCase()) {
metadata[name.substr(metaPrefix.length)] = reqMetadata[item];
break;
}
}
}
}
}
return metadata;
}
}
exports.default = QueueHandler;
//# sourceMappingURL=QueueHandler.js.map