UNPKG

dl

Version:

DreamLab Libs

211 lines (160 loc) 6.39 kB
var core = require('core'); var path = require('path'); var Event = core.event.Event; var EventDispatcher = core.event.EventDispatcher; var Types = core.common.Types; var ZooKeeperDataProvider = require('../dataprovider/ZooKeeperDataProvider.js').ZooKeeperDataProvider; var instances = {}; var dataProvider = null; var dataProviderInitialized = false; var dataProviderCallbacks = []; var ConfigServiceClient = function (application, segment) { return ConfigServiceClient.getInstance(application, segment); }; ConfigServiceClient.getInstance = function (application, segment) { // segment '' is good as well as any other :) application = application || ConfigServiceClient._getMyIdentity(); segment = (segment !== undefined) ? segment : ConfigServiceClient._getMySegment(); if (!application || (segment === undefined)) { //TODO: jakas walidacja _application / _segment throw new Error('Cannot determine application or segment'); } var instanceId = application + '_' + segment; if (!instances.hasOwnProperty(instanceId)) { instances[instanceId] = ConfigServiceClient.createInstance(application, segment); } return instances[instanceId]; }; ConfigServiceClient._getMyIdentity = function () { if (process.env['OPAL_IDENTITY']) { var L = process.env['OPAL_IDENTITY'].split('.').reverse(); return [L[2], L[3]].join('/'); } }; ConfigServiceClient._getMySegment = function () { return process.env['ONET_SEGMENT']; }; ConfigServiceClient.createInstance = function (application, segment) { var obj = Object.create(ConfigServiceClient.prototype); EventDispatcher.call(obj); obj._initialized = false; obj._application = application; obj._segment = segment; obj._suffix = ConfigServiceClient.SUFFIX; obj.data = null; obj.dataTimestamp = null; obj.stat = null; obj._refreshTimer = null; obj._refreshTimeout = ConfigServiceClient.DEFAULT_RETRY_WATCH_TIMEOUT; obj._watchCreated = false; obj._watchers = []; if (!dataProvider) { dataProvider = new ZooKeeperDataProvider({ credential: ConfigServiceClient.DS_ALIAS, identity: ConfigServiceClient.DS_AUTH }); } obj._dataProvider = dataProvider; return obj; }; ConfigServiceClient.prototype = Object.create(EventDispatcher.prototype); ConfigServiceClient.prototype._getKey = function(suffix) { suffix = (suffix === undefined) ? this._suffix : suffix; if (this._segment) { return path.join(ConfigServiceClient.APPS_ROOT_PATH, this._application, 'segments', this._segment, suffix); } else { return path.join(ConfigServiceClient.APPS_ROOT_PATH, this._application, suffix); } }; ConfigServiceClient.prototype.start = function() { if (this._initialized) { console.warn('ConfigServiceClient/start', this._application, 'already started'); return; } if (!dataProviderInitialized) { dataProvider.init(function() { console.log('ConfigServiceClient/ready'); }, function() { console.log('ConfigServiceClient/reload'); for (var i = 0, l = dataProviderCallbacks.length; i < l; i++) { dataProviderCallbacks[i](); } }); dataProviderInitialized = true; } var appIdentity = ConfigServiceClient._getMyIdentity(); var appService = appIdentity.split('/')[0]; dataProvider.addAuth('digest', 'srv/' + appService + ':'); dataProvider.addAuth('digest', 'app/' + appIdentity + ':'); dataProviderCallbacks.push(this._watchForData.bind(this)); if (dataProvider.isConnected()) { this._watchForData(); } this._initialized = true; }; ConfigServiceClient.prototype._watchForData = function() { var key = this._getKey(); var that = this; if (this._watchCreated) { console.log('ConfigServiceClient/watch already created for', key); return; } console.log('ConfigServiceClient/creating watch for', key); dataProvider.watch(key, function(err, data, stat) { if (err) { console.error('ConfigServiceClient/error creating watch for', key, ':', err); that._scheduleRetryWatch(); that._watchCreated = false; that.dispatchEvent(new Event(ConfigServiceClient.Event.ERROR, err)); return; } else { that._resetRetryWatch(); that._watchCreated = true; } if (Types.isString(data)) { that.data = JSON.parse(data); } else { that.data = data; } that.dataTimestamp = Date.now(); that.stat = stat; console.log('ConfigServiceClient/watch for', key, 'data fetched'); that.dispatchEvent(new Event(ConfigServiceClient.Event.LOADED)); }); }; ConfigServiceClient.prototype._resetRetryWatch = function() { if (this._refreshTimer) { clearTimeout(this._refreshTimer); } this._refreshTimer = null; this._refreshTimeout = ConfigServiceClient.DEFAULT_RETRY_WATCH_TIMEOUT; }; ConfigServiceClient.prototype._scheduleRetryWatch = function() { var that = this; this._refreshTimeout *= 1.05; this._refreshTimer = setTimeout(function() { that._refreshTimer = null; that._watchForData(); }, this._refreshTimeout); }; ConfigServiceClient.prototype.getData = function(noThrow) { if (!this.data && !noThrow) { throw new Error('Config data not yet loaded'); } return JSON.parse(JSON.stringify(this.data)); }; ConfigServiceClient.prototype.getDataTimestamp = function(noThrow) { if ((!this.dataTimestamp || !this.data) && !noThrow) { throw new Error('Config data not yet loaded'); } return this.dataTimestamp; }; ConfigServiceClient.DS_ALIAS = 'configservice.zookeeper-a2.configuration.onetapi.pl'; ConfigServiceClient.DS_AUTH = 'client.configservice.zookeeper.configuration.onetapi.pl'; ConfigServiceClient.APPS_ROOT_PATH = '/onetapi.pl/'; ConfigServiceClient.SUFFIX = 'settings.json'; ConfigServiceClient.DEFAULT_RETRY_WATCH_TIMEOUT = 476; ConfigServiceClient.Event = {}; ConfigServiceClient.Event.LOADED = 'ConfigServiceClient.Event.LOADED'; ConfigServiceClient.Event.ERROR = 'ConfigServiceClient.Event.ERROR'; exports.ConfigServiceClient = ConfigServiceClient;