{"id":182,"date":"2016-07-04T23:13:42","date_gmt":"2016-07-04T22:13:42","guid":{"rendered":"https:\/\/solidt.eu\/blog\/?p=182"},"modified":"2022-07-25T08:35:46","modified_gmt":"2022-07-25T07:35:46","slug":"node-js-promisified-services","status":"publish","type":"post","link":"https:\/\/solidt.eu\/site\/node-js-promisified-services\/","title":{"rendered":"Node JS promisified services"},"content":{"rendered":"<p>A promisified file system:<\/p>\n<pre lang=\"javascript\">var fs = require('fs');\r\nvar Promise = require('bluebird');\r\n\r\nfs = Promise.promisifyAll(fs);\r\n\r\nmodule.exports = fs;\r\n<\/pre>\n<p>A promisified FTP service:<\/p>\n<pre lang=\"javascript\">var config = require('..\/config');\r\nvar Promise = require('bluebird');\r\nvar log = require('..\/services\/logService');\r\nvar fs = require('..\/services\/fsService');\r\nvar FtpClient = require('ftp');\r\n\r\nvar ftp = {};\r\n\r\nvar _connectionPromise = null;\r\n\r\nftp.getConnectionAsync = function () {\r\n    if (!_connectionPromise) {\r\n        _connectionPromise = new Promise(function (resolve, reject) {\r\n            var c = new FtpClient();\r\n            c.connect({\r\n                host: config.ftp.host, \/\/ string - The hostname or IP address of the FTP server. Default: 'localhost'\r\n                port: config.ftp.port, \/\/ integer - The port of the FTP server. Default: 21\r\n                secure: config.ftp.secure, \/\/ mixed - Set to true for both control and data connection encryption,\r\n                \/\/ 'control' for control connection encryption only, or\r\n                \/\/ 'implicit' for implicitly encrypted control connection (this mode is deprecated in modern times, but usually uses port 990) Default: false\r\n                secureOptions: {\r\n                    rejectUnauthorized: false,\r\n                    checkServerIdentity: function(servername, cert) {}\r\n                }, \/\/ object - Additional options to be passed to tls.connect(). Default: (none)\r\n                user: config.ftp.user, \/\/ string - Username for authentication. Default: 'anonymous'\r\n                password: config.ftp.password, \/\/ - string - Password for authentication. Default: 'anonymous@'\r\n                connTimeout: 10000, \/\/ - integer - How long (in milliseconds) to wait for the control connection to be established. Default: 10000\r\n                pasvTimeout: 10000, \/\/ - integer - How long (in milliseconds) to wait for a PASV data connection to be established. Default: 10000\r\n                keepalive: 10000 \/\/ - integer - How often (in milliseconds) to send a 'dummy' (NOOP) command to keep the connection alive. Default: 10000\r\n            });\r\n            c.on('ready', function () {\r\n                c = Promise.promisifyAll(c);\r\n                resolve(c);\r\n            });\r\n            c.on('error', function(error) {\r\n                reject(error);\r\n            });\r\n        });\r\n    }\r\n    return _connectionPromise;\r\n};\r\n\r\nftp.closeConnectionAsync = function() {\r\n    return ftp.getConnectionAsync()\r\n        .then(function(c) {\r\n            c.end();\r\n        })\r\n        .timeout(2000)\r\n        .finally(function() {\r\n            _connectionPromise = null;\r\n            return Promise.resolve('Connection closed');\r\n        });\r\n};\r\n\r\nftp.onError = function(error) {\r\n    var stack = new Error().stack;\r\n    log.error(error);\r\n    log.error(stack);\r\n    return ftp.closeConnectionAsync()\r\n        .finally(function() {\r\n            return Promise.reject(error);\r\n        });\r\n};\r\n\r\nvar writeStreamToFile = function(stream, fileName) {\r\n    return new Promise(function(resolve, reject) {\r\n        stream.once('close', resolve);\r\n        stream.on('error', reject);\r\n        stream.pipe(fs.createWriteStream(fileName));\r\n    });\r\n};\r\n\r\nftp.lsAsync = function(folder) {\r\n    return ftp.getConnectionAsync()\r\n        .then(function(c) {\r\n            return c.listAsync(folder);\r\n        })\r\n        .catch(ftp.onError);\r\n};\r\n\r\nftp.getAsync = function(remotePath, localPath) {\r\n    return ftp.getConnectionAsync()\r\n        .then(function(c) {\r\n            return c.getAsync(remotePath)\r\n                .then(function(stream) {\r\n                    return writeStreamToFile(stream, localPath);\r\n                });\r\n        })\r\n        .catch(ftp.onError);\r\n};\r\n\r\nftp.putAsync = function(localPath, remotePath) {\r\n    return ftp.getConnectionAsync()\r\n        .then(function(c) {\r\n            return c.putAsync(localPath, remotePath);\r\n        })\r\n        .catch(ftp.onError);\r\n};\r\n\r\nftp.deleteAsync = function(remotePath) {\r\n    return ftp.getConnectionAsync()\r\n        .then(function(c) {\r\n            return c.deleteAsync(remotePath);\r\n        })\r\n        .catch(ftp.onError);\r\n};\r\n\r\nftp.renameAsync = function(remotePath, newRemotePath) {\r\n    return ftp.getConnectionAsync()\r\n        .then(function(c) {\r\n            return c.renameAsync(remotePath, newRemotePath);\r\n        })\r\n        .catch(ftp.onError);\r\n};\r\n\r\nmodule.exports = ftp;\r\n<\/pre>\n<p>A promisified ODBC service:<\/p>\n<pre lang=\"javascript\">\r\nvar config = require('..\/config');\r\nvar Promise = require('bluebird');\r\nvar log =  require('..\/services\/logService');\r\n\r\nvar db = require('odbc')();\r\ndb = Promise.promisifyAll(db);\r\n\r\nvar _db = null;\r\ndb.getDB = function() {\r\n\tif (_db) {\r\n\t\treturn Promise.resolve(_db);\r\n\t}\r\n    log.info('opening database connection ..');\r\n\treturn db.openAsync(config.odbc.connectionString)\r\n\t\t.then(function(){\r\n            log.info('database connection opened.');\r\n\t\t\t_db = db;\r\n\t\t\treturn Promise.resolve(_db);\r\n\t\t});\r\n};\r\n\r\ndb.closeDB = function() {\r\n    if (_db) {\r\n        log.info('closing database connection ..');\r\n\t\tdb.closeSync();\r\n\t\tlog.info('database connection closed.');\r\n\r\n        \/\/ return db.closeAsync(function () {\r\n        \/\/     log.info('database connection closed.');\r\n\t\t\/\/ \treturn Promise.resolve('OK');\r\n        \/\/ });\r\n    }\r\n    return Promise.resolve('OK');\r\n};\r\n\r\nmodule.exports = db;\r\n<\/pre>\n<p>A promisified Samba client:<\/p>\n<pre lang=\"javascript\">var config = require('..\/config');\r\nvar Promise = require('bluebird');\r\nvar SambaClient = require('samba-client');\r\n\r\nvar client = new SambaClient({\r\n    address: config.smb.share \/\/ required\r\n        \/\/ username: 'test', \/\/ not required, defaults to guest\r\n        \/\/ password: 'test', \/\/ not required\r\n});\r\n\r\nclient = Promise.promisifyAll(client);\r\n\r\nmodule.exports = client;\r\n\r\n<\/pre>\n<p>A promisified (recursive) mkdir:<\/p>\n<pre lang=\"javascript\">var mkdirp = require('mkdirp');\r\n\r\nvar Promise = require('bluebird');\r\n\r\nmkdirp = Promise.promisify(mkdirp);\t\/\/ single function\r\n\r\nmodule.exports = mkdirp;\r\n<\/pre>\n<p>A (unpromisified) bunyan logger service:<\/p>\n<pre lang=\"javascript\">var config = require('..\/config');\r\n\r\nvar bunyan = require('bunyan');\r\n\r\nfunction MyRawStream() {};\r\nMyRawStream.prototype.write = function (rec) {\r\n    console.log('[%s] %s: %s',\r\n        rec.time.toISOString(),\r\n        bunyan.nameFromLevel[rec.level],\r\n        rec.msg);\r\n};\r\n\r\nvar log = bunyan.createLogger({\r\n    name: config.log.loggerName,\r\n    streams: [{\r\n        level: config.log.level,\r\n        stream: new MyRawStream(),\r\n        type: 'raw'\r\n    }, {\r\n        level: config.log.level,\r\n        path: config.log.file, \/\/ log ERROR and above to a file\r\n\ttype: 'rotating-file',\r\n\tperiod: '1d',\r\n\tcount: 3 \r\n    }]\r\n});\r\n\r\nlog.on('error', function (err, stream) {    \r\n\tconsole.log('[%s] %s: %s',\r\n        new Date().toISOString(),\r\n        \"ERROR\",\r\n        err,\r\n\tstream);\r\n});\r\n\r\n\r\n\/\/ examle usage\r\n\/\/log.info({message: 'test', status: 'ok'});\r\n\r\nmodule.exports = log;\r\n\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>A promisified file system: var fs = require(&#8216;fs&#8217;); var Promise = require(&#8216;bluebird&#8217;); fs = Promise.promisifyAll(fs); module.exports = fs; A promisified FTP service: var config = require(&#8216;..\/config&#8217;); var Promise = require(&#8216;bluebird&#8217;); var log = require(&#8216;..\/services\/logService&#8217;); var fs = require(&#8216;..\/services\/fsService&#8217;); var FtpClient = require(&#8216;ftp&#8217;); var ftp = {}; var _connectionPromise = null; ftp.getConnectionAsync = function () { [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[5,4],"tags":[],"class_list":["post-182","post","type-post","status-publish","format-standard","hentry","category-javascript","category-programming"],"_links":{"self":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/182","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/comments?post=182"}],"version-history":[{"count":2,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/182\/revisions"}],"predecessor-version":[{"id":355,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/182\/revisions\/355"}],"wp:attachment":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/media?parent=182"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/categories?post=182"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/tags?post=182"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}