lockService.js 19.80 KiB
/**
 * @name : lockService.js
 * @description :: Service responsible for locking mechanism
 * @author      :: Sourav Dey
 */
var async = require('async')
var path = require('path')
var respUtil = require('response_util')
var LOG = require('sb_logger_util')
var configUtil = require('sb-config-util')
var request = require('request')
var messageUtils = require('./messageUtil')
var utilsService = require('../service/utilsService')
var lodash = require('lodash')
var dbModel = require('./../utils/cassandraUtil').getConnections('lock_db')
var Joi = require('joi')
var filename = path.basename(__filename)
var contentMessage = messageUtils.CONTENT
var responseCode = messageUtils.RESPONSE_CODE
var defaultLockExpiryTime = parseInt(configUtil.getConfig('LOCK_EXPIRY_TIME'))
var contentProvider = require('sb_content_provider_util')
function createLock (req, response) {
  var lockId = dbModel.uuid()
  var newDateObj = createExpiryTime()
  var data = req.body
  var rspObj = req.rspObj
  var contentBody = ''
  var versionKey = ''
  if (!req.get('x-device-id')) {
    rspObj.errCode = contentMessage.CREATE_LOCK.FAILED_CODE
    rspObj.errMsg = contentMessage.CREATE_LOCK.DEVICE_ID_MISSING
    rspObj.responseCode = responseCode.CLIENT_ERROR
    return response.status(400).send(respUtil.errorResponse(rspObj))
  if (req.get('x-authenticated-userid') !== data.request.createdBy) {
    rspObj.errCode = contentMessage.CREATE_LOCK.FAILED_CODE
    rspObj.errMsg = contentMessage.CREATE_LOCK.UNAUTHORIZED
    rspObj.responseCode = responseCode.CLIENT_ERROR
    return response.status(403).send(respUtil.errorResponse(rspObj))
  if (!data.request) {
    LOG.error(utilsService.getLoggerData(rspObj, 'ERROR', filename, 'createLockAPI',
      'Error due to required params are missing', data.request))
    rspObj.errCode = contentMessage.CREATE_LOCK.MISSING_CODE
    rspObj.errMsg = contentMessage.CREATE_LOCK.MISSING_MESSAGE
    rspObj.responseCode = responseCode.CLIENT_ERROR
    return response.status(400).send(respUtil.errorResponse(rspObj))
  var result = validateCreateLockRequestBody(data.request)
  if (result.error) {
    rspObj.errCode = contentMessage.CREATE_LOCK.MISSING_CODE
    rspObj.errMsg = result.error.details[0].message
    rspObj.responseCode = responseCode.CLIENT_ERROR
    return response.status(400).send(respUtil.errorResponse(rspObj))
  // Adding objectData in telemetry
  if (rspObj.telemetryData) {
    rspObj.telemetryData.object = utilsService.getObjectData(data.request.resourceId, 'contentLock', '', {})
  async.waterfall([
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
function (CBW) { checkResourceTypeValidation(req, function (res, body) { if (!res) { LOG.error(utilsService.getLoggerData(rspObj, 'ERROR', filename, 'createLockAPI', 'Error as resource type validation failed', 'res = ' + res + ', body = ' + body)) rspObj.errCode = contentMessage.CREATE_LOCK.FAILED_CODE rspObj.errMsg = body.message rspObj.responseCode = responseCode.CLIENT_ERROR return response.status(412).send(respUtil.errorResponse(rspObj)) } contentBody = body versionKey = contentBody.contentdata.versionKey CBW() }) }, function (CBW) { dbModel.instance.lock.findOne({ resourceId: data.request.resourceId, resourceType: data.request.resourceType }, function (error, result) { if (error) { LOG.error(utilsService.getLoggerData(rspObj, 'ERROR', filename, 'createLockAPI', 'error while getting data from db', error)) rspObj.errCode = contentMessage.CREATE_LOCK.FAILED_CODE rspObj.errMsg = contentMessage.CREATE_LOCK.FAILED_MESSAGE rspObj.responseCode = responseCode.SERVER_ERROR return response.status(500).send(respUtil.errorResponse(rspObj)) } else if (result) { if (req.get('x-authenticated-userid') === result.createdBy && req.get('x-device-id') === result.deviceId && data.request.resourceType === result.resourceType) { rspObj.result.lockKey = result.lockId rspObj.result.expiresAt = result.expiresAt rspObj.result.expiresIn = defaultLockExpiryTime / 60 rspObj.result.versionKey = versionKey return response.status(200).send(respUtil.successResponse(rspObj)) } else if (req.get('x-authenticated-userid') === result.createdBy) { rspObj.errCode = contentMessage.CREATE_LOCK.SELF_LOCKED_CODE rspObj.errMsg = contentMessage.CREATE_LOCK.SAME_USER_ERR_MSG var statusCode = 400 } else { rspObj.errCode = contentMessage.CREATE_LOCK.LOCKED_CODE statusCode = 423 try { var user = JSON.parse(result.creatorInfo).name } catch (e) { user = 'another user' } rspObj.errMsg = contentMessage.CREATE_LOCK.ALREADY_LOCKED.replace(/{{Name}}/g, user) } rspObj.responseCode = responseCode.CLIENT_ERROR return response.status(statusCode).send(respUtil.errorResponse(rspObj)) } else { var lockObject = new dbModel.instance.lock({ lockId: lockId, resourceId: data.request.resourceId, resourceType: data.request.resourceType, resourceInfo: data.request.resourceInfo, createdBy: data.request.createdBy, creatorInfo: data.request.creatorInfo, deviceId: req.get('x-device-id'), createdOn: new Date(), expiresAt: newDateObj }) lockObject.save({ ttl: defaultLockExpiryTime }, function (err, resp) { if (err) { LOG.error(utilsService.getLoggerData(rspObj, 'ERROR', filename, 'createLockAPI', 'error while saving lock data from db', err)) rspObj.errCode = contentMessage.CREATE_LOCK.FAILED_CODE rspObj.errMsg = contentMessage.CREATE_LOCK.FAILED_MESSAGE rspObj.responseCode = responseCode.SERVER_ERROR return response.status(500).send(respUtil.errorResponse(rspObj))
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
} else CBW() }) } }) }, function (CBW) { var ekStepReqData = { 'request': { 'content': { 'lockKey': lockId, 'versionKey': versionKey } } } contentProvider.updateContent(ekStepReqData, data.request.resourceId, req.headers, function (err, res) { if (err || res.responseCode !== responseCode.SUCCESS) { LOG.error(utilsService.getLoggerData(rspObj, 'ERROR', filename, 'createLockAPI', 'Updating content failed with lock key', 'err = ' + err + ', res = ' + res)) // Sending success CBW as content is already locked in db and ignoring content update error CBW(null, res) } else { versionKey = lodash.get(res.result.versionKey) CBW(null, res) } }) }, function () { rspObj.result.lockKey = lockId rspObj.result.expiresAt = newDateObj rspObj.result.expiresIn = defaultLockExpiryTime / 60 rspObj.result.versionKey = versionKey return response.status(200).send(respUtil.successResponse(rspObj)) } ]) } function refreshLock (req, response) { var lockId = '' var contentBody = '' var newDateObj = createExpiryTime() var data = req.body var rspObj = req.rspObj if (!req.get('x-device-id')) { rspObj.errCode = contentMessage.REFRESH_LOCK.FAILED_CODE rspObj.errMsg = contentMessage.REFRESH_LOCK.DEVICE_ID_MISSING rspObj.responseCode = responseCode.CLIENT_ERROR return response.status(400).send(respUtil.errorResponse(rspObj)) } if (!data.request) { LOG.error(utilsService.getLoggerData(rspObj, 'ERROR', filename, 'refreshLockAPI', 'Error due to required params are missing', data.request)) rspObj.errCode = contentMessage.REFRESH_LOCK.MISSING_CODE rspObj.errMsg = contentMessage.REFRESH_LOCK.MISSING_MESSAGE rspObj.responseCode = responseCode.CLIENT_ERROR return response.status(400).send(respUtil.errorResponse(rspObj)) } var result = validateRefreshLockRequestBody(data.request) if (result.error) { rspObj.errCode = contentMessage.REFRESH_LOCK.MISSING_CODE rspObj.errMsg = result.error.details[0].message rspObj.responseCode = responseCode.CLIENT_ERROR return response.status(400).send(respUtil.errorResponse(rspObj)) } // Adding objectData in telemetry if (rspObj.telemetryData) { rspObj.telemetryData.object = utilsService.getObjectData(data.request.resourceId, 'refreshLock', '', {})
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
} async.waterfall([ function (CBW) { checkResourceTypeValidation(req, function (res, body) { if (!res) { LOG.error(utilsService.getLoggerData(rspObj, 'ERROR', filename, 'refreshLockAPI', 'Error as resource type validation failed', 'res = ' + res + ', body = ' + body)) rspObj.errCode = contentMessage.REFRESH_LOCK.FAILED_CODE rspObj.errMsg = body.message rspObj.responseCode = responseCode.CLIENT_ERROR return response.status(412).send(respUtil.errorResponse(rspObj)) } contentBody = body CBW() }) }, function (CBW) { dbModel.instance.lock.findOne({ resourceId: data.request.resourceId, resourceType: data.request.resourceType }, function (error, result) { if (error) { LOG.error(utilsService.getLoggerData(rspObj, 'ERROR', filename, 'refreshLockAPI', 'error while getting data from db for refreshing lock', error)) rspObj.errCode = contentMessage.REFRESH_LOCK.FAILED_CODE rspObj.errMsg = contentMessage.REFRESH_LOCK.FAILED_MESSAGE rspObj.responseCode = responseCode.SERVER_ERROR return response.status(500).send(respUtil.errorResponse(rspObj)) } else if (result) { lockId = result.lockId if (result.createdBy !== req.get('x-authenticated-userid')) { rspObj.errCode = contentMessage.REFRESH_LOCK.FAILED_CODE rspObj.errMsg = contentMessage.REFRESH_LOCK.UNAUTHORIZED rspObj.responseCode = responseCode.CLIENT_ERROR return response.status(403).send(respUtil.errorResponse(rspObj)) } var options = { ttl: defaultLockExpiryTime, if_exists: true } dbModel.instance.lock.update( { resourceId: data.request.resourceId, resourceType: data.request.resourceType }, { lockId: result.lockId, resourceInfo: result.resourceInfo, createdBy: result.createdBy, creatorInfo: result.creatorInfo, deviceId: result.deviceId, createdOn: result.createdOn, expiresAt: newDateObj }, options, function (err) { if (err) { LOG.error(utilsService.getLoggerData(rspObj, 'ERROR', filename, 'refreshLockAPI', 'error while updating lock data from db', err)) rspObj.errCode = contentMessage.REFRESH_LOCK.FAILED_CODE rspObj.errMsg = contentMessage.REFRESH_LOCK.FAILED_MESSAGE rspObj.responseCode = responseCode.SERVER_ERROR return response.status(500).send(respUtil.errorResponse(rspObj)) } CBW() }) } else { var requestBody = req.body requestBody.request.resourceInfo = JSON.stringify(contentBody.contentdata) requestBody.request.createdBy = req.get('x-authenticated-userid') requestBody.request.creatorInfo = JSON.stringify({'name': req.rspObj.userName, 'id': req.get('x-authenticated-userid')}) if (contentBody.contentdata.lockKey === data.request.lockId) { delete requestBody.request.lockId createLock(req, response) } else { LOG.error(utilsService.getLoggerData(rspObj, 'ERROR', filename, 'refreshLockAPI', 'no data found from db for refreshing lock', data.request)) rspObj.errCode = contentMessage.REFRESH_LOCK.FAILED_CODE rspObj.errMsg = contentMessage.REFRESH_LOCK.NOT_FOUND_FAILED_MESSAGE rspObj.responseCode = responseCode.CLIENT_ERROR
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
return response.status(400).send(respUtil.errorResponse(rspObj)) } } }) }, function () { rspObj.result.lockKey = lockId rspObj.result.expiresAt = newDateObj rspObj.result.expiresIn = defaultLockExpiryTime / 60 return response.status(200).send(respUtil.successResponse(rspObj)) } ]) } function retireLock (req, response) { var data = req.body var rspObj = req.rspObj if (!req.get('x-device-id')) { rspObj.errCode = contentMessage.RETIRE_LOCK.FAILED_CODE rspObj.errMsg = contentMessage.RETIRE_LOCK.DEVICE_ID_MISSING rspObj.responseCode = responseCode.CLIENT_ERROR return response.status(400).send(respUtil.errorResponse(rspObj)) } if (!data.request) { LOG.error(utilsService.getLoggerData(rspObj, 'ERROR', filename, 'retireLockAPI', 'Error due to required params are missing', data.request)) rspObj.errCode = contentMessage.RETIRE_LOCK.MISSING_CODE rspObj.errMsg = contentMessage.RETIRE_LOCK.MISSING_MESSAGE rspObj.responseCode = responseCode.CLIENT_ERROR return response.status(400).send(respUtil.errorResponse(rspObj)) } var result = validateCommonRequestBody(data.request) if (result.error) { rspObj.errCode = contentMessage.RETIRE_LOCK.MISSING_CODE rspObj.errMsg = result.error.details[0].message rspObj.responseCode = responseCode.CLIENT_ERROR return response.status(400).send(respUtil.errorResponse(rspObj)) } // Adding objectData in telemetry if (rspObj.telemetryData) { rspObj.telemetryData.object = utilsService.getObjectData(data.request.resourceId, 'retireLock', '', {}) } async.waterfall([ function (CBW) { checkResourceTypeValidation(req, function (res, body) { if (!res) { LOG.error(utilsService.getLoggerData(rspObj, 'ERROR', filename, 'retireLockAPI', 'Error as resource type validation failed', 'res = ' + res + ', body = ' + body)) rspObj.errCode = contentMessage.RETIRE_LOCK.FAILED_CODE rspObj.errMsg = body.message rspObj.responseCode = responseCode.CLIENT_ERROR return response.status(412).send(respUtil.errorResponse(rspObj)) } CBW() }) }, function (CBW) { dbModel.instance.lock.findOne({ resourceId: data.request.resourceId }, { resourceType: data.request.resourceType }, function (error, result) { if (error) { LOG.error(utilsService.getLoggerData(rspObj, 'ERROR', filename, 'retireLockAPI', 'error while getting data from db for retiring lock', error)) rspObj.errCode = contentMessage.RETIRE_LOCK.FAILED_CODE rspObj.errMsg = contentMessage.RETIRE_LOCK.FAILED_MESSAGE
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
rspObj.responseCode = responseCode.SERVER_ERROR return response.status(500).send(respUtil.errorResponse(rspObj)) } else if (result) { if (result.createdBy !== req.get('x-authenticated-userid')) { rspObj.errCode = contentMessage.RETIRE_LOCK.FAILED_CODE rspObj.errMsg = contentMessage.RETIRE_LOCK.UNAUTHORIZED rspObj.responseCode = responseCode.CLIENT_ERROR return response.status(403).send(respUtil.errorResponse(rspObj)) } dbModel.instance.lock.delete({ resourceId: data.request.resourceId }, { resourceType: data.request.resourceType }, function (err) { if (err) { LOG.error(utilsService.getLoggerData(rspObj, 'ERROR', filename, 'retireLockAPI', 'error while deleting lock data from db', err)) rspObj.errCode = contentMessage.RETIRE_LOCK.FAILED_CODE rspObj.errMsg = contentMessage.RETIRE_LOCK.FAILED_MESSAGE rspObj.responseCode = responseCode.SERVER_ERROR return response.status(500).send(respUtil.errorResponse(rspObj)) } else CBW() }) } else { LOG.error(utilsService.getLoggerData(rspObj, 'ERROR', filename, 'retireLockAPI', 'no data found from db for retiring lock', data.request)) rspObj.errCode = contentMessage.RETIRE_LOCK.FAILED_CODE rspObj.errMsg = contentMessage.RETIRE_LOCK.NOT_FOUND_FAILED_MESSAGE rspObj.responseCode = responseCode.CLIENT_ERROR return response.status(400).send(respUtil.errorResponse(rspObj)) } }) }, function () { return response.status(200).send(respUtil.successResponse(rspObj)) } ]) } function listLock (req, response) { var data = req.body var rspObj = req.rspObj if (!req.get('x-device-id')) { rspObj.errCode = contentMessage.LIST_LOCK.FAILED_CODE rspObj.errMsg = contentMessage.LIST_LOCK.DEVICE_ID_MISSING rspObj.responseCode = responseCode.CLIENT_ERROR return response.status(400).send(respUtil.errorResponse(rspObj)) } // Adding objectData in telemetry if (rspObj.telemetryData) { rspObj.telemetryData.object = utilsService.getObjectData(data, 'ListLockAPI', '', {}) } var query = {} if (lodash.get(data, 'request.filters.resourceId')) { if (typeof data.request.filters === 'string') { query = { resourceId: { '$in': [data.request.filters.resourceId] } } } else { query = { resourceId: { '$in': data.request.filters.resourceId } } } } dbModel.instance.lock.find(query, function (error, result) { if (error) { LOG.error(utilsService.getLoggerData(rspObj, 'ERROR', filename, 'ListLockAPI', 'error while fetching lock list data from db', error)) rspObj.errCode = contentMessage.LIST_LOCK.FAILED_CODE rspObj.errMsg = contentMessage.LIST_LOCK.FAILED_MESSAGE rspObj.responseCode = responseCode.SERVER_ERROR return response.status(500).send(respUtil.errorResponse(rspObj))
421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
} else { rspObj.result.count = result.length rspObj.result.data = result return response.status(200).send(respUtil.successResponse(rspObj)) } }) } function validateCreateLockRequestBody (request) { var schema = Joi.object().keys({ resourceId: Joi.string().required(), resourceType: Joi.string().required(), resourceInfo: Joi.string().required(), createdBy: Joi.string().required(), creatorInfo: Joi.string().required() }) return Joi.validate(request, schema) } function validateRefreshLockRequestBody (request) { var schema = Joi.object().keys({ lockId: Joi.string().required(), resourceId: Joi.string().required(), resourceType: Joi.string().required() }) return Joi.validate(request, schema) } function validateCommonRequestBody (request) { var schema = Joi.object().keys({ resourceId: Joi.string().required(), resourceType: Joi.string().required() }) return Joi.validate(request, schema) } function createExpiryTime () { var dateObj = new Date() dateObj.setTime(new Date().getTime() + (defaultLockExpiryTime * 1000)) return dateObj } function checkResourceTypeValidation (req, CBW) { switch (lodash.lowerCase(req.body.request.resourceType)) { case 'content': var httpOptions = { url: configUtil.getConfig('CONTENT_SERVICE_LOCAL_BASE_URL') + '/v1/content/getContentLockValidation', headers: req.headers, method: 'POST', body: req.body, json: true } request(httpOptions, function (err, httpResponse, body) { if (err) { LOG.error(utilsService.getLoggerData(req.rspObj, 'ERROR', filename, 'checkResourceTypeValidation', 'error in lock service in checkResourceTypeValidation', err)) CBW(false, err) } else if (lodash.get(body, 'result.message')) { CBW(body.result.validation, body.result) } else { CBW(false, body) } }) break default: CBW(false, 'Resource type is not valid') } } module.exports = { createLock, refreshLock, retireLock, listLock }
491