Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

# adding service calls for queues + error handling helper on core-ser…

…vice
  • Loading branch information...
commit 1847b059f9382f1b3a339a6ecbfb32bebba253e4 1 parent 2108e70
Juan Pablo Garcia Dalolla authored
View
4 lib/waz-queues/index.js
@@ -0,0 +1,4 @@
+exports.load = function(base) {
+ exports.container = require('./queues').load(base);
+ return this;
+}
View
84 lib/waz-queues/service.js
@@ -0,0 +1,84 @@
+var utils = require('../waz-storage/utils')
+ , xml2js = require('xml2js')
+ , _ = require('underscore')
+ , CoreService = require('../waz-storage/core-service');
+
+exports = module.exports = Service;
+
+function Service(options) {
+ this.options = options;
+ this.init();
+}
+
+Service.prototype = new CoreService;
+
+Service.prototype.list = function(options, callback){
+ var options = {comp: 'list'}.merge(options);
+ var service = this;
+
+ service.execute('get', null, options, {'x-ms-version': '2009-09-19'}, null, function(response) {
+ if (service.parseError(response, callback))
+ return;
+
+ new xml2js.Parser().on('end', function(result) {
+ callback(null, result);
+ }).parseString(response.body);
+ });
+};
+
+Service.prototype.create = function(name, metadata, callback){
+ var service = this;
+
+ service.execute('put', name, null, {'x-ms-version': '2009-09-19'}.merge(metadata), null, function(response) {
+ if (service.parseError(response, callback))
+ return;
+
+ callback(null);
+ });
+};
+
+Service.prototype.delete = function(name, callback){
+ var service = this;
+
+ service.execute('delete', name, null, {'x-ms-version': '2009-09-19'}, null, function(response) {
+ if (service.parseError(response, callback))
+ return;
+
+ callback(null);
+ });
+};
+
+Service.prototype.getMetadata = function(name, callback){
+ var service = this;
+
+ service.execute('get', name, {comp: 'metadata'}, {'x-ms-version': '2009-09-19'}, null, function(response) {
+ if (service.parseError(response, callback))
+ return;
+
+ callback(null);
+ });
+};
+
+Service.prototype.putMetadata = function(name, metadata, callback){
+ var service = this;
+
+ service.execute('put', name, {comp: 'metadata'}, {'x-ms-version': '2009-09-19'}.merge(metadata), null, function(response) {
+ if (service.parseError(response, callback))
+ return;
+
+ callback(null);
+ });
+};
+
+Service.prototype.putMessage = function(name, message, messagettl, callback){
+ var service = this;
+
+ var payload = '<QueueMessage><MessageText>' + message + '</MessageText></QueueMessage>';
+
+ service.execute('put', name + '/messages', {messagettl: messagettl}, {'x-ms-version': '2009-09-19'}, payload, function(response) {
+ if (service.parseError(response, callback))
+ return;
+
+ callback(null);
+ });
+};
View
28 lib/waz-storage/core-service.js
@@ -2,7 +2,8 @@ var crypto = require('crypto')
, querystring = require('querystring')
, http = require('http')
, https = require('https')
- , url = require('url')
+ , url = require('url')
+ , xml2js = require('xml2js')
, utils = require('./utils');
exports.CoreService = new CoreService;
@@ -149,6 +150,21 @@ CoreService.prototype.generateRequestOptions = function(verb, path, query, heade
};
}
+CoreService.prototype.parseError = function(response, callback){
+ if (response.statusCode < 400)
+ return false;
+
+ if (!response.body) {
+ callback({Code: response.statusCode, Message: 'An error ocurred'});
+ } else {
+ new xml2js.Parser().on('end', function(result) {
+ callback(result);
+ }).parseString(response.body);
+ }
+
+ return true;
+}
+
CoreService.prototype.execute = function(verb, path, query, headers, payload, callback){
this.init();
var error, data;
@@ -163,12 +179,10 @@ CoreService.prototype.execute = function(verb, path, query, headers, payload, ca
});
response.addListener('end', function () {
- if (response.statusCode >= 400)
- error = { statusCode: response.statusCode };
- else
- data = { headers: response.headers, body: body.join(""), statusCode: response.statusCode };
-
- callback(error, data);
+ var response = reponse.merge({body: body.join("")});
+
+ // TODO: remove on parameter previously used to return err as the first parameter
+ callback(response, response);
});
});
View
226 test/waz-queues/service.test.js
@@ -0,0 +1,226 @@
+var waz = require('waz-storage')
+ , assert = require('assert')
+ , sinon = require('sinon')
+ , Service = require('waz-queues/service');
+
+module.exports = {
+
+ 'should list queues': function(){
+ var mockResponse = '<?xml version="1.0" encoding="utf-8"?> \
+ <EnumerationResults AccountName="http://myaccount.queue.core.windows.net"> \
+ <Prefix>q</Prefix> \
+ <MaxResults>3</MaxResults> \
+ <Queues> \
+ <Queue> \
+ <Name>q1</Name> \
+ <Url>http://myaccount.queue.core.windows.net/q1</Url> \
+ <Metadata> \
+ <Color>red</Color> \
+ <SomeMetadataName>SomeMetadataValue</SomeMetadataName> \
+ <Metadata> \
+ </Queue> \
+ <Queue> \
+ <Name>q2</Name> \
+ <Url>http://myaccount.queue.core.windows.net/q2</Url> \
+ <Metadata> \
+ <Color>blue</Color> \
+ <SomeMetadataName>SomeMetadataValue</SomeMetadataName> \
+ <Metadata> \
+ </Queue> \
+ <Queue> \
+ <Name>q3</Name> \
+ <Url>http://myaccount.queue.core.windows.net/q3</Url> \
+ <Metadata> \
+ <Color>yellow</Color> \
+ <SomeMetadataName>SomeMetadataValue</SomeMetadataName> \
+ <Metadata> \
+ </Queue> \
+ </Queues> \
+ <NextMarker>q4</NextMarker> \
+ </EnumerationResults>';
+
+ var mockData = { body: mockResponse, headers: {'x-ms-request-id': 'id', 'x-ms-version': '2009-09-19', 'Date': 'date' } , statusCode: 200};
+
+ var service = new Service({});
+ var mock = sinon.mock(service);
+
+ mock.expects("execute").withArgs('get', null, { comp: 'list', prefix: 'q' }, {'x-ms-version': '2009-09-19'}, null)
+ .yields({statusCode: 200, body: mockData})
+ .once();
+
+ var options = { prefix: 'q' };
+
+ service.list(options, function(err, data){
+ assert.isNull(err);
+ assert.equal(data['@'].AccountName, 'http://myaccount.queue.core.windows.net');
+ assert.equal(data.Prefix, 'q');
+ assert.equal(data.Marker, undefined);
+ assert.equal(data.NextMarker, 'q4');
+
+ assert.equal(data.MaxResults, 3);
+ assert.equal(data.Queues.Queue.length, 3);
+
+ assert.equal(data.Queues.Queue[0].Name, 'q1');
+ assert.equal(data.Queues.Queue[0].Url, 'http://myaccount.queue.core.windows.net/q1');
+ assert.equal(data.Queues.Queue[0].Metadata.Color, 'red');
+ assert.equal(data.Queues.Queue[0].Metadata.SomeMetadataName, 'SomeMetadataValue');
+ });
+
+ mock.verify();
+ },
+
+ 'should return an error when list fails': function(){
+ var service = new Service({});
+ var mock = sinon.mock(service);
+
+ mock.expects("execute").yields({statusCode: 400}).once();
+
+ service.list(null, function(err, data){
+ assert.equal(err.Code, 400)
+ });
+
+ mock.verify();
+ },
+
+ 'should create a queue with given metadata': function(){
+ var service = new Service({});
+ var mock = sinon.mock(service);
+
+ mock.expects("execute").withArgs('put', 'queue1', null, { 'x-ms-version': '2009-09-19', 'x-ms-meta-name': 'value' }, null)
+ .yields({statusCode: 201})
+ .once();
+
+ service.create('queue1', {'x-ms-meta-name': 'value'}, function(err){
+ assert.equal(err, null);
+ });
+
+ mock.verify();
+ },
+
+ 'should return an error when create fails': function(){
+ var service = new Service({});
+ var mock = sinon.mock(service);
+
+ mock.expects("execute").yields({statusCode: 400}).once();
+
+ service.create('queue1', null, function(err){
+ assert.equal(err.Code, 400);
+ });
+
+ mock.verify();
+ },
+
+ 'should delete a queue': function(){
+ var service = new Service({});
+ var mock = sinon.mock(service);
+
+ mock.expects("execute").withArgs('delete', 'queue1', null, { 'x-ms-version': '2009-09-19' }, null)
+ .yields({statusCode: 204})
+ .once();
+
+ service.delete('queue1', function(err){
+ assert.equal(err, null);
+ });
+
+ mock.verify();
+ },
+
+ 'should return an error when delete fails': function(){
+ var service = new Service({});
+ var mock = sinon.mock(service);
+
+ mock.expects("execute").yields({statusCode: 404}).once();
+
+ service.delete('queue1', function(err){
+ assert.equal(err.Code, 404);
+ });
+
+ mock.verify();
+ },
+
+ 'should get queue metadata': function(){
+ var service = new Service({});
+ var mock = sinon.mock(service);
+
+ mock.expects("execute").withArgs('get', 'queue1', {comp: 'metadata'}, { 'x-ms-version': '2009-09-19' }, null)
+ .yields({statusCode: 200, headers: { 'x-ms-approximate-message-count': 10, 'x-ms-meta-name': 'value' }})
+ .once();
+
+ service.getMetadata('queue1', function(err){
+ assert.equal(err, null);
+ });
+
+ mock.verify();
+ },
+
+ 'should return an error when retrieving metadata': function(){
+ var service = new Service({});
+ var mock = sinon.mock(service);
+
+ mock.expects("execute").yields({statusCode: 404}).once();
+
+ service.getMetadata('queue1', function(err){
+ assert.equal(err.Code, 404);
+ });
+
+ mock.verify();
+ },
+
+ 'should set queue metadata': function(){
+ var service = new Service({});
+ var mock = sinon.mock(service);
+
+ mock.expects("execute").withArgs('put', 'queue1', {comp: 'metadata'}, { 'x-ms-version': '2009-09-19', 'x-ms-meta-name': 'value' }, null)
+ .yields({statusCode: 200, headers: { 'x-ms-version': '2009-09-19', 'x-ms-request-id': 'id'}})
+ .once();
+
+ service.putMetadata('queue1', {'x-ms-meta-name': 'value'},function(err){
+ assert.equal(err, null);
+ });
+
+ mock.verify();
+ },
+
+ 'should return an error when setting metadata': function(){
+ var service = new Service({});
+ var mock = sinon.mock(service);
+
+ mock.expects("execute").yields({statusCode: 404}).once();
+
+ service.putMetadata('queue1', {'x-ms-meta-name': 'value'}, function(err){
+ assert.equal(err.Code, 404);
+ });
+
+ mock.verify();
+ },
+
+ 'should add a new message on a queue': function(){
+ var service = new Service({});
+ var mock = sinon.mock(service);
+
+ var expectedPayload = '<QueueMessage><MessageText>message-content</MessageText></QueueMessage>'
+
+ mock.expects("execute").withArgs('put', 'queue1/messages', {messagettl: 10}, { 'x-ms-version': '2009-09-19', }, expectedPayload)
+ .yields({statusCode: 201, headers: { 'x-ms-version': '2009-09-19', 'x-ms-request-id': 'id'}})
+ .once();
+
+ service.putMessage('queue1', 'message-content', 10, function(err){
+ assert.equal(err, null);
+ });
+
+ mock.verify();
+ },
+
+ 'should return an error when adding a new message': function(){
+ var service = new Service({});
+ var mock = sinon.mock(service);
+
+ mock.expects("execute").yields({statusCode: 400}).once();
+
+ service.putMessage('queue1', 'message-content', 10, function(err){
+ assert.equal(err.Code, 400);
+ });
+
+ mock.verify();
+ },
+}
View
29 test/waz-storage/core-service.test.js
@@ -145,4 +145,33 @@ module.exports = {
assert.equal(requestOptions.headers['Content-Length'], 0);
},
+
+ 'should return false when statusCode is less than 400' : function(){
+ var error = new CoreService({}).parseError({statusCode: 100});
+ assert.ok(!error);
+ },
+
+ 'should return true when statusCode equals 400' : function(){
+ var error = new CoreService({}).parseError({statusCode: 400},function(err){
+ assert.equal(err.Code, 400);
+ assert.equal(err.Message, 'An error ocurred');
+ });
+
+ assert.ok(error);
+ },
+
+ 'should return true when statusCode is grater than 400' : function(){
+ var mockBody = '<?xml version="1.0" encoding="utf-8"?> \
+ <Error> \
+ <Code>InvalidMarker</Code> \
+ <Message>InvalidMarker Message</Message> \
+ </Error>';
+
+ var error = new CoreService({}).parseError({statusCode: 404, body: mockBody}, function(err){
+ assert.equal(err.Code, 'InvalidMarker');
+ assert.equal(err.Message, 'InvalidMarker Message');
+ });
+
+ assert.ok(error);
+ },
}
Please sign in to comment.
Something went wrong with that request. Please try again.