feat: configuration loader.

This commit is contained in:
2021-10-07 13:46:34 +08:00
parent e4c6718e43
commit a02bc282bb
11 changed files with 224 additions and 37 deletions

View File

@@ -1,29 +1,68 @@
import { AppConfig } from "./app-config.model";
import { debug } from "console";
import { AppConfig } from "./app-config.model.js";
import { Etcd3 } from "etcd3";
import { load } from "js-yaml";
import { hostname } from "os";
import { getEtcdInstance } from "./etcd-connection";
import { getEtcdInstance } from "./etcd-connection.js";
import { readFile } from "fs/promises";
import debug from "debug";
class ConfigLoader {
export class ConfigLoader {
private etcd: Etcd3;
private readonly currHost = hostname();
private readonly configKeyPrefix = "share/config";
private readonly logger = debug("fennec:config:loader");
constructor(config: AppConfig) {
constructor(config?: AppConfig) {
this.etcd = getEtcdInstance(config);
}
async loadConfig(configKey: string): Promise<any> {
const str = await this.etcd
.get(`${this.configKeyPrefix}/${this.currHost}/${configKey}`)
.string();
async loadConfig<T extends Object>(configKey?: string): Promise<any> {
const config = await (await import("find-up"))
.findUp(["config,yml", "config.yaml"])
.then((path) => {
if (path) {
return readFile(path, "utf8").then((str) => load(str));
} else {
return undefined;
}
});
if (!str) {
debug("config-loader", `No config found for ${configKey}`);
return null;
if (configKey === undefined) {
if (process.env.CONFIG_KEY) {
configKey = process.env.CONFIG_KEY;
} else if (process.env.config_key) {
configKey = process.env.config_key;
} else {
configKey = await (
await import("find-up")
)
.findUp("package.json")
.then((path) => {
if (path) {
return readFile(path, "utf8");
} else {
throw new Error(
"Fallback to using package name as configuration name"
);
}
})
.then((json) => JSON.parse(json)?.name as string);
}
}
return load(str);
const etcdConfigKey = `${this.configKeyPrefix}/${this.currHost}/${configKey}`;
const str = await this.etcd.get(etcdConfigKey).string();
if (!str || !config) {
this.logger(
`Not define configuration.
- Put configuration in %s
- Provide configuration key in CONFIG_KEY environment variable
- Create "config.yml" file in current working directory (CWD)`,
etcdConfigKey
);
throw new Error(`Not define configuration.`);
}
return Object.assign(config, load(str)) as T;
}
}

View File

@@ -1,14 +1,14 @@
import { Etcd3 } from "etcd3";
import { AppConfig } from "./app-config.model";
function connectEtcd(config: AppConfig) {
import { AppConfig } from "./app-config.model.js";
function connectEtcd(config?: AppConfig) {
return new Etcd3({
...config.etcd,
...(config?.etcd ?? { hosts: ["http://rpi:2379"] }),
});
}
let instance: Etcd3;
export function getEtcdInstance(config: AppConfig) {
export function getEtcdInstance(config?: AppConfig) {
if (!instance) {
instance = connectEtcd(config);
}

View File

@@ -1,4 +1,4 @@
export * from "./app-config.model";
export * from "./config-loader";
export * from "./etcd-connection";
export * from "./service-register";
export * from "./app-config.model.js";
export * from "./config-loader.js";
export * from "./etcd-connection.js";
export * from "./service-register.js";

View File

@@ -1,7 +1,7 @@
import { AppConfig } from "./app-config.model";
import { AppConfig } from "./app-config.model.js";
import { Etcd3 } from "etcd3";
import { hostname } from "os";
import { getEtcdInstance } from "./etcd-connection";
import { getEtcdInstance } from "./etcd-connection.js";
import debug from "debug";
export class ServiceRegister {
@@ -12,7 +12,7 @@ export class ServiceRegister {
private readonly logger = debug("fennec:config:register");
constructor(config: AppConfig) {
constructor(config?: AppConfig) {
this.etcd = getEtcdInstance(config);
}