mvp to send requests to 2 backends

This commit is contained in:
Henry Oswald 2018-06-14 17:41:30 +01:00
parent 55112dc7dc
commit 5f8985811d
4 changed files with 64 additions and 19 deletions

View file

@ -7,31 +7,35 @@ if Settings.redis.clsi_cookie_secondary?
Cookie = require('cookie') Cookie = require('cookie')
logger = require "logger-sharelatex" logger = require "logger-sharelatex"
buildKey = (project_id)->
return "clsiserver:#{project_id}"
clsiCookiesEnabled = Settings.clsiCookie?.key? and Settings.clsiCookie.key.length != 0 clsiCookiesEnabled = Settings.clsiCookie?.key? and Settings.clsiCookie.key.length != 0
module.exports = ClsiCookieManager = module.exports = (backendGroup)->
buildKey : (project_id)->
if backendGroup?
return "clsiserver:#{backendGroup}:#{project_id}"
else
return "clsiserver:#{project_id}"
_getServerId : (project_id, callback = (err, serverId)->)-> _getServerId : (project_id, callback = (err, serverId)->)->
rclient.get buildKey(project_id), (err, serverId)-> rclient.get @buildKey(project_id), (err, serverId)=>
if err? if err?
return callback(err) return callback(err)
if !serverId? or serverId == "" if !serverId? or serverId == ""
return ClsiCookieManager._populateServerIdViaRequest project_id, callback return @_populateServerIdViaRequest project_id, callback
else else
return callback(null, serverId) return callback(null, serverId)
_populateServerIdViaRequest :(project_id, callback = (err, serverId)->)-> _populateServerIdViaRequest :(project_id, callback = (err, serverId)->)->
url = "#{Settings.apis.clsi.url}/project/#{project_id}/status" url = "#{Settings.apis.clsi.url}/project/#{project_id}/status"
request.get url, (err, res, body)-> request.get url, (err, res, body)=>
if err? if err?
logger.err err:err, project_id:project_id, "error getting initial server id for project" logger.err err:err, project_id:project_id, "error getting initial server id for project"
return callback(err) return callback(err)
ClsiCookieManager.setServerId project_id, res, (err, serverId)-> @setServerId project_id, res, (err, serverId)->
if err? if err?
logger.err err:err, project_id:project_id, "error setting server id via populate request" logger.err err:err, project_id:project_id, "error setting server id via populate request"
callback(err, serverId) callback(err, serverId)
@ -43,7 +47,7 @@ module.exports = ClsiCookieManager =
setServerId: (project_id, response, callback = (err, serverId)->)-> setServerId: (project_id, response, callback = (err, serverId)->)->
if !clsiCookiesEnabled if !clsiCookiesEnabled
return callback() return callback()
serverId = ClsiCookieManager._parseServerIdFromResponse(response) serverId = @_parseServerIdFromResponse(response)
if !serverId? # We don't get a cookie back if it hasn't changed if !serverId? # We don't get a cookie back if it hasn't changed
return callback() return callback()
if rclient_secondary? if rclient_secondary?
@ -53,19 +57,19 @@ module.exports = ClsiCookieManager =
_setServerIdInRedis: (rclient, project_id, serverId, callback = (err) ->) -> _setServerIdInRedis: (rclient, project_id, serverId, callback = (err) ->) ->
multi = rclient.multi() multi = rclient.multi()
multi.set buildKey(project_id), serverId multi.set @buildKey(project_id), serverId
multi.expire buildKey(project_id), Settings.clsiCookie.ttl multi.expire @buildKey(project_id), Settings.clsiCookie.ttl
multi.exec callback multi.exec callback
clearServerId: (project_id, callback = (err)->)-> clearServerId: (project_id, callback = (err)->)->
if !clsiCookiesEnabled if !clsiCookiesEnabled
return callback() return callback()
rclient.del buildKey(project_id), callback rclient.del @buildKey(project_id), callback
getCookieJar: (project_id, callback = (err, jar)->)-> getCookieJar: (project_id, callback = (err, jar)->)->
if !clsiCookiesEnabled if !clsiCookiesEnabled
return callback(null, request.jar()) return callback(null, request.jar())
ClsiCookieManager._getServerId project_id, (err, serverId)=> @_getServerId project_id, (err, serverId)=>
if err? if err?
logger.err err:err, project_id:project_id, "error getting server id" logger.err err:err, project_id:project_id, "error getting server id"
return callback(err) return callback(err)

