UNPKG

dubbo-client-zookeeper-hessian

Version:

dubbo的hessian协议、zookeeper中心客户端

867 lines (756 loc) 49 kB
'use strict'; exports.__esModule = true; var _stringify = require('babel-runtime/core-js/json/stringify'); var _stringify2 = _interopRequireDefault(_stringify); var _promise = require('babel-runtime/core-js/promise'); var _promise2 = _interopRequireDefault(_promise); var _regenerator = require('babel-runtime/regenerator'); var _regenerator2 = _interopRequireDefault(_regenerator); var _typeof2 = require('babel-runtime/helpers/typeof'); var _typeof3 = _interopRequireDefault(_typeof2); var _keys = require('babel-runtime/core-js/object/keys'); var _keys2 = _interopRequireDefault(_keys); var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _createClass2 = require('babel-runtime/helpers/createClass'); var _createClass3 = _interopRequireDefault(_createClass2); var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn'); var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); var _inherits2 = require('babel-runtime/helpers/inherits'); var _inherits3 = _interopRequireDefault(_inherits2); var _url = require('url'); var _url2 = _interopRequireDefault(_url); var _events = require('events'); var _events2 = _interopRequireDefault(_events); var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs); var _domain = require('domain'); var _domain2 = _interopRequireDefault(_domain); var _querystring = require('querystring'); var _querystring2 = _interopRequireDefault(_querystring); var _nodeZookeeperClient = require('node-zookeeper-client'); var _nodeZookeeperClient2 = _interopRequireDefault(_nodeZookeeperClient); var _javaClassParserGenerics = require('java-class-parser-generics'); var _javaClassParserGenerics2 = _interopRequireDefault(_javaClassParserGenerics); var _hessianProxyGarbled = require('hessian-proxy-garbled'); var _hessianProxyGarbled2 = _interopRequireDefault(_hessianProxyGarbled); var _toolkit = require('./toolkit.js'); var _toolkit2 = _interopRequireDefault(_toolkit); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var str = '', vider = 'providers'; var readDir = _toolkit2.default.P(_fs2.default.readdir); var parser2 = _toolkit2.default.P(_javaClassParserGenerics2.default); var Adubbo = false; var Dubbo = function (_events$EventEmitter) { (0, _inherits3.default)(Dubbo, _events$EventEmitter); function Dubbo() { var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; var _ref$name = _ref.name; var name = _ref$name === undefined ? 'node_client' : _ref$name; var zk = _ref.zk; var _ref$host = _ref.host; var host = _ref$host === undefined ? 'node-host' : _ref$host; var _ref$connectTimeout = _ref.connectTimeout; var connectTimeout = _ref$connectTimeout === undefined ? 1000 : _ref$connectTimeout; var _ref$retries = _ref.retries; var retries = _ref$retries === undefined ? 3 : _ref$retries; var _ref$dubbo_version = _ref.dubbo_version; var dubbo_version = _ref$dubbo_version === undefined ? '2.8.4' : _ref$dubbo_version; var _ref$service_version = _ref.service_version; var service_version = _ref$service_version === undefined ? false : _ref$service_version; var _ref$service_group = _ref.service_group; var service_group = _ref$service_group === undefined ? 'dubbo' : _ref$service_group; var _ref$strictString = _ref.strictString; var strictString = _ref$strictString === undefined ? true : _ref$strictString; var _ref$ip = _ref.ip; var ip = _ref$ip === undefined ? false : _ref$ip; var _ref$username = _ref.username; var username = _ref$username === undefined ? '' : _ref$username; var _ref$password = _ref.password; var password = _ref$password === undefined ? '' : _ref$password; var data = _ref.data; (0, _classCallCheck3.default)(this, Dubbo); if (!zk) { throw '必须定义zk地址!'; } if (_fs2.default.existsSync('./interface') === false) { throw 'interface目录不存在!'; } var _this = (0, _possibleConstructorReturn3.default)(this, _events$EventEmitter.call(this)); _this._client = _nodeZookeeperClient2.default.createClient(zk, { connectTimeout: connectTimeout, retries: retries }); _this._connectTimeout = connectTimeout; _this._name = name; _this._service_version = dubbo_version; _this._service_version = service_version; _this._service_group = service_group; _this._strictString = strictString; _this._ip = ip; _this._clientHost = host; _this._username = username; _this._password = password; _this._data = data; _this._init(); return _this; } Dubbo.one = function one(param) { if (Adubbo === false) { Adubbo = new Dubbo(param); } return this; }; Dubbo.on = function on(event, fn) { if (Adubbo !== false) { Adubbo.on(event, fn); } return this; }; Dubbo.invoke = function invoke(clzName, methodName, args, host) { if (Adubbo !== false) return Adubbo._invoke(clzName, methodName, args, host); }; Dubbo.election = function election(arr) { if (Adubbo !== false) return Adubbo._election(arr); }; Dubbo.prototype._readFile = function () { var _ref2 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee4() { var _this2 = this; var type = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0]; return _regenerator2.default.wrap(function _callee4$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: if (!(type < 2)) { _context4.next = 2; break; } return _context4.delegateYield(_regenerator2.default.mark(function _callee() { var domains; return _regenerator2.default.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _context.next = 2; return readDir('./interface/domain'); case 2: domains = _context.sent; _this2._domains = {}; domains.forEach(function (ele, index) { return domains[index] = './interface/domain/' + ele; }); _context.next = 7; return parser2(domains); case 7: domains = _context.sent; (0, _keys2.default)(domains).forEach(function (clzName) { var fns = {}; var name = clzName.substr(clzName.lastIndexOf('.') + 1); domains[clzName].methods.forEach(function (method) { var regs = /^get(\w*)/.exec(method.name); if (regs !== null) { var type = method.ret, fn; switch (type) { case 'java.lang.String': fn = function fn(value) { if (value === null || value === undefined || value === 'null') { return null; } return _toolkit2.default.stringSafeChange(_this2._strictString, value + str); }; break; case 'int': case 'float': case 'double': case 'long': fn = function fn(value) { if (value === '' || value === undefined || value === null) { return 0; } return +value; }; break; case 'java.lang.Integer': case 'java.lang.Double': case 'java.lang.Float': case 'java.lang.Long': case 'java.lang.Number': fn = function fn(value) { if (value === '' || value === undefined || value === null) { return null; } return +value; }; break; case 'java.math.BigDecimal': fn = function fn(value) { if (value === '' || value === undefined || value === null) { return null; } else if ((typeof value === 'undefined' ? 'undefined' : (0, _typeof3.default)(value)) === 'object') { if (value.value === '' || value.value === undefined || value.value === null) return null;else return { value: +value.value }; } else { return { value: +value }; } }; break; case 'boolean': fn = function fn(value) { if (value === '' || value === undefined || value === null) { return false; } else if (typeof value === 'string') { return value === 'true'; } else { return value; } }; break; case 'java.lang.Boolean': fn = function fn(value) { if (value === '' || value === undefined) { return null; } else if (typeof value === 'string') { return value === 'true'; } else { return value; } }; break; default: fn = function fn(value) { return value; }; break; } fns[_toolkit2.default.firstLowCase(regs[1])] = fn; } }); _this2._domains[clzName] = fns; _this2._domains[name] = function () { return _this2._dataCheck(false, clzName); }; }); case 9: case 'end': return _context.stop(); } } }, _callee, _this2); })(), 't0', 2); case 2: if (!(type !== 1)) { _context4.next = 4; break; } return _context4.delegateYield(_regenerator2.default.mark(function _callee3() { var services; return _regenerator2.default.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: _context3.next = 2; return readDir('./interface/service'); case 2: services = _context3.sent; _this2._service = {}; services.forEach(function (ele, index) { return services[index] = './interface/service/' + ele; }); _context3.next = 7; return parser2(services); case 7: services = _context3.sent; (0, _keys2.default)(services).forEach(function (clzName) { var methods = {}; var name = clzName.substr(clzName.lastIndexOf('.') + 1); services[clzName].methods.forEach(function (method) { var fns = []; method.args.forEach(function (el) { switch (el) { case 'java.lang.String': fns.push(function (value) { if (value === null || value === undefined || value === 'null') { return null; } return _toolkit2.default.stringSafeChange(_this2._strictString, value + str); }); break; case 'int': case 'float': case 'double': case 'long': fns.push(function (value) { return +value; }); break; case 'java.lang.Integer': case 'java.lang.Double': case 'java.lang.Float': case 'java.lang.Long': case 'java.lang.Number': fns.push(function (value) { if (value !== null && value !== undefined && value !== '') { return +value; } return null; }); break; case 'java.math.BigDecimal': fns.push(function (value) { if (value === '' || value === undefined || value === null) { return null; } else if ((typeof value === 'undefined' ? 'undefined' : (0, _typeof3.default)(value)) === 'object') { if (value.value === '' || value.value === undefined || value.value === null) return null;else return { value: +value.value }; } else { return { value: +value }; } }); break; case 'java.lang.Boolean': fns.push(function (value) { if (value === '' || value === undefined) { return null; } else if (typeof value === 'string') { return value === 'true'; } else { return value; } }); break; default: var type_, isArray = false; if (el.indexOf('java.util.List') === -1) { type_ = el; } else { type_ = el.match(/<(.*)>/); isArray = true; type_ !== null && (type_ = type_[1]); } if (_this2._domains[type_] !== undefined) { if (isArray === true) { fns.push(function (value) { if (value !== null && value !== undefined) { value.forEach(function (valuei, i) { if (valuei !== null && valuei !== undefined) { value[i] = _this2._dataCheck(valuei, type_); } }); } return value; }); } else { fns.push(function (value) { if (value !== null && value !== undefined) { value = _this2._dataCheck(value, type_); } return value; }); } } else { fns.push(function (value) { return value; }); } break; } }); methods[method.name] = function () { var _ref3 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee2() { for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return _regenerator2.default.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: if (!(args.length !== _this2._service[name][method.name].check.length)) { _context2.next = 3; break; } _this2.emit('error', { host: null, className: clzName, methodName: method.name, param: args, time: 0, error: '调用' + clzName + '/' + method.name + '参数不符,期望' + _this2._service[name][method.name].check.length + '个,传了' + args.length + '个!' }); throw { state: 101006, status: 101006, statusMessage: '调用' + clzName + '/' + method.name + '参数不符,期望' + _this2._service[name][method.name].check.length + '个,传了' + args.length + '个!', message: '调用' + clzName + '/' + method.name + '参数不符,期望' + _this2._service[name][method.name].check.length + '个,传了' + args.length + '个!', error: '调用' + clzName + '/' + method.name + '参数不符,期望' + _this2._service[name][method.name].check.length + '个,传了' + args.length + '个!' }; case 3: args.forEach(function (value, index) { args[index] = _this2._service[name][method.name].check[index](value); }); _context2.next = 6; return _this2._invoke(clzName, method.name, args); case 6: return _context2.abrupt('return', _context2.sent); case 7: case 'end': return _context2.stop(); } } }, _callee2, _this2); })); return function (_x4) { return _ref3.apply(this, arguments); }; }(); methods[method.name].check = fns; }); _this2._service[name] = methods; if (_this2._host[clzName]) { _this2.emit(name, _this2._host[clzName]); } }); case 9: case 'end': return _context3.stop(); } } }, _callee3, _this2); })(), 't1', 4); case 4: if (type === 0) { this._file_finished = true; this._finish_call(); } case 5: case 'end': return _context4.stop(); } } }, _callee4, this); })); function _readFile(_x2) { return _ref2.apply(this, arguments); } return _readFile; }(); Dubbo.prototype._readNode = function () { var _ref4 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee6(node) { var _this3 = this; var children; return _regenerator2.default.wrap(function _callee6$(_context6) { while (1) { switch (_context6.prev = _context6.next) { case 0: if (!(node === undefined)) { _context6.next = 10; break; } _context6.next = 3; return this._getChildren('/' + this._service_group, function () { return _this3._readNode(); }); case 3: children = _context6.sent; children.forEach(function (child) { return _this3._readNode(child); }); this._node_finished = true; this._finish_call(); this.emit('node'); _context6.next = 11; break; case 10: return _context6.delegateYield(_regenerator2.default.mark(function _callee5() { var hosts, services, consumer, name; return _regenerator2.default.wrap(function _callee5$(_context5) { while (1) { switch (_context5.prev = _context5.next) { case 0: hosts = []; if (_this3._version[node] === undefined) { _this3._version[node] = []; } _context5.next = 4; return _this3._getChildren('/' + _this3._service_group + '/' + node + '/' + vider, function () { return _this3._readNode(node); }); case 4: services = _context5.sent; consumer = _this3._consumer(); name = node.substr(node.lastIndexOf('.') + 1); consumer.query.interface = node; consumer.host = _this3._clientHost + '/' + node; consumer.query.timestamp = consumer.query['×tamp'] = new Date().getTime(); consumer.query.version = consumer.query.revision = _this3._service_version || str; services.forEach(function (service) { service = decodeURIComponent(service); var ser_param = _querystring2.default.parse(service); if (_this3._service_version !== false && (ser_param['default.version'] || ser_param['version']) !== _this3._service_version) return; var ser_host = _url2.default.parse(service); if (_this3._ip !== false && ser_host.hostname !== _this3._ip) return; hosts.findIndex(function (h) { return h === ser_host.host; }) === -1 && hosts.push(ser_host.host); var version = ser_param['default.version'] || ser_param['version']; if (_this3._version[node].indexOf(version) === -1) { _this3._version[node].push(consumer.query.version = consumer.query.revision = version); _this3._addNode('/' + _this3._service_group + '/' + node + '/consumers/' + encodeURIComponent(_url2.default.format(consumer))); } }); _this3._host[node] = hosts; if (_this3._service[name]) { _this3.emit(name, _this3._host[node]); } _this3.emit('node-' + name, _this3._host[node]); case 15: case 'end': return _context5.stop(); } } }, _callee5, _this3); })(), 't0', 11); case 11: case 'end': return _context6.stop(); } } }, _callee6, this); })); function _readNode(_x5) { return _ref4.apply(this, arguments); } return _readNode; }(); Dubbo.prototype._finish_call = function _finish_call() { if (this._file_finished === true && this._node_finished === true && this._called === false) { this._called = true; this.emit('all'); } }; Dubbo.prototype._consumer = function _consumer() { return { protocol: 'consumer', slashes: 'true', host: str, query: { application: this._name, category: 'consumers', 'default.timeout': this._connectTimeout, check: 'false', dubbo: this._service_version, interface: str, revision: str, version: str, side: 'consumer', timestamp: str } }; }; Dubbo.prototype._init = function _init() { var _this4 = this; this._host = {}; this._version = {}; this._domains = {}; this._service = {}; this._called = false; this._client.once('connected', function () { _this4._getChildren = _toolkit2.default.P(_this4._client.getChildren, _this4._client); _this4._exists = _toolkit2.default.P(_this4._client.exists, _this4._client); _this4._createNode = _toolkit2.default.P(_this4._client.create, _this4._client); _this4._readNode(); }).once('disconnected', function () {}); //fs.watch('./interface/domain', () => this._readFile(1)); //fs.watch('./interface/service', () => this._readFile(2)); this._readFile(); this._client.connect(); }; Dubbo.prototype._addNode = function () { var _ref5 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee7(node) { var stat; return _regenerator2.default.wrap(function _callee7$(_context7) { while (1) { switch (_context7.prev = _context7.next) { case 0: _context7.next = 2; return this._exists(node); case 2: stat = _context7.sent; if (!stat) { _context7.next = 5; break; } return _context7.abrupt('return'); case 5: this._createNode(node, 1); case 6: case 'end': return _context7.stop(); } } }, _callee7, this); })); function _addNode(_x6) { return _ref5.apply(this, arguments); } return _addNode; }(); Dubbo.prototype._election = function _election(arr) { return arr[Math.floor(Math.random() * arr.length)]; }; Dubbo.prototype._invoke = function _invoke(clzName, methodName, args, host) { var _this5 = this; return new _promise2.default(function (resolve, reject) { var begin = +new Date(); if (_this5._host[clzName] === undefined || _this5._host[clzName].length === 0) { _this5.emit('error', { host: null, className: clzName, methodName: methodName, param: args, time: 0, error: clzName + '/' + methodName + 'zk中找不到对应的服务节点' }); throw { status: 101002, statusMessage: clzName + '/' + methodName + 'zk中找不到对应的服务节点', message: clzName + '/' + methodName + 'zk中找不到对应的服务节点', error: clzName + '/' + methodName + 'zk中找不到对应的服务节点', state: 101002 }; } if (host === undefined) { host = _this5._election(_this5._host[clzName]); } var domain_ = _domain2.default.create(); domain_.on('error', function (err) { if (err.code && err.code.toString() === 'ECONNREFUSED') { var end = +new Date(); _this5.emit('error', { host: host, className: clzName, methodName: methodName, param: args, time: end - begin, error: host + '/' + clzName + '/' + methodName + '连接失败!' }); reject({ message: host + '/' + clzName + '/' + methodName + '连接失败!', error: host + '/' + clzName + '/' + methodName + '连接失败!', state: 101005 }); } else { var _end = +new Date(); _this5.emit('error', { host: host, className: clzName, methodName: methodName, param: args, time: _end - begin, error: host + '/' + clzName + '/' + methodName + '发生未知异常:' + (0, _stringify2.default)(err) + '!' }); reject({ message: host + '/' + clzName + '/' + methodName + '发生未知异常:' + (0, _stringify2.default)(err) + '!', error: host + '/' + clzName + '/' + methodName + '发生未知异常:' + (0, _stringify2.default)(err) + '!', state: 101004 }); } }); domain_.run(function () { var proxy = new _hessianProxyGarbled2.default.Proxy('http://' + host + '/' + clzName, _this5._username, _this5._password, proxy); proxy.invoke(methodName, args, function (err, reply) { if (reply && reply.fault === true) { var end = +new Date(); _this5.emit('error', { host: host, className: clzName, methodName: methodName, param: args, time: end - begin, error: host + '/' + clzName + '/' + methodName + '发生故障' + (0, _stringify2.default)(reply) + '!' }); reject({ message: host + '/' + clzName + '/' + methodName + '发生故障' + (0, _stringify2.default)(reply) + '!', error: host + '/' + clzName + '/' + methodName + '发生故障' + (0, _stringify2.default)(reply) + '!', state: 101004 }); } else if (err) { var _end2 = +new Date(); _this5.emit('error', { host: host, className: clzName, methodName: methodName, param: args, time: _end2 - begin, error: host + '/' + clzName + '/' + methodName + '发生异常' + (0, _stringify2.default)(err) + '!' }); reject({ message: host + '/' + clzName + '/' + methodName + '发生异常' + (0, _stringify2.default)(err) + '!', error: host + '/' + clzName + '/' + methodName + '发生异常' + (0, _stringify2.default)(err) + '!', state: 101004 }); } else { var _end3 = +new Date(); _this5.emit('data', { host: host, className: clzName, methodName: methodName, param: args, time: _end3 - begin, data: reply }); if (_this5._data) { try { resolve(_this5._data(reply)); } catch (error) { _this5.emit('error', { host: host, className: clzName, methodName: methodName, param: args, time: _end3 - begin, error: host + '/' + clzName + '/' + methodName + '发生异常' + (0, _stringify2.default)(error) + '!' }); reject(error); } } else { resolve(reply); } } }); }); }); }; Dubbo.prototype._dataCheck = function _dataCheck(domain, fullName) { var fn = this._domains[fullName]; var pre = {}; if (domain === false) { (0, _keys2.default)(fn).forEach(function (i) { return pre[i] = fn[i](''); }); } else { (0, _keys2.default)(domain).forEach(function (i) { return fn.hasOwnProperty(i) && (pre[i] = fn[i](domain[i])); }); } pre.__type__ = fullName; return pre; }; (0, _createClass3.default)(Dubbo, null, [{ key: 'service', get: function get() { if (Adubbo !== false) return Adubbo._service; } }, { key: 'domain', get: function get() { if (Adubbo !== false) return Adubbo._domains; } }]); return Dubbo; }(_events2.default.EventEmitter); exports.default = Dubbo; module.exports = exports.default; //# sourceMappingURL=index.js.map