UNPKG

enhancer-data-bridge

Version:

A bridge between Enhancer Clould and user business datasource

186 lines (170 loc) 6.39 kB
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0; var express = require( 'express' ); var router = express.Router(); var os = require('os'); var request = require('request'); var axios = require('axios'); var requireNocache = require('require-nocache')(module); var fs = require('fs-extra'); var path = require('path'); var mocker = require('../mock'); var DatabaseService = require('../database-service'); var config = require('../config'); var customInterfacePathBase = '../repository/project/custom-interface/'; var customModuleBase = path.resolve(__dirname, '../repository/project/custom-module'); if (os.platform() === 'win32') { customModuleBase = customModuleBase.replace(/\\/g, '/') + '/'; } else { customModuleBase = customModuleBase + '/'; } var requireNocacheDefine = "var requireNocache = require('require-nocache')(module);"; var interfaceCache = {}; function fetchCustomInterface(host, project_id, interface_name, method, _u_t_k_, callback) { var url = host + '/proj/' + project_id + '/httpinterface/name/' + interface_name + '/' + method; var result = interfaceCache[url]; if (result) { console.log('Cache hit for ', interface_name, method); callback(null, result); return; } axios.get(url, { headers: { 'Cookie': 'token=' + _u_t_k_ } }).then(function(res) { if (!res.data || !res.data.success || !res.data.result) { var err = new Error('Failed to get interface \'' + interface_name + '\'. responseText: ' + res.data); callback(err); return } var data = res.data; var interface = requireNocacheDefine + data.result.interface.replace(/@\w+(\.\w+)*@/g, function(s) { return 'Enhancer.getVariable("' + s.split(/@/g)[1].toUpperCase() + '")'; }) .replace(/require\(\s*(\'|\")@custom\//g, function(s, $1) { return 'requireNocache(' + $1 + customModuleBase; }); var file = path.resolve(__dirname, customInterfacePathBase + interface_name); fs.ensureFileSync(file); fs.writeFileSync(file, interface); var f; try { f = requireNocache(customInterfacePathBase + interface_name); } catch (e) { e.message = '[Interface Calling Error] Error occured when calling interface: ' + e.message.replace(customModuleBase, '@custom'); callback(e); return } if (typeof f !== 'function') { var err = new Error('[Interface Error] No function module is exported.'); callback(err); return } var result = data.result; result.interface = f; interfaceCache[url] = result; callback(null, result); setTimeout(function() { delete interfaceCache[url]; }, 5000); }) .catch(function(err) { callback(err); }); } router.all('/custom-interface/p/:project_id/call/:interface_name', function(req, res, next) { if (req.method === 'OPTIONS') { res.send('OK'); return } var dbConfiguration; try { dbConfiguration = JSON.parse(req.query._d_b_ || '{"default":"","connections":{}}'); } catch (e) { console.warn('Invalid database settings for calling custom interface which is caused by bad url string.'); console.warn('The database service of Enhancer is not available in this test environment.'); } // Mock getDatabaseService req.getDatabaseService = function() { return new DatabaseService(dbConfiguration); }; var serverVars = req.query._s_v_ || '{}'; try { serverVars = JSON.parse(decodeURIComponent(serverVars)); } catch(e) { serverVars = {}; } // Append Session Variables var vbs = req.session._variables; if (vbs) { for (var i in vbs) { serverVars[i.toUpperCase()] = vbs[i]; } } // Mock getServerVariables req.getServerVariables = function() { return serverVars; }; // Mock getUser req.getUser = function() { return { getId: function() { return serverVars['USER_ID']; }, getName: function() { return serverVars['USER_NAME']; }, getRoles: function() { return serverVars['ROLES']; } } }; // Mock enhancer api global.Enhancer = mocker.mockEnhancer(dbConfiguration, serverVars, req, res); res.setHeader('Access-Control-Allow-Origin', '*'); var that = this; var pid = req.params.project_id; var iname = req.params.interface_name; var host = 'https://workbench.wuyuan.io'; if (/previewer\.enhancer\.cc/.test(req.headers.referer)) { host = 'http://workbench.enhancer.cc'; } var method = req.method if (method == 'OPTIONS') { method = req.headers['access-control-request-method']; } fetchCustomInterface(host, pid, iname, method, req.query._u_t_k_, function(err, result) { if (err) { var msg = 'Error occured when fetch custom interface. Reason:' + err.message; console.error(err); res.status(500).send(msg) return; } var isCompleted = false; res.on('finish', function(e) { isCompleted = true; }); setTimeout(function() { if (!isCompleted) { isCompleted = true; res.status(500) .end('[Timeout Error] Interface response timeout, please check if it responses correctly.'); res.jsonp = res.send = res.end = function() { console.log('The request has been timeout and the response has been ended.'); } } }, config.isOfficialEnv ? 5000 : (parseInt(result.timeout) || 5000)); try { result.interface.apply(that, [req, res, Enhancer]); } catch(err) { console.log(err); isCompleted = true; return res.status(500) .send('[Interface Calling Error] Error occured when calling interface: ' + err.stack); } }); }); module.exports = router;