UNPKG

vulcain-corejs

Version:
142 lines (140 loc) 5.75 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments)).next()); }); }; const system_1 = require("./../globals/system"); const configurationSource_1 = require("./configurationSource"); const Consul = require('consul'); class ConsulConfigurationSource { constructor(globalKeys, serviceKey, consulAddress) { // Local cache this._changes = new Map(); this._allkeys = new Set(); try { if (!globalKeys) { let env = system_1.System.environment; globalKeys = `vulcain/${env}/configurations/shared`; } this.globalKeys = globalKeys; if (!serviceKey) { let env = system_1.System.environment; let serviceName = system_1.System.serviceName; if (serviceName) serviceKey = `vulcain/${env}/configurations/${serviceName}`; } this.serviceKey = serviceKey; this.consul = Consul({ host: consulAddress || "local-storage" }); } catch (err) { system_1.System.log.error(null, err, "CONFIG: Error when using consul configuration source"); this.consul = null; } } /** * get configurations from consul * First time retrieve all then watch for changes and * store them locally for the next polling. */ pollPropertiesAsync(timeoutInMs) { return __awaiter(this, void 0, void 0, function* () { try { if (!this._initialized && this.consul) { if (timeoutInMs > 0) this.consul.timeout = timeoutInMs; this._initialized = true; // First time, retrieve all this._changes = new Map(); this._allkeys.clear(); let data = yield this.getAsync(this.globalKeys); data && this.merge(this.globalKeys, data); if (this.serviceKey) { data = yield this.getAsync(this.serviceKey); data && this.merge(this.serviceKey, data); } this.watchDefinitionsChanges(); } let result = new configurationSource_1.PollResult(this, this._changes); if (this._changes.size > 0) this._changes = new Map(); return result; } catch (e) { system_1.System.log.error(null, e, "CONFIG: Consul configuration source."); this._initialized = true; return new configurationSource_1.PollResult(this); } }); } getAsync(key) { return new Promise((resolve, reject) => { try { this.consul.kv.get({ key: key, recurse: true }, (err, data) => { if (err) reject(err); else { resolve(data); } }); } catch (e) { reject(e); } }); } merge(prefix, data) { let max = 0; // Add new or existing keys data.filter(d => !d.Key.endsWith('/')).forEach(v => { let k = v.Key.substr(prefix.length + 1).replace('/', '.'); if (v.Value) { try { let item = JSON.parse(v.Value); this._changes.set(k, item); this._allkeys.add(k); } catch (e) { system_1.System.log.info(null, "CONFIG: Consul configuration source : Invalid json value for property " + k); } } if (v.ModifyIndex > max) max = v.ModifyIndex; }); // Remove deleted keys let keys = Array.from(this._allkeys.keys()); for (let key of keys) { if (!this._changes.has(key)) { this._changes.set(key, null); this._allkeys.delete(key); } } return max; } watchDefinitionsChanges() { this.globalWatch = this.watchChanges(this.globalKeys); if (this.serviceKey) this.serviceWatch = this.watchChanges(this.serviceKey); } watchChanges(key) { let self = this; let watch = this.consul.watch({ method: this.consul.kv.get, options: { key: key, recurse: true } }); // TODO modifyIndex watch.on('change', function (data, res) { data && system_1.System.log.info(null, "CONFIG: Detecting changes on configuration properties for consul key " + key); data && self.merge(key, data); }); watch.on('error', function (err) { system_1.System.log.error(null, err, "CONFIG: Error when watching configurations for " + key); self.globalWatch.end(); self.serviceWatch && self.serviceWatch.end(); self._initialized = false; }); return watch; } } exports.ConsulConfigurationSource = ConsulConfigurationSource; //# sourceMappingURL=consulConfigurationSource.js.map