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