UNPKG

kvclient-js

Version:

Oracle NoSQL Database node.js Client API.

364 lines (320 loc) 15.4 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>JSDoc: Source: Proxy.js</title> <script src="scripts/prettify/prettify.js"> </script> <script src="scripts/prettify/lang-css.js"> </script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> </head> <body> <div id="main"> <h1 class="page-title">Source: Proxy.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>/*- * * This file is part of Oracle NoSQL Database * Copyright (C) 2011, 2014 Oracle and/or its affiliates. All rights reserved. * * If you have received this file as part of Oracle NoSQL Database the * following applies to the work as a whole: * * Oracle NoSQL Database server software is free software: you can * redistribute it and/or modify it under the terms of the GNU Affero * General Public License as published by the Free Software Foundation, * version 3. * * Oracle NoSQL Database is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Affero General Public License for more details. * * If you have received this file as part of Oracle NoSQL Database Client or * distributed separately the following applies: * * Oracle NoSQL Database client software is free software: you can * redistribute it and/or modify it under the terms of the Apache License * as published by the Apache Software Foundation, version 2.0. * * You should have received a copy of the GNU Affero General Public License * and/or the Apache License in the LICENSE file along with Oracle NoSQL * Database client or server distribution. If not, see * &lt;http://www.gnu.org/licenses/> * or * &lt;http://www.apache.org/licenses/LICENSE-2.0>. * * An active Oracle commercial licensing agreement for this product supersedes * these licenses and in such case the license notices, but not the copyright * notice, may be removed by you in connection with your distribution that is * in accordance with the commercial licensing terms. * * For more information please contact: * * berkeleydb-info_us@oracle.com * */ "use strict"; /*global kvLogger*/ /*global Errors*/ /*global kvmodule_dir*/ /*global fs*/ var child_process = require('child_process'); var PROXY_TIMEOUT = 4000; var PROXY_ERROR_TIMEOUT = 1000; var proxyPid = null; var PID_FILE = "/tmp/kvstore_proxy.pid"; function getPortFlag(hostPort){ var colon = hostPort.indexOf(':'); var port = hostPort.substr(colon+1); if (port) return ' -port ' + port; return ''; } function getHostsFlag(kvStoreHelperHosts) { kvLogger.debug("[PROXY] Helper hosts: " + kvStoreHelperHosts); var hosts, flag=""; if (kvStoreHelperHosts){ kvLogger.debug("[PROXY] Helper hosts: " + typeof kvStoreHelperHosts); var hosts; if (typeof kvStoreHelperHosts === 'array') { var firstComa = true; for (var _host in kvStoreHelperHosts) { hosts += (firstComa?"":",") + _host; firstComa = false; } } else { hosts = kvStoreHelperHosts; } flag = " -helper-hosts " + hosts; kvLogger.debug("Host flag for proxy: " + flag); } return flag; } function getStoreFlag(store) { if (typeof store === 'string') if (store.length > 0) return " -store " + store; return ""; } function getProxyClasspath(proxyConfiguration) { var separator = (process.platform==='win32'?";":":"); return " -cp " + path.normalize(proxyConfiguration.PROXY_HOME + '/kvproxy.jar') + separator + path.normalize(proxyConfiguration.PROXY_HOME + '/lib/libthrift-0.9.1.jar') + separator + path.normalize(proxyConfiguration.KVCLIENT_JAR) + separator + path.normalize(proxyConfiguration.PROXY_HOME + '/lib/slf4j-log4j12-1.5.8.jar') + separator + path.normalize(proxyConfiguration.PROXY_HOME + '/lib/log4j-1.2.14.jar') + separator + path.normalize(proxyConfiguration.PROXY_HOME + '/lib/slf4j-api-1.5.8.jar'); } /** * Defines a set of configuration values used to connect or create a proxy instance, this is just the constructor with * no parameters, once this object is created feel free to change any parameter. * @property {boolean} startProxy indicates if the module should try to start a proxy instance from which it will * connect to a NoSQL Server * @property {string} host indicates the host:port for a proxy to connect, not used when * startProxy = true * @property {string} KVCLIENT_JAR the path where the file kvclient.jar is located, required to start a local proxy * @property {string} PROXY_HOME the path where the proxy files are located, by default they are located in this module * path, but a different value can be specified to start a local proxy with different binaries * @property {String} kvStoreName the store name to be used * @property {String|Array} kvStoreHelperHosts the helper hosts to be used by the proxy when connecting to a NoSQL Server * @property {String|Array} readZones the read zones to be used by the proxy when connecting to a NoSQL Server * @property {SecurityProperties} securityProperties used for the connection * @property {Number} requestTimeout a number in milliseconds to specify the timeout default value for a request * @property {Number} socketOpenTimeout a number in milliseconds to specify the timeout for the socket to connect * @property {Number} socketReadTimeout a number in milliseconds to specify the timeout for the socket to read * @constructor */ function ProxyConfiguration () { this.startProxy = false; this.host = "localhost:5010"; this.KVCLIENT_JAR = process.env.KVSTORE_HOME_DIR + "/dist/lib/kvclient.jar"; this.PROXY_HOME = path.normalize(kvmodule_dir + "/proxy/"); this.kvStoreName = "kvstore"; this.kvStoreHelperHosts = "localhost:5000"; this.readZones = ""; this.username = ""; this.securityProperties = new Types.SecurityProperties(); this.requestTimeout = 1000; //todo: send this parameter to the proxy this.socketOpenTimeout = 1000; //todo: send this parameter to the proxy this.socketReadTimeout = 1000; //todo: send this parameter to the proxy } exports.ProxyConfiguration = ProxyConfiguration; function validateConfiguration (/*ProxyConfiguration*/ conf) { if (typeof conf.startProxy === 'undefined') throw new Error(Errors.ERROR_IN_PARAMETER + "startProxy"); if (typeof conf.host === 'undefined') throw new Error(Errors.ERROR_IN_PARAMETER + "host"); if (typeof conf.KVCLIENT_JAR === 'undefined') throw new Error(Errors.ERROR_IN_PARAMETER + "KVCLIENT_JAR"); if (typeof conf.PROXY_HOME === 'undefined') throw new Error(Errors.ERROR_IN_PARAMETER + "PROXY_HOME"); if (typeof conf.kvStoreName === 'undefined') throw new Error(Errors.ERROR_IN_PARAMETER + "kvStoreName"); if (typeof conf.kvStoreHelperHosts === 'undefined') throw new Error(Errors.ERROR_IN_PARAMETER + "kvStoreHelperHosts"); if (typeof conf.readZones === 'undefined') throw new Error(Errors.ERROR_IN_PARAMETER + "readZones"); if (typeof conf.requestTimeout === 'undefined') throw new Error(Errors.ERROR_IN_PARAMETER + "requestTimeout"); if (typeof conf.socketOpenTimeout === 'undefined') throw new Error(Errors.ERROR_IN_PARAMETER + "socketOpenTimeout"); if (typeof conf.socketReadTimeout === 'undefined') throw new Error(Errors.ERROR_IN_PARAMETER + "socketReadTimeout"); } exports.validateConfiguration = validateConfiguration; /** * Tries to read a file with a ProxyConfiguration object * @param {string} filename the full path for the file * @returns {ProxyConfiguration} */ function readProxyConfiguration (filename) { var conf = {}; if (fs.existsSync(filename)){ conf = JSON.parse(fs.readFileSync(filename)); validateConfiguration(conf); return conf; } else { throw (new Error(Errors.FILE_NOT_FOUND)); } } exports.readProxyConfiguration = readProxyConfiguration; function checkJava (callback) { kvLogger.debug('Check that Java environment is installed'); var java = child_process.spawn('java', ['-version']); java.stderr.on('data', function (data) { if (callback) callback(); callback = null; clearTimeout(timeout); removeall(); }); java.stdin.on('data', function (data) { if (callback) callback(); callback = null; clearTimeout(timeout); removeall(); }); java.stdout.on('data', function (data) { if (callback) callback(); callback = null; clearTimeout(timeout); removeall(); }); java.on('error', function (error) { if (callback) callback(error); callback = null; clearTimeout(timeout); removeall(); }); var timeout = setTimeout(function(){ if (callback) callback(false) }, 4000); function removeall() { java.stderr.removeAllListeners('data'); java.stdin.removeAllListeners('data'); java.stdout.removeAllListeners('data'); java.removeAllListeners('error'); } } exports.checkJava = checkJava; /** * starts a proxy with the given configuration * @param {ProxyConfiguration} proxyConfiguration the configuration used to start the proxy * @param {function} callback function called after the proxy is started */ function startProxy (proxyConfiguration, callback) { kvLogger.info('[PROXY] Start proxy'); checkJava(function(err){ if (err) { kvLogger.error('Java not found') if (callback) callback(new Error(Errors.NO_JAVA_CLIENT)); return; } var launchFile = '/tmp/launch.sh'; /// flags... var jarClasspath = getProxyClasspath(proxyConfiguration); var hostsFlag = getHostsFlag(proxyConfiguration.kvStoreHelperHosts); var portFlag = getPortFlag(proxyConfiguration.host); var logConfiguration = ' -Dlog4j.configuration=' + path.normalize(kvmodule_dir + '/proxy/log4j.ini'); var storeFlag = getStoreFlag(proxyConfiguration.kvStoreName); var commandLine = 'java ' + logConfiguration + jarClasspath + ' oracle.kv.proxy.KVProxy ' + hostsFlag + portFlag + storeFlag + ' &amp;'; kvLogger.debug('[PROXY] Launch proxy cmd: ' + commandLine); fs.writeFileSync(launchFile, commandLine); fs.appendFileSync(launchFile, 'echo $! > ' + PID_FILE); fs.chmodSync(launchFile, '777'); var timeoutOnError, timeoutStartProxy; var proxy = child_process.exec(launchFile, function(error, stdout, stderr){ kvLogger.debug('[PROXY] error: ' + error); kvLogger.debug('[PROXY] stdout: ' + stdout); kvLogger.debug('[PROXY] stderr: ' + stderr); if (callback) timeoutOnError = setTimeout(function(){ clearTimeout(timeoutStartProxy); kvLogger.debug('[PROXY] Error setting up the proxy'); if (callback) callback(new Error(Errors.PROXY_ERROR)); callback=null; }, PROXY_ERROR_TIMEOUT); }); proxy.on('exit', function(code){ if (fs.existsSync(launchFile)) fs.unlinkSync(launchFile); if (fs.existsSync(PID_FILE)) { proxyPid = fs.readFileSync(PID_FILE); fs.unlinkSync(PID_FILE); } kvLogger.debug('[PROXY] Proxy launched with pid:' + proxyPid); if (callback) timeoutStartProxy = setTimeout(function(){ clearTimeout(timeoutOnError); kvLogger.debug('[PROXY] Return after ' + (PROXY_TIMEOUT / 1000) + ' secs'); if(callback) callback(null, proxyPid); callback=null; }, PROXY_TIMEOUT); proxy.removeAllListeners('on'); }); }) } exports.startProxy = startProxy; /** * Shutdown the proxy. If a proxy was started, this method will shutdown it. * @param {ProxyConfiguration} proxyConfiguration the configuration used to start the proxy * @param {function} callback function called after trying to shutdown the proxy */ function stopProxy (proxyConfiguration, callback) { kvLogger.info('Shutdown proxy'); var colon = proxyConfiguration.host.indexOf(':'); var host = proxyConfiguration.host.substr(0, colon); var port = proxyConfiguration.host.substr(colon+1); var connection = thrift.createConnection(host, port, { transport: thrift.TFramedTransport, protocol: thrift.TBinaryProtocol }).on('error', function(err) { kvLogger.debug("Can't connect to the proxy to stop it - " + err); if (callback) callback(err); connection.removeAllListeners('error'); connection.removeAllListeners('connect'); }).on('connect', function(err){ kvLogger.debug('Thrift Connection successful'); var client = thrift.createClient(ONDBClient, that.thriftConnection); client.shutdown(); connection.end(); if (callback) callback(); connection.removeAllListeners('error'); connection.removeAllListeners('connect'); }); } exports.stopProxy = stopProxy;</code></pre> </article> </section> </div> <nav> <h2><a href="index.html">Index</a></h2><h3>Classes</h3><ul><li><a href="Configuration.html">Configuration</a></li><li><a href="Durability.html">Durability</a></li><li><a href="FieldRange.html">FieldRange</a></li><li><a href="Iterator.html">Iterator</a></li><li><a href="Logger.html">Logger</a></li><li><a href="Operation.html">Operation</a></li><li><a href="ProxyConfiguration.html">ProxyConfiguration</a></li><li><a href="Readable.html">Readable</a></li><li><a href="ReadOptions.html">ReadOptions</a></li><li><a href="SecurityProperties.html">SecurityProperties</a></li><li><a href="Store.html">Store</a></li><li><a href="VerifyProperties.html">VerifyProperties</a></li><li><a href="WriteOptions.html">WriteOptions</a></li></ul><h3>Global</h3><ul><li><a href="global.html#readProxyConfiguration">readProxyConfiguration</a></li><li><a href="global.html#ReplicaAckPolicy">ReplicaAckPolicy</a></li><li><a href="global.html#ReturnChoice">ReturnChoice</a></li><li><a href="global.html#SimpleConsistency">SimpleConsistency</a></li><li><a href="global.html#startProxy">startProxy</a></li><li><a href="global.html#stopProxy">stopProxy</a></li><li><a href="global.html#SyncPolicy">SyncPolicy</a></li></ul> </nav> <br clear="both"> <footer> Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.3.0-alpha10</a> on Mon Dec 01 2014 16:17:12 GMT-0600 (CST) </footer> <script> prettyPrint(); </script> <script src="scripts/linenumber.js"> </script> </body> </html>