/** * @author xiangshouding * @date 2017-07-06 12:02:41 */ import {URL} from 'url'; import {consul} from './consul'; import {Map} from './types/lang'; import {Address} from './protocol/protocol'; /** * The Config Class */ export class Config { env: string = 'prod'; encoding: string; /** * protocol: (THRIFT | HTTP | HTTPS) */ protocol: string; /** * transport ( Framed | Buffered ) */ transport: string; searchHostType: string = 'LOCAL'; // or 'CONSUL' /** * the connect server timeout settings. */ timeout: number = 2000; /** * request balance. */ balance: string; retry: number = 1; consul: { host: string, port: number, action ?: string, timeout ?: number}; /** * { * "bj": [ * { * 'host': '127.0.0.1', * 'port': 80888 * }, * { * ... * } * ] * } * * @var Map[]> */ hosts: any = {}; host: string; port: number; address: string; options: Map; log: {logFile: string, logLevel: string, logId: number}; constructor (public service: string | Map, public idc?: string, public ctx?: any) { if (typeof service != 'string') { this.create(service); } else { this.loadFile( this.service); } } public getHosts(cb: (err: any, hosts: Array
) => void): void { if (this.searchHostType == 'LOCAL') { let hosts = this.hosts[this.idc]; //if idc hosts not exist, return `hosts` or `[{host:, port:}]` if (Array.isArray(hosts)) { return cb(null, hosts); } if (Array.isArray(this.hosts)) { hosts = this.hosts; } else if (this.host && this.port) { hosts = [new Address(this.host, this.port)]; } else { cb(new Error('please given `hosts` or `host` and `port`'), []); } return cb(null, hosts); } else if (this.searchHostType == 'CONSUL') { this.getHostsWithConsul(cb); } else { return cb(new Error(`unsupport '${this.searchHostType}' searchHostType`), []); } } /** * git the host list with `idc` */ public getHostsWithIDC() { return []; } public getProtocol() { if (!this.protocol) { if (this.searchHostType === 'CONSUL') { this.protocol = 'THRIFT'; } else { this.protocol = 'HTTP'; } } return this.protocol; } public getConsulAddress() { if (!this.consul) { this.consul = { host: 'consul.service.byted.org', port: 2280 }; } return new Address( this.consul.host, this.consul.port ); } public getLogFile() { return this.log.logFile; } public getLogLevel() { return this.log.logLevel; } /** * config information load from a config file * @param {string} file * @return void */ protected loadFile(file: string) { let config = {}; /** * if set ctx, read from ctx. * it's config is preload to context. */ if (this.ctx && this.ctx[file]) { config = this.ctx[file]; } else { config = require(file); } this.create(config); } /** * create a instance of the Config from a Map. * * @param config Map */ private create(config: Map) { if (config['timeout']) { config['timeout'] = this.timeFromString(config['timeout']); } else { // default 2s config['timeout'] = this.timeout; } this.options = config; if (config.hosts) { for (var idc in config.hosts) { if (config.hosts.hasOwnProperty(idc)) { let hosts = config.hosts[idc]; this.hosts[idc] = hosts.map(function (address) { return new Address(address.host, address.port); }); } } } for (var key in config) { if (config.hasOwnProperty(key) && ['hosts'].indexOf(key) == -1) { this[key] = config[key]; } } } /** * the time 1s\1ms to \d+(ms) * * @param s string | any */ private timeFromString(s: string) { if (/([\d.]+)ms/i.test(s)) { return parseFloat(RegExp.$1); } else if (/([\d.]+)s/i.test(s)) { return parseFloat(RegExp.$1) * 1000; } else { return parseFloat(s) * 1000; } } /** * */ private getHostsWithConsul(cb) { // require consul get hosts. return consul.get( this.getConsulAddress(), this.service, cb, this.env, null, // idc this.consul.action || 'lookup', {timeout: this.consul.timeout} ); } /** * { * 'address': '127.0.0.1:8099' * } * * host = 127.0.0.1 * port = 8099 * * if not set consul address, use it. */ private getHostsWithAddress() : boolean { if (typeof this.address != 'string') { return false; } if (this.address.length == 0) { return false; } let url_ = new URL(this.address); if (!url_) { return false; } this.host = url_.hostname; this.port = parseInt(url_.port); return true; } };