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