Skip to content

Commit

Permalink
started refactoring the libraries and tests to utilize the async module
Browse files Browse the repository at this point in the history
  • Loading branch information
supernomad committed Jun 24, 2015
1 parent 9c9fcff commit e0276fc
Show file tree
Hide file tree
Showing 2 changed files with 307 additions and 246 deletions.
249 changes: 145 additions & 104 deletions routes/chunked-upload-routes.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* global Buffer */
var apiModels = require.main.require('libs/models/apiModels'),
var async = require('async'),
apiModels = require.main.require('libs/models/apiModels'),
errorModels = require.main.require('libs/models/errorModels'),
guidHelper = require.main.require('libs/helpers/guidHelper'),
errorHelper = require.main.require('libs/helpers/errorHelper'),
Expand All @@ -14,126 +15,166 @@ var debug = false,
dataCache = null;

var routes = {
"get": new apiModels.RouteHandler(routePrefix + "/:uploadId", function (req, res) {
if (!guidHelper.isGuid(req.params.uploadId)){
throw errorModels.ValidationError("The supplied uploadId is not a valid v4 GUID");
"get": new apiModels.RouteHandler(routePrefix + "/:uploadId", function (req, res, next) {
if (!guidHelper.isGuid(req.params.uploadId)) {
next(errorModels.ValidationError("The supplied uploadId is not a valid v4 GUID"));
} else {
dataCache.restore(req.params.uploadId, function name(error, upload) {
if(typeHelper.doesExist(error)) {
next(error);
} else if(!typeHelper.doesExist(upload.value)) {
next(errorModels.UploadMissing());
} else {
res.json(new apiModels.ApiResponse(routePrefix, {}, upload.value));
}
});
}

dataCache.restore(req.params.uploadId, function name(error, upload) {
errorHelper.genericErrorHandler(error, debug);
if(typeHelper.doesExist(upload.value)){
res.json(new apiModels.ApiResponse(routePrefix, {}, upload.value));
} else {
throw errorModels.UploadMissing();
}
});
}),
"post": new apiModels.RouteHandler(routePrefix, function (req, res) {
var valid = validators.validateUploadRequest(req.body);
if(valid !== validators.valid) {
throw errorModels.ValidationError(valid);
"post": new apiModels.RouteHandler(routePrefix, function (req, res, next) {
var validity = validators.validateUploadRequest(req.body);
if(validity !== validators.valid) {
next(errorModels.ValidationError(validity));
} else {
var upload = new apiModels.Upload(req.body);
upload.configure(guidHelper.newGuid());

async.waterfall([
function(callback) {
dataCache.create(upload.id, upload, defaultTtl, function (error, success) {
if(!success) {
callback(errorModels.ServerError());
} else {
callback(error, upload);
}
});
},
function(upload, callback) {
var buff = new Buffer(upload.fileSize);
buff.fill(0);

io.CreateFile(upload.tempPath, buff, 0, buff.length, function(error) {
callback(error, upload);
});
}
], function(error, upload) {
if(typeHelper.doesExist(error)) next(error);
res.json(new apiModels.ApiResponse(routePrefix, {}, upload.id));
});
}

var upload = new apiModels.Upload(req.body);
upload.configure(guidHelper.newGuid());

dataCache.create(upload.id, upload, defaultTtl, function (error, success) {
errorHelper.genericErrorHandler(error);
if(success) {
var buff = new Buffer(upload.fileSize);
buff.fill(0);
io.CreateFile(upload.tempPath, buff, 0, buff.length, function(createError) {
errorHelper.genericErrorHandler(createError);
res.json(new apiModels.ApiResponse(routePrefix, {}, upload.id));
});
} else {
throw errorModels.ServerError();
}
});
}),
"put": new apiModels.RouteHandler(routePrefix + "/:uploadId/:index", function (req, res) {
var valid = validators.validateChunkRequest(req);
"put": new apiModels.RouteHandler(routePrefix + "/:uploadId/:index", function (req, res, next) {
var validity = validators.validateChunkRequest(req);
var index = parseInt(req.params.index);
if(valid !== validators.valid) {
throw errorModels.ValidationError(valid);
if(validity !== validators.valid) {
next(errorModels.ValidationError(validity));
} else if (!guidHelper.isGuid(req.params.uploadId)){
throw errorModels.ValidationError("The supplied uploadId is not a valid v4 GUID");
next(errorModels.ValidationError("The supplied uploadId is not a valid v4 GUID"));
} else if (!typeHelper.isNumber(index)) {
throw errorModels.ValidationError("The supplied index is not a valid number");
}

dataCache.restore(req.params.uploadId, function(error, keyVal) {
if(typeHelper.doesExist(keyVal.value)) {
errorHelper.genericErrorHandler(error, debug);
var file = {};
var upload = keyVal.value;
for (var key in req.files) {
if (req.files.hasOwnProperty(key)) {
file = req.files[key];
break;
}
}

function readCallback(error, data) {
errorHelper.genericErrorHandler(error, debug);
io.WriteFileChunk(upload.TempPath, data, 0, data.length, index * upload.ChunkSize, writeChunkCallback);
next(errorModels.ValidationError("The supplied index is not a valid number"));
} else {
var file = {};
for (var key in req.files) {
if (req.files.hasOwnProperty(key)) {
file = req.files[key];
break;
}

function writeChunkCallback(error) {
errorHelper.genericErrorHandler(error, debug);
if (upload.chunks.every(function(val){
return val === true;
}))
{
io.RenameFile(upload.TempPath, upload.FinalPath, renameCallback);
}
async.waterfall([
function(callback) {
dataCache.restore(req.params.uploadId, function(error, upload) {
if(typeHelper.doesExist(error)) {
callback(error);
} else if(!typeHelper.doesExist(upload.value)) {
callback(errorModels.UploadMissing());
} else {
callback(null, upload.value);
}
});
},
function(upload, callback) {
upload.chunks[index] = true;
dataCache.update(upload.Id, upload, defaultTtl, function(error, success) {
if(typeHelper.doesExist(error)) {
callback(error);
} else if(!success) {
callback(errorModels.ServerError());
} else {
callback(null, upload);
}
});
},
function(upload, callback) {
io.ReadFile(file.path, function(error, data) {
callback(error, upload, data);
});
},
function(upload, data, callback) {
io.WriteFileChunk(upload.TempPath, data, 0, data.length, index * upload.ChunkSize, function(error) {
callback(error, upload);
});
},
function(upload, callback) {
async.every(upload.chunks, function(item, call) {
call(item === true);
}, function(result) {
callback(null, upload, result);
});
},
function(upload, complete, callback) {
if(complete) {
async.series([
function(call) {
io.RenameFile(upload.TempPath, upload.FinalPath, function(error) {
call(error);
});
},
function(call) {
dataCache.delete(upload.id, function(error, count) {
call(error);
});
}
], function(error, results) {
callback(error, upload, complete);
});
} else {
res.json(new apiModels.ApiResponse(routePrefix, {}, "Chunk Recieved"));
callback(null, upload, complete);
}
}

function renameCallback(error) {
errorHelper.genericErrorHandler(error, debug);
dataCache.delete(upload.id, function(error, count) {
errorHelper.genericErrorHandler(error, debug);
});

], function(error, upload, complete) {
if(typeHelper.doesExist(error)) next(error);
else if(complete) {
res.json(new apiModels.ApiResponse(routePrefix, {}, "Upload Complete"));
};


upload.chunks[index] = true;
dataCache.update(upload.Id, upload, defaultTtl, function(error, success) {
errorHelper.genericErrorHandler(error, debug);

if(success) {
io.ReadFile(file.path, readCallback);
} else {
throw errorModels.ServerError();
}
});
} else {
throw errorModels.UploadMissing();
}
});
} else {
res.json(new apiModels.ApiResponse(routePrefix, {}, "Chunk Recieved"));
}
});
}
}),
"delete": new apiModels.RouteHandler(routePrefix + "/:uploadId", function (req, res) {
"delete": new apiModels.RouteHandler(routePrefix + "/:uploadId", function (req, res, next) {
if (!guidHelper.isGuid(req.params.uploadId)){
throw errorModels.ValidationError("The supplied uploadId is not a valid v4 GUID");
}

dataCache.restore(req.params.uploadId, function name(error, upload) {
errorHelper.genericErrorHandler(error, debug);

dataCache.delete(upload.id, function (error, count) {
errorHelper.genericErrorHandler(error);
if(count === 1) {
next(errorModels.ValidationError("The supplied uploadId is not a valid v4 GUID"));
} else {
async.waterfall([
function(callback) {
dataCache.restore(req.params.uploadId, function name(error, upload) {
callback(error, upload);
});
},
function(upload, callback) {
dataCache.delete(upload.id, function (error, count) {
callback(error, upload);
});
},
function(upload, callback) {
io.DeleteFile(upload.tempPath, function(deleteError) {
errorHelper.genericErrorHandler(deleteError);
res.json(new apiModels.ApiResponse(routePrefix, {}, "Upload: " + req.params.uploadId + ", deleted successfuly."));
callback(deleteError);
});
}
], function(error) {
if(typeHelper.doesExist(error)) next(error);
res.json(new apiModels.ApiResponse(routePrefix, {}, "Upload: " + req.params.uploadId + ", deleted successfuly."));
});
});
}
}),
"error": new apiModels.ErrorHandler(function (error, req, res, next) {
if(error instanceof errorModels.GenericError) {
Expand All @@ -143,7 +184,7 @@ var routes = {
Message: error.Message
});
} else {
next();
next(error);
}
})
};
Expand Down
Loading

0 comments on commit e0276fc

Please sign in to comment.