View file

@ -7,7 +7,8 @@ ProjectGetter = require("../Project/ProjectGetter")
ProjectEntityHandler = require("../Project/ProjectEntityHandler") ProjectEntityHandler = require("../Project/ProjectEntityHandler")
logger = require "logger-sharelatex" logger = require "logger-sharelatex"
Url = require("url") Url = require("url")
ClsiCookieManager = require("./ClsiCookieManager") ClsiCookieManager = require("./ClsiCookieManager")()
GoogleCloudClsiCookieManager = require("./ClsiCookieManager")("googlecloud")
ClsiStateManager = require("./ClsiStateManager") ClsiStateManager = require("./ClsiStateManager")
_ = require("underscore") _ = require("underscore")
async = require("async") async = require("async")
@ -75,21 +76,45 @@ module.exports = ClsiManager =
callback() callback()
_makeRequest: (project_id, opts, callback)-> _makeRequest: (project_id, opts, callback)->
ClsiManager._makeGoogleCloudRequest project_id, opts, ->
ClsiCookieManager.getCookieJar project_id, (err, jar)-> ClsiCookieManager.getCookieJar project_id, (err, jar)->
if err? if err?
logger.err err:err, "error getting cookie jar for clsi request" logger.err err:err, "error getting cookie jar for clsi request"
return callback(err) return callback(err)
opts.jar = jar opts.jar = jar
timer = new Metrics.Timer("compile.linode")
request opts, (err, response, body)-> request opts, (err, response, body)->
timer.done()
if err? if err?
logger.err err:err, project_id:project_id, url:opts?.url, "error making request to clsi" logger.err err:err, project_id:project_id, url:opts?.url, "error making request to clsi"
return callback(err) return callback(err)
ClsiCookieManager.setServerId project_id, response, (err)-> ClsiCookieManager.setServerId project_id, response, (err)->
if err? if err?
logger.warn err:err, project_id:project_id, "error setting server id" logger.warn err:err, project_id:project_id, "error setting server id"
return callback err, response, body return callback err, response, body
_makeGoogleCloudRequest: (project_id, baseOpts, callback)->
if !Settings.apis.clsigc?.url?
return callback()
opts = _.clone(baseOpts)
opts.url = opts.url.replace(Settings.apis.clsi.url, Settings.apis.clsigc?.url)
GoogleCloudClsiCookieManager.getCookieJar project_id, (err, jar)->
if err?
logger.err err:err, "error getting cookie jar for clsi request"
return callback(err)
opts.jar = jar
timer = new Metrics.Timer("compile.google")
request opts, (err, response, body)->
timer.done()
if err?
logger.err err:err, project_id:project_id, url:opts?.url, "error making request to clsi"
return callback(err)
GoogleCloudClsiCookieManager.setServerId project_id, response, (err)->
if err?
logger.warn err:err, project_id:project_id, "error setting server id"
return callback err, response, body
_getCompilerUrl: (compileGroup, project_id, user_id, action) -> _getCompilerUrl: (compileGroup, project_id, user_id, action) ->
host = Settings.apis.clsi.url host = Settings.apis.clsi.url
path = "/project/#{project_id}" path = "/project/#{project_id}"

View file

