UNPKG

on-http-y1

Version:
262 lines (215 loc) 8.03 kB
// Copyright 2015, EMC, Inc. 'use strict'; var di = require('di'), crypto = require('crypto'), stream = require('stream'), util = require('util'); module.exports = factory; di.annotate(factory, new di.Provide('fileService')); di.annotate(factory, new di.Inject( "Assert", "_", di.Injector, 'Errors', 'Constants' ) ); function HashStream() { this.md5 = crypto.createHash('md5'); this.sha256 = crypto.createHash('sha256'); stream.Transform.call(this); return this; } util.inherits(HashStream, stream.Transform); HashStream.prototype._transform = function (chunk, encoding, done) { this.md5.update(chunk); this.sha256.update(chunk); this.push(chunk); done(); }; HashStream.prototype._flush = function (done) { this.hashes = { md5: this.md5.digest('hex'), sha256: this.sha256.digest('hex') }; done(); }; function factory(assert, _, injector, Errors, Constants) { function FileStreamer() { this.injectorMap = { FileSystem: 'Files.FS' }; this.backEnds = {}; this.defaultBackend = 'defaultBackend'; return this; } FileStreamer.prototype.get = function(uuid, backend) { backend = backend || this.defaultBackend; assert.ok(backend in this.backEnds, "fileService backend"); return this.backEnds[backend].get(uuid); }; FileStreamer.prototype.put = function(rdStream, filename, backend) { backend = backend || this.defaultBackend; assert.ok(backend in this.backEnds, "fileService backend"); var hashStream = new HashStream(); return this.backEnds[backend].put(filename) .then(function(streamObj) { assert.object(streamObj, "write stream object"); hashStream.on('end', function() { streamObj.stream.emit('metadata', hashStream.hashes); }); hashStream.pipe(streamObj.stream); return { writeStream:streamObj.stream, transformHashStream: hashStream, id: streamObj.id }; }); }; FileStreamer.prototype.delete = function(uuid, backend) { backend = backend || this.defaultBackend; assert.ok(backend in this.backEnds, "fileService backend"); return this.backEnds[backend].delete(uuid); }; FileStreamer.prototype.verify = function(uuid, backend) { backend = backend || this.defaultBackend; assert.ok(backend in this.backEnds, "fileService backend"); return this.backEnds[backend].getMeta(uuid); }; FileStreamer.prototype.list = function(query, backend) { backend = backend || this.defaultBackend; assert.ok(backend in this.backEnds, "fileService backend"); query = query || {}; return this.backEnds[backend].list(query); }; FileStreamer.prototype.getFile = function(req, res, id) { var self = this; var uuidFound; if (id.match(Constants.Regex.uuid)) { uuidFound = Promise.resolve(id); } else { uuidFound = self.verify(id) .then(function(metadata) { return metadata[metadata.length - 1].uuid; }); } return new Promise(function(resolve, reject) { uuidFound .then(function(uuid) { if (!uuid) { reject(new Errors.NotFoundError('File: ' + id + ' not found')); } return self.get(uuid); }) .then(function(rdStream) { rdStream.on('error', function(err) { reject(new Errors.BadRequestError( 'Failed to serve file request: ' + err.message) ); }); rdStream.on('end', function() { resolve(); }); rdStream.pipe(res); }, function(err) { reject(new Errors.NotFoundError( 'Failed to get stream reader: ' + err.message) ); }) .catch(function(err) { reject(new Errors.NotFoundError( 'Failed to serve file request: ' + err.message) ); }); }); }; FileStreamer.prototype.putFile = function(req, filename) { var self = this; return new Promise(function(resolve, reject) { self.put(req, filename) .then(function(streamObj){ streamObj.transformHashStream.on('error', function(err) { reject(new Errors.BadRequestError( 'Failed to serve file request: ' + err.message) ); }); streamObj.writeStream.on('ready', function() { //todo make me work with uuid resolve( self.getFileMetadata(filename) ); }); streamObj.writeStream.on('error', function(err) { reject(new Errors.BadRequestError( 'Failed to serve file request: ' + err.message) ); }); req.pipe(streamObj.transformHashStream); }) .catch(function(err) { reject(new Errors.NotFoundError( 'Failed to serve file request: ' + err.message) ); }); }); }; FileStreamer.prototype.getFileMetadata = function(filename) { var self = this; return new Promise(function(resolve, reject) { self.verify(filename) .then(function(metadata){ resolve(metadata[metadata.length - 1]); }) .catch(function(err) { reject(new Errors.NotFoundError( 'Failed to serve file request: ' + err.message) ); }); }); }; FileStreamer.prototype.getFilesAll = function() { var self = this; return new Promise(function(resolve, reject) { self.list() .then(function(files){ resolve(files); }) .catch(function(err) { reject(new Errors.NotFoundError( 'Failed to serve file request: ' + err.message) ); }); }); }; FileStreamer.prototype.deleteFile = function(uuid) { var self = this; return new Promise(function(resolve, reject) { self.delete(uuid) .then(function() { resolve(); }) .catch(function(err) { reject(new Errors.NotFoundError( 'Failed to serve file request: ' + err.message) ); }); }); }; FileStreamer.prototype.start = function(config) { var self = this; self.config = config; _.forEach(self.config, function(contents, key) { if (!(contents.type in self.injectorMap)) { throw new Error("unrecognized back end string"); } var BackEndConstructor = injector.get(self.injectorMap[contents.type]); self.backEnds[key] = new BackEndConstructor(contents); }); if(!_.has(self.backEnds,self.defaultBackend)) { throw new Error("No defaultBackend in config"); } return; }; return new FileStreamer(); }