From 7e86afe55e1bbd24d33035092f3519522159e794 Mon Sep 17 00:00:00 2001 From: Hayden Faulds Date: Mon, 6 Nov 2017 16:14:27 +0000 Subject: [PATCH] version file renames --- .../app/coffee/HttpController.coffee | 6 +-- .../app/coffee/ProjectManager.coffee | 12 ++++-- .../app/coffee/RedisManager.coffee | 25 +++++++++---- .../HttpController/HttpControllerTests.coffee | 9 +++-- .../ProjectManager/updateProjectTests.coffee | 37 ++++++++++++++----- .../RedisManager/RedisManagerTests.coffee | 30 +++++++++++++-- 6 files changed, 90 insertions(+), 29 deletions(-) diff --git a/services/document-updater/app/coffee/HttpController.coffee b/services/document-updater/app/coffee/HttpController.coffee index 78de5fb765..38e82fb04e 100644 --- a/services/document-updater/app/coffee/HttpController.coffee +++ b/services/document-updater/app/coffee/HttpController.coffee @@ -155,10 +155,10 @@ module.exports = HttpController = updateProject: (req, res, next = (error) ->) -> timer = new Metrics.Timer("http.updateProject") project_id = req.params.project_id - {userId, docUpdates} = req.body - logger.log {project_id, docUpdates}, "updating project via http" + {userId, docUpdates, fileUpdates} = req.body + logger.log {project_id, docUpdates, fileUpdates}, "updating project via http" - ProjectManager.updateProjectWithLocks project_id, userId, docUpdates, (error) -> + ProjectManager.updateProjectWithLocks project_id, userId, docUpdates, fileUpdates, (error) -> timer.done() return next(error) if error? logger.log project_id: project_id, "updated project via http" diff --git a/services/document-updater/app/coffee/ProjectManager.coffee b/services/document-updater/app/coffee/ProjectManager.coffee index 6b320e6e28..2f85173b4c 100644 --- a/services/document-updater/app/coffee/ProjectManager.coffee +++ b/services/document-updater/app/coffee/ProjectManager.coffee @@ -94,14 +94,20 @@ module.exports = ProjectManager = clearProjectState: (project_id, callback = (error) ->) -> RedisManager.clearProjectState project_id, callback - updateProjectWithLocks: (project_id, user_id, updates, _callback = (error) ->) -> + updateProjectWithLocks: (project_id, user_id, docUpdates, fileUpdates, _callback = (error) ->) -> timer = new Metrics.Timer("projectManager.updateProject") callback = (args...) -> timer.done() _callback(args...) - handleUpdate = (update, cb) -> + handleDocUpdate = (update, cb) -> doc_id = update.id DocumentManager.renameDocWithLock project_id, doc_id, user_id, update, cb - async.each updates, handleUpdate, callback + handleFileUpdate = (update, cb) -> + file_id = update.id + RedisManager.renameFile project_id, file_id, user_id, update, cb + + async.each docUpdates, handleDocUpdate, (error) -> + return callback(error) if error? + async.each fileUpdates, handleFileUpdate, callback diff --git a/services/document-updater/app/coffee/RedisManager.coffee b/services/document-updater/app/coffee/RedisManager.coffee index cde2ccddc9..56ce0fb9f9 100644 --- a/services/document-updater/app/coffee/RedisManager.coffee +++ b/services/document-updater/app/coffee/RedisManager.coffee @@ -273,21 +273,32 @@ module.exports = RedisManager = callback null, docUpdateCount renameDoc: (project_id, doc_id, user_id, update, callback = (error) ->) -> + RedisManager.getDoc project_id, doc_id, (error, lines, version) -> + return callback(error) if error? + + if lines? and version? + rclient.set keys.pathname(doc_id:doc_id), update.newPathname, (error) -> + return callback(error) if error? + RedisManager._renameEntity project_id, 'doc', doc_id, user_id, update, callback + else + RedisManager._renameEntity project_id, 'doc', doc_id, user_id, update, callback + + renameFile: (project_id, file_id, user_id, update, callback = (error) ->) -> + RedisManager._renameEntity project_id, 'file', file_id, user_id, update, callback + + _renameEntity: (project_id, entity_type, entity_id, user_id, update, callback = (error) ->) -> update = - doc: doc_id pathname: update.pathname new_pathname: update.newPathname meta: user_id: user_id ts: new Date() + update[entity_type] = entity_id + + logger.log {project_id, update}, "queue rename operation to project-history" jsonUpdate = JSON.stringify(update) - RedisManager.getDoc project_id, doc_id, (error, lines, version) -> - return callback(error) if error? - if lines? and version? - rclient.set keys.pathname(doc_id:doc_id), update.new_pathname - - rclient.rpush projectHistoryKeys.projectHistoryOps({project_id}), jsonUpdate, callback + rclient.rpush projectHistoryKeys.projectHistoryOps({project_id}), jsonUpdate, callback clearUnflushedTime: (doc_id, callback = (error) ->) -> rclient.del keys.unflushedTime(doc_id:doc_id), callback diff --git a/services/document-updater/test/unit/coffee/HttpController/HttpControllerTests.coffee b/services/document-updater/test/unit/coffee/HttpController/HttpControllerTests.coffee index 5ddefefaa3..b5ebe02339 100644 --- a/services/document-updater/test/unit/coffee/HttpController/HttpControllerTests.coffee +++ b/services/document-updater/test/unit/coffee/HttpController/HttpControllerTests.coffee @@ -497,19 +497,20 @@ describe "HttpController", -> beforeEach -> @userId = "user-id-123" @docUpdates = sinon.stub() + @fileUpdates = sinon.stub() @req = - body: {@userId, @docUpdates} + body: {@userId, @docUpdates, @fileUpdates} params: project_id: @project_id describe "successfully", -> beforeEach -> - @ProjectManager.updateProjectWithLocks = sinon.stub().callsArgWith(3) + @ProjectManager.updateProjectWithLocks = sinon.stub().callsArgWith(4) @HttpController.updateProject(@req, @res, @next) it "should accept the change", -> @ProjectManager.updateProjectWithLocks - .calledWith(@project_id, @userId, @docUpdates) + .calledWith(@project_id, @userId, @docUpdates, @fileUpdates) .should.equal true it "should return a successful No Content response", -> @@ -522,7 +523,7 @@ describe "HttpController", -> describe "when an errors occurs", -> beforeEach -> - @ProjectManager.updateProjectWithLocks = sinon.stub().callsArgWith(3, new Error("oops")) + @ProjectManager.updateProjectWithLocks = sinon.stub().callsArgWith(4, new Error("oops")) @HttpController.updateProject(@req, @res, @next) it "should call next with the error", -> diff --git a/services/document-updater/test/unit/coffee/ProjectManager/updateProjectTests.coffee b/services/document-updater/test/unit/coffee/ProjectManager/updateProjectTests.coffee index fc81834782..7009405842 100644 --- a/services/document-updater/test/unit/coffee/ProjectManager/updateProjectTests.coffee +++ b/services/document-updater/test/unit/coffee/ProjectManager/updateProjectTests.coffee @@ -20,25 +20,35 @@ describe "ProjectManager", -> describe "updateProjectWithLocks", -> beforeEach -> - @firstUpdate = + @firstDocUpdate = id: 1 update: 'foo' - @secondUpdate = + @secondDocUpdate = id: 2 update: 'bar' - @updates = [ @firstUpdate, @secondUpdate ] + @docUpdates = [ @firstDocUpdate, @secondDocUpdate ] + @firstFileUpdate = + id: 2 + update: 'bar' + @fileUpdates = [ @firstFileUpdate ] + @DocumentManager.renameDocWithLock = sinon.stub().yields() + @RedisManager.renameFile = sinon.stub().yields() describe "successfully", -> beforeEach -> - @DocumentManager.renameDocWithLock = sinon.stub().yields() - @ProjectManager.updateProjectWithLocks @project_id, @user_id, @updates, @callback + @ProjectManager.updateProjectWithLocks @project_id, @user_id, @docUpdates, @fileUpdates, @callback - it "should rename the documents in the updates", -> + it "should rename the docs in the updates", -> @DocumentManager.renameDocWithLock - .calledWith(@project_id, @firstUpdate.id, @user_id, @firstUpdate) + .calledWith(@project_id, @firstDocUpdate.id, @user_id, @firstDocUpdate) .should.equal true @DocumentManager.renameDocWithLock - .calledWith(@project_id, @secondUpdate.id, @user_id, @secondUpdate) + .calledWith(@project_id, @secondDocUpdate.id, @user_id, @secondDocUpdate) + .should.equal true + + it "should rename the files in the updates", -> + @RedisManager.renameFile + .calledWith(@project_id, @firstFileUpdate.id, @user_id, @firstFileUpdate) .should.equal true it "should call the callback", -> @@ -48,7 +58,16 @@ describe "ProjectManager", -> beforeEach -> @error = new Error('error') @DocumentManager.renameDocWithLock = sinon.stub().yields(@error) - @ProjectManager.updateProjectWithLocks @project_id, @user_id, @updates, @callback + @ProjectManager.updateProjectWithLocks @project_id, @user_id, @docUpdates, @fileUpdates, @callback + + it "should call the callback with the error", -> + @callback.calledWith(@error).should.equal true + + describe "when renaming a file fails", -> + beforeEach -> + @error = new Error('error') + @RedisManager.renameFile = sinon.stub().yields(@error) + @ProjectManager.updateProjectWithLocks @project_id, @user_id, @docUpdates, @fileUpdates, @callback it "should call the callback with the error", -> @callback.calledWith(@error).should.equal true diff --git a/services/document-updater/test/unit/coffee/RedisManager/RedisManagerTests.coffee b/services/document-updater/test/unit/coffee/RedisManager/RedisManagerTests.coffee index 2b81c18a18..157c315b63 100644 --- a/services/document-updater/test/unit/coffee/RedisManager/RedisManagerTests.coffee +++ b/services/document-updater/test/unit/coffee/RedisManager/RedisManagerTests.coffee @@ -676,8 +676,8 @@ describe "RedisManager", -> describe "renameDoc", -> beforeEach () -> - @rclient.rpush = sinon.stub().callsArg(2) - @rclient.set = sinon.stub() + @rclient.rpush = sinon.stub().yields() + @rclient.set = sinon.stub().yields() @update = id: @doc_id pathname: @pathname = 'pathname' @@ -695,12 +695,12 @@ describe "RedisManager", -> it "should queue an update", -> update = - doc: @doc_id pathname: @pathname new_pathname: @newPathname meta: user_id: @userId ts: new Date() + doc: @doc_id @rclient.rpush .calledWith("ProjectHistory:Ops:#{@project_id}", JSON.stringify(update)) .should.equal true @@ -715,3 +715,27 @@ describe "RedisManager", -> it "does not update the cached pathname", -> @rclient.set.called.should.equal false + + describe "renameFile", -> + beforeEach () -> + @rclient.rpush = sinon.stub().yields() + @file_id = 1234 + + @update = + pathname: @pathname = '/old' + newPathname: @newPathname = '/new' + + @RedisManager.renameFile @project_id, @file_id, @userId, @update + + it "should queue an update", -> + update = + pathname: @pathname + new_pathname: @newPathname + meta: + user_id: @userId + ts: new Date() + file: @file_id + + @rclient.rpush + .calledWith("ProjectHistory:Ops:#{@project_id}", JSON.stringify(update)) + .should.equal true