From: Jérôme Benoit Date: Wed, 25 Aug 2021 20:42:45 +0000 (+0200) Subject: Performance statistics: add JSON file storage support. X-Git-Tag: v1.0.43~2 X-Git-Url: https://git.piment-noir.org/?a=commitdiff_plain;h=72f041bd50fc25ca5d233565cbc0ea836220ec0f;p=e-mobility-charging-stations-simulator.git Performance statistics: add JSON file storage support. Signed-off-by: Jérôme Benoit --- diff --git a/.gitignore b/.gitignore index 5dfe331f..16320497 100644 --- a/.gitignore +++ b/.gitignore @@ -90,3 +90,4 @@ Thumbs.db mta_archives/ *.tar.gz +performanceMeasurements.json diff --git a/README.md b/README.md index 407c160e..2aed8173 100644 --- a/README.md +++ b/README.md @@ -22,13 +22,13 @@ Key | Value(s) | Default Value | Value type | Description --- | -------| --------------| ---------- | ------------ supervisionURLs | | [] | string[] | array of connection URIs to OCPP-J servers distributeStationsToTenantsEqually | true/false | true | boolean | distribute charging stations uniformly to the OCPP-J servers -statisticsDisplayInterval | | 60 | integer | seconds between charging stations statistics output in the logs workerProcess | workerSet/staticPool/dynamicPool | workerSet | string | worker threads process type workerStartDelay | | 500 | integer | milliseconds to wait at charging station worker threads startup workerPoolMinSize | | 4 | integer | worker threads pool minimum number of threads workerPoolMaxSize | | 16 | integer | worker threads pool maximum number of threads workerPoolStrategy | ROUND_ROBIN/LESS_RECENTLY_USED/... | [poolifier](https://github.com/poolifier/poolifier) default: ROUND_ROBBIN | string | worker threads pool [poolifier](https://github.com/poolifier/poolifier) worker choice strategy chargingStationsPerWorker | | 1 | integer | number of charging stations per worker threads for the `workerSet` process type +logStatisticsInterval | | 60 | integer | seconds between charging stations statistics output in the logs logConsole | true/false | false | boolean | output logs on the console logFormat | | simple | string | winston log format logRotate | true/false | true | boolean | enable daily log files rotation @@ -36,7 +36,8 @@ logMaxFiles | | 7 | integer | maximum number of log files to keep logLevel | emerg/alert/crit/error/warning/notice/info/debug | info | string | winston logging level logFile | | combined.log | string | log file relative path logErrorFile | | error.log | string | error log file relative path -stationTemplateURLs | | {}[] | { file: string; numberOfStations: number; }[] | array of charging template file URIs +performanceStorage | | { "enabled": false, "type": "jsonfile", "file:///performanceMeasurements.json" } | { enabled: string; type: string; URI: string; } | performance storage configuration section +stationTemplateURLs | | {}[] | { file: string; numberOfStations: number; }[] | array of charging station templates URIs configuration section (template file name and number of stations) ### Charging station template @@ -77,9 +78,9 @@ meteringPerTransaction | true/false | true | boolean | enable metering history o transactionDataMeterValues | true/false | false | boolean | enable transaction data MeterValues at stop transaction mainVoltageMeterValues | true/false | true | boolean | include charging station main voltage MeterValues on three phased charging stations phaseLineToLineVoltageMeterValues | true/false | true | boolean | include charging station line to line voltage MeterValues on three phased charging stations -Configuration | | | ChargingStationConfiguration | charging stations OCPP configuration parameters -AutomaticTransactionGenerator | | | AutomaticTransactionGenerator | charging stations ATG configuration -Connectors | | | Connectors | charging stations connectors configuration +Configuration | | | ChargingStationConfiguration | charging stations OCPP parameters configuration section +AutomaticTransactionGenerator | | | AutomaticTransactionGenerator | charging stations ATG configuration section +Connectors | | | Connectors | charging stations connectors configuration section #### Configuration section diff --git a/mta.yaml b/mta.yaml deleted file mode 100644 index 6fa93508..00000000 --- a/mta.yaml +++ /dev/null @@ -1,20 +0,0 @@ -ID: ev-simulator -_schema-version: '3.3' -version: 0.0.1 - -build-parameters: - before-all: - - builder: custom - commands: - - npm install - - npm run build - -resources: - - name: dynatrace-service - type: user-provided-service - optional: true - -modules: - - name: ev-simulator - type: nodejs - path: dist diff --git a/package-lock.json b/package-lock.json index 36735fc7..19343c08 100644 --- a/package-lock.json +++ b/package-lock.json @@ -966,12 +966,12 @@ } }, "@es-joy/jsdoccomment": { - "version": "0.10.7", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.10.7.tgz", - "integrity": "sha512-aNKZEoMESDzOBjKxCWrFuG50mcpMeKVBnBNko4+IZZ5t9zXYs8GT1KB0ZaOq1YUsKumDRc6YII/TQm309MJ0KQ==", + "version": "0.10.8", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.10.8.tgz", + "integrity": "sha512-3P1JiGL4xaR9PoTKUHa2N/LKwa2/eUdRqGwijMWWgBqbFEqJUVpmaOi2TcjcemrsRMgFLBzQCK4ToPhrSVDiFQ==", "dev": true, "requires": { - "comment-parser": "1.2.3", + "comment-parser": "1.2.4", "esquery": "^1.4.0", "jsdoc-type-pratt-parser": "1.1.1" } @@ -1794,6 +1794,12 @@ "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", "dev": true }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, "@types/keyv": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.2.tgz", @@ -2694,73 +2700,12 @@ "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==", "dev": true }, - "binary": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", - "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", - "dev": true, - "requires": { - "buffers": "~0.1.1", - "chainsaw": "~0.1.0" - } - }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, - "binwrap": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/binwrap/-/binwrap-0.2.2.tgz", - "integrity": "sha512-Y+Wvypk3JhH5GPZAvlwJAWOVH/OsOhQMSj37vySuWHwQivoALplPxfBA8b973rFJI7OS+O+1YmmYXIiEXVMAcw==", - "dev": true, - "requires": { - "mustache": "^3.0.1", - "request": "^2.88.0", - "request-promise": "^4.2.4", - "tar": "^4.4.10", - "unzip-stream": "^0.3.0" - }, - "dependencies": { - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - }, - "tar": { - "version": "4.4.17", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.17.tgz", - "integrity": "sha512-q7OwXq6NTdcYIa+k58nEMV3j1euhDhGCs/VRw9ymx/PbH0jtIM2+VTgDE/BW3rbLkrBUXs5fzEKgic5oUciu7g==", - "dev": true, - "requires": { - "chownr": "^1.1.4", - "fs-minipass": "^1.2.7", - "minipass": "^2.9.0", - "minizlib": "^1.3.3", - "mkdirp": "^0.5.5", - "safe-buffer": "^5.2.1", - "yallist": "^3.1.1" - } - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - } - } - }, "bit-twiddle": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bit-twiddle/-/bit-twiddle-1.0.2.tgz", @@ -2807,12 +2752,6 @@ } } }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, "bn.js": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", @@ -3110,9 +3049,9 @@ } }, "bson": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/bson/-/bson-4.4.1.tgz", - "integrity": "sha512-Uu4OCZa0jouQJCKOk1EmmyqtdWAP5HVLru4lQxTwzJzxT+sJ13lVpEZU/MATDxtHiekWMAL84oQY3Xn1LpJVSg==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/bson/-/bson-4.5.1.tgz", + "integrity": "sha512-XqFP74pbTVLyLy5KFxVfTUyRrC1mgOlmu/iXHfXqfCKT59jyP9lwbotGfbN59cHBRbJSamZNkrSopjv+N0SqAA==", "requires": { "buffer": "^5.6.0" }, @@ -3155,12 +3094,6 @@ "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", "dev": true }, - "buffers": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", - "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=", - "dev": true - }, "bufferutil": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.3.tgz", @@ -3403,15 +3336,6 @@ "integrity": "sha512-twuUuJRrIrsELHz6foJtZlqrz6FC36zoHZJvvThsrM1UWPKxyoilw1Rka6Hk0AmPFKHKUoGwGfAtvNZNtNZu0g==", "dev": true }, - "chainsaw": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", - "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", - "dev": true, - "requires": { - "traverse": ">=0.3.0 <0.4" - } - }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -3446,10 +3370,9 @@ } }, "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" }, "ci-info": { "version": "1.6.0", @@ -4227,9 +4150,9 @@ "dev": true }, "comment-parser": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.2.3.tgz", - "integrity": "sha512-vnqDwBSXSsdAkGS5NjwMIPelE47q+UkEgWKHvCDNhVIIaQSUFY6sNnEYGzdoPGMdpV+7KR3ZkRd7oyWIjtuvJg==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.2.4.tgz", + "integrity": "sha512-pm0b+qv+CkWNriSTMsfnjChF9kH0kxz55y44Wo5le9qLxMj5xDQAaEd9ZN1ovSuk9CsrncWaFwgpOMg7ClJwkw==", "dev": true }, "commist": { @@ -4924,9 +4847,9 @@ "dev": true }, "denque": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.0.tgz", - "integrity": "sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ==" + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", + "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==" }, "depcheck": { "version": "0.8.3", @@ -5883,9 +5806,9 @@ } }, "eslint-plugin-import": { - "version": "2.24.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.1.tgz", - "integrity": "sha512-KSFWhNxPH8OGJwpRJJs+Z7I0a13E2iFQZJIvSnCu6KUs4qmgAm3xN9GYBCSoiGWmwA7gERZPXqYQjcoCROnYhQ==", + "version": "2.24.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.2.tgz", + "integrity": "sha512-hNVtyhiEtZmpsabL4neEj+6M5DCLgpYyG9nzJY8lZQeQXEn5UPW1DpUdsMHMXsq98dbNm7nt1w9ZMSVpfJdi8Q==", "dev": true, "requires": { "array-includes": "^3.1.3", @@ -5902,7 +5825,7 @@ "pkg-up": "^2.0.0", "read-pkg-up": "^3.0.0", "resolve": "^1.20.0", - "tsconfig-paths": "^3.10.1" + "tsconfig-paths": "^3.11.0" }, "dependencies": { "debug": { @@ -6052,13 +5975,13 @@ } }, "eslint-plugin-jsdoc": { - "version": "36.0.7", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-36.0.7.tgz", - "integrity": "sha512-x73l/WCRQ1qCjLq46Ca7csuGd5o3y3vbJIa3cktg11tdf3UZleBdIXKN9Cf0xjs3tXYPEy2SoNXowT8ydnjNDQ==", + "version": "36.0.8", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-36.0.8.tgz", + "integrity": "sha512-brNjHvRuBy5CaV01mSp6WljrO/T8fHNj0DXG38odOGDnhI7HdcbLKX7DpSvg2Rfcifwh8GlnNFzx13sI05t3bg==", "dev": true, "requires": { - "@es-joy/jsdoccomment": "0.10.7", - "comment-parser": "1.2.3", + "@es-joy/jsdoccomment": "0.10.8", + "comment-parser": "1.2.4", "debug": "^4.3.2", "esquery": "^1.4.0", "jsdoc-type-pratt-parser": "^1.1.1", @@ -6769,12 +6692,11 @@ } }, "fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "dev": true, + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", "requires": { - "minipass": "^2.6.0" + "minipass": "^3.0.0" } }, "fs.realpath": { @@ -8835,7 +8757,8 @@ "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true }, "lodash.clonedeep": { "version": "4.5.0", @@ -9073,15 +8996,6 @@ "integrity": "sha1-XZXBqGDRSFNSl4MqFX5L5Z6YgNQ=", "dev": true }, - "mbt": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/mbt/-/mbt-1.2.3.tgz", - "integrity": "sha512-gQuq1yYKUNg4IVVBsJ35YVqIHJOaKY2FMoselaZpHA6rxU0A6kijyBrHsT82uAXBoIUUQyxZcLfa6az0XJPcbA==", - "dev": true, - "requires": { - "binwrap": "0.2.2" - } - }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -9266,30 +9180,34 @@ "dev": true }, "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" + "yallist": "^4.0.0" }, "dependencies": { "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, "minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "dev": true, + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", "requires": { - "minipass": "^2.9.0" + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } } }, "mkdirp": { @@ -9870,23 +9788,23 @@ "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" }, "mongodb": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.1.0.tgz", - "integrity": "sha512-Gx9U9MsFWgJ3E0v4oHAdWvYTGBznNYPCkhmD/3i/kPTY/URnPfHD5/6VoKUFrdgQTK3icFiM9976hVbqCRBO9Q==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.1.1.tgz", + "integrity": "sha512-fbACrWEyvr6yl0sSiCGV0sqEiBwTtDJ8iSojmkDjAfw9JnOZSAkUyv9seFSPYhPPKwxp1PDtyjvBNfMDz0WBLQ==", "requires": { - "bson": "^4.4.0", + "bson": "^4.5.1", "denque": "^1.5.0", - "mongodb-connection-string-url": "^1.0.1", + "mongodb-connection-string-url": "^2.0.0", "saslprep": "^1.0.0" } }, "mongodb-connection-string-url": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-1.1.2.tgz", - "integrity": "sha512-mp5lv4guWuykOpkwNNqQ0tKKytuJUjL/aC/bu/DqoJVWL5NSh4j/u+gJ+EiOdweLujHyq6JZZqcTVipHhL5xRg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.0.0.tgz", + "integrity": "sha512-M0I1vyLoq5+HQTuPSJWbt+hIXsMCfE8sS1fS5mvP9R2DOMoi2ZD32yWqgBIITyu0dFu4qtS50erxKjvUeBiyog==", "requires": { - "@types/whatwg-url": "^8.0.0", - "whatwg-url": "^8.4.0" + "@types/whatwg-url": "^8.2.1", + "whatwg-url": "^9.1.0" } }, "morphdom": { @@ -9900,12 +9818,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" }, - "mustache": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.2.1.tgz", - "integrity": "sha512-RERvMFdLpaFfSRIEe632yDm5nsd0SDKn8hGmcUwswnyiE5mtdZLDybtHAz6hjJhawokF0hXvGLtx9mrQfm6FkA==", - "dev": true - }, "mute-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", @@ -13270,39 +13182,6 @@ } } }, - "request-promise": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.6.tgz", - "integrity": "sha512-HCHI3DJJUakkOr8fNoCc73E5nU5bqITjOYFMDrKHYOXWXrgD/SBaC7LjwuPymUprRyuF06UK7hd/lMHkmUXglQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.0", - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - }, - "dependencies": { - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - } - } - }, - "request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "dev": true, - "requires": { - "lodash": "^4.17.19" - } - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -14163,12 +14042,6 @@ "through2": "~2.0.3" } }, - "stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", - "dev": true - }, "stream-browserify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", @@ -14546,36 +14419,6 @@ "yallist": "^4.0.0" }, "dependencies": { - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" - }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", - "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", - "requires": { - "yallist": "^4.0.0" - } - }, - "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - } - }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -14794,12 +14637,6 @@ } } }, - "traverse": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", - "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", - "dev": true - }, "trim-newlines": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", @@ -14852,14 +14689,26 @@ } }, "tsconfig-paths": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.10.1.tgz", - "integrity": "sha512-rETidPDgCpltxF7MjBZlAFPUHv5aHH2MymyPvh+vEyWAED4Eb/WeMbsnD/JDr4OKPOA1TssDHgIcpTN5Kh0p6Q==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", + "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==", "dev": true, "requires": { - "json5": "^2.2.0", + "@types/json5": "^0.0.29", + "json5": "^1.0.1", "minimist": "^1.2.0", "strip-bom": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + } } }, "tslib": { @@ -15067,27 +14916,6 @@ "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", "dev": true }, - "unzip-stream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/unzip-stream/-/unzip-stream-0.3.1.tgz", - "integrity": "sha512-RzaGXLNt+CW+T41h1zl6pGz3EaeVhYlK+rdAap+7DxW5kqsqePO8kRtWPaCiVqdhZc86EctSPVYNix30YOMzmw==", - "dev": true, - "requires": { - "binary": "^0.3.0", - "mkdirp": "^0.5.1" - }, - "dependencies": { - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - } - } - }, "update-notifier": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", @@ -15281,11 +15109,10 @@ "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==" }, "whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-9.1.0.tgz", + "integrity": "sha512-CQ0UcrPHyomtlOCot1TL77WyMIm/bCwrJ2D6AOKGwEczU9EpyoqAokfqrf/MioU9kHcMsmJZcg1egXix2KYEsA==", "requires": { - "lodash": "^4.7.0", "tr46": "^2.1.0", "webidl-conversions": "^6.1.0" } diff --git a/package.json b/package.json index d12b1059..afb93a9f 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ }, "dependencies": { "basic-ftp": "^4.6.6", - "mongodb": "^4.1.0", + "mongodb": "^4.1.1", "poolifier": "^2.0.2", "source-map-support": "^0.5.19", "tar": "^6.1.10", @@ -93,11 +93,10 @@ "clinic": "^9.0.0", "cross-env": "^7.0.3", "eslint": "^7.32.0", - "eslint-plugin-import": "^2.24.1", - "eslint-plugin-jsdoc": "^36.0.7", + "eslint-plugin-import": "^2.24.2", + "eslint-plugin-jsdoc": "^36.0.8", "eslint-plugin-node": "^11.1.0", "expect": "^27.0.6", - "mbt": "^1.2.3", "mocha": "^9.1.0", "mochawesome": "^6.2.2", "npm-check": "^5.9.2", diff --git a/src/assets/config-template.json b/src/assets/config-template.json index 0bc2c309..0267c1a7 100644 --- a/src/assets/config-template.json +++ b/src/assets/config-template.json @@ -3,7 +3,9 @@ "ws://localhost:8010/OCPP16/5be7fb271014d90008992f06" ], "distributeStationsToTenantsEqually": true, - "statisticsDisplayInterval": 60, + "performanceStorage": { + "enabled": true + }, "chargingStationsPerWorker": 1, "workerProcess": "workerSet", "workerPoolMinSize": 4, @@ -30,6 +32,7 @@ "numberOfStations": 1 } ], + "logStatisticsInterval": 0, "logFile": "combined.log", "logErrorFile": "error.log", "logConsole": false diff --git a/src/types/ConfigurationData.ts b/src/types/ConfigurationData.ts index 91437807..1a2dd165 100644 --- a/src/types/ConfigurationData.ts +++ b/src/types/ConfigurationData.ts @@ -1,3 +1,4 @@ +import { StorageType } from './Storage'; import type { WorkerChoiceStrategy } from 'poolifier'; import { WorkerProcessType } from './Worker'; @@ -6,10 +7,16 @@ export interface StationTemplateURL { numberOfStations: number; } +export interface StorageConfiguration { + enabled?: boolean; + type?: StorageType; + URI?: string; +} + export default interface ConfigurationData { supervisionURLs?: string[]; stationTemplateURLs: StationTemplateURL[]; - statisticsDisplayInterval?: number; + performanceStorage?: StorageConfiguration; autoReconnectMaxRetries?: number; distributeStationsToTenantsEqually?: boolean; workerProcess?: WorkerProcessType; @@ -18,6 +25,7 @@ export default interface ConfigurationData { workerPoolMaxSize?: number; workerPoolStrategy?: WorkerChoiceStrategy; chargingStationsPerWorker?: number; + logStatisticsInterval?: number; logFormat?: string; logLevel?: string; logRotate?: boolean; diff --git a/src/types/Statistics.ts b/src/types/Statistics.ts index f6f17ca2..7999e14a 100644 --- a/src/types/Statistics.ts +++ b/src/types/Statistics.ts @@ -18,5 +18,7 @@ export interface StatisticsData { export default interface Statistics { id: string; + createdAt: Date; + lastUpdatedAt?: Date; statisticsData: Record; } diff --git a/src/types/Storage.ts b/src/types/Storage.ts new file mode 100644 index 00000000..32a6b22f --- /dev/null +++ b/src/types/Storage.ts @@ -0,0 +1,5 @@ +export enum StorageType { + JSON_FILE = 'jsonfile', + MONGO_DB = 'mongodb' +} + diff --git a/src/utils/Configuration.ts b/src/utils/Configuration.ts index a65e6c99..8be9a1da 100644 --- a/src/utils/Configuration.ts +++ b/src/utils/Configuration.ts @@ -1,6 +1,7 @@ -import ConfigurationData, { StationTemplateURL } from '../types/ConfigurationData'; +import ConfigurationData, { StationTemplateURL, StorageConfiguration } from '../types/ConfigurationData'; import Constants from './Constants'; +import { StorageType } from '../types/Storage'; import type { WorkerChoiceStrategy } from 'poolifier'; import { WorkerProcessType } from '../types/Worker'; import fs from 'fs'; @@ -16,9 +17,30 @@ export default class Configuration { Configuration.configurationChangeCallback = cb; } - static getStatisticsDisplayInterval(): number { + static getLogStatisticsInterval(): number { + Configuration.deprecateConfigurationKey('statisticsDisplayInterval', 'Use \'logStatisticsInterval\' instead'); // Read conf - return Configuration.objectHasOwnProperty(Configuration.getConfig(), 'statisticsDisplayInterval') ? Configuration.getConfig().statisticsDisplayInterval : 60; + return Configuration.objectHasOwnProperty(Configuration.getConfig(), 'logStatisticsInterval') ? Configuration.getConfig().logStatisticsInterval : 60; + } + + static getPerformanceStorage(): StorageConfiguration { + let storageConfiguration: StorageConfiguration; + if (Configuration.objectHasOwnProperty(Configuration.getConfig(), 'performanceStorage')) { + storageConfiguration = + { + ...Configuration.objectHasOwnProperty(Configuration.getConfig().performanceStorage, 'enabled') ? { enabled: Configuration.getConfig().performanceStorage.enabled } : { enabled: false }, + ...Configuration.objectHasOwnProperty(Configuration.getConfig().performanceStorage, 'type') ? { type: Configuration.getConfig().performanceStorage.type } : { type: StorageType.JSON_FILE }, + ...Configuration.objectHasOwnProperty(Configuration.getConfig().performanceStorage, 'URI') ? { URI: Configuration.getConfig().performanceStorage.URI } : { URI: 'file:///performanceMeasurements.json' } + }; + } else { + storageConfiguration = + { + enabled: false, + type: StorageType.JSON_FILE, + URI: 'file:///performanceMeasurements.json' + }; + } + return storageConfiguration; } static getAutoReconnectMaxRetries(): number { @@ -159,8 +181,12 @@ export default class Configuration { const prefix = logPrefix.length !== 0 ? logPrefix + ' ' : ''; if (error.code === 'ENOENT') { console.error(prefix + fileType + ' file ' + filePath + ' not found: ', error); + } else if (error.code === 'EEXIST') { + console.error(prefix + fileType + ' file ' + filePath + ' already exists: ', error); + } else if (error.code === 'EACCES') { + console.error(prefix + fileType + ' file ' + filePath + ' access denied: ', error); } else { - console.error(prefix + fileType + ' file ' + filePath + ' opening error: ', error); + console.error(prefix + fileType + ' file ' + filePath + ' error: ', error); } throw error; } diff --git a/src/utils/FileUtils.ts b/src/utils/FileUtils.ts index c0891e64..b3940b71 100644 --- a/src/utils/FileUtils.ts +++ b/src/utils/FileUtils.ts @@ -9,11 +9,23 @@ export default class FileUtils { } else { logger.warn(prefix + fileType + ' file ' + filePath + ' not found: %j', error); } + } else if (error.code === 'EEXIST') { + if (consoleOut) { + console.warn(prefix + fileType + ' file ' + filePath + ' already exists: ', error); + } else { + logger.warn(prefix + fileType + ' file ' + filePath + ' already exists: %j', error); + } + } else if (error.code === 'EACCES') { + if (consoleOut) { + console.warn(prefix + fileType + ' file ' + filePath + ' access denied: ', error); + } else { + logger.warn(prefix + fileType + ' file ' + filePath + ' access denied: %j', error); + } } else { if (consoleOut) { - console.error(prefix + fileType + ' file ' + filePath + ' opening error: ', error); + console.error(prefix + fileType + ' file ' + filePath + ' error: ', error); } else { - logger.error(prefix + fileType + ' file ' + filePath + ' opening error: %j', error); + logger.error(prefix + fileType + ' file ' + filePath + ' error: %j', error); } throw error; } diff --git a/src/utils/PerformanceStatistics.ts b/src/utils/PerformanceStatistics.ts index 8c536f85..02b2854e 100644 --- a/src/utils/PerformanceStatistics.ts +++ b/src/utils/PerformanceStatistics.ts @@ -7,10 +7,13 @@ import Statistics, { StatisticsData } from '../types/Statistics'; import Configuration from './Configuration'; import { MessageType } from '../types/ocpp/MessageType'; +import { Storage } from './performance-storage/Storage'; +import { StorageFactory } from './performance-storage/StorageFactory'; import Utils from './Utils'; import logger from './Logger'; export default class PerformanceStatistics { + private static storage: Storage; private objId: string; private performanceObserver: PerformanceObserver; private statistics: Statistics; @@ -19,7 +22,7 @@ export default class PerformanceStatistics { public constructor(objId: string) { this.objId = objId; this.initializePerformanceObserver(); - this.statistics = { id: this.objId ?? 'Object id not specified', statisticsData: {} }; + this.statistics = { id: this.objId ?? 'Object id not specified', createdAt: new Date(), statisticsData: {} }; } public static beginMeasure(id: string): string { @@ -74,7 +77,10 @@ export default class PerformanceStatistics { } public start(): void { - this.startDisplayInterval(); + this.startLogStatisticsInterval(); + if (Configuration.getPerformanceStorage().enabled) { + logger.info(`${this.logPrefix()} storage enabled: type ${Configuration.getPerformanceStorage().type}, URI: ${Configuration.getPerformanceStorage().URI}`); + } } public stop(): void { @@ -102,14 +108,14 @@ export default class PerformanceStatistics { logger.info(this.logPrefix() + ' %j', this.statistics); } - private startDisplayInterval(): void { - if (Configuration.getStatisticsDisplayInterval() > 0) { + private startLogStatisticsInterval(): void { + if (Configuration.getLogStatisticsInterval() > 0) { this.displayInterval = setInterval(() => { this.logStatistics(); - }, Configuration.getStatisticsDisplayInterval() * 1000); - logger.info(this.logPrefix() + ' displayed every ' + Utils.secondsToHHMMSS(Configuration.getStatisticsDisplayInterval())); + }, Configuration.getLogStatisticsInterval() * 1000); + logger.info(this.logPrefix() + ' logged every ' + Utils.secondsToHHMMSS(Configuration.getLogStatisticsInterval())); } else { - logger.info(this.logPrefix() + ' display interval is set to ' + Configuration.getStatisticsDisplayInterval().toString() + '. Not displaying statistics'); + logger.info(this.logPrefix() + ' log interval is set to ' + Configuration.getLogStatisticsInterval().toString() + '. Not logging statistics'); } } @@ -173,6 +179,7 @@ export default class PerformanceStatistics { this.statistics.statisticsData[entryName] = {} as StatisticsData; } // Update current statistics + this.statistics.lastUpdatedAt = new Date(); this.statistics.statisticsData[entryName].countTimeMeasurement = this.statistics.statisticsData[entryName].countTimeMeasurement ? this.statistics.statisticsData[entryName].countTimeMeasurement + 1 : 1; this.statistics.statisticsData[entryName].currentTimeMeasurement = entry.duration; this.statistics.statisticsData[entryName].minTimeMeasurement = this.statistics.statisticsData[entryName].minTimeMeasurement ? (this.statistics.statisticsData[entryName].minTimeMeasurement > entry.duration ? entry.duration : this.statistics.statisticsData[entryName].minTimeMeasurement) : entry.duration; @@ -183,9 +190,19 @@ export default class PerformanceStatistics { this.statistics.statisticsData[entryName].medTimeMeasurement = this.median(this.statistics.statisticsData[entryName].timeMeasurementSeries); this.statistics.statisticsData[entryName].ninetyFiveThPercentileTimeMeasurement = this.percentile(this.statistics.statisticsData[entryName].timeMeasurementSeries, 95); this.statistics.statisticsData[entryName].stdDevTimeMeasurement = this.stdDeviation(this.statistics.statisticsData[entryName].timeMeasurementSeries); + if (Configuration.getPerformanceStorage().enabled) { + this.getStorage().storePerformanceStatistics(this.statistics); + } } private logPrefix(): string { return Utils.logPrefix(` ${this.objId} | Performance statistics`); } + + private getStorage(): Storage { + if (!PerformanceStatistics.storage) { + PerformanceStatistics.storage = StorageFactory.getStorage(Configuration.getPerformanceStorage().type ,Configuration.getPerformanceStorage().URI, this.logPrefix()); + } + return PerformanceStatistics.storage; + } } diff --git a/src/utils/performance-storage/JSONFileStorage.ts b/src/utils/performance-storage/JSONFileStorage.ts new file mode 100644 index 00000000..af709d91 --- /dev/null +++ b/src/utils/performance-storage/JSONFileStorage.ts @@ -0,0 +1,20 @@ +import FileUtils from '../FileUtils'; +import Statistics from '../../types/Statistics'; +import { Storage } from './Storage'; +import fs from 'fs'; +import path from 'path'; + +export class JSONFileStorage extends Storage { + constructor(storageURI: string, logPrefix: string) { + super(storageURI, logPrefix); + } + + public storePerformanceStatistics(performanceStatistics: Statistics): void { + const performanceJSONFilePath = path.join(path.resolve(__dirname, '../../../'), this.storageURI.pathname.replace(/^\/|\/$/g, '')); + fs.appendFile(performanceJSONFilePath, JSON.stringify(performanceStatistics, null, 2), 'utf8', (err) => { + if (err) { + FileUtils.handleFileException(this.logPrefix, 'Performance measurements', performanceJSONFilePath, err); + } + }); + } +} diff --git a/src/utils/performance-storage/MongoDBStorage.ts b/src/utils/performance-storage/MongoDBStorage.ts new file mode 100644 index 00000000..a47984c1 --- /dev/null +++ b/src/utils/performance-storage/MongoDBStorage.ts @@ -0,0 +1,16 @@ +import Statistics from '../../types/Statistics'; +import { Storage } from './Storage'; + +export class MongoDBStorage extends Storage { + constructor(storageURI: string, logPrefix: string) { + super(storageURI, logPrefix); + } + + public storePerformanceStatistics(performanceStatistics: Statistics): void { + throw new Error('Method not yet implemented'); + } + + private open(): void {} + + private close(): void {} +} diff --git a/src/utils/performance-storage/Storage.ts b/src/utils/performance-storage/Storage.ts new file mode 100644 index 00000000..890dce7a --- /dev/null +++ b/src/utils/performance-storage/Storage.ts @@ -0,0 +1,14 @@ +import Statistics from '../../types/Statistics'; +import { URL } from 'url'; + +export abstract class Storage { + protected storageURI: URL; + protected logPrefix: string; + + constructor(storageURI: string, logPrefix: string) { + this.storageURI = new URL(storageURI); + this.logPrefix = logPrefix; + } + + public abstract storePerformanceStatistics(performanceStatistics: Statistics): void; +} diff --git a/src/utils/performance-storage/StorageFactory.ts b/src/utils/performance-storage/StorageFactory.ts new file mode 100644 index 00000000..4d04dee2 --- /dev/null +++ b/src/utils/performance-storage/StorageFactory.ts @@ -0,0 +1,25 @@ +import { JSONFileStorage } from './JSONFileStorage'; +import { MongoDBStorage } from './MongoDBStorage'; +import { Storage } from './Storage'; +import { StorageType } from '../../types/Storage'; +import logger from '../Logger'; + +export class StorageFactory { + // eslint-disable-next-line @typescript-eslint/no-empty-function + private constructor() {} + + public static getStorage(type: StorageType, connectionURI: string, logPrefix: string): Storage { + let storageInstance: Storage = null; + switch (type) { + case StorageType.JSON_FILE: + storageInstance = new JSONFileStorage(connectionURI, logPrefix); + break; + case StorageType.MONGO_DB: + storageInstance = new MongoDBStorage(connectionURI, logPrefix); + break; + default: + logger.error(`${logPrefix} Unknown storage type: ${type}`); + } + return storageInstance; + } +}