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