Commit | Line | Data |
---|---|---|
66a7748d JB |
1 | import { type FSWatcher, readFileSync, watch } from 'node:fs' |
2 | import { dirname, join } from 'node:path' | |
3 | import { env } from 'node:process' | |
4 | import { fileURLToPath } from 'node:url' | |
8114d10e | 5 | |
66a7748d JB |
6 | import chalk from 'chalk' |
7 | import merge from 'just-merge' | |
8114d10e | 8 | |
a418c77b | 9 | import { |
4354af5a JB |
10 | buildPerformanceUriFilePath, |
11 | checkWorkerElementsPerWorker, | |
12 | checkWorkerProcessType, | |
13 | getDefaultPerformanceStorageUri, | |
14 | handleFileException, | |
66a7748d JB |
15 | logPrefix |
16 | } from './ConfigurationUtils.js' | |
17 | import { Constants } from './Constants.js' | |
18 | import { hasOwnProp, isCFEnvironment, isUndefined, once } from './Utils.js' | |
83e00df1 | 19 | import { |
268a74bb | 20 | ApplicationProtocol, |
83e00df1 | 21 | type ConfigurationData, |
5d049829 | 22 | ConfigurationSection, |
268a74bb | 23 | FileType, |
3d48c1c1 | 24 | type LogConfiguration, |
83e00df1 JB |
25 | type StationTemplateUrl, |
26 | type StorageConfiguration, | |
268a74bb | 27 | StorageType, |
e7aeea18 | 28 | SupervisionUrlDistribution, |
83e00df1 | 29 | type UIServerConfiguration, |
66a7748d JB |
30 | type WorkerConfiguration |
31 | } from '../types/index.js' | |
769d3b10 JB |
32 | import { |
33 | DEFAULT_ELEMENT_START_DELAY, | |
34 | DEFAULT_POOL_MAX_SIZE, | |
35 | DEFAULT_POOL_MIN_SIZE, | |
36 | DEFAULT_WORKER_START_DELAY, | |
66a7748d JB |
37 | WorkerProcessType |
38 | } from '../worker/index.js' | |
7dde0b73 | 39 | |
e7c0fce0 JB |
40 | type ConfigurationSectionType = |
41 | | LogConfiguration | |
42 | | StorageConfiguration | |
43 | | WorkerConfiguration | |
66a7748d | 44 | | UIServerConfiguration |
e7c0fce0 | 45 | |
66a7748d | 46 | // eslint-disable-next-line @typescript-eslint/no-extraneous-class |
268a74bb | 47 | export class Configuration { |
66a7748d | 48 | public static configurationChangeCallback: () => Promise<void> |
6501eda9 | 49 | |
66a7748d | 50 | private static readonly configurationFile = join( |
d972af76 | 51 | dirname(fileURLToPath(import.meta.url)), |
e7aeea18 | 52 | 'assets', |
66a7748d JB |
53 | 'config.json' |
54 | ) | |
10068088 | 55 | |
66a7748d JB |
56 | private static configurationFileReloading = false |
57 | private static configurationData?: ConfigurationData | |
58 | private static configurationFileWatcher?: FSWatcher | |
59 | private static readonly configurationSectionCache = new Map< | |
60 | ConfigurationSection, | |
61 | ConfigurationSectionType | |
5d049829 JB |
62 | >([ |
63 | [ConfigurationSection.log, Configuration.buildLogSection()], | |
64 | [ConfigurationSection.performanceStorage, Configuration.buildPerformanceStorageSection()], | |
65 | [ConfigurationSection.worker, Configuration.buildWorkerSection()], | |
66a7748d JB |
66 | [ConfigurationSection.uiServer, Configuration.buildUIServerSection()] |
67 | ]) | |
974efe6c | 68 | |
66a7748d | 69 | private constructor () { |
d5bd1c00 JB |
70 | // This is intentional |
71 | } | |
72 | ||
e7c0fce0 | 73 | public static getConfigurationSection<T extends ConfigurationSectionType>( |
66a7748d | 74 | sectionName: ConfigurationSection |
e7c0fce0 | 75 | ): T { |
81b9a105 | 76 | if (!Configuration.isConfigurationSectionCached(sectionName)) { |
66a7748d | 77 | Configuration.cacheConfigurationSection(sectionName) |
c1c97db8 | 78 | } |
66a7748d | 79 | return Configuration.configurationSectionCache.get(sectionName) as T |
5d049829 JB |
80 | } |
81 | ||
66a7748d | 82 | public static getStationTemplateUrls (): StationTemplateUrl[] | undefined { |
5f742aac JB |
83 | const checkDeprecatedConfigurationKeysOnce = once( |
84 | Configuration.checkDeprecatedConfigurationKeys.bind(Configuration), | |
66a7748d JB |
85 | Configuration |
86 | ) | |
87 | checkDeprecatedConfigurationKeysOnce() | |
88 | return Configuration.getConfigurationData()?.stationTemplateUrls | |
5d049829 JB |
89 | } |
90 | ||
66a7748d | 91 | public static getSupervisionUrls (): string | string[] | undefined { |
a37fc6dc JB |
92 | if ( |
93 | !isUndefined( | |
66a7748d | 94 | Configuration.getConfigurationData()?.['supervisionURLs' as keyof ConfigurationData] |
a37fc6dc JB |
95 | ) |
96 | ) { | |
66a7748d | 97 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion |
5d049829 | 98 | Configuration.getConfigurationData()!.supervisionUrls = Configuration.getConfigurationData()![ |
a37fc6dc | 99 | 'supervisionURLs' as keyof ConfigurationData |
66a7748d | 100 | ] as string | string[] |
5d049829 | 101 | } |
66a7748d | 102 | return Configuration.getConfigurationData()?.supervisionUrls |
5d049829 JB |
103 | } |
104 | ||
66a7748d | 105 | public static getSupervisionUrlDistribution (): SupervisionUrlDistribution | undefined { |
5d049829 JB |
106 | return hasOwnProp(Configuration.getConfigurationData(), 'supervisionUrlDistribution') |
107 | ? Configuration.getConfigurationData()?.supervisionUrlDistribution | |
66a7748d | 108 | : SupervisionUrlDistribution.ROUND_ROBIN |
5d049829 JB |
109 | } |
110 | ||
66a7748d | 111 | public static workerPoolInUse (): boolean { |
1d8f226b | 112 | return [WorkerProcessType.dynamicPool, WorkerProcessType.fixedPool].includes( |
66a7748d | 113 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion |
eb979012 | 114 | Configuration.getConfigurationSection<WorkerConfiguration>(ConfigurationSection.worker) |
66a7748d JB |
115 | .processType! |
116 | ) | |
c831d2bc JB |
117 | } |
118 | ||
66a7748d | 119 | public static workerDynamicPoolInUse (): boolean { |
eb979012 JB |
120 | return ( |
121 | Configuration.getConfigurationSection<WorkerConfiguration>(ConfigurationSection.worker) | |
122 | .processType === WorkerProcessType.dynamicPool | |
66a7748d | 123 | ) |
c831d2bc JB |
124 | } |
125 | ||
66a7748d JB |
126 | private static isConfigurationSectionCached (sectionName: ConfigurationSection): boolean { |
127 | return Configuration.configurationSectionCache.has(sectionName) | |
81b9a105 JB |
128 | } |
129 | ||
66a7748d | 130 | private static cacheConfigurationSection (sectionName: ConfigurationSection): void { |
81b9a105 JB |
131 | switch (sectionName) { |
132 | case ConfigurationSection.log: | |
66a7748d JB |
133 | Configuration.configurationSectionCache.set(sectionName, Configuration.buildLogSection()) |
134 | break | |
81b9a105 JB |
135 | case ConfigurationSection.performanceStorage: |
136 | Configuration.configurationSectionCache.set( | |
137 | sectionName, | |
66a7748d JB |
138 | Configuration.buildPerformanceStorageSection() |
139 | ) | |
140 | break | |
81b9a105 | 141 | case ConfigurationSection.worker: |
66a7748d JB |
142 | Configuration.configurationSectionCache.set(sectionName, Configuration.buildWorkerSection()) |
143 | break | |
81b9a105 JB |
144 | case ConfigurationSection.uiServer: |
145 | Configuration.configurationSectionCache.set( | |
146 | sectionName, | |
66a7748d JB |
147 | Configuration.buildUIServerSection() |
148 | ) | |
149 | break | |
81b9a105 JB |
150 | default: |
151 | // eslint-disable-next-line @typescript-eslint/restrict-template-expressions | |
66a7748d | 152 | throw new Error(`Unknown configuration section '${sectionName}'`) |
81b9a105 JB |
153 | } |
154 | } | |
155 | ||
66a7748d | 156 | private static buildUIServerSection (): UIServerConfiguration { |
675fa8e3 | 157 | let uiServerConfiguration: UIServerConfiguration = { |
b803eefa | 158 | enabled: false, |
1f7fa4de | 159 | type: ApplicationProtocol.WS, |
c127bd64 | 160 | options: { |
adbddcb4 | 161 | host: Constants.DEFAULT_UI_SERVER_HOST, |
66a7748d JB |
162 | port: Constants.DEFAULT_UI_SERVER_PORT |
163 | } | |
164 | } | |
f74e97ac | 165 | if (hasOwnProp(Configuration.getConfigurationData(), ConfigurationSection.uiServer)) { |
598c886d JB |
166 | uiServerConfiguration = merge<UIServerConfiguration>( |
167 | uiServerConfiguration, | |
66a7748d JB |
168 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion |
169 | Configuration.getConfigurationData()!.uiServer! | |
170 | ) | |
6a49ad23 | 171 | } |
66a7748d JB |
172 | if (isCFEnvironment()) { |
173 | delete uiServerConfiguration.options?.host | |
174 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | |
175 | uiServerConfiguration.options!.port = parseInt(env.PORT!) | |
b803eefa | 176 | } |
66a7748d | 177 | return uiServerConfiguration |
6a49ad23 JB |
178 | } |
179 | ||
66a7748d | 180 | private static buildPerformanceStorageSection (): StorageConfiguration { |
6a49ad23 JB |
181 | let storageConfiguration: StorageConfiguration = { |
182 | enabled: false, | |
183 | type: StorageType.JSON_FILE, | |
66a7748d JB |
184 | uri: getDefaultPerformanceStorageUri(StorageType.JSON_FILE) |
185 | } | |
f74e97ac | 186 | if (hasOwnProp(Configuration.getConfigurationData(), ConfigurationSection.performanceStorage)) { |
e7aeea18 | 187 | storageConfiguration = { |
1ba1e8fb | 188 | ...storageConfiguration, |
f74e97ac JB |
189 | ...Configuration.getConfigurationData()?.performanceStorage, |
190 | ...(Configuration.getConfigurationData()?.performanceStorage?.type === | |
191 | StorageType.JSON_FILE && | |
66a7748d JB |
192 | Configuration.getConfigurationData()?.performanceStorage?.uri != null && { |
193 | uri: buildPerformanceUriFilePath( | |
194 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | |
195 | new URL(Configuration.getConfigurationData()!.performanceStorage!.uri!).pathname | |
196 | ) | |
197 | }) | |
198 | } | |
72f041bd | 199 | } |
66a7748d | 200 | return storageConfiguration |
7dde0b73 JB |
201 | } |
202 | ||
66a7748d | 203 | private static buildLogSection (): LogConfiguration { |
3d48c1c1 JB |
204 | const defaultLogConfiguration: LogConfiguration = { |
205 | enabled: true, | |
206 | file: 'logs/combined.log', | |
207 | errorFile: 'logs/error.log', | |
208 | statisticsInterval: Constants.DEFAULT_LOG_STATISTICS_INTERVAL, | |
209 | level: 'info', | |
210 | format: 'simple', | |
66a7748d JB |
211 | rotate: true |
212 | } | |
3d48c1c1 | 213 | const deprecatedLogConfiguration: LogConfiguration = { |
f74e97ac | 214 | ...(hasOwnProp(Configuration.getConfigurationData(), 'logEnabled') && { |
66a7748d | 215 | enabled: Configuration.getConfigurationData()?.logEnabled |
3d48c1c1 | 216 | }), |
f74e97ac | 217 | ...(hasOwnProp(Configuration.getConfigurationData(), 'logFile') && { |
66a7748d | 218 | file: Configuration.getConfigurationData()?.logFile |
3d48c1c1 | 219 | }), |
f74e97ac | 220 | ...(hasOwnProp(Configuration.getConfigurationData(), 'logErrorFile') && { |
66a7748d | 221 | errorFile: Configuration.getConfigurationData()?.logErrorFile |
3d48c1c1 | 222 | }), |
f74e97ac | 223 | ...(hasOwnProp(Configuration.getConfigurationData(), 'logStatisticsInterval') && { |
66a7748d | 224 | statisticsInterval: Configuration.getConfigurationData()?.logStatisticsInterval |
3d48c1c1 | 225 | }), |
f74e97ac | 226 | ...(hasOwnProp(Configuration.getConfigurationData(), 'logLevel') && { |
66a7748d | 227 | level: Configuration.getConfigurationData()?.logLevel |
3d48c1c1 | 228 | }), |
f74e97ac | 229 | ...(hasOwnProp(Configuration.getConfigurationData(), 'logConsole') && { |
66a7748d | 230 | console: Configuration.getConfigurationData()?.logConsole |
3d48c1c1 | 231 | }), |
f74e97ac | 232 | ...(hasOwnProp(Configuration.getConfigurationData(), 'logFormat') && { |
66a7748d | 233 | format: Configuration.getConfigurationData()?.logFormat |
3d48c1c1 | 234 | }), |
f74e97ac | 235 | ...(hasOwnProp(Configuration.getConfigurationData(), 'logRotate') && { |
66a7748d | 236 | rotate: Configuration.getConfigurationData()?.logRotate |
3d48c1c1 | 237 | }), |
f74e97ac | 238 | ...(hasOwnProp(Configuration.getConfigurationData(), 'logMaxFiles') && { |
66a7748d | 239 | maxFiles: Configuration.getConfigurationData()?.logMaxFiles |
3d48c1c1 | 240 | }), |
f74e97ac | 241 | ...(hasOwnProp(Configuration.getConfigurationData(), 'logMaxSize') && { |
66a7748d JB |
242 | maxSize: Configuration.getConfigurationData()?.logMaxSize |
243 | }) | |
244 | } | |
3d48c1c1 JB |
245 | const logConfiguration: LogConfiguration = { |
246 | ...defaultLogConfiguration, | |
247 | ...deprecatedLogConfiguration, | |
f74e97ac | 248 | ...(hasOwnProp(Configuration.getConfigurationData(), ConfigurationSection.log) && |
66a7748d JB |
249 | Configuration.getConfigurationData()?.log) |
250 | } | |
251 | return logConfiguration | |
3d48c1c1 JB |
252 | } |
253 | ||
66a7748d | 254 | private static buildWorkerSection (): WorkerConfiguration { |
3602e107 JB |
255 | const defaultWorkerConfiguration: WorkerConfiguration = { |
256 | processType: WorkerProcessType.workerSet, | |
257 | startDelay: DEFAULT_WORKER_START_DELAY, | |
258 | elementsPerWorker: 'auto', | |
259 | elementStartDelay: DEFAULT_ELEMENT_START_DELAY, | |
260 | poolMinSize: DEFAULT_POOL_MIN_SIZE, | |
66a7748d JB |
261 | poolMaxSize: DEFAULT_POOL_MAX_SIZE |
262 | } | |
3602e107 JB |
263 | const deprecatedWorkerConfiguration: WorkerConfiguration = { |
264 | ...(hasOwnProp(Configuration.getConfigurationData(), 'workerProcess') && { | |
66a7748d | 265 | processType: Configuration.getConfigurationData()?.workerProcess |
3602e107 JB |
266 | }), |
267 | ...(hasOwnProp(Configuration.getConfigurationData(), 'workerStartDelay') && { | |
66a7748d | 268 | startDelay: Configuration.getConfigurationData()?.workerStartDelay |
3602e107 JB |
269 | }), |
270 | ...(hasOwnProp(Configuration.getConfigurationData(), 'chargingStationsPerWorker') && { | |
66a7748d | 271 | elementsPerWorker: Configuration.getConfigurationData()?.chargingStationsPerWorker |
3602e107 JB |
272 | }), |
273 | ...(hasOwnProp(Configuration.getConfigurationData(), 'elementStartDelay') && { | |
66a7748d | 274 | elementStartDelay: Configuration.getConfigurationData()?.elementStartDelay |
3602e107 JB |
275 | }), |
276 | ...(hasOwnProp(Configuration.getConfigurationData(), 'workerPoolMinSize') && { | |
66a7748d | 277 | poolMinSize: Configuration.getConfigurationData()?.workerPoolMinSize |
3602e107 JB |
278 | }), |
279 | ...(hasOwnProp(Configuration.getConfigurationData(), 'workerPoolMaxSize') && { | |
66a7748d JB |
280 | poolMaxSize: Configuration.getConfigurationData()?.workerPoolMaxSize |
281 | }) | |
282 | } | |
3602e107 | 283 | hasOwnProp(Configuration.getConfigurationData(), 'workerPoolStrategy') && |
66a7748d | 284 | delete Configuration.getConfigurationData()?.workerPoolStrategy |
3602e107 JB |
285 | const workerConfiguration: WorkerConfiguration = { |
286 | ...defaultWorkerConfiguration, | |
287 | ...deprecatedWorkerConfiguration, | |
288 | ...(hasOwnProp(Configuration.getConfigurationData(), ConfigurationSection.worker) && | |
66a7748d JB |
289 | Configuration.getConfigurationData()?.worker) |
290 | } | |
291 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | |
292 | checkWorkerProcessType(workerConfiguration.processType!) | |
293 | checkWorkerElementsPerWorker(workerConfiguration.elementsPerWorker) | |
294 | return workerConfiguration | |
3602e107 JB |
295 | } |
296 | ||
66a7748d | 297 | private static checkDeprecatedConfigurationKeys (): void { |
3602e107 JB |
298 | // connection timeout |
299 | Configuration.warnDeprecatedConfigurationKey( | |
300 | 'autoReconnectTimeout', | |
301 | undefined, | |
66a7748d JB |
302 | "Use 'ConnectionTimeOut' OCPP parameter in charging station template instead" |
303 | ) | |
3602e107 JB |
304 | Configuration.warnDeprecatedConfigurationKey( |
305 | 'connectionTimeout', | |
306 | undefined, | |
66a7748d JB |
307 | "Use 'ConnectionTimeOut' OCPP parameter in charging station template instead" |
308 | ) | |
3602e107 JB |
309 | // connection retries |
310 | Configuration.warnDeprecatedConfigurationKey( | |
311 | 'autoReconnectMaxRetries', | |
312 | undefined, | |
66a7748d JB |
313 | 'Use it in charging station template instead' |
314 | ) | |
3602e107 JB |
315 | // station template url(s) |
316 | Configuration.warnDeprecatedConfigurationKey( | |
317 | 'stationTemplateURLs', | |
318 | undefined, | |
66a7748d JB |
319 | "Use 'stationTemplateUrls' instead" |
320 | ) | |
3602e107 | 321 | !isUndefined( |
66a7748d | 322 | Configuration.getConfigurationData()?.['stationTemplateURLs' as keyof ConfigurationData] |
3602e107 | 323 | ) && |
66a7748d | 324 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion |
3602e107 | 325 | (Configuration.getConfigurationData()!.stationTemplateUrls = |
66a7748d | 326 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion |
3602e107 JB |
327 | Configuration.getConfigurationData()![ |
328 | 'stationTemplateURLs' as keyof ConfigurationData | |
66a7748d | 329 | ] as StationTemplateUrl[]) |
1c9de2b9 | 330 | Configuration.getConfigurationData()?.stationTemplateUrls.forEach( |
3602e107 | 331 | (stationTemplateUrl: StationTemplateUrl) => { |
1c9de2b9 | 332 | if (!isUndefined(stationTemplateUrl?.['numberOfStation' as keyof StationTemplateUrl])) { |
3602e107 | 333 | console.error( |
4354af5a | 334 | `${chalk.green(logPrefix())} ${chalk.red( |
66a7748d JB |
335 | `Deprecated configuration key 'numberOfStation' usage for template file '${stationTemplateUrl.file}' in 'stationTemplateUrls'. Use 'numberOfStations' instead` |
336 | )}` | |
337 | ) | |
3602e107 | 338 | } |
66a7748d JB |
339 | } |
340 | ) | |
3602e107 JB |
341 | // supervision url(s) |
342 | Configuration.warnDeprecatedConfigurationKey( | |
343 | 'supervisionURLs', | |
344 | undefined, | |
66a7748d JB |
345 | "Use 'supervisionUrls' instead" |
346 | ) | |
3602e107 JB |
347 | // supervision urls distribution |
348 | Configuration.warnDeprecatedConfigurationKey( | |
349 | 'distributeStationToTenantEqually', | |
350 | undefined, | |
66a7748d JB |
351 | "Use 'supervisionUrlDistribution' instead" |
352 | ) | |
3602e107 JB |
353 | Configuration.warnDeprecatedConfigurationKey( |
354 | 'distributeStationsToTenantsEqually', | |
355 | undefined, | |
66a7748d JB |
356 | "Use 'supervisionUrlDistribution' instead" |
357 | ) | |
3602e107 | 358 | // worker section |
e7aeea18 | 359 | Configuration.warnDeprecatedConfigurationKey( |
e80bc579 | 360 | 'useWorkerPool', |
1895299d | 361 | undefined, |
66a7748d JB |
362 | `Use '${ConfigurationSection.worker}' section to define the type of worker process model instead` |
363 | ) | |
cf2a5d9b JB |
364 | Configuration.warnDeprecatedConfigurationKey( |
365 | 'workerProcess', | |
1895299d | 366 | undefined, |
66a7748d JB |
367 | `Use '${ConfigurationSection.worker}' section to define the type of worker process model instead` |
368 | ) | |
cf2a5d9b JB |
369 | Configuration.warnDeprecatedConfigurationKey( |
370 | 'workerStartDelay', | |
1895299d | 371 | undefined, |
66a7748d JB |
372 | `Use '${ConfigurationSection.worker}' section to define the worker start delay instead` |
373 | ) | |
cf2a5d9b JB |
374 | Configuration.warnDeprecatedConfigurationKey( |
375 | 'chargingStationsPerWorker', | |
1895299d | 376 | undefined, |
66a7748d JB |
377 | `Use '${ConfigurationSection.worker}' section to define the number of element(s) per worker instead` |
378 | ) | |
cf2a5d9b JB |
379 | Configuration.warnDeprecatedConfigurationKey( |
380 | 'elementStartDelay', | |
1895299d | 381 | undefined, |
66a7748d JB |
382 | `Use '${ConfigurationSection.worker}' section to define the worker's element start delay instead` |
383 | ) | |
cf2a5d9b JB |
384 | Configuration.warnDeprecatedConfigurationKey( |
385 | 'workerPoolMinSize', | |
1895299d | 386 | undefined, |
66a7748d JB |
387 | `Use '${ConfigurationSection.worker}' section to define the worker pool minimum size instead` |
388 | ) | |
e7aeea18 | 389 | Configuration.warnDeprecatedConfigurationKey( |
1d8f226b | 390 | 'workerPoolSize', |
1895299d | 391 | undefined, |
66a7748d JB |
392 | `Use '${ConfigurationSection.worker}' section to define the worker pool maximum size instead` |
393 | ) | |
cf2a5d9b | 394 | Configuration.warnDeprecatedConfigurationKey( |
1d8f226b | 395 | 'workerPoolMaxSize', |
1895299d | 396 | undefined, |
66a7748d JB |
397 | `Use '${ConfigurationSection.worker}' section to define the worker pool maximum size instead` |
398 | ) | |
cf2a5d9b | 399 | Configuration.warnDeprecatedConfigurationKey( |
1d8f226b | 400 | 'workerPoolStrategy', |
1895299d | 401 | undefined, |
66a7748d JB |
402 | `Use '${ConfigurationSection.worker}' section to define the worker pool strategy instead` |
403 | ) | |
eda9c451 JB |
404 | Configuration.warnDeprecatedConfigurationKey( |
405 | 'poolStrategy', | |
974efe6c | 406 | ConfigurationSection.worker, |
66a7748d JB |
407 | 'Not publicly exposed to end users' |
408 | ) | |
1d8f226b JB |
409 | if ( |
410 | Configuration.getConfigurationData()?.worker?.processType === | |
411 | ('staticPool' as WorkerProcessType) | |
412 | ) { | |
413 | console.error( | |
4354af5a | 414 | `${chalk.green(logPrefix())} ${chalk.red( |
66a7748d JB |
415 | `Deprecated configuration 'staticPool' value usage in worker section 'processType' field. Use '${WorkerProcessType.fixedPool}' value instead` |
416 | )}` | |
417 | ) | |
1d8f226b | 418 | } |
3602e107 JB |
419 | // log section |
420 | Configuration.warnDeprecatedConfigurationKey( | |
421 | 'logEnabled', | |
422 | undefined, | |
66a7748d JB |
423 | `Use '${ConfigurationSection.log}' section to define the logging enablement instead` |
424 | ) | |
3602e107 JB |
425 | Configuration.warnDeprecatedConfigurationKey( |
426 | 'logFile', | |
427 | undefined, | |
66a7748d JB |
428 | `Use '${ConfigurationSection.log}' section to define the log file instead` |
429 | ) | |
3602e107 JB |
430 | Configuration.warnDeprecatedConfigurationKey( |
431 | 'logErrorFile', | |
432 | undefined, | |
66a7748d JB |
433 | `Use '${ConfigurationSection.log}' section to define the log error file instead` |
434 | ) | |
3602e107 JB |
435 | Configuration.warnDeprecatedConfigurationKey( |
436 | 'logConsole', | |
437 | undefined, | |
66a7748d JB |
438 | `Use '${ConfigurationSection.log}' section to define the console logging enablement instead` |
439 | ) | |
3602e107 JB |
440 | Configuration.warnDeprecatedConfigurationKey( |
441 | 'logStatisticsInterval', | |
442 | undefined, | |
66a7748d JB |
443 | `Use '${ConfigurationSection.log}' section to define the log statistics interval instead` |
444 | ) | |
3602e107 JB |
445 | Configuration.warnDeprecatedConfigurationKey( |
446 | 'logLevel', | |
447 | undefined, | |
66a7748d JB |
448 | `Use '${ConfigurationSection.log}' section to define the log level instead` |
449 | ) | |
3602e107 JB |
450 | Configuration.warnDeprecatedConfigurationKey( |
451 | 'logFormat', | |
452 | undefined, | |
66a7748d JB |
453 | `Use '${ConfigurationSection.log}' section to define the log format instead` |
454 | ) | |
3602e107 JB |
455 | Configuration.warnDeprecatedConfigurationKey( |
456 | 'logRotate', | |
457 | undefined, | |
66a7748d JB |
458 | `Use '${ConfigurationSection.log}' section to define the log rotation enablement instead` |
459 | ) | |
3602e107 JB |
460 | Configuration.warnDeprecatedConfigurationKey( |
461 | 'logMaxFiles', | |
462 | undefined, | |
66a7748d JB |
463 | `Use '${ConfigurationSection.log}' section to define the log maximum files instead` |
464 | ) | |
3602e107 JB |
465 | Configuration.warnDeprecatedConfigurationKey( |
466 | 'logMaxSize', | |
467 | undefined, | |
66a7748d JB |
468 | `Use '${ConfigurationSection.log}' section to define the log maximum size instead` |
469 | ) | |
3602e107 JB |
470 | // performanceStorage section |
471 | Configuration.warnDeprecatedConfigurationKey( | |
472 | 'URI', | |
473 | ConfigurationSection.performanceStorage, | |
66a7748d JB |
474 | "Use 'uri' instead" |
475 | ) | |
3602e107 JB |
476 | // uiServer section |
477 | if (hasOwnProp(Configuration.getConfigurationData(), 'uiWebSocketServer')) { | |
478 | console.error( | |
4354af5a | 479 | `${chalk.green(logPrefix())} ${chalk.red( |
66a7748d JB |
480 | `Deprecated configuration section 'uiWebSocketServer' usage. Use '${ConfigurationSection.uiServer}' instead` |
481 | )}` | |
482 | ) | |
b5b2c3e8 | 483 | } |
7dde0b73 | 484 | } |
eb3937cb | 485 | |
66a7748d | 486 | private static warnDeprecatedConfigurationKey ( |
e7aeea18 JB |
487 | key: string, |
488 | sectionName?: string, | |
66a7748d JB |
489 | logMsgToAppend = '' |
490 | ): void { | |
e7aeea18 | 491 | if ( |
66a7748d | 492 | sectionName != null && |
1c9de2b9 | 493 | !isUndefined( |
66a7748d | 494 | Configuration.getConfigurationData()?.[sectionName as keyof ConfigurationData] |
1c9de2b9 | 495 | ) && |
f74e97ac | 496 | !isUndefined( |
a37fc6dc | 497 | ( |
1c9de2b9 | 498 | Configuration.getConfigurationData()?.[sectionName as keyof ConfigurationData] as Record< |
66a7748d JB |
499 | string, |
500 | unknown | |
a37fc6dc | 501 | > |
66a7748d | 502 | )?.[key] |
f74e97ac | 503 | ) |
e7aeea18 JB |
504 | ) { |
505 | console.error( | |
4354af5a | 506 | `${chalk.green(logPrefix())} ${chalk.red( |
c5e52a07 JB |
507 | `Deprecated configuration key '${key}' usage in section '${sectionName}'${ |
508 | logMsgToAppend.trim().length > 0 ? `. ${logMsgToAppend}` : '' | |
66a7748d JB |
509 | }` |
510 | )}` | |
511 | ) | |
a37fc6dc | 512 | } else if ( |
1c9de2b9 | 513 | !isUndefined(Configuration.getConfigurationData()?.[key as keyof ConfigurationData]) |
a37fc6dc | 514 | ) { |
e7aeea18 | 515 | console.error( |
4354af5a | 516 | `${chalk.green(logPrefix())} ${chalk.red( |
c5e52a07 JB |
517 | `Deprecated configuration key '${key}' usage${ |
518 | logMsgToAppend.trim().length > 0 ? `. ${logMsgToAppend}` : '' | |
66a7748d JB |
519 | }` |
520 | )}` | |
521 | ) | |
eb3937cb JB |
522 | } |
523 | } | |
524 | ||
66a7748d JB |
525 | private static getConfigurationData (): ConfigurationData | undefined { |
526 | if (Configuration.configurationData == null) { | |
23132a44 | 527 | try { |
f74e97ac | 528 | Configuration.configurationData = JSON.parse( |
66a7748d JB |
529 | readFileSync(Configuration.configurationFile, 'utf8') |
530 | ) as ConfigurationData | |
531 | if (Configuration.configurationFileWatcher == null) { | |
532 | Configuration.configurationFileWatcher = Configuration.getConfigurationFileWatcher() | |
1f8f6332 | 533 | } |
23132a44 | 534 | } catch (error) { |
4354af5a | 535 | handleFileException( |
a95873d8 | 536 | Configuration.configurationFile, |
7164966d JB |
537 | FileType.Configuration, |
538 | error as NodeJS.ErrnoException, | |
66a7748d JB |
539 | logPrefix() |
540 | ) | |
23132a44 | 541 | } |
eb3937cb | 542 | } |
66a7748d | 543 | return Configuration.configurationData |
eb3937cb | 544 | } |
963ee397 | 545 | |
66a7748d | 546 | private static getConfigurationFileWatcher (): FSWatcher | undefined { |
23132a44 | 547 | try { |
d972af76 | 548 | return watch(Configuration.configurationFile, (event, filename): void => { |
1b4ccee3 JB |
549 | if ( |
550 | !Configuration.configurationFileReloading && | |
66a7748d | 551 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion |
1b4ccee3 JB |
552 | filename!.trim()!.length > 0 && |
553 | event === 'change' | |
554 | ) { | |
66a7748d JB |
555 | Configuration.configurationFileReloading = true |
556 | const consoleWarnOnce = once(console.warn, this) | |
1b4ccee3 | 557 | consoleWarnOnce( |
4354af5a | 558 | `${chalk.green(logPrefix())} ${chalk.yellow( |
66a7748d JB |
559 | `${FileType.Configuration} ${this.configurationFile} file have changed, reload` |
560 | )}` | |
561 | ) | |
562 | delete Configuration.configurationData | |
563 | Configuration.configurationSectionCache.clear() | |
9bf0ef23 | 564 | if (!isUndefined(Configuration.configurationChangeCallback)) { |
1b4ccee3 JB |
565 | Configuration.configurationChangeCallback() |
566 | .catch((error) => { | |
66a7748d | 567 | throw typeof error === 'string' ? new Error(error) : error |
1b4ccee3 JB |
568 | }) |
569 | .finally(() => { | |
66a7748d JB |
570 | Configuration.configurationFileReloading = false |
571 | }) | |
41d95b76 | 572 | } else { |
66a7748d | 573 | Configuration.configurationFileReloading = false |
3ec10737 | 574 | } |
23132a44 | 575 | } |
66a7748d | 576 | }) |
23132a44 | 577 | } catch (error) { |
4354af5a | 578 | handleFileException( |
a95873d8 | 579 | Configuration.configurationFile, |
7164966d JB |
580 | FileType.Configuration, |
581 | error as NodeJS.ErrnoException, | |
66a7748d JB |
582 | logPrefix() |
583 | ) | |
23132a44 | 584 | } |
ded13d97 | 585 | } |
7dde0b73 | 586 | } |