From df0747ec486c80c6290eaf1711f39926ef2319ab Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Fri, 21 Aug 2020 17:50:01 +0100 Subject: [PATCH] [misc] migrate the app to the native mongo driver acceptance tests to follow in a separate commit --- services/docstore/app.js | 22 ++- services/docstore/app/js/HealthChecker.js | 15 +- services/docstore/app/js/MongoManager.js | 154 ++++++++++-------- services/docstore/app/js/RangeManager.js | 2 +- services/docstore/app/js/mongodb.js | 19 +++ services/docstore/package-lock.json | 64 ++++---- services/docstore/package.json | 1 + .../test/unit/js/DocArchiveManagerTests.js | 2 +- .../docstore/test/unit/js/DocManagerTests.js | 2 +- .../test/unit/js/HttpControllerTests.js | 2 +- .../test/unit/js/MongoManagerTests.js | 65 +++++--- .../test/unit/js/RangeManagerTests.js | 4 +- 12 files changed, 207 insertions(+), 145 deletions(-) create mode 100644 services/docstore/app/js/mongodb.js diff --git a/services/docstore/app.js b/services/docstore/app.js index 555f31137b..7296d311de 100644 --- a/services/docstore/app.js +++ b/services/docstore/app.js @@ -10,6 +10,7 @@ const Settings = require('settings-sharelatex') const logger = require('logger-sharelatex') const express = require('express') const bodyParser = require('body-parser') +const mongodb = require('./app/js/mongodb') const Errors = require('./app/js/Errors') const HttpController = require('./app/js/HttpController') @@ -76,12 +77,21 @@ const { host } = Settings.internal.docstore if (!module.parent) { // Called directly - app.listen(port, host, function (error) { - if (error != null) { - throw error - } - return logger.info(`Docstore starting up, listening on ${host}:${port}`) - }) + mongodb + .waitForDb() + .then(() => { + app.listen(port, host, function (err) { + if (err) { + logger.fatal({ err }, `Cannot bind to ${host}:${port}. Exiting.`) + process.exit(1) + } + return logger.info(`Docstore starting up, listening on ${host}:${port}`) + }) + }) + .catch((err) => { + logger.fatal({ err }, 'Cannot connect to mongo. Exiting.') + process.exit(1) + }) } module.exports = app diff --git a/services/docstore/app/js/HealthChecker.js b/services/docstore/app/js/HealthChecker.js index 70ebc85ad9..a32452a1b2 100644 --- a/services/docstore/app/js/HealthChecker.js +++ b/services/docstore/app/js/HealthChecker.js @@ -10,7 +10,7 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const { db, ObjectId } = require('./mongojs') +const { getCollection, ObjectId } = require('./mongodb') const request = require('request') const async = require('async') const _ = require('underscore') @@ -19,6 +19,9 @@ const settings = require('settings-sharelatex') const { port } = settings.internal.docstore const logger = require('logger-sharelatex') +const docsCollectionPromise = getCollection('docs') +const docOpsCollectionPromise = getCollection('docOps') + module.exports = { check(callback) { const doc_id = ObjectId() @@ -60,8 +63,14 @@ module.exports = { } }) }, - (cb) => db.docs.remove({ _id: doc_id, project_id }, cb), - (cb) => db.docOps.remove({ doc_id }, cb) + (cb) => + docsCollectionPromise.then((docs) => + docs.deleteOne({ _id: doc_id, project_id }, cb) + ), + (cb) => + docOpsCollectionPromise.then((docOps) => + docOps.deleteOne({ doc_id }, cb) + ) ] return async.series(jobs, callback) } diff --git a/services/docstore/app/js/MongoManager.js b/services/docstore/app/js/MongoManager.js index b6e90a7ad3..ba1ec83f3d 100644 --- a/services/docstore/app/js/MongoManager.js +++ b/services/docstore/app/js/MongoManager.js @@ -11,28 +11,28 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ let MongoManager -const { db, ObjectId } = require('./mongojs') +const { getCollection, ObjectId } = require('./mongodb') const logger = require('logger-sharelatex') const metrics = require('metrics-sharelatex') const { promisify } = require('util') +const docsCollectionPromise = getCollection('docs') +const docOpsCollectionPromise = getCollection('docOps') + module.exports = MongoManager = { findDoc(project_id, doc_id, filter, callback) { if (callback == null) { callback = function (error, doc) {} } - return db.docs.find( - { - _id: ObjectId(doc_id.toString()), - project_id: ObjectId(project_id.toString()) - }, - filter, - function (error, docs) { - if (docs == null) { - docs = [] - } - return callback(error, docs[0]) - } + docsCollectionPromise.then((docs) => + docs.findOne( + { + _id: ObjectId(doc_id.toString()), + project_id: ObjectId(project_id.toString()) + }, + filter, + callback + ) ) }, @@ -44,7 +44,9 @@ module.exports = MongoManager = { if (!options.include_deleted) { query.deleted = { $ne: true } } - return db.docs.find(query, filter, callback) + docsCollectionPromise.then((docs) => + docs.find(query, filter).toArray(callback) + ) }, getArchivedProjectDocs(project_id, callback) { @@ -52,7 +54,7 @@ module.exports = MongoManager = { project_id: ObjectId(project_id.toString()), inS3: true } - return db.docs.find(query, {}, callback) + docsCollectionPromise.then((docs) => docs.find(query).toArray(callback)) }, upsertIntoDocCollection(project_id, doc_id, updates, callback) { @@ -66,24 +68,28 @@ module.exports = MongoManager = { } } update.$set.project_id = ObjectId(project_id) - return db.docs.update( - { _id: ObjectId(doc_id) }, - update, - { upsert: true }, - callback + docsCollectionPromise.then((docs) => + docs.updateOne( + { _id: ObjectId(doc_id) }, + update, + { upsert: true }, + callback + ) ) }, markDocAsDeleted(project_id, doc_id, callback) { - return db.docs.update( - { - _id: ObjectId(doc_id), - project_id: ObjectId(project_id) - }, - { - $set: { deleted: true } - }, - callback + docsCollectionPromise.then((docs) => + docs.updateOne( + { + _id: ObjectId(doc_id), + project_id: ObjectId(project_id) + }, + { + $set: { deleted: true } + }, + callback + ) ) }, @@ -99,30 +105,30 @@ module.exports = MongoManager = { _id: doc_id, rev } - return db.docs.update(query, update, (err) => callback(err)) + docsCollectionPromise.then((docs) => + docs.updateOne(query, update, callback) + ) }, getDocVersion(doc_id, callback) { if (callback == null) { callback = function (error, version) {} } - return db.docOps.find( - { - doc_id: ObjectId(doc_id) - }, - { - version: 1 - }, - function (error, docs) { - if (error != null) { - return callback(error) + docOpsCollectionPromise.then((docOps) => + docOps.findOne( + { + doc_id: ObjectId(doc_id) + }, + { + version: 1 + }, + function (error, doc) { + if (error != null) { + return callback(error) + } + callback(null, (doc && doc.version) || 0) } - if (docs.length < 1 || docs[0].version == null) { - return callback(null, 0) - } else { - return callback(null, docs[0].version) - } - } + ) ) }, @@ -130,36 +136,42 @@ module.exports = MongoManager = { if (callback == null) { callback = function (error) {} } - return db.docOps.update( - { - doc_id: ObjectId(doc_id) - }, - { - $set: { version } - }, - { - upsert: true - }, - callback + docOpsCollectionPromise.then((docOps) => + docOps.updateOne( + { + doc_id: ObjectId(doc_id) + }, + { + $set: { version } + }, + { + upsert: true + }, + callback + ) ) }, destroyDoc(doc_id, callback) { - return db.docs.remove( - { - _id: ObjectId(doc_id) - }, - function (err) { - if (err != null) { - return callback(err) + docsCollectionPromise.then((docs) => + docs.deleteOne( + { + _id: ObjectId(doc_id) + }, + function (err) { + if (err != null) { + return callback(err) + } + docOpsCollectionPromise.then((docOps) => + docOps.deleteOne( + { + doc_id: ObjectId(doc_id) + }, + callback + ) + ) } - return db.docOps.remove( - { - doc_id: ObjectId(doc_id) - }, - callback - ) - } + ) ) } } diff --git a/services/docstore/app/js/RangeManager.js b/services/docstore/app/js/RangeManager.js index b11019657f..fd719e5b15 100644 --- a/services/docstore/app/js/RangeManager.js +++ b/services/docstore/app/js/RangeManager.js @@ -13,7 +13,7 @@ */ let RangeManager const _ = require('underscore') -const { ObjectId } = require('./mongojs') +const { ObjectId } = require('./mongodb') module.exports = RangeManager = { shouldUpdateRanges(doc_ranges, incoming_ranges) { diff --git a/services/docstore/app/js/mongodb.js b/services/docstore/app/js/mongodb.js new file mode 100644 index 0000000000..5b0168bda8 --- /dev/null +++ b/services/docstore/app/js/mongodb.js @@ -0,0 +1,19 @@ +const Settings = require('settings-sharelatex') +const { MongoClient, ObjectId } = require('mongodb') + +const clientPromise = MongoClient.connect(Settings.mongo.url) +const dbPromise = clientPromise.then((client) => client.db()) + +async function getCollection(name) { + return (await dbPromise).collection(name) +} + +async function waitForDb() { + await clientPromise +} + +module.exports = { + ObjectId, + getCollection, + waitForDb +} diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index a4c04f4fe1..fe80c62e79 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -1438,7 +1438,7 @@ "archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==" + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" }, "argparse": { "version": "1.0.10", @@ -1727,9 +1727,9 @@ "dev": true }, "bson": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.3.tgz", - "integrity": "sha512-TdiJxMVnodVS7r0BdL42y/pqC9cL2iKynVwA0Ho3qbsQYr428veL3l7BQyuqiw+Q5SqqoT0m4srSY/BlZ9AxXg==" + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.5.tgz", + "integrity": "sha512-kDuEzldR21lHciPQAIulLs1LZlCXdLziXI6Mb/TDkwXhb//UORJNPXgcRs2CuO4H0DcMkpfT3/ySsP3unoZjBg==" }, "buffer": { "version": "4.9.2", @@ -1974,7 +1974,7 @@ "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" }, "compressible": { "version": "2.0.18", @@ -2225,7 +2225,7 @@ "default-require-extensions": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", - "integrity": "sha512-B0n2zDIXpzLzKeoEozorDSa1cHc1t0NjmxP0zuAxbizNU2MBqYJJKYXrrFdKuQliojXynrxgd7l4ahfg/+aA5g==", + "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", "requires": { "strip-bom": "^3.0.0" } @@ -2316,7 +2316,7 @@ "each-series": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/each-series/-/each-series-1.0.0.tgz", - "integrity": "sha512-4MQloCGGCmT5GJZK5ibgJSvTK1c1QSrNlDvLk6fEyRxjZnXjl+NNFfzhfXpmnWh33Owc9D9klrdzCUi7yc9r4Q==" + "integrity": "sha1-+Ibmxm39sl7x/nNWQUbuXLR4r8s=" }, "ecc-jsbn": { "version": "0.1.2", @@ -3184,7 +3184,7 @@ "foreground-child": { "version": "1.5.6", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", - "integrity": "sha512-3TOY+4TKV0Ml83PXJQY+JFQaHNV38lzQDIzzXYg1kWdBLenGgoZhAs0CKgzI31vi2pWEpQMq/Yi4bpKwCPkw7g==", + "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", "requires": { "cross-spawn": "^4", "signal-exit": "^3.0.0" @@ -3193,7 +3193,7 @@ "cross-spawn": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", - "integrity": "sha512-yAXz/pA1tD8Gtg2S98Ekf/sewp3Lcp3YoFKJ4Hkp5h5yLWnKVTDU0kwjKJ8NDCYcfTLfyGkzTikst+jWypT1iA==", + "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", "requires": { "lru-cache": "^4.0.1", "which": "^1.2.9" @@ -3211,7 +3211,7 @@ "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" } } }, @@ -3584,7 +3584,7 @@ "hasha": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", - "integrity": "sha512-w0Kz8lJFBoyaurBiNrIvxPqr/gJ6fOfSkpAPOepN3oECqGJag37xPbOv57izi/KP8auHgNYxn5fXtAb+1LsJ6w==", + "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", "requires": { "is-stream": "^1.0.1" }, @@ -3592,7 +3592,7 @@ "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==" + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" } } }, @@ -3613,9 +3613,9 @@ "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==" }, "html-escaper": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.1.tgz", - "integrity": "sha512-hNX23TjWwD3q56HpWjUHOKj1+4KKlnjv9PcmBUYKVpga+2cnb9nDx/B1o0yO4n+RZXZdiNxzx6B24C9aNMTkkQ==" + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" }, "http-errors": { "version": "1.7.2", @@ -4301,7 +4301,7 @@ "lodash.flattendeep": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==" + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=" }, "lodash.get": { "version": "4.4.2", @@ -4804,12 +4804,12 @@ "optional": true }, "mongodb": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.5.5.tgz", - "integrity": "sha512-GCjDxR3UOltDq00Zcpzql6dQo1sVry60OXJY3TDmFc2SWFY6c8Gn1Ardidc5jDirvJrx2GC3knGOImKphbSL3A==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.0.tgz", + "integrity": "sha512-/XWWub1mHZVoqEsUppE0GV7u9kanLvHxho6EvBxQbShXTKYF9trhZC2NzbulRGeG7xMJHD8IOWRcdKx5LPjAjQ==", "requires": { "bl": "^2.2.0", - "bson": "^1.1.1", + "bson": "^1.1.4", "denque": "^1.4.1", "require_optional": "^1.0.1", "safe-buffer": "^5.1.2", @@ -5186,7 +5186,7 @@ "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==" + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" }, "os-tmpdir": { "version": "1.0.2", @@ -5270,7 +5270,7 @@ "parse-mongo-url": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/parse-mongo-url/-/parse-mongo-url-1.1.1.tgz", - "integrity": "sha512-7bZUusQIrFLwvsLHBnCz2WKYQ5LKO/LwKPnvQxbMIh9gDx8H5ZsknRmLjZdn6GVdrgVOwqDrZKsY0qDLNmRgcw==" + "integrity": "sha1-ZiON9fjnwMjKTNlw1KtqE3PrdbU=" }, "parse-ms": { "version": "2.1.0", @@ -6037,7 +6037,7 @@ "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, "psl": { "version": "1.7.0", @@ -6249,7 +6249,7 @@ "release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", "requires": { "es6-error": "^4.0.1" } @@ -6365,7 +6365,7 @@ "resolve-from": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", - "integrity": "sha512-qpFcKaXsq8+oRoLilkwyc7zHGF5i9Q2/25NIgLQQ/+VVv9rU4qvr6nXVAw1DsnXJyQkZsR4Ytfbtg5ehfcUssQ==" + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" }, "restore-cursor": { "version": "3.1.0", @@ -6666,7 +6666,7 @@ "sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", - "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", "optional": true, "requires": { "memory-pager": "^1.0.2" @@ -6927,7 +6927,7 @@ "stubs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==" + "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=" }, "supports-color": { "version": "6.0.0", @@ -7055,7 +7055,7 @@ "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "requires": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", @@ -7083,7 +7083,7 @@ "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "requires": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" @@ -7100,12 +7100,12 @@ "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==" + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" }, "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", "requires": { "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", @@ -7178,7 +7178,7 @@ "to-mongodb-core": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-mongodb-core/-/to-mongodb-core-2.0.0.tgz", - "integrity": "sha512-vfXXcGYFP8+0L5IPOtUzzVIvPE/G3GN0TKa/PRBlzPqYyhm+UxhPmvv634EQgO4Ot8dHbBFihOslMJQclY8Z9A==" + "integrity": "sha1-NZbsdhOsmtO5ioncua77pWnNJ+s=" }, "to-no-case": { "version": "1.0.2", diff --git a/services/docstore/package.json b/services/docstore/package.json index 8ecba94090..cb2d020599 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -26,6 +26,7 @@ "logger-sharelatex": "^2.2.0", "metrics-sharelatex": "^2.7.0", "mongojs": "3.1.0", + "mongodb": "^3.6.0", "settings-sharelatex": "^1.1.0", "streamifier": "^0.1.1", "tiny-async-pool": "^1.1.0", diff --git a/services/docstore/test/unit/js/DocArchiveManagerTests.js b/services/docstore/test/unit/js/DocArchiveManagerTests.js index 026c7654b4..dbe6069572 100644 --- a/services/docstore/test/unit/js/DocArchiveManagerTests.js +++ b/services/docstore/test/unit/js/DocArchiveManagerTests.js @@ -3,7 +3,7 @@ const chai = require('chai') const { expect } = chai const modulePath = '../../../app/js/DocArchiveManager.js' const SandboxedModule = require('sandboxed-module') -const { ObjectId } = require('mongojs') +const { ObjectId } = require('mongodb') const Errors = require('../../../app/js/Errors') chai.use(require('chai-as-promised')) diff --git a/services/docstore/test/unit/js/DocManagerTests.js b/services/docstore/test/unit/js/DocManagerTests.js index e7f5baa567..55955f3704 100644 --- a/services/docstore/test/unit/js/DocManagerTests.js +++ b/services/docstore/test/unit/js/DocManagerTests.js @@ -19,7 +19,7 @@ const { assert } = require('chai') chai.should() const { expect } = chai const modulePath = require('path').join(__dirname, '../../../app/js/DocManager') -const { ObjectId } = require('mongojs') +const { ObjectId } = require('mongodb') const Errors = require('../../../app/js/Errors') describe('DocManager', function () { diff --git a/services/docstore/test/unit/js/HttpControllerTests.js b/services/docstore/test/unit/js/HttpControllerTests.js index 46132737f2..0c7626baaf 100644 --- a/services/docstore/test/unit/js/HttpControllerTests.js +++ b/services/docstore/test/unit/js/HttpControllerTests.js @@ -19,7 +19,7 @@ const modulePath = require('path').join( __dirname, '../../../app/js/HttpController' ) -const { ObjectId } = require('mongojs') +const { ObjectId } = require('mongodb') describe('HttpController', function () { beforeEach(function () { diff --git a/services/docstore/test/unit/js/MongoManagerTests.js b/services/docstore/test/unit/js/MongoManagerTests.js index fec3ec0682..fab71a6618 100644 --- a/services/docstore/test/unit/js/MongoManagerTests.js +++ b/services/docstore/test/unit/js/MongoManagerTests.js @@ -16,14 +16,18 @@ const modulePath = require('path').join( __dirname, '../../../app/js/MongoManager' ) -const { ObjectId } = require('mongojs') +const { ObjectId } = require('mongodb') const { assert } = require('chai') describe('MongoManager', function () { beforeEach(function () { + this.db = {} this.MongoManager = SandboxedModule.require(modulePath, { requires: { - './mongojs': { + './mongodb': { + getCollection: sinon.stub().callsFake((name) => { + return Promise.resolve((this.db[name] = {})) + }), db: (this.db = { docs: {}, docOps: {} }), ObjectId }, @@ -36,14 +40,14 @@ describe('MongoManager', function () { }) this.project_id = ObjectId().toString() this.doc_id = ObjectId().toString() - this.callback = sinon.stub() return (this.stubbedErr = new Error('hello world')) }) describe('findDoc', function () { - beforeEach(function () { + beforeEach(function (done) { + this.callback = sinon.stub().callsFake(() => done()) this.doc = { name: 'mock-doc' } - this.db.docs.find = sinon.stub().callsArgWith(2, null, [this.doc]) + this.db.docs.findOne = sinon.stub().callsArgWith(2, null, this.doc) this.filter = { lines: true } return this.MongoManager.findDoc( this.project_id, @@ -54,7 +58,7 @@ describe('MongoManager', function () { }) it('should find the doc', function () { - return this.db.docs.find + this.db.docs.findOne .calledWith( { _id: ObjectId(this.doc_id), @@ -77,13 +81,16 @@ describe('MongoManager', function () { this.doc2 = { name: 'mock-doc2' } this.doc3 = { name: 'mock-doc3' } this.doc4 = { name: 'mock-doc4' } - return (this.db.docs.find = sinon - .stub() - .callsArgWith(2, null, [this.doc, this.doc3, this.doc4])) + this.db.docs.find = sinon.stub().returns({ + toArray: sinon + .stub() + .callsArgWith(0, null, [this.doc, this.doc3, this.doc4]) + }) }) describe('with included_deleted = false', function () { - beforeEach(function () { + beforeEach(function (done) { + this.callback = sinon.stub().callsFake(() => done()) return this.MongoManager.getProjectsDocs( this.project_id, { include_deleted: false }, @@ -112,7 +119,8 @@ describe('MongoManager', function () { }) return describe('with included_deleted = true', function () { - beforeEach(function () { + beforeEach(function (done) { + this.callback = sinon.stub().callsFake(() => done()) return this.MongoManager.getProjectsDocs( this.project_id, { include_deleted: true }, @@ -142,7 +150,7 @@ describe('MongoManager', function () { describe('upsertIntoDocCollection', function () { beforeEach(function () { - this.db.docs.update = sinon.stub().callsArgWith(3, this.stubbedErr) + this.db.docs.updateOne = sinon.stub().callsArgWith(3, this.stubbedErr) return (this.oldRev = 77) }) @@ -152,7 +160,7 @@ describe('MongoManager', function () { this.doc_id, { lines: this.lines }, (err) => { - const args = this.db.docs.update.args[0] + const args = this.db.docs.updateOne.args[0] assert.deepEqual(args[0], { _id: ObjectId(this.doc_id) }) assert.equal(args[1].$set.lines, this.lines) assert.equal(args[1].$inc.rev, 1) @@ -177,7 +185,7 @@ describe('MongoManager', function () { describe('markDocAsDeleted', function () { beforeEach(function () { - this.db.docs.update = sinon.stub().callsArgWith(2, this.stubbedErr) + this.db.docs.updateOne = sinon.stub().callsArgWith(2, this.stubbedErr) return (this.oldRev = 77) }) @@ -186,7 +194,7 @@ describe('MongoManager', function () { this.project_id, this.doc_id, (err) => { - const args = this.db.docs.update.args[0] + const args = this.db.docs.updateOne.args[0] assert.deepEqual(args[0], { _id: ObjectId(this.doc_id), project_id: ObjectId(this.project_id) @@ -211,19 +219,19 @@ describe('MongoManager', function () { describe('destroyDoc', function () { beforeEach(function (done) { - this.db.docs.remove = sinon.stub().yields() - this.db.docOps.remove = sinon.stub().yields() + this.db.docs.deleteOne = sinon.stub().yields() + this.db.docOps.deleteOne = sinon.stub().yields() return this.MongoManager.destroyDoc('123456789012', done) }) it('should destroy the doc', function () { - return sinon.assert.calledWith(this.db.docs.remove, { + return sinon.assert.calledWith(this.db.docs.deleteOne, { _id: ObjectId('123456789012') }) }) return it('should destroy the docOps', function () { - return sinon.assert.calledWith(this.db.docOps.remove, { + return sinon.assert.calledWith(this.db.docOps.deleteOne, { doc_id: ObjectId('123456789012') }) }) @@ -231,14 +239,15 @@ describe('MongoManager', function () { describe('getDocVersion', function () { describe('when the doc exists', function () { - beforeEach(function () { + beforeEach(function (done) { + this.callback = sinon.stub().callsFake(() => done()) this.doc = { version: (this.version = 42) } - this.db.docOps.find = sinon.stub().callsArgWith(2, null, [this.doc]) + this.db.docOps.findOne = sinon.stub().callsArgWith(2, null, this.doc) return this.MongoManager.getDocVersion(this.doc_id, this.callback) }) it('should look for the doc in the database', function () { - return this.db.docOps.find + return this.db.docOps.findOne .calledWith({ doc_id: ObjectId(this.doc_id) }, { version: 1 }) .should.equal(true) }) @@ -249,8 +258,9 @@ describe('MongoManager', function () { }) return describe("when the doc doesn't exist", function () { - beforeEach(function () { - this.db.docOps.find = sinon.stub().callsArgWith(2, null, []) + beforeEach(function (done) { + this.callback = sinon.stub().callsFake(() => done()) + this.db.docOps.findOne = sinon.stub().callsArgWith(2, null, null) return this.MongoManager.getDocVersion(this.doc_id, this.callback) }) @@ -261,9 +271,10 @@ describe('MongoManager', function () { }) return describe('setDocVersion', function () { - beforeEach(function () { + beforeEach(function (done) { + this.callback = sinon.stub().callsFake(() => done()) this.version = 42 - this.db.docOps.update = sinon.stub().callsArg(3) + this.db.docOps.updateOne = sinon.stub().callsArg(3) return this.MongoManager.setDocVersion( this.doc_id, this.version, @@ -272,7 +283,7 @@ describe('MongoManager', function () { }) it('should update the doc version', function () { - return this.db.docOps.update + return this.db.docOps.updateOne .calledWith( { doc_id: ObjectId(this.doc_id) diff --git a/services/docstore/test/unit/js/RangeManagerTests.js b/services/docstore/test/unit/js/RangeManagerTests.js index eafc60110b..471f60e2c8 100644 --- a/services/docstore/test/unit/js/RangeManagerTests.js +++ b/services/docstore/test/unit/js/RangeManagerTests.js @@ -18,7 +18,7 @@ const modulePath = require('path').join( __dirname, '../../../app/js/RangeManager' ) -const { ObjectId } = require('mongojs') +const { ObjectId } = require('mongodb') const { assert } = require('chai') const _ = require('underscore') @@ -26,7 +26,7 @@ describe('RangeManager', function () { beforeEach(function () { return (this.RangeManager = SandboxedModule.require(modulePath, { requires: { - './mongojs': { + './mongodb': { ObjectId } }