@ -40,7 +40,7 @@ describe "ClsiCookieManager", ->
"request": @request "request": @request
"logger-sharelatex": @logger = { log: sinon.stub(), error: sinon.stub(), warn: sinon.stub() } "logger-sharelatex": @logger = { log: sinon.stub(), error: sinon.stub(), warn: sinon.stub() }
@ClsiCookieManager = SandboxedModule.require modulePath, requires:@requires @ClsiCookieManager = SandboxedModule.require(modulePath, {requires:@requires})()
@ -107,7 +107,7 @@ describe "ClsiCookieManager", ->
it "should not set the server id if clsiCookies are not enabled", (done)-> it "should not set the server id if clsiCookies are not enabled", (done)->
delete @settings.clsiCookie.key delete @settings.clsiCookie.key
@ClsiCookieManager = SandboxedModule.require modulePath, requires:@requires @ClsiCookieManager = SandboxedModule.require(modulePath, requires:@requires)()
@ClsiCookieManager.setServerId @project_id, @response, (err, serverId)=> @ClsiCookieManager.setServerId @project_id, @response, (err, serverId)=>
@redisMulti.exec.called.should.equal false @redisMulti.exec.called.should.equal false
done() done()
@ -129,7 +129,7 @@ describe "ClsiCookieManager", ->
@RedisWrapper.client = sinon.stub() @RedisWrapper.client = sinon.stub()
@RedisWrapper.client.withArgs("clsi_cookie").returns(@redis) @RedisWrapper.client.withArgs("clsi_cookie").returns(@redis)
@RedisWrapper.client.withArgs("clsi_cookie_secondary").returns(@redis_secondary) @RedisWrapper.client.withArgs("clsi_cookie_secondary").returns(@redis_secondary)
@ClsiCookieManager = SandboxedModule.require modulePath, requires:@requires @ClsiCookieManager = SandboxedModule.require(modulePath, requires:@requires)()
@ClsiCookieManager._parseServerIdFromResponse = sinon.stub().returns("clsi-8") @ClsiCookieManager._parseServerIdFromResponse = sinon.stub().returns("clsi-8")
@ClsiCookieManager.setServerId @project_id, @response, (err, serverId)=> @ClsiCookieManager.setServerId @project_id, @response, (err, serverId)=>
@redisSecondaryMulti.set.calledWith("clsiserver:#{@project_id}", "clsi-8").should.equal true @redisSecondaryMulti.set.calledWith("clsiserver:#{@project_id}", "clsi-8").should.equal true
@ -150,7 +150,7 @@ describe "ClsiCookieManager", ->
it "should return empty cookie jar if clsiCookies are not enabled", (done)-> it "should return empty cookie jar if clsiCookies are not enabled", (done)->
delete @settings.clsiCookie.key delete @settings.clsiCookie.key
@ClsiCookieManager = SandboxedModule.require modulePath, requires:@requires @ClsiCookieManager = SandboxedModule.require(modulePath, requires:@requires)()
@ClsiCookieManager.getCookieJar @project_id, (err, jar)-> @ClsiCookieManager.getCookieJar @project_id, (err, jar)->
assert.deepEqual jar, realRequst.jar() assert.deepEqual jar, realRequst.jar()
done() done()

View file

@ -31,7 +31,7 @@ describe "ClsiManager", ->
"../Project/ProjectGetter": @ProjectGetter = {} "../Project/ProjectGetter": @ProjectGetter = {}
"../DocumentUpdater/DocumentUpdaterHandler": @DocumentUpdaterHandler = "../DocumentUpdater/DocumentUpdaterHandler": @DocumentUpdaterHandler =
getProjectDocsIfMatch: sinon.stub().callsArgWith(2,null,null) getProjectDocsIfMatch: sinon.stub().callsArgWith(2,null,null)
"./ClsiCookieManager": @ClsiCookieManager "./ClsiCookieManager": => @ClsiCookieManager
"./ClsiStateManager": @ClsiStateManager "./ClsiStateManager": @ClsiStateManager
"logger-sharelatex": @logger = { log: sinon.stub(), error: sinon.stub(), err: sinon.stub(), warn: sinon.stub() } "logger-sharelatex": @logger = { log: sinon.stub(), error: sinon.stub(), err: sinon.stub(), warn: sinon.stub() }
"request": @request = sinon.stub() "request": @request = sinon.stub()
@ -486,6 +486,22 @@ describe "ClsiManager", ->
done() done()
describe "_makeGoogleCloudRequest", ->
beforeEach ->
@settings.apis.clsigc =
url : "https://compiles.googlecloud.test"
@response = {there:"something"}
@request.callsArgWith(1, null, @response)
it "should change the domain on the url", (done)->
@opts =
url: @ClsiManager._getCompilerUrl(null, @project_id)
@ClsiManager._makeGoogleCloudRequest @project_id, @opts, =>
args = @request.args[0]
args[0].url.should.equal "https://compiles.googlecloud.test/project/#{@project_id}"
done()