Permalink
Browse files

[api test] Added basic support for CloudFiles Containers and StorageO…

…bject
  • Loading branch information...
1 parent 65b5c74 commit 71df419b7c97a1b802682d445aa17e031c7f9a79 @indexzero indexzero committed Sep 19, 2010
View
@@ -1,4 +1,4 @@
-# node-cloudservers
+# node-cloudfiles
A client implementation for Rackspace CloudFiles in node.js
View
@@ -5,9 +5,20 @@
* MIT LICENSE
*
*/
-
+
+require.paths.unshift(__dirname);
+
var cloudfiles = exports;
// Core
-cloudfiles.setAuth = require('cloudfiles/core').setAuth;
-cloudfiles.config = require('cloudfiles/config').config;
+cloudfiles.config = require('cloudfiles/config').config;
+cloudfiles.setAuth = require('cloudfiles/core').setAuth;
+
+// Containers
+cloudfiles.Container = require('cloudfiles/container').Container;
+cloudfiles.getContainers = require('cloudfiles/core').getContainers;
+cloudfiles.getContainer = require('cloudfiles/core').getContainer;
+
+// Storage Object
+cloudfiles.StorageObject = require('cloudfiles/storage-object').StorageObject;
+cloudfiles.getFiles = require('cloudfiles/core').getFiles;
@@ -18,12 +18,20 @@ var Container = function (details) {
throw new Error("Container must be constructed with at least basic details.")
}
+ this.files = [];
this._setProperties(details);
};
Container.prototype = {
+ destory: function () {
+
+ },
_setProperties: function (details) {
-
+ this.name = details.name;
+ this.count = details.count;
+ this.bytes = details.bytes;
}
-};
+};
+
+exports.Container = Container;
View
@@ -44,16 +44,47 @@ core.setAuth = function (options, callback) {
cloudfiles.config.storageUrl = res.headers['x-storage-url'];
cloudfiles.config.cdnUrl = res.headers['x-cdn-management-url'];
cloudfiles.config.authToken = res.headers['x-auth-token'];
+ cloudfiles.config.storageToken = res.headers['x-storage-token']
callback(null, res);
});
};
-core.getContainers = function () {
-
+// Remark: What about CDN Containers?
+core.getContainers = function (callback) {
+ utils.rackspace(utils.storageUrl(), callback, function (body) {
+ var results = [], containers = JSON.parse(body);
+ containers.forEach(function (container) {
+ results.push(new (cloudfiles.Container)(container));
+ });
+
+ callback(null, results);
+ });
+};
+
+// Remark: What about CDN Containers?
+core.getContainer = function (container, callback) {
+ utils.rackspace('HEAD', utils.storageUrl(container), callback, function (body, res) {
+ var container = {
+ name: name,
+ count: new Number(res.headers['x-container-object-count']),
+ bytes: new Number(res.headers['x-container-bytes-used'])
+ };
+ callback(null, new (cloudfiles.Container)(container));
+ });
};
-core.getContainer = function (name, callback) {
+core.createContainer = function (container, callback) {
};
+core.getFiles = function (container, callback) {
+ utils.rackspace(utils.storageUrl(container, true), callback, function (body) {
+ var results = [], files = JSON.parse(body);
+ files.forEach(function (file) {
+ file.container = container;
+ results.push(new (cloudfiles.StorageObject)(file));
+ });
+ callback(null, results);
+ });
+};
@@ -22,8 +22,51 @@ var StorageObject = function (details) {
};
StorageObject.prototype = {
+ copy: function (destination, callback) {
+ var copyOptions = {
+ method: 'COPY',
+ uri: this.fullPath,
+ headers: {
+ 'Destination': destination
+ }
+ };
+
+ utils.rackspace(copyOptions, callback, function (body, res) {
+ eyes.inspect(body);
+ eyes.inspect(res.statusCode);
+ });
+ },
- _setProperties: function (details) {
+ destroy: function () {
+ utils.rackspace('DELETE', this.fullPath, callback, function (body, res) {
+ eyes.inspect(body);
+ eyes.inspect(res.statusCode);
+ });
+ },
+
+ // Adds metadata to this instance .... getter / setter?
+ addMetadata: function () {
+
+ },
+
+ // Updates this instance with a new target bytes??
+ update: function () {
+ },
+
+ get fullPath() {
+ var containerName = this.container instanceof cloudfiles.Container ? this.container.name : this.container;
+ return utils.storageUrl(containerName, this.name);
+ },
+
+ _setProperties: function (details) {
+ this.container = details.container;
+ this.name = details.name;
+ this.hash = details.hash;
+ this.bytes = details.bytes;
+ this.contentType = details.content_type;
+ this.lastModified = details.last_modified;
}
-};
+};
+
+exports.StorageObject = StorageObject;
View
@@ -11,6 +11,7 @@ require.paths.unshift(require('path').join(__dirname, '..'));
var cloudfiles = require('cloudfiles'),
sys = require('sys'),
eyes = require('eyes'),
+ url = require('url'),
spawn = require('child_process').spawn,
exec = require('child_process').exec,
request = require('request');
@@ -68,7 +69,7 @@ utils.rackspace = function () {
var args = Array.prototype.slice.call(arguments),
success = (typeof(args[args.length - 1]) === 'function') && args.pop(),
callback = (typeof(args[args.length - 1]) === 'function') && args.pop(),
- uri, method, requestBody;
+ uri, method, requestBody, headers = {};
// Now that we've popped off the two callbacks
// We can make decisions about other arguments
@@ -80,22 +81,24 @@ utils.rackspace = function () {
uri = args[0];
}
else {
- method = args[0]['method'] || 'GET',
+ method = args[0]['method'] || 'GET';
uri = args[0]['uri'];
requestBody = args[0]['body'];
+ headers = args[0]['headers'] || {};
}
}
else {
method = args[0];
uri = args[1];
}
+
+ // Append the X-Auth-Token header for Rackspace authentication
+ headers['X-AUTH-TOKEN'] = cloudfiles.config.authToken;
var serverOptions = {
uri: uri,
method: method,
- headers: {
- 'X-AUTH-TOKEN': cloudfiles.config.authToken
- }
+ headers: headers
};
if (typeof requestBody !== 'undefined') {
@@ -158,9 +161,10 @@ utils.rackspaceCurl = function (method, uri, callback, success) {
// storageUrl.
//
utils.storageUrl = function () {
- var args = args = Array.prototype.slice.call(arguments);
+ var args = Array.prototype.slice.call(arguments),
+ json = (typeof(args[args.length - 1]) === 'boolean') && args.pop();
- return [cloudservers.config.storageUrl].concat(args).join('/');
+ return [cloudfiles.config.storageUrl].concat(args).join('/') + (json ? '?format=json' : '');
};
//
@@ -169,7 +173,8 @@ utils.storageUrl = function () {
// cdnUrl.
//
utils.cdnUrl = function () {
- var args = args = Array.prototype.slice.call(arguments);
+ var args = Array.prototype.slice.call(arguments),
+ json = (typeof(args[args.length - 1]) === 'boolean') && args.pop();
- return [cloudservers.config.cdnUrl].concat(args).join('/');
+ return [cloudfiles.config.cdnUrl].concat(args).join('/') + (json ? '?format=json' : '');
};
@@ -1,5 +1,5 @@
/*
- * authentication-test.js: Tests for rackspace cloudservers authentication
+ * authentication-test.js: Tests for rackspace cloudfiles authentication
*
* (C) 2010 Charlie Robbins
* MIT LICENSE
View
@@ -0,0 +1,52 @@
+/*
+ * container-test.js: Tests for rackspace cloudfiles containers
+ *
+ * (C) 2010 Charlie Robbins
+ * MIT LICENSE
+ *
+ */
+
+var path = require('path'),
+ vows = require('vows'),
+ eyes = require('eyes'),
+ helpers = require('./helpers')
+ assert = require('assert');
+
+require.paths.unshift(path.join(__dirname, '..', 'lib'));
+
+var cloudfiles = require('cloudfiles');
+
+vows.describe('node-cloudfiles/containers').addBatch({
+ "The node-cloudfiles client": {
+ "when authenticated": {
+ topic: function () {
+ var options = cloudfiles.config
+ cloudfiles.setAuth(options.auth, this.callback);
+ },
+ "should return with 204": function (err, res) {
+ assert.equal(res.statusCode, 204);
+ }
+ }
+ }
+}).addBatch({
+ "The node-cloudfiles client": {
+ "the getContainers() method": {
+ topic: function () {
+ cloudfiles.getContainers(this.callback);
+ },
+ "should return a list of containers": function (err, containers) {
+ containers.forEach(function (container) {
+ helpers.assertContainer(container);
+ });
+ }
+ },
+ "the getContainer() method": {
+ topic: function () {
+ cloudfiles.getContainer('test_container', this.callback);
+ },
+ "should return a valid container": function (err, container) {
+ helpers.assertContainer(container);
+ }
+ }
+ }
+}).export(module);
View
@@ -0,0 +1,33 @@
+/*
+ * helpers.js: Test helpers for node-cloudservers
+ *
+ * (C) 2010 Charlie Robbins
+ * MIT LICENSE
+ *
+ */
+
+var path = require('path'),
+ vows = require('vows'),
+ assert = require('assert');
+
+require.paths.unshift(path.join(__dirname, '..', 'lib'));
+
+var cloudfiles = require('cloudfiles');
+
+var helpers = exports;
+
+helpers.assertContainer = function (container) {
+ assert.instanceOf(container, cloudfiles.Container);
+ assert.isNotNull(container.name);
+ assert.isNotNull(container.count);
+ assert.isNotNull(container.bytes);
+};
+
+helpers.assertFile = function (file) {
+ assert.instanceOf(file, cloudfiles.StorageObject);
+ assert.isNotNull(file.name);
+ assert.isNotNull(file.bytes);
+ assert.isNotNull(file.hash);
+ assert.isNotNull(file.lastModified);
+ assert.isNotNull(file.contentType);
+}
@@ -0,0 +1,44 @@
+/*
+ * container-test.js: Tests for rackspace cloudfiles containers
+ *
+ * (C) 2010 Charlie Robbins
+ * MIT LICENSE
+ *
+ */
+
+var path = require('path'),
+ vows = require('vows'),
+ eyes = require('eyes'),
+ helpers = require('./helpers')
+ assert = require('assert');
+
+require.paths.unshift(path.join(__dirname, '..', 'lib'));
+
+var cloudfiles = require('cloudfiles');
+
+vows.describe('node-cloudfiles/storage-object').addBatch({
+ "The node-cloudfiles client": {
+ "when authenticated": {
+ topic: function () {
+ var options = cloudfiles.config
+ cloudfiles.setAuth(options.auth, this.callback);
+ },
+ "should return with 204": function (err, res) {
+ assert.equal(res.statusCode, 204);
+ }
+ }
+ }
+}).addBatch({
+ "The node-cloudfiles client": {
+ "the getFiles() method": {
+ topic: function () {
+ cloudfiles.getFiles('test_container', this.callback);
+ },
+ "should return a valid list of files": function (err, files) {
+ files.forEach(function (file) {
+ helpers.assertFile(file);
+ });
+ }
+ }
+ }
+}).export(module);

0 comments on commit 71df419

Please sign in to comment.