} from '../types';
import { WorkerConstants, WorkerProcessType } from '../worker';
+enum ConfigurationSection {
+ log = 'log',
+ performanceStorage = 'storage',
+ worker = 'worker',
+ uiServer = 'uiServer',
+}
+
export class Configuration {
private static configurationFile = join(
dirname(fileURLToPath(import.meta.url)),
private static configurationFileWatcher: FSWatcher | undefined;
private static configuration: ConfigurationData | null = null;
+ private static configurationSectionCache = new Map<
+ ConfigurationSection,
+ LogConfiguration | StorageConfiguration | WorkerConfiguration | UIServerConfiguration
+ >();
+
private static configurationChangeCallback: () => Promise<void>;
private constructor() {
if (hasOwnProp(Configuration.getConfig(), 'uiWebSocketServer')) {
console.error(
`${chalk.green(Configuration.logPrefix())} ${chalk.red(
- "Deprecated configuration section 'uiWebSocketServer' usage. Use 'uiServer' instead",
+ `Deprecated configuration section 'uiWebSocketServer' usage. Use '${ConfigurationSection.uiServer}' instead`,
)}`,
);
}
port: Constants.DEFAULT_UI_SERVER_PORT,
},
};
- if (hasOwnProp(Configuration.getConfig(), 'uiServer')) {
+ if (hasOwnProp(Configuration.getConfig(), ConfigurationSection.uiServer)) {
uiServerConfiguration = merge<UIServerConfiguration>(
uiServerConfiguration,
Configuration.getConfig()!.uiServer!,
delete uiServerConfiguration.options?.host;
uiServerConfiguration.options!.port = parseInt(process.env.PORT!);
}
- return uiServerConfiguration;
+ return Configuration.getConfigurationSection<UIServerConfiguration>(
+ ConfigurationSection.uiServer,
+ uiServerConfiguration,
+ );
}
public static getPerformanceStorage(): StorageConfiguration {
- Configuration.warnDeprecatedConfigurationKey('URI', 'performanceStorage', "Use 'uri' instead");
+ Configuration.warnDeprecatedConfigurationKey(
+ 'URI',
+ ConfigurationSection.performanceStorage,
+ "Use 'uri' instead",
+ );
let storageConfiguration: StorageConfiguration = {
enabled: false,
type: StorageType.JSON_FILE,
uri: this.getDefaultPerformanceStorageUri(StorageType.JSON_FILE),
};
- if (hasOwnProp(Configuration.getConfig(), 'performanceStorage')) {
+ if (hasOwnProp(Configuration.getConfig(), ConfigurationSection.performanceStorage)) {
storageConfiguration = {
...storageConfiguration,
...Configuration.getConfig()?.performanceStorage,
}),
};
}
- return storageConfiguration;
+ return Configuration.getConfigurationSection<StorageConfiguration>(
+ ConfigurationSection.performanceStorage,
+ storageConfiguration,
+ );
}
public static getAutoReconnectMaxRetries(): number | undefined {
Configuration.warnDeprecatedConfigurationKey(
'logEnabled',
undefined,
- "Use 'log' section to define the logging enablement instead",
+ `Use '${ConfigurationSection.log}' section to define the logging enablement instead`,
);
Configuration.warnDeprecatedConfigurationKey(
'logFile',
undefined,
- "Use 'log' section to define the log file instead",
+ `Use '${ConfigurationSection.log}' section to define the log file instead`,
);
Configuration.warnDeprecatedConfigurationKey(
'logErrorFile',
undefined,
- "Use 'log' section to define the log error file instead",
+ `Use '${ConfigurationSection.log}' section to define the log error file instead`,
);
Configuration.warnDeprecatedConfigurationKey(
'logConsole',
undefined,
- "Use 'log' section to define the console logging enablement instead",
+ `Use '${ConfigurationSection.log}' section to define the console logging enablement instead`,
);
Configuration.warnDeprecatedConfigurationKey(
'logStatisticsInterval',
undefined,
- "Use 'log' section to define the log statistics interval instead",
+ `Use '${ConfigurationSection.log}' section to define the log statistics interval instead`,
);
Configuration.warnDeprecatedConfigurationKey(
'logLevel',
undefined,
- "Use 'log' section to define the log level instead",
+ `Use '${ConfigurationSection.log}' section to define the log level instead`,
);
Configuration.warnDeprecatedConfigurationKey(
'logFormat',
undefined,
- "Use 'log' section to define the log format instead",
+ `Use '${ConfigurationSection.log}' section to define the log format instead`,
);
Configuration.warnDeprecatedConfigurationKey(
'logRotate',
undefined,
- "Use 'log' section to define the log rotation enablement instead",
+ `Use '${ConfigurationSection.log}' section to define the log rotation enablement instead`,
);
Configuration.warnDeprecatedConfigurationKey(
'logMaxFiles',
undefined,
- "Use 'log' section to define the log maximum files instead",
+ `Use '${ConfigurationSection.log}' section to define the log maximum files instead`,
);
Configuration.warnDeprecatedConfigurationKey(
'logMaxSize',
undefined,
- "Use 'log' section to define the log maximum size instead",
+ `Use '${ConfigurationSection.log}' section to define the log maximum size instead`,
);
const defaultLogConfiguration: LogConfiguration = {
enabled: true,
const logConfiguration: LogConfiguration = {
...defaultLogConfiguration,
...deprecatedLogConfiguration,
- ...(hasOwnProp(Configuration.getConfig(), 'log') && Configuration.getConfig()?.log),
+ ...(hasOwnProp(Configuration.getConfig(), ConfigurationSection.log) &&
+ Configuration.getConfig()?.log),
};
- return logConfiguration;
+ return Configuration.getConfigurationSection<LogConfiguration>(
+ ConfigurationSection.log,
+ logConfiguration,
+ );
}
public static getWorker(): WorkerConfiguration {
Configuration.warnDeprecatedConfigurationKey(
'useWorkerPool',
undefined,
- "Use 'worker' section to define the type of worker process model instead",
+ `Use '${ConfigurationSection.worker}' section to define the type of worker process model instead`,
);
Configuration.warnDeprecatedConfigurationKey(
'workerProcess',
undefined,
- "Use 'worker' section to define the type of worker process model instead",
+ `Use '${ConfigurationSection.worker}' section to define the type of worker process model instead`,
);
Configuration.warnDeprecatedConfigurationKey(
'workerStartDelay',
undefined,
- "Use 'worker' section to define the worker start delay instead",
+ `Use '${ConfigurationSection.worker}' section to define the worker start delay instead`,
);
Configuration.warnDeprecatedConfigurationKey(
'chargingStationsPerWorker',
undefined,
- "Use 'worker' section to define the number of element(s) per worker instead",
+ `Use '${ConfigurationSection.worker}' section to define the number of element(s) per worker instead`,
);
Configuration.warnDeprecatedConfigurationKey(
'elementStartDelay',
undefined,
- "Use 'worker' section to define the worker's element start delay instead",
+ `Use '${ConfigurationSection.worker}' section to define the worker's element start delay instead`,
);
Configuration.warnDeprecatedConfigurationKey(
'workerPoolMinSize',
undefined,
- "Use 'worker' section to define the worker pool minimum size instead",
+ `Use '${ConfigurationSection.worker}' section to define the worker pool minimum size instead`,
);
Configuration.warnDeprecatedConfigurationKey(
'workerPoolSize;',
undefined,
- "Use 'worker' section to define the worker pool maximum size instead",
+ `Use '${ConfigurationSection.worker}' section to define the worker pool maximum size instead`,
);
Configuration.warnDeprecatedConfigurationKey(
'workerPoolMaxSize;',
undefined,
- "Use 'worker' section to define the worker pool maximum size instead",
+ `Use '${ConfigurationSection.worker}' section to define the worker pool maximum size instead`,
);
Configuration.warnDeprecatedConfigurationKey(
'workerPoolStrategy;',
undefined,
- "Use 'worker' section to define the worker pool strategy instead",
+ `Use '${ConfigurationSection.worker}' section to define the worker pool strategy instead`,
);
const defaultWorkerConfiguration: WorkerConfiguration = {
processType: WorkerProcessType.workerSet,
};
Configuration.warnDeprecatedConfigurationKey(
'poolStrategy',
- 'worker',
+ ConfigurationSection.worker,
'Not publicly exposed to end users',
);
const workerConfiguration: WorkerConfiguration = {
...defaultWorkerConfiguration,
...deprecatedWorkerConfiguration,
- ...(hasOwnProp(Configuration.getConfig(), 'worker') && Configuration.getConfig()?.worker),
+ ...(hasOwnProp(Configuration.getConfig(), ConfigurationSection.worker) &&
+ Configuration.getConfig()?.worker),
};
if (!Object.values(WorkerProcessType).includes(workerConfiguration.processType!)) {
throw new SyntaxError(
`Invalid worker process type '${workerConfiguration.processType}' defined in configuration`,
);
}
- return workerConfiguration;
+ return Configuration.getConfigurationSection<WorkerConfiguration>(
+ ConfigurationSection.worker,
+ workerConfiguration,
+ );
}
public static workerPoolInUse(): boolean {
}
}
- // Read the config file
+ private static getConfigurationSection<T>(
+ sectionName: ConfigurationSection,
+ sectionConfiguration?: T,
+ ): T {
+ if (!Configuration.configurationSectionCache.has(sectionName) && sectionConfiguration) {
+ Configuration.configurationSectionCache.set(sectionName, sectionConfiguration);
+ }
+ return Configuration.configurationSectionCache.get(sectionName) as T;
+ }
+
private static getConfig(): ConfigurationData | null {
if (!Configuration.configuration) {
try {
if (filename!.trim()!.length > 0 && event === 'change') {
// Nullify to force configuration file reading
Configuration.configuration = null;
+ Configuration.configurationSectionCache.clear();
if (!isUndefined(Configuration.configurationChangeCallback)) {
Configuration.configurationChangeCallback().catch((error) => {
throw typeof error === 'string' ? new Error(error) : error;