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