|
@@ -0,0 +1,125 @@
|
|
|
|
|
+const ConfigLoader = require('../service/config-loader')
|
|
|
|
|
+ , debug = require('debug')('growi:service:ConfigManager');
|
|
|
|
|
+
|
|
|
|
|
+class ConfigManager {
|
|
|
|
|
+
|
|
|
|
|
+ constructor(configModel) {
|
|
|
|
|
+ this.configModel = configModel;
|
|
|
|
|
+ this.configLoader = new ConfigLoader(this.configModel);
|
|
|
|
|
+ this.configObject = null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * load configs from the database and the environment variables
|
|
|
|
|
+ */
|
|
|
|
|
+ async loadConfigs() {
|
|
|
|
|
+ this.configObject = await this.configLoader.load();
|
|
|
|
|
+
|
|
|
|
|
+ debug('ConfigManager#loadConfigs', this.configObject);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * get a config specified by namespace & key
|
|
|
|
|
+ *
|
|
|
|
|
+ * Basically, search a specified config from configs loaded from database at first
|
|
|
|
|
+ * and then from configs loaded from env vars.
|
|
|
|
|
+ *
|
|
|
|
|
+ * In some case, this search method changes.(not yet implemented)
|
|
|
|
|
+ */
|
|
|
|
|
+ getConfig(namespace, key) {
|
|
|
|
|
+ return this.defaultSearch(namespace, key);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * private api
|
|
|
|
|
+ *
|
|
|
|
|
+ * Search a specified config from configs loaded from database at first
|
|
|
|
|
+ * and then from configs loaded from env vars.
|
|
|
|
|
+ *
|
|
|
|
|
+ * the followings are the meanings of each special return value.
|
|
|
|
|
+ * - null: a specified config is not set.
|
|
|
|
|
+ * - undefined: a specified config does not exist.
|
|
|
|
|
+ */
|
|
|
|
|
+ defaultSearch(namespace, key) {
|
|
|
|
|
+ if (!this.configExistsInDB(namespace, key) && !this.configExistsInEnvVars(namespace, key)) {
|
|
|
|
|
+ return undefined;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (this.configExistsInDB(namespace, key) && !this.configExistsInEnvVars(namespace, key) ) {
|
|
|
|
|
+ return this.configObject.fromDB[namespace][key];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!this.configExistsInDB(namespace, key) && this.configExistsInEnvVars(namespace, key) ) {
|
|
|
|
|
+ return this.configObject.fromEnvVars[namespace][key];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (this.configExistsInDB(namespace, key) && this.configExistsInEnvVars(namespace, key) ) {
|
|
|
|
|
+ if (this.configObject.fromDB[namespace][key] !== null) {
|
|
|
|
|
+ return this.configObject.fromDB[namespace][key];
|
|
|
|
|
+ }
|
|
|
|
|
+ else {
|
|
|
|
|
+ return this.configObject.fromEnvVars[namespace][key];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * check whether a specified config exists in configs loaded from the database
|
|
|
|
|
+ * @returns {boolean}
|
|
|
|
|
+ */
|
|
|
|
|
+ configExistsInDB(namespace, key) {
|
|
|
|
|
+ if (this.configObject.fromDB[namespace] === undefined) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return this.configObject.fromDB[namespace][key] !== undefined;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * check whether a specified config exists in configs loaded from the environment variables
|
|
|
|
|
+ * @returns {boolean}
|
|
|
|
|
+ */
|
|
|
|
|
+ configExistsInEnvVars(namespace, key) {
|
|
|
|
|
+ if (this.configObject.fromEnvVars[namespace] === undefined) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return this.configObject.fromEnvVars[namespace][key] !== undefined;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * update configs by a iterable object consisting of several objects with ns, key, value fields
|
|
|
|
|
+ *
|
|
|
|
|
+ * For example:
|
|
|
|
|
+ * ```
|
|
|
|
|
+ * updateConfigs(
|
|
|
|
|
+ * [{
|
|
|
|
|
+ * ns: 'some namespace 1',
|
|
|
|
|
+ * key: 'some key 1',
|
|
|
|
|
+ * value: 'some value 1'
|
|
|
|
|
+ * }, {
|
|
|
|
|
+ * ns: 'some namespace 2',
|
|
|
|
|
+ * key: 'some key 2',
|
|
|
|
|
+ * value: 'some value 2'
|
|
|
|
|
+ * }]
|
|
|
|
|
+ * );
|
|
|
|
|
+ * ```
|
|
|
|
|
+ */
|
|
|
|
|
+ async updateConfigs(configs) {
|
|
|
|
|
+ const results = [];
|
|
|
|
|
+ for (const config of configs) {
|
|
|
|
|
+ results.push(
|
|
|
|
|
+ this.configModel.findOneAndUpdate(
|
|
|
|
|
+ { ns: config.ns, key: config.key },
|
|
|
|
|
+ { ns: config.ns, key: config.key, value: JSON.stringify(config.value) },
|
|
|
|
|
+ { upsert: true, }
|
|
|
|
|
+ ).exec()
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+ await Promise.all(results);
|
|
|
|
|
+
|
|
|
|
|
+ await this.loadConfigs();
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+module.exports = ConfigManager;
|