UNPKG

pvserverhelper

Version:

This is an npm module design to perform common uses with pVelocity's pvserver

1,333 lines (1,199 loc) 47.6 kB
/*global PV*/ 'use strict'; /* jshint strict: true */ /* jshint node: true */ /* jshint unused: false */ var iconv = require('iconv-lite'); var fs = require('fs'); var prom = require('bluebird'); var mongodb = require('mongodb'); var pvserver = require('pvserver'); var request = require('request'); var Converter = require('csvtojson').Converter; require('pvjs'); module.exports = { sessionJsapiCache: {}, addOrGetSessionJsapiObject: function(jsapi, sessionId) { if (this.sessionJsapiCache.hasOwnProperty(sessionId)) { return this.sessionJsapiCache[sessionId]; } else { jsapi.isCached = true; this.sessionJsapiCache[sessionId] = jsapi; return jsapi; } }, getSessionJsapiObject: function(jsapi, sessionId) { if (PV.isObject(this.sessionJsapiCache[sessionId])) { return this.sessionJsapiCache[sessionId]; } else { return jsapi; } }, removeSessionJsapiObject: function(jsapi, sessionId) { if (PV.isObject(this.sessionJsapiCache[sessionId])) { var cachedJsapi = this.sessionJsapiCache[sessionId]; cachedJsapi.isCached = null; delete this.sessionJsapiCache[sessionId]; return cachedJsapi; } else { return jsapi; } }, cleanupForNonCached: function(jsapi) { if (PV.isBoolean(jsapi.isCached) && jsapi.isCached) { } else { this.cleanup(jsapi); } }, serializePromises: function(workFunction, workContext, workArray) { var results = []; return new prom(function(resolve, reject) { var func = workFunction; var context = workContext; var next = function(curIndex) { if (curIndex < workArray.length) { if (PV.isArray(workFunction)) { func = workFunction[curIndex]; } if (PV.isArray(workContext)) { context = workContext[curIndex]; } func.apply(context, workArray[curIndex]).then(function(result) { results.push(result); setImmediate(function() { next(curIndex + 1); }); }).catch(function(err) { reject(err); }); } else { resolve(results); } }; try { next(0); } catch (err) { reject(err); } }); }, cleanup: function(jsapi) { if (jsapi.mongoConn) { jsapi.mongoConn.close(); jsapi.mongoConn = null; } if (jsapi.sfdcConn) { if (PV.isObject(jsapi.sfdc) === false || jsapi.sfdc.isSession !== true) { jsapi.sfdcConn.logout(); } jsapi.sfdcConn = null; } if (jsapi.pv) { jsapi.pv.logout(); jsapi.pv = null; } }, returnImmediately: function(callback) { throw { 'code': 'RETURN_IMMEDIATELY', 'callback': function() { callback(null, null); } }; }, scriptErrHandler: function(jsapi, callback, passError) { var fn = function(err) { this.cleanupForNonCached(jsapi); if (PV.isString(err.message)) { err.message = err.message; } else if (PV.isString(err.Message)) { err.message = err.Message; } else if (PV.isFunction(err.message)) { err.message = err.message(); } else { err.message = 'No Relevant Message'; } if (PV.isString(err.code)) { err.code = err.code; } else if (PV.isString(err.Code)) { err.Code = err.Code; } else if (PV.isFunction(err.code)) { err.code = err.code(); } else { err.code = 'JSAPI2_UNKNOWN_ERROR'; } if (err.code === 'RETURN_IMMEDIATELY' && typeof(err.callback) === 'function') { err.callback(); } else { if (PV.isBoolean(passError) && passError) { callback(null, { 'code': `${err.code}`, 'message': `${err.message}` }); } else { callback({ 'code': `${err.code}`, 'message': `${err.message}` }, null); } } }.bind(this); return fn; }, genericErrHandler: function(jsapi, callback, passError) { var fn = function(err) { this.cleanupForNonCached(jsapi); if (PV.isBoolean(passError) && passError) { callback(null, { 'code': 'JSAPI2_UNKNOWN_ERROR', 'message': `The function encountered an unknown error.\n${JSON.stringify(err)}\n` }); } else { callback({ 'code': 'JSAPI2_UNKNOWN_ERROR', 'message': `The function encountered an unknown error.\n${JSON.stringify(err)}\n` }, null); } }.bind(this); return fn; }, setupLogger: function(jsapi, enableConsoleInfo) { if (PV.isObject(jsapi.logger) === false) { jsapi.logger = { enableConsoleInfo: enableConsoleInfo }; } jsapi.logger.info = function(message, noTimeStamp) { var timedMsg = ''; if (noTimeStamp) { timedMsg = message; } else { timedMsg = PV.getTimeStamp() + ' - ' + message; } if (PV.isObject(jsapi.logger) && PV.isFunction(jsapi.logger.log)) { jsapi.logger.log('info', timedMsg); } else { if (jsapi.logger.enableConsoleInfo === true) { console.log('INFO: ' + timedMsg); } } }; jsapi.logger.error = function(error, throwError) { var message = 'ERROR'; if (PV.isString(error.message)) { message = error.message; } else if (PV.isString(error.Message)) { message = error.Message; } var timedMsg = PV.getTimeStamp() + ' - ' + message; if (PV.isObject(jsapi.logger) && PV.isFunction(jsapi.logger.log)) { jsapi.logger.log('error', timedMsg); } else { console.log('ERROR: ' + timedMsg); } if (throwError !== false) { throw error; } }; jsapi.logger.startTime = function(message) { var timerObj = { startTime: new Date(), message: message }; return timerObj; }; jsapi.logger.endTime = function(timerObj) { var timedMsg = timerObj.message; var endTime = new Date(); var elapsedTime = (endTime - timerObj.startTime) / 1e3; timedMsg = timedMsg + ' - ElaspedTime: ' + elapsedTime + 's'; if (PV.isObject(jsapi.logger) && PV.isFunction(jsapi.logger.log)) { jsapi.logger.log('TIMER', timedMsg); } else { console.log('TIMER: ' + timedMsg); } }; }, convertFile: function(source, target, options, decoding, encoding) { var converter = null; if (PV.isObject(options)) { converter = new Converter(options); } else { converter = new Converter(); } return new prom(function(resolve, reject) { var rd = fs.createReadStream(source); rd.on('error', rejectCleanup); var wr = fs.createWriteStream(target); wr.on('error', rejectCleanup); function rejectCleanup(err) { rd.destroy(); wr.end(); reject(err); } wr.on('finish', resolve); if (PV.isString(decoding) && PV.isString(encoding)) { rd.pipe(iconv.decodeStream(decoding)) .pipe(iconv.encodeStream(encoding)) .pipe(converter) .pipe(wr); } else { rd.pipe(converter).pipe(wr); } }); }, execServlet: function(jsapi, username, password, operation, params, headers) { var options = { headers: { 'user-agent': 'pvserverhelper', 'content-type': 'application/x-www-form-urlencoded', 'cache-control': 'no-cache', 'pragma': 'no-cache', 'authorization': 'Basic ' + new Buffer(username + ':' + password).toString('base64') } }; if (PV.isObject(headers)) { for (var headerKey in headers) { if (headerKey !== 'authorization') { options.headers[headerKey] = headers[headerKey]; } } } options.url = jsapi.pv.urlScheme + '://' + jsapi.pv.hostName + ':' + jsapi.pv.hostPort + '/admin/' + operation; if (PV.isObject(params)) { var args = [] for (var paramKey in params) { args.push(paramKey + '=' + params[paramKey]); } options.url = options.url + '?' + args.join('&'); } options.method = 'POST'; return this.httpMethod(options); }, httpMethod: function(options) { return new prom(function(resolve, reject) { request(options, function(err, httpResponse, body) { if (err) { reject(err); } else { resolve(body); } }); }); }, exec: function(jsapi, cmd, options) { return new prom(function(resolve, reject) { try { var exec = require('child_process').exec; if (PV.isObject(options) === false) { options = { maxBuffer: 1024 * 500 }; } exec(cmd, options, function(error, stdout, stderr) { if (error) { reject(error); } else { jsapi.logger.info('stdout: ' + stdout, true); jsapi.logger.info('stderr: ' + stderr, true); resolve(); } }); } catch (err) { reject(err); } }); }, bulkExecute: function(bulk) { return new prom(function(resolve, reject) { bulk.execute(function(err, result) { if (err) { reject(err); } else { resolve(result); } }); }); }, dropSomeCollections: function(jsapi, matchFunction) { return jsapi.mongoConn.listCollections({}).toArray().then(function(result) { var promises = []; result.forEach(function(collection) { if (matchFunction(collection.name)) { promises.push(jsapi.mongoConn.collection(collection.name).dropAsync()); } }); return prom.all(promises); }); }, dropCollection: function(jsapi, collectionName) { return jsapi.mongoConn.listCollections({ name: collectionName }).toArray().then(function(result) { if (result.length > 0) { return jsapi.mongoConn.collection(collectionName).dropAsync(); } else { return; } }); }, createCollection: function(jsapi, collectionName, drop, indices) { return jsapi.mongoConn.listCollections({ name: collectionName }).toArray().then(function(result) { if (result.length === 0) { return jsapi.mongoConn.createCollectionAsync(collectionName); } else if (drop) { return jsapi.mongoConn.collection(collectionName).dropAsync(); } else { return false; } }).then(function(result) { if (PV.isObject(result)) { return result; } else if (drop) { return jsapi.mongoConn.createCollectionAsync(collectionName); } else { return; } }).then(function(result) { if (PV.isObject(result) && (PV.isArray(indices)) || PV.isObject(indices)) { return this.createIndices(jsapi, collectionName, indices); } else { return result; } }.bind(this)); }, createIndices: function(jsapi, collectionName, indices) { var promises = []; var keys = {}; var options = {}; if (PV.isArray(indices)) { indices.forEach(function(index) { keys = index.keys; if (PV.isObject(keys)) { options = index.options; if (PV.isObject(options) === false) { options = {}; } promises.push(jsapi.mongoConn.collection(collectionName).ensureIndexAsync(keys, options)); } }); } else if (PV.isObject(indices)) { for (var prop in indices) { keys = {}; options = {}; if (prop !== '_id_') { var indicesInfo = indices[prop]; options.name = prop; for (var i = 0; i < indicesInfo.length; i++) { var index = indicesInfo[i]; keys[index[0]] = index[1]; } promises.push(jsapi.mongoConn.collection(collectionName).ensureIndexAsync(keys, options)); } } } return prom.all(promises); }, // this replaces your source collection with a projection that includes the lookup fields // lookupField: field in lookupCollectionName that is being looked up // sourceKey: field in sourceCollectionName used as a key to match with lookupCollectionName // lookupKey: fields in lookupCollectionName used $project to construct a key that matches sourceKey // defaultValue: a $set value used to set a default for the lookupField // rename: field that the lookup will be set to, defaulted to lookupField // var lookupInfo = { // 'lookupField': { // sourceKey: 'sourceKey', // lookupKey: { // $toUpper: { // $concat: ['$lookupProperty1', '-', '$lookupProperty2'] // } // }, // defaultValue: 'defaultValue', // rename: 'rename' // } // }; aggregateLookup: function(jsapi, sourceCollectionName, lookupCollectionName, lookupInfo, lookupOperations) { var timestamp = PV.createHash(PV.getTimeStamp()); var tempLookupCollection = 'AG_' + PV.createHash(lookupCollectionName + '_' + timestamp); var tempSourceCollection = 'AG_' + PV.createHash(sourceCollectionName + '_' + timestamp); var lookupDuplicate = []; var indices = []; var project = { _id: 0 }; for (var lookupField in lookupInfo) { project[lookupField] = '$' + lookupField; var lookup = lookupInfo[lookupField]; var lookupKeyString = JSON.stringify(lookup.lookupKey); var lookupKey = PV.createHash(lookupKeyString + '1_' + timestamp); if (lookupDuplicate.indexOf(lookupKeyString) === -1) { project[lookupKey] = PV.isString(lookup.lookupKey) ? '$' + lookup.lookupKey : lookup.lookupKey; lookupDuplicate.push(lookupKeyString); var keys = {}; keys[lookupKey] = 1; indices.push({ keys: keys }); } } lookupDuplicate = []; var promises = []; promises.push(jsapi.mongoConn.collection(sourceCollectionName).indexInformationAsync()); promises.push(this.createCollection(jsapi, tempLookupCollection, true, indices)); return prom.all(promises).then(function(results) { var pipeline = []; if (PV.isArray(lookupOperations)) { lookupOperations.forEach(function(operation) { pipeline.push(operation); }); } pipeline.push({ $project: project }); pipeline.push({ $out: tempLookupCollection }); var promises = []; promises.push(this.getAggregateProjectMapping(jsapi, sourceCollectionName)); promises.push(this.createCollection(jsapi, tempSourceCollection, true, results[0])); promises.push(jsapi.mongoConn.collection(lookupCollectionName).aggregateAsync(pipeline, { allowDiskUse: true })); return prom.all(promises); }.bind(this)).then(function(results) { var project = results[0]; var pipelineLookup = []; var pipelineUnwind = []; var tempKeyDuplicate = []; for (var lookupField in lookupInfo) { var lookup = lookupInfo[lookupField]; var lookupKeyString = JSON.stringify(lookup.lookupKey); var lookupKey = PV.createHash(lookupKeyString + '1_' + timestamp); var tempKey = PV.createHash(lookup.sourceKey + '2_' + timestamp); var lookupFieldKey = PV.createHash(lookupField + '3_' + timestamp); if (lookupDuplicate.indexOf(lookupKeyString) === -1 && tempKeyDuplicate.indexOf(tempKey) === -1) { pipelineLookup.push({ $lookup: { from: tempLookupCollection, localField: lookup.sourceKey, foreignField: lookupKey, as: tempKey } }); pipelineUnwind.push({ $unwind: { path: '$' + tempKey, preserveNullAndEmptyArrays: true } }); } project[lookupFieldKey] = '$' + tempKey + '.' + lookupField; if (lookupDuplicate.indexOf(lookupKeyString) === -1) { lookupDuplicate.push(lookupKey); } if (tempKeyDuplicate.indexOf(tempKey) === -1) { tempKeyDuplicate.push(tempKey); } } var pipeline = pipelineLookup.concat(pipelineUnwind); pipeline.push({ $project: project }); pipeline.push({ $out: tempSourceCollection }); return jsapi.mongoConn.collection(sourceCollectionName).aggregateAsync(pipeline, { allowDiskUse: true }); }.bind(this)).then(function() { var promises = []; promises.push(this.dropCollection(jsapi, tempLookupCollection)); promises.push(this.dropCollection(jsapi, sourceCollectionName)); var bulk = jsapi.mongoConn.collection(tempSourceCollection).initializeOrderedBulkOp(); for (var lookupField in lookupInfo) { var lookup = lookupInfo[lookupField]; var lookupFieldKey = PV.createHash(lookupField + '3_' + timestamp); var defaultValue = lookup.defaultValue; if (PV.isNull(defaultValue) === false && PV.isUndefined(defaultValue) === false) { var filter = {}; filter[lookupFieldKey] = { $exists: false }; var set = {}; set[PV.isString(lookup.rename) ? lookup.rename : lookupField] = defaultValue; bulk.find(filter).update({ $set: set }); } var rename = {}; rename[lookupFieldKey] = PV.isString(lookup.rename) ? lookup.rename : lookupField; var filter2 = {}; filter2[lookupFieldKey] = { $exists: true }; bulk.find(filter2).update({ $rename: rename }); promises.push(this.bulkExecute(bulk)); } return prom.all(promises); }.bind(this)).then(function() { return jsapi.mongoConn.collection(tempSourceCollection).rename(sourceCollectionName); }.bind(this)); }, createExpressionMapping: function(objectOrArray, accumulator, aggregated, include_id) { var arr = null; if (PV.isArray(objectOrArray)) { arr = objectOrArray; } else if (PV.isObject(objectOrArray)) { arr = Object.keys(objectOrArray); } var project = {}; if (PV.isArray(arr)) { arr.forEach(function(element) { var value = null; if (aggregated === true) { value = '$_id.' + element; } else { value = '$' + element; } if (PV.isString(accumulator)) { project[element] = {}; project[element][accumulator] = value; } else { project[element] = value; } }); } if (include_id !== true) { project._id = 0; } return project; }, find: function(jsapi, collectionName, id, projection) { var filter = {}; if (PV.isString(id)) { filter._id = new mongodb.ObjectId.createFromHexString(id); } else if (PV.isObject(id)) { filter._id = id; } if (PV.isObject(projection) === false) { projection = {}; } return jsapi.mongoConn.collection(collectionName).find(filter, projection).toArrayAsync(); }, copy: function(jsapi, sourceCollection, targetCollection, filter, projection, overwriteKey) { if (PV.isObject(filter) === false) { filter = {}; } if (PV.isObject(projection) === false) { projection = {}; } return jsapi.mongoConn.collection(sourceCollection).find(filter, projection).toArrayAsync().then(function(result) { if (result.length > 0) { if (PV.isString(overwriteKey)) { var bulk = jsapi.mongoConn.collection(targetCollection).initializeOrderedBulkOp(); result.forEach(function(item) { var filter2 = {}; filter2[overwriteKey] = item[overwriteKey]; bulk.find(filter2).remove(); bulk.insert(item); }); return this.bulkExecute(bulk); } else { return jsapi.mongoConn.collection(targetCollection).insertManyAsync(result); } } else { return result; } }.bind(this)); }, move: function(jsapi, sourceCollection, targetCollection, filter, cleanId) { var projection = {}; if (cleanId === true) { projection = { _id: 0 }; } return this.copy(jsapi, sourceCollection, targetCollection, filter, projection).then(function(result) { if (PV.isObject(filter) === false) { return this.dropCollection(jsapi, sourceCollection); } else { return jsapi.mongoConn.collection(sourceCollection).removeAsync(filter); } }.bind(this)); }, getAggregateProjectMapping: function(jsapi, collectionName, filter) { if (PV.isObject(filter) === false) { filter = {}; } return jsapi.mongoConn.collection(collectionName).findOneAsync(filter).then(function(result) { return this.createExpressionMapping(result); }.bind(this)); }, cleanupChildren: function(jsapi, collectionName, id, childrenMap) { var projection = {}; for (var child in childrenMap) { projection[childrenMap[child]] = 1; } return this.find(jsapi, collectionName, id, projection).then(function(result) { var promises = []; var set = {}; for (var child in childrenMap) { var targets = result[0][childrenMap[child]]; if (PV.isArray(targets)) { set[childrenMap[child]] = []; } else { set[childrenMap[child]] = null; } var filter = null; if (PV.isArray(targets)) { filter = { _id: { $in: targets } }; } else if (PV.isObject(targets)) { filter = { _id: targets }; } if (PV.isObject(filter)) { promises.push(jsapi.mongoConn.collection(child).removeAsync(filter)); } } var updateFilter = {}; if (PV.isString(id)) { updateFilter._id = new mongodb.ObjectId.createFromHexString(id); } else if (PV.isObject(id)) { updateFilter._id = id; } promises.push(jsapi.mongoConn.collection(collectionName).updateOneAsync(updateFilter, { $set: set })); return prom.all(promises); }); }, isEmptyValue: function(value) { return PV.isNull(value) || PV.isUndefined(value) || value === '-N/A-' || value === '- N/A -' || (PV.isString(value) && value.trim().length === 0); }, setCallbackTimeout: function(jsapi, timeout, callback) { setTimeout(function() { if (jsapi.callbackTracker !== true) { jsapi.callbackTracker = true; callback(null, null); } }, timeout); }, checkCallbackTimeout: function(jsapi, callback) { if (jsapi.callbackTracker !== true) { jsapi.callbackTracker = true; callback(null, null); } }, login: function(jsapi, protocol, host, port, username, password) { jsapi.logger.info('Logging in ' + protocol + '://' + host + ':' + port); jsapi.pv = new pvserver.PVServerAPI(protocol + '://' + host + ':' + port); return jsapi.pv.login(username, password, null).then(function(resp) { if (this.isResultOk(resp)) { return true; } else { jsapi.logger.error(this.getPVStatus(resp)); return false; } }.bind(this)); }, loginWithSession: function(jsapi) { return new prom(function(resolve, reject) { if (PV.isObject(jsapi.pv) === false) { jsapi.pv = new pvserver.PVServerAPI(jsapi.PVSession.engineSessionInfo.url); jsapi.pv.login(null, null, jsapi.PVSession.engineSessionInfo.apiKey).then(function(resp) { if (this.isResultOk(resp)) { resolve(true); } else { jsapi.pv = null; jsapi.logger.error(this.getPVStatus(resp)); resolve(false); } }.bind(this)); } else { resolve(true); } }.bind(this)); }, parseProviderModelUrl: function(url) { var info = {}; var re = /:[\/][\/]([^\/]+)[\/]([^\/?]+)[?\/]?.*/; var m = null; if ((m = re.exec(url)) !== null) { var host = m[1].split('@'); if (host.length > 1) { var auth = host[0].split(':'); info.username = auth[0]; info.password = auth[1]; info.host = host[1]; } else { info.username = null; info.password = null; info.host = m[1]; } info.dbname = m[2]; } else { info.host = null; info.dbname = null; } var reOptions = /[?](.*)/; if ((m = reOptions.exec(url)) !== null) { var allOptions = m[1]; var options = allOptions.split('&'); info.options = {}; options.forEach(function(opt) { var opValues = opt.split('='); info.options[opValues[0]] = opValues[1]; }); } else { info.options = null; } return info; }, getProviderModelInfo: function(jsapi, tag, params) { var infoTag = null; if (tag === 'MongoDB') { infoTag = 'mongo'; } else if (tag === 'Salesforce') { infoTag = 'sfdc'; } if (PV.isObject(jsapi[infoTag]) === false) { jsapi[infoTag] = {}; } try { var connectionInfo = jsapi.PVSession.engineSessionInfo.providerModelsByTag[tag]; for (var prop in connectionInfo) { jsapi[infoTag][prop] = connectionInfo[prop]; } jsapi.logger.info(infoTag + ' Engine Session Info'); } catch (e1) { try { jsapi[infoTag].modelId = JSON.parse(params.OpRequest).PVRequest.Operation.Params.ProfitModel.text; jsapi.logger.info(infoTag + ' OpRequest'); } catch (e2) { try { var domain = tag.toUpperCase(); var models = JSON.parse(params.ProviderModels); jsapi[infoTag].modelId = models[domain]; jsapi.logger.info(infoTag + ' ProviderModels'); } catch (e2) {} } } return PV.isString(jsapi[infoTag].modelId); }, createSalesforceProviderModel: function(jsapi, access_token, instance_url) { if (PV.isObject(jsapi.sfdc) === false) { jsapi.sfdc = {}; } var dataSetQuery = { 'Type': 'Salesforce', 'KeyValue': [{ 'Key': 'access_token', 'Value': access_token }, { 'Key': 'instance_url', 'Value': instance_url }] }; jsapi.logger.info('Creating provider model with ' + access_token + ' on ' + instance_url); return jsapi.pv.sendRequest('CreateProviderModel', dataSetQuery).then(function(resp) { if (this.isResultOk(resp)) { var status = this.getPVStatus(resp); jsapi.sfdc.modelId = status.ModelId; } else { jsapi.sfdc.modelId = null; jsapi.logger.error(this.getPVStatus(resp)); return false; } }.bind(this)); }, createMongoProviderModel: function(jsapi, username, appName, dbHostName, options) { return new prom(function(resolve, reject) { if (PV.isObject(jsapi.mongo) === false) { jsapi.mongo = {}; } if (PV.isString(jsapi.mongo.url) && PV.isString(jsapi.mongo.host) && PV.isString(jsapi.mongo.dbname)) { jsapi.logger.info('Provider model id already already exist'); resolve(this.getProviderModelUrl(jsapi, options)); } else { var dataSetQuery = { 'Type': 'MongoDB', 'KeyValue': [{ 'Key': 'userId', 'Value': username }, { 'Key': 'appName', 'Value': appName }, { 'Key': 'mongoDBHostName', 'Value': dbHostName }] }; jsapi.logger.info('Creating provider model with ' + username + ' for ' + appName + ' accessing ' + dbHostName); return jsapi.pv.sendRequest('CreateProviderModel', dataSetQuery).then(function(resp) { if (this.isResultOk(resp)) { var status = this.getPVStatus(resp); jsapi.mongo.modelId = status.ModelId; jsapi.logger.info('Getting provider model url with ' + status.ModelId); resolve(this.getProviderModelUrl(jsapi, options)); } else { jsapi.mongo.modelId = null; jsapi.logger.error(this.getPVStatus(resp)); resolve(false); } }.bind(this)); } }.bind(this)); }, getProviderModelUrl: function(jsapi, options) { return new prom(function(resolve, reject) { if (PV.isString(jsapi.mongo.url) && PV.isString(jsapi.mongo.host) && PV.isString(jsapi.mongo.dbname)) { jsapi.logger.info('Mongo Host, Database and Url already exist'); resolve(true); } else { return jsapi.pv.sendRequest('GetProviderModelUrl', { 'ProfitModel': jsapi.mongo.modelId }).then(function(resp) { if (this.isResultOk(resp)) { var status = this.getPVStatus(resp); var info = this.parseProviderModelUrl(status.Url); jsapi.mongo.host = info.host; jsapi.mongo.dbname = info.dbname; var optionsStr = PV.convertObjectToStr(options); if (optionsStr !== '') { if (status.Url.indexOf('?') === -1) { optionsStr = '?' + optionsStr; } else { optionsStr = '&' + optionsStr; } } jsapi.mongo.url = status.Url + optionsStr; if (PV.isObject(info.options)) { jsapi.mongo.options = info.options; } else { jsapi.mongo.options = null; } if (PV.isString(info.username)) { jsapi.mongo.username = info.username; } else { jsapi.mongo.username = null; } if (PV.isString(info.password)) { jsapi.mongo.password = info.password; } else { jsapi.mongo.password = null; } if (PV.isString(info.host) && PV.isString(info.dbname)) { jsapi.logger.info('Mongo Host: ' + jsapi.mongo.host); jsapi.logger.info('Mongo Database: ' + jsapi.mongo.dbname); resolve(true); } else { jsapi.logger.error({ message: 'Unable to extract Mongo host from data source url', code: 'Parsing Error' }); resolve(false); } } else { jsapi.mongo.url = null; jsapi.mongo.host = null; jsapi.mongo.dbname = null; jsapi.mongo.options = null; jsapi.mongo.username = null; jsapi.mongo.password = null; jsapi.logger.error(this.getPVStatus(resp)); resolve(false); } }.bind(this)); } }.bind(this)); }, setupMongoDBUrl: function(jsapi, serverHost, serverPort, serverUserId, serverPassword, serverAuthDatabase, database, options) { return new prom(function(resolve, reject) { if (PV.isObject(jsapi.mongo) === false) { jsapi.mongo = {}; } if (PV.isString(jsapi.mongo.url) && PV.isString(jsapi.mongo.host) && PV.isString(jsapi.mongo.dbname)) { jsapi.logger.info('Mongo Host, Database and Url already exist'); resolve(true); } else { if (PV.isString(serverHost) && PV.isString(database)) { jsapi.mongo.host = serverHost; jsapi.mongo.dbname = database; var arr = []; arr.push('mongodb://'); if (PV.isString(serverUserId)) { arr.push(encodeURIComponent(serverUserId)); jsapi.mongo.username = serverUserId; if (PV.isString(serverPassword)) { arr.push(':' + encodeURIComponent(serverPassword)); jsapi.mongo.password = serverPassword; } else { jsapi.mongo.password = null; } arr.push('@'); } else { jsapi.mongo.username = null; jsapi.mongo.password = null; } arr.push(serverHost); if (PV.isString(serverPort)) { arr.push(':' + serverPort); } arr.push('/' + database); var optionsStr = null; if (PV.isString(serverAuthDatabase)) { var optionsObj = {}; if (PV.isObject(options)) { for (var k in options) { optionsObj[k] = options[k]; } } optionsObj.authSource = serverAuthDatabase; jsapi.mongo.options = optionsObj; optionsStr = PV.convertObjectToStr(optionsObj); } else { if (PV.isObject(options)) { jsapi.mongo.options = options; optionsStr = PV.convertObjectToStr(options); } else { jsapi.mongo.options = null; } } if (optionsStr !== '') { arr.push('?' + optionsStr); } jsapi.mongo.url = arr.join(''); resolve(true); } else { jsapi.mongo.url = null; jsapi.mongo.host = null; jsapi.mongo.dbname = null; jsapi.mongo.options = null; jsapi.mongo.username = null; jsapi.mongo.password = null; jsapi.logger.error({ message: 'Missing data source url parameters', code: 'Bad Parameters' }); resolve(false); } } }); }, createMongoDB: function(jsapi) { return new prom(function(resolve, reject) { if (PV.isObject(jsapi.mongoConn) === false) { if (PV.isObject(jsapi.mongo) && PV.isString(jsapi.mongo.url)) { var MongoClient = prom.promisifyAll(mongodb); MongoClient.connect(jsapi.mongo.url).then(function(dbconn) { jsapi.mongoConn = dbconn; resolve(true); }); } else { jsapi.mongoConn = null; jsapi.logger.error({ message: 'Missing data source url', code: 'No Connection' }); resolve(false); } } else { resolve(true); } }); }, getEntityGroupsAndFields: function(entity, entityArray) { var result = null; entityArray.forEach(function(obj) { if (obj.Name === entity) { result = obj; } }); result.Groups = result.Groups.Group; result.Fields = result.Fields.Field; return result; }, convertGroupOrFieldArrayForQueryParams: function(arr) { var uniqueArr = arr.filter(function(elem, index, self) { if (PV.isString(elem)) { return index === self.indexOf(elem); } else { return false; } }); var newArray = []; uniqueArr.forEach(function(field) { if (PV.isString(field)) { newArray.push({ '_attrs': { 'name': 'Res1' }, '_text': field }); } }); return newArray; }, removeEntityRelationshipGroupAndFields: function(meta, entity, relationshipPatterns, not) { if (PV.isBoolean(not) === false) { not = false; } relationshipPatterns.forEach(function(pattern) { var relationPattern = entity + '_' + pattern; var reg = null; eval('reg=/' + relationPattern + '.+/i'); var groups = meta.Groups; var i = 0; do { if (reg.test(groups[i])) { if (not) { i++; } else { groups.splice(i, 1); } } else { if (not) { groups.splice(i, 1); } else { i++; } } } while (i < groups.length); var fields = meta.Fields; var j = 0; do { if (reg.test(fields[j])) { if (not) { j++; } else { fields.splice(j, 1); } } else { if (not) { fields.splice(j, 1); } else { j++; } } } while (j < fields.length); }); }, getGroupValueFromQueryParams: function(queryParams, objectName, groupName) { var result = null; var regexp = /^([^=]+)=[']([^']+)[']$/i; try { var dp = queryParams.AndFilter; PV.ensureArray(dp.OrFilter).forEach(function(compTerm) { var category = compTerm._attrs.category; if ((!objectName || (!category || category === objectName)) && compTerm.AndFilter.Filter) { PV.ensureArray(compTerm.AndFilter.Filter).forEach(function(filterTerm) { var term = filterTerm; if (PV.isObject(filterTerm) && filterTerm.hasOwnProperty('text')){ term = filterTerm.text; } var matches = regexp.exec(term); if (matches) { var group = matches[1]; var value = matches[2]; if (group === groupName && value !== '[object Object]') { result = value; } } }); } }); } catch (ignore) {} return result; }, getPVStatus: function(response) { var PVStatus = null; if (response) { PVStatus = response.PVResponse.PVStatus; } return PVStatus; }, getResultCode: function(response) { var code = null; if (response) { var PVStatus = this.getPVStatus(response); if (PVStatus) { code = PVStatus.Code; } } return code; }, getResultMessage: function(response) { var message = null; if (response) { var PVStatus = this.getPVStatus(response); if (PVStatus) { message = PVStatus.Message; } } return message; }, getResultScriptMessage: function(response) { var message = null; if (response) { var PVStatus = this.getPVStatus(response); if (PVStatus && PV.isString(PVStatus.SCRIPT_ERROR_MSG)) { message = PVStatus.SCRIPT_ERROR_MSG; } } return message; }, isResultOk: function(response) { var result = false; if (response) { var codeText = this.getResultCode(response); var message = this.getResultMessage(response); if (codeText === 'RPM_PE_STATUS_OK' && message === 'Okay') { result = true; } } return result; }, isResultTruncated: function(response) { var result = false; if (response) { var codeText = this.getResultCode(response); if (codeText === 'RPM_PE_QUERY_RESULT_TRUNCATED') { result = true; } } return result; }, isResultTooLarge: function(response) { var result = false; if (response) { var codeText = this.getResultCode(response); var messageText = this.getResultMessage(response); if (codeText === 'RPM_PE_QUERY_FAILED' && messageText === 'Error: Request Entity Too Large: head') { result = true; } } return result; }, isBulkUpsertInProgress: function(response) { var result = false; if (response) { var codeText = this.getResultCode(response); if (codeText === 'RPM_PE_QUERY_RESULT_OK_UPSERT_IN_PROGRESS' || codeText === 'RPM_PE_QUERY_RESULT_TRUNCATED_UPSERT_IN_PROGRESS') { result = true; } } return result; } };