48c72fd4bb2399d8bdd199bc016c0085c7a32711
[e-mobility-charging-stations-simulator.git] / src / charging-station / AuthorizedTagsCache.ts
1 import fs from 'node:fs';
2
3 import { FileType } from '../types';
4 import { FileUtils, Utils, logger } from '../utils';
5
6 type TagsCacheValueType = {
7 tags: string[];
8 tagsFileWatcher: fs.FSWatcher | undefined;
9 };
10
11 export class AuthorizedTagsCache {
12 private static instance: AuthorizedTagsCache | null = null;
13 private readonly tagsCaches: Map<string, TagsCacheValueType>;
14
15 private constructor() {
16 this.tagsCaches = new Map<string, TagsCacheValueType>();
17 }
18
19 public static getInstance(): AuthorizedTagsCache {
20 if (AuthorizedTagsCache.instance === null) {
21 AuthorizedTagsCache.instance = new AuthorizedTagsCache();
22 }
23 return AuthorizedTagsCache.instance;
24 }
25
26 public getAuthorizedTags(file: string): string[] | undefined {
27 if (this.hasTags(file) === false) {
28 this.setTags(file, this.getAuthorizedTagsFromFile(file));
29 }
30 return this.getTags(file);
31 }
32
33 public deleteAuthorizedTags(file: string): boolean {
34 return this.deleteTags(file);
35 }
36
37 private hasTags(file: string): boolean {
38 return this.tagsCaches.has(file);
39 }
40
41 private setTags(file: string, tags: string[]) {
42 return this.tagsCaches.set(file, {
43 tags,
44 tagsFileWatcher: FileUtils.watchJsonFile(
45 file,
46 FileType.Authorization,
47 this.logPrefix(file),
48 undefined,
49 (event, filename) => {
50 if (Utils.isNotEmptyString(filename) && event === 'change') {
51 try {
52 logger.debug(
53 `${this.logPrefix(file)} ${FileType.Authorization} file have changed, reload`
54 );
55 this.deleteTags(file);
56 } catch (error) {
57 FileUtils.handleFileException(
58 file,
59 FileType.Authorization,
60 error as NodeJS.ErrnoException,
61 this.logPrefix(file),
62 {
63 throwError: false,
64 }
65 );
66 }
67 }
68 }
69 ),
70 });
71 }
72
73 private getTags(file: string): string[] | undefined {
74 return this.tagsCaches.get(file)?.tags;
75 }
76
77 private deleteTags(file: string): boolean {
78 this.tagsCaches.get(file)?.tagsFileWatcher?.close();
79 return this.tagsCaches.delete(file);
80 }
81
82 private getAuthorizedTagsFromFile(file: string): string[] {
83 let authorizedTags: string[] = [];
84 if (file) {
85 try {
86 // Load authorization file
87 authorizedTags = JSON.parse(fs.readFileSync(file, 'utf8')) as string[];
88 } catch (error) {
89 FileUtils.handleFileException(
90 file,
91 FileType.Authorization,
92 error as NodeJS.ErrnoException,
93 this.logPrefix(file)
94 );
95 }
96 } else {
97 logger.info(`${this.logPrefix(file)} No authorization file given`);
98 }
99 return authorizedTags;
100 }
101
102 private logPrefix = (file: string): string => {
103 return Utils.logPrefix(` Authorized tags cache for authorization file '${file}' |`);
104 };
105 }