diff --git a/.eslintrc.json b/.eslintrc.json index d1a7ec4fc0..22d82cf47e 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -22,6 +22,12 @@ "@typescript-eslint/explicit-member-accessibility": "off", "jsdoc/require-jsdoc": "off", "indent": "off", + "@typescript-eslint/unbound-method": [ + "error", + { + "ignoreStatic": true + } + ], "@typescript-eslint/indent": [ "error", 2, @@ -138,7 +144,7 @@ "max-len": [ "warn", { - "code": 180, + "code": 220, "ignoreComments": true, "ignoreUrls": true, "ignoreStrings": true, @@ -213,7 +219,7 @@ }, "overrides": [ { - "files": ["*.ts", "*.tsx"], + "files": ["src/**/*.ts", "src/**/*.tsx"], "rules": { "@typescript-eslint/explicit-member-accessibility": ["error"] } diff --git a/.vscode/launch.json b/.vscode/launch.json index 157c024388..98f9f31d29 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -140,6 +140,26 @@ "/**" ], "stopOnEntry": true + }, + { + "name": "Debug Tests 'createContext:utbilling'", + "type": "pwa-node", + "request": "launch", + "cwd": "${workspaceFolder}", + "runtimeExecutable": "npm", + "runtimeArgs": [ + "run-script", + "test:create:utbilling" + ], + "sourceMaps": true, + "resolveSourceMapLocations": [ + "${workspaceFolder}/**", + "!**/node_modules/**" + ], + "skipFiles": [ + "/**" + ], + "stopOnEntry": true } ] } diff --git a/package-lock.json b/package-lock.json index 18d475491b..d7304ac424 100644 --- a/package-lock.json +++ b/package-lock.json @@ -73,7 +73,7 @@ "tslib": "^2.4.0", "tz-lookup": "^6.1.25", "urlencode": "^1.1.0", - "uWebSockets.js": "github:uNetworking/uWebSockets.js#v20.10.0", + "uWebSockets.js": "github:uNetworking/uWebSockets.js#v20.19.0", "validator": "^13.7.0", "ws": "^8.10.0" }, @@ -157,8 +157,7 @@ "webpack-cli": "^4.10.0", "webpack-merge": "^5.8.0", "webpack-node-externals": "^3.0.0", - "webpack-shell-plugin-next": "^2.2.2", - "xml2json": "^0.12.0" + "webpack-shell-plugin-next": "^2.2.2" }, "engines": { "node": "16.x.x", @@ -6697,15 +6696,6 @@ "node": ">=8" } }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, "node_modules/bintrees": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.2.tgz", @@ -11054,12 +11044,6 @@ "node": ">=6" } }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true - }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -12283,16 +12267,6 @@ "minimalistic-crypto-utils": "^1.0.1" } }, - "node_modules/hoek": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", - "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", - "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", - "dev": true, - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/hogan.js": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/hogan.js/-/hogan.js-3.0.2.tgz", @@ -13603,27 +13577,6 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" }, - "node_modules/isemail": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/isemail/-/isemail-3.2.0.tgz", - "integrity": "sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg==", - "dev": true, - "dependencies": { - "punycode": "2.x.x" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/isemail/node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -14989,31 +14942,6 @@ "regenerator-runtime": "^0.13.3" } }, - "node_modules/joi": { - "version": "13.7.0", - "resolved": "https://registry.npmjs.org/joi/-/joi-13.7.0.tgz", - "integrity": "sha512-xuY5VkHfeOYK3Hdi91ulocfuFopwgbSORmIwzcwHKESQhC7w1kD5jaVSPnqDxS2I8t3RZ9omCKAxNwXN5zG1/Q==", - "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", - "dev": true, - "dependencies": { - "hoek": "5.x.x", - "isemail": "3.x.x", - "topo": "3.x.x" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/joi/node_modules/hoek": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-5.0.4.tgz", - "integrity": "sha512-Alr4ZQgoMlnere5FZJsIyfIjORBqZll5POhDsF4q64dPuJR6rNxXdDxtHSQq8OXRurhmx+PWYEE8bXRROY8h0w==", - "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", - "dev": true, - "engines": { - "node": ">=8.9.0" - } - }, "node_modules/jose": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/jose/-/jose-2.0.6.tgz", @@ -17224,12 +17152,6 @@ "queue-tick": "^1.0.0" } }, - "node_modules/nan": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", - "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", - "dev": true - }, "node_modules/nanoassert": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-1.1.0.tgz", @@ -17555,17 +17477,6 @@ "lodash": "^4.17.21" } }, - "node_modules/node-expat": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/node-expat/-/node-expat-2.4.0.tgz", - "integrity": "sha512-X8Y/Zk/izfNgfayeOeUGqze7KlaOwVJ9SDTjHUMKd0hu0aFTRpLlLCBwmx79cTPiQWD24I1YOafF+U+rTvEMfQ==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "bindings": "^1.5.0", - "nan": "^2.13.2" - } - }, "node_modules/node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", @@ -22928,23 +22839,6 @@ "node": ">=0.6" } }, - "node_modules/topo": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/topo/-/topo-3.0.3.tgz", - "integrity": "sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ==", - "deprecated": "This module has moved and is now available at @hapi/topo. Please update your dependencies as this version is no longer maintained an may contain bugs and security issues.", - "dev": true, - "dependencies": { - "hoek": "6.x.x" - } - }, - "node_modules/topo/node_modules/hoek": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.3.tgz", - "integrity": "sha512-YXXAAhmF9zpQbC7LEcREFtXfGq5K1fmd+4PHkBq8NUqmzW3G+Dq10bI/i0KucLRwss3YYFQ0fSfoxBZYiGUqtQ==", - "deprecated": "This module has moved and is now available at @hapi/hoek. Please update your dependencies as this version is no longer maintained an may contain bugs and security issues.", - "dev": true - }, "node_modules/touch": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", @@ -24674,20 +24568,6 @@ "node": ">=4.0" } }, - "node_modules/xml2json": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/xml2json/-/xml2json-0.12.0.tgz", - "integrity": "sha512-EPJHRWJnJUYbJlzR4pBhZODwWdi2IaYGtDdteJi0JpZ4OD31IplWALuit8r73dJuM4iHZdDVKY1tLqY2UICejg==", - "dev": true, - "dependencies": { - "hoek": "^4.2.1", - "joi": "^13.1.2", - "node-expat": "^2.3.18" - }, - "bin": { - "xml2json": "bin/xml2json" - } - }, "node_modules/xmlbuilder": { "version": "15.0.0", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.0.0.tgz", @@ -30053,15 +29933,6 @@ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, "bintrees": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.2.tgz", @@ -33568,12 +33439,6 @@ "resolved": "https://registry.npmjs.org/file-type/-/file-type-9.0.0.tgz", "integrity": "sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw==" }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true - }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -34511,12 +34376,6 @@ "minimalistic-crypto-utils": "^1.0.1" } }, - "hoek": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", - "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", - "dev": true - }, "hogan.js": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/hogan.js/-/hogan.js-3.0.2.tgz", @@ -35500,23 +35359,6 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" }, - "isemail": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/isemail/-/isemail-3.2.0.tgz", - "integrity": "sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg==", - "dev": true, - "requires": { - "punycode": "2.x.x" - }, - "dependencies": { - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - } - } - }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -36589,25 +36431,6 @@ "regenerator-runtime": "^0.13.3" } }, - "joi": { - "version": "13.7.0", - "resolved": "https://registry.npmjs.org/joi/-/joi-13.7.0.tgz", - "integrity": "sha512-xuY5VkHfeOYK3Hdi91ulocfuFopwgbSORmIwzcwHKESQhC7w1kD5jaVSPnqDxS2I8t3RZ9omCKAxNwXN5zG1/Q==", - "dev": true, - "requires": { - "hoek": "5.x.x", - "isemail": "3.x.x", - "topo": "3.x.x" - }, - "dependencies": { - "hoek": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-5.0.4.tgz", - "integrity": "sha512-Alr4ZQgoMlnere5FZJsIyfIjORBqZll5POhDsF4q64dPuJR6rNxXdDxtHSQq8OXRurhmx+PWYEE8bXRROY8h0w==", - "dev": true - } - } - }, "jose": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/jose/-/jose-2.0.6.tgz", @@ -38497,12 +38320,6 @@ "queue-tick": "^1.0.0" } }, - "nan": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", - "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", - "dev": true - }, "nanoassert": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-1.1.0.tgz", @@ -38793,16 +38610,6 @@ "lodash": "^4.17.21" } }, - "node-expat": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/node-expat/-/node-expat-2.4.0.tgz", - "integrity": "sha512-X8Y/Zk/izfNgfayeOeUGqze7KlaOwVJ9SDTjHUMKd0hu0aFTRpLlLCBwmx79cTPiQWD24I1YOafF+U+rTvEMfQ==", - "dev": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.13.2" - } - }, "node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", @@ -43003,23 +42810,6 @@ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" }, - "topo": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/topo/-/topo-3.0.3.tgz", - "integrity": "sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ==", - "dev": true, - "requires": { - "hoek": "6.x.x" - }, - "dependencies": { - "hoek": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.3.tgz", - "integrity": "sha512-YXXAAhmF9zpQbC7LEcREFtXfGq5K1fmd+4PHkBq8NUqmzW3G+Dq10bI/i0KucLRwss3YYFQ0fSfoxBZYiGUqtQ==", - "dev": true - } - } - }, "touch": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", @@ -43746,7 +43536,7 @@ }, "uWebSockets.js": { "version": "git+ssh://git@github.com/uNetworking/uWebSockets.js.git#806df48c9da86af7b3341f3e443388c7cd15c3de", - "from": "uWebSockets.js@github:uNetworking/uWebSockets.js#v20.10.0" + "from": "uWebSockets.js@github:uNetworking/uWebSockets.js#v20.19.0" }, "v8-compile-cache-lib": { "version": "3.0.1", @@ -44327,17 +44117,6 @@ } } }, - "xml2json": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/xml2json/-/xml2json-0.12.0.tgz", - "integrity": "sha512-EPJHRWJnJUYbJlzR4pBhZODwWdi2IaYGtDdteJi0JpZ4OD31IplWALuit8r73dJuM4iHZdDVKY1tLqY2UICejg==", - "dev": true, - "requires": { - "hoek": "^4.2.1", - "joi": "^13.1.2", - "node-expat": "^2.3.18" - } - }, "xmlbuilder": { "version": "15.0.0", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.0.0.tgz", diff --git a/package.json b/package.json index 6dd725b8be..a10d610212 100644 --- a/package.json +++ b/package.json @@ -30,9 +30,9 @@ "start": "npm version && npm run start:prod", "start:dev": "npm version && cross-env NODE_OPTIONS=\"--max-old-space-size=4096\" NODE_ENV=development-build node -r source-map-support/register dist/start.js", "start:dev:debug": "npm version && cross-env NODE_ENV=development ts-node-dev --inspect --files --max-old-space-size=4096 -- src/start.ts", - "start:dev:debug:ocppj": "npm version && cross-env SERVER_ROLE=ocppj NODE_ENV=development ts-node-dev --inspect --files --max-old-space-size=4096 -- src/start.ts", - "start:dev:debug:rest": "npm version && cross-env SERVER_ROLE=rest NODE_ENV=development ts-node-dev --inspect --files --max-old-space-size=4096 -- src/start.ts", - "start:dev:debug:batch": "npm version && cross-env SERVER_ROLE=batch NODE_ENV=development ts-node-dev --inspect --files --max-old-space-size=4096 -- src/start.ts", + "start:dev:debug:ocppj": "npm version && cross-env SERVER_ROLE=ocppj NODE_ENV=development ts-node-dev --inspect --files -- src/start.ts", + "start:dev:debug:rest": "npm version && cross-env SERVER_ROLE=rest NODE_ENV=development ts-node-dev --files -- src/start.ts", + "start:dev:debug:batch": "npm version && cross-env SERVER_ROLE=batch NODE_ENV=development ts-node-dev --inspect --files -- src/start.ts", "start:dev:debug:nodemon": "npm version && nodemon --exec \"ts-node --files\" src/start.ts 9229", "start:dev:nodemon": "npm version && nodemon --exec \"ts-node --files\" src/start.ts", "start:dev:prof": "npm version && cross-env NODE_OPTIONS=\"--max-old-space-size=4096\" NODE_ENV=development node -r source-map-support/register --prof -- dist/start.js", @@ -62,8 +62,8 @@ "import-sort": "npx import-sort-cli --write 'src/**/*.ts{,x}' 'test/**/*.ts{,x}' 'types/**/*.ts{,x}'", "test-jest-pluggin": "npm version && cross-env TS_NODE_FILES=true jest --config='test/jest.config.ts' --reporters='default' --reporters='./JestEvseReporter.js' --runInBand --logHeapUsage --verbose --colors --silent --forceExit --testPathIgnorePatterns='.*Runner.ts$'", "test": "npm run test:jest -- test/api/*Test.ts", - "test:createContext": "npm run test:jest -- test/api/context/ContextBuilderRunner.ts", - "test:create:utbilling": "cross-env TS_NODE_FILES=true TENANT_FILTER=utbilling.* jest --config='test/jest.config.ts' --runInBand --logHeapUsage --verbose --colors --silent --forceExit -- test/**/**/ContextBuilderRunner.ts", + "test:createContext": "cross-env TS_NODE_FILES=true jest --config='test/jest.config.ts' --runInBand --logHeapUsage --verbose --colors --silent --forceExit -- test/api/context/ContextBuilderRunner.ts", + "test:create:utbilling": "cross-env TS_NODE_FILES=true TENANT_FILTER=utbilling.* jest --config='test/jest.config.ts' --runInBand --logHeapUsage --verbose --colors --silent --forceExit -- test/api/context/ContextBuilderRunner.ts", "test:asset": "npm run test:jest -- test/api/AssetTest.ts", "test:authentication": "npm run test:jest -- test/api/AuthenticationTest.ts", "test:billing": "npm run test:jest -- test/api/BillingTest.ts", @@ -160,7 +160,7 @@ "tslib": "^2.4.0", "tz-lookup": "^6.1.25", "urlencode": "^1.1.0", - "uWebSockets.js": "github:uNetworking/uWebSockets.js#v20.10.0", + "uWebSockets.js": "github:uNetworking/uWebSockets.js#v20.19.0", "validator": "^13.7.0", "ws": "^8.10.0" }, @@ -248,7 +248,6 @@ "webpack-cli": "^4.10.0", "webpack-merge": "^5.8.0", "webpack-node-externals": "^3.0.0", - "webpack-shell-plugin-next": "^2.2.2", - "xml2json": "^0.12.0" + "webpack-shell-plugin-next": "^2.2.2" } } diff --git a/src/async-task/AsyncTaskBuilder.ts b/src/async-task/AsyncTaskBuilder.ts index c8adac2703..d81d1854a0 100644 --- a/src/async-task/AsyncTaskBuilder.ts +++ b/src/async-task/AsyncTaskBuilder.ts @@ -25,7 +25,7 @@ export default class AsyncTaskBuilder { // Save await AsyncTaskStorage.saveAsyncTask(asyncTask as AsyncTask); // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.ASYNC_TASK, module: MODULE_NAME, method: 'createAndSaveAsyncTasks', diff --git a/src/async-task/AsyncTaskManager.ts b/src/async-task/AsyncTaskManager.ts index 527a19401d..ae727dc16a 100644 --- a/src/async-task/AsyncTaskManager.ts +++ b/src/async-task/AsyncTaskManager.ts @@ -59,7 +59,7 @@ export default class AsyncTaskManager { public static async handleAsyncTasks(): Promise { let failedToAcquireLock = false; - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.ASYNC_TASK, module: MODULE_NAME, method: 'handleAsyncTasks', @@ -80,7 +80,7 @@ export default class AsyncTaskManager { { status: AsyncTaskStatus.PENDING }, Constants.DB_PARAMS_MAX_LIMIT); // Process them if (!Utils.isEmptyArray(asyncTasks.result)) { - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.ASYNC_TASK, module: MODULE_NAME, method: 'handleAsyncTasks', @@ -103,7 +103,7 @@ export default class AsyncTaskManager { asyncTask.lastChangedOn = asyncTask.execTimestamp; await AsyncTaskStorage.saveAsyncTask(asyncTask); // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.ASYNC_TASK, module: MODULE_NAME, method: 'handleAsyncTasks', @@ -120,7 +120,7 @@ export default class AsyncTaskManager { await AsyncTaskStorage.saveAsyncTask(asyncTask); processedTask.inSuccess++; // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.ASYNC_TASK, module: MODULE_NAME, method: 'handleAsyncTasks', @@ -135,7 +135,7 @@ export default class AsyncTaskManager { asyncTask.lastChangedOn = new Date(); await AsyncTaskStorage.saveAsyncTask(asyncTask); // Log error - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, module: MODULE_NAME, method: 'handleAsyncTasks', action: ServerAction.ASYNC_TASK, @@ -169,7 +169,7 @@ export default class AsyncTaskManager { }); } } else { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.ASYNC_TASK, module: MODULE_NAME, method: 'handleAsyncTasks', @@ -210,7 +210,7 @@ export default class AsyncTaskManager { case AsyncTasks.OCPI_PUSH_EVSE_STATUSES: return new OCPIPushEVSEStatusesAsyncTask(asyncTask, correlationID); default: - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.ASYNC_TASK, module: MODULE_NAME, method: 'handleAsyncTasks', diff --git a/src/async-task/TenantAsyncTask.ts b/src/async-task/TenantAsyncTask.ts index 913d6a30dd..86c219155a 100644 --- a/src/async-task/TenantAsyncTask.ts +++ b/src/async-task/TenantAsyncTask.ts @@ -23,7 +23,7 @@ export default abstract class TenantAsyncTask extends AbstractAsyncTask { (taskSettings.task.disableAllTasks || !Utils.isEmptyArray(taskSettings.task.disableTasksInEnv) && taskSettings.task.disableTasksInEnv.includes(currentTaskEnv))) { // Tasks are disabled for this environment isTaskExecutionDisabled = true; - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.ASYNC_TASK, module: MODULE_NAME, method: 'executeAsyncTask', @@ -43,7 +43,7 @@ export default abstract class TenantAsyncTask extends AbstractAsyncTask { } // Check if tenant task needs to run on a specific env if (tenant.taskExecutionEnv && tenant.taskExecutionEnv !== currentTaskEnv) { - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.ASYNC_TASK, module: MODULE_NAME, method: 'executeAsyncTask', @@ -54,13 +54,13 @@ export default abstract class TenantAsyncTask extends AbstractAsyncTask { } const tenantCorrelationID = Utils.generateShortNonUniqueID(); const startTimeInTenant = moment(); - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.ASYNC_TASK, module: MODULE_NAME, method: 'executeAsyncTask', message: `The Task '${this.getAsyncTask().name}~${this.getCorrelationID()}~${tenantCorrelationID}' is running for Tenant ${Utils.buildTenantName(tenant)}...` }); - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, action: ServerAction.ASYNC_TASK, module: MODULE_NAME, method: 'executeAsyncTask', @@ -74,14 +74,14 @@ export default abstract class TenantAsyncTask extends AbstractAsyncTask { // Hook await this.afterExecuteTenantAsyncTask(tenant); } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.ASYNC_TASK, module: MODULE_NAME, method: 'executeAsyncTask', message: `Error while running the Task '${this.getAsyncTask().name}~${this.getCorrelationID()}~${tenantCorrelationID}' for Tenant ${Utils.buildTenantName(tenant)}: ${error.message as string}`, detailedMessages: { error: error.stack } }); - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: ServerAction.ASYNC_TASK, module: MODULE_NAME, method: 'executeAsyncTask', @@ -91,13 +91,13 @@ export default abstract class TenantAsyncTask extends AbstractAsyncTask { } // Log Total Processing Time in Tenant const totalTimeSecsInTenant = moment.duration(moment().diff(startTimeInTenant)).asSeconds(); - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.ASYNC_TASK, module: MODULE_NAME, method: 'executeAsyncTask', message: `The Task '${this.getAsyncTask().name}~${this.getCorrelationID()}~${tenantCorrelationID}' has been run successfully in ${totalTimeSecsInTenant} secs for Tenant ${Utils.buildTenantName(tenant)}` }); - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, action: ServerAction.ASYNC_TASK, module: MODULE_NAME, method: 'executeAsyncTask', diff --git a/src/async-task/tasks/BillTransactionAsyncTask.ts b/src/async-task/tasks/BillTransactionAsyncTask.ts index 696d369af6..db9fbec8af 100644 --- a/src/async-task/tasks/BillTransactionAsyncTask.ts +++ b/src/async-task/tasks/BillTransactionAsyncTask.ts @@ -53,7 +53,7 @@ export default class BillTransactionAsyncTask extends AbstractAsyncTask { } } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.BILLING_TRANSACTION, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.BILLING_TRANSACTION, error); } } } diff --git a/src/async-task/tasks/EndTransactionAsyncTask.ts b/src/async-task/tasks/EndTransactionAsyncTask.ts index a8278bbc6f..fd8f3a5792 100644 --- a/src/async-task/tasks/EndTransactionAsyncTask.ts +++ b/src/async-task/tasks/EndTransactionAsyncTask.ts @@ -37,7 +37,7 @@ export default class EndTransactionAsyncTask extends AbstractAsyncTask { // Let's trigger the end of the transaction await ocppService.triggerEndTransaction(tenant, chargingStation, transactionID, connectorId); } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPP_STATUS_NOTIFICATION, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPP_STATUS_NOTIFICATION, error); } } } diff --git a/src/async-task/tasks/ImportHelper.ts b/src/async-task/tasks/ImportHelper.ts index f1899e5911..42042b5ec1 100644 --- a/src/async-task/tasks/ImportHelper.ts +++ b/src/async-task/tasks/ImportHelper.ts @@ -140,7 +140,7 @@ export default class ImportHelper { await UserStorage.addSiteToUser(tenant, user.id, importedSiteID); } else { // Site does not exist - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: ServerAction.USERS_IMPORT, module: MODULE_NAME, method: 'executeAsyncTask', diff --git a/src/async-task/tasks/SynchronizeCarCatalogsAsyncTask.ts b/src/async-task/tasks/SynchronizeCarCatalogsAsyncTask.ts index 32b541be11..4930a81fe0 100644 --- a/src/async-task/tasks/SynchronizeCarCatalogsAsyncTask.ts +++ b/src/async-task/tasks/SynchronizeCarCatalogsAsyncTask.ts @@ -24,7 +24,7 @@ export default class SynchronizeCarCatalogsAsyncTask extends AbstractAsyncTask { await carDatabaseImpl.synchronizeCarCatalogs(); } catch (error) { // Log error - await Logging.logActionExceptionMessage(Constants.DEFAULT_TENANT_ID, ServerAction.SYNCHRONIZE_CAR_CATALOGS, error); + Logging.logActionExceptionMessage(Constants.DEFAULT_TENANT_ID, ServerAction.SYNCHRONIZE_CAR_CATALOGS, error); } finally { // Release the lock await LockingManager.release(syncCarCatalogsLock); diff --git a/src/async-task/tasks/TagsImportAsyncTask.ts b/src/async-task/tasks/TagsImportAsyncTask.ts index 550912d519..c127618fce 100644 --- a/src/async-task/tasks/TagsImportAsyncTask.ts +++ b/src/async-task/tasks/TagsImportAsyncTask.ts @@ -43,7 +43,7 @@ export default class TagsImportAsyncTask extends AbstractAsyncTask { // Get total number of Tags to import const totalTagsToImport = await TagStorage.getImportedTagsCount(tenant); if (totalTagsToImport > 0) { - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, action: ServerAction.TAGS_IMPORT, module: MODULE_NAME, method: 'processTenant', @@ -66,7 +66,7 @@ export default class TagsImportAsyncTask extends AbstractAsyncTask { importedTag.errorDescription = error.message; result.inError++; await TagStorage.saveImportedTag(tenant, importedTag); - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: ServerAction.TAGS_IMPORT, module: MODULE_NAME, method: 'processTenant', @@ -77,7 +77,7 @@ export default class TagsImportAsyncTask extends AbstractAsyncTask { } if (!Utils.isEmptyArray(importedTags.result) && (result.inError + result.inSuccess) > 0) { const intermediateDurationSecs = Math.round((new Date().getTime() - startTime) / 1000); - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, action: ServerAction.TAGS_IMPORT, module: MODULE_NAME, method: 'processTenant', @@ -95,7 +95,7 @@ export default class TagsImportAsyncTask extends AbstractAsyncTask { ); } catch (error) { // Log error - await Logging.logActionExceptionMessage(tenant.id, ServerAction.TAGS_IMPORT, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.TAGS_IMPORT, error); } finally { // Release the lock await LockingManager.release(importTagsLock); diff --git a/src/async-task/tasks/UsersImportAsyncTask.ts b/src/async-task/tasks/UsersImportAsyncTask.ts index 400351c935..38c987d71a 100644 --- a/src/async-task/tasks/UsersImportAsyncTask.ts +++ b/src/async-task/tasks/UsersImportAsyncTask.ts @@ -42,7 +42,7 @@ export default class UsersImportAsyncTask extends AbstractAsyncTask { // Get total number of Users to import const totalUsersToImport = await UserStorage.getImportedUsersCount(tenant); if (totalUsersToImport > 0) { - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, action: ServerAction.USERS_IMPORT, module: MODULE_NAME, method: 'processTenant', @@ -66,7 +66,7 @@ export default class UsersImportAsyncTask extends AbstractAsyncTask { result.inError++; // Update it await UserStorage.saveImportedUser(tenant, importedUser); - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: ServerAction.USERS_IMPORT, module: MODULE_NAME, method: 'executeAsyncTask', @@ -77,7 +77,7 @@ export default class UsersImportAsyncTask extends AbstractAsyncTask { } if (importedUsers.result.length > 0 && (result.inError + result.inSuccess) > 0) { const intermediateDurationSecs = Math.round((new Date().getTime() - startTime) / 1000); - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, action: ServerAction.USERS_IMPORT, module: MODULE_NAME, method: 'processTenant', @@ -95,7 +95,7 @@ export default class UsersImportAsyncTask extends AbstractAsyncTask { ); } catch (error) { // Log error - await Logging.logActionExceptionMessage(tenant.id, ServerAction.USERS_IMPORT, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.USERS_IMPORT, error); } finally { // Release the lock await LockingManager.release(importUsersLock); diff --git a/src/async-task/tasks/ocpi/OCPICheckCdrsAsyncTask.ts b/src/async-task/tasks/ocpi/OCPICheckCdrsAsyncTask.ts index 65800f53f4..82083f0913 100644 --- a/src/async-task/tasks/ocpi/OCPICheckCdrsAsyncTask.ts +++ b/src/async-task/tasks/ocpi/OCPICheckCdrsAsyncTask.ts @@ -35,7 +35,7 @@ export default class OCPICheckCdrsAsyncTask extends AbstractAsyncTask { } } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_CHECK_CDRS, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_CHECK_CDRS, error); } } } diff --git a/src/async-task/tasks/ocpi/OCPICheckLocationsAsyncTask.ts b/src/async-task/tasks/ocpi/OCPICheckLocationsAsyncTask.ts index 928b3648e4..310f4e27f5 100644 --- a/src/async-task/tasks/ocpi/OCPICheckLocationsAsyncTask.ts +++ b/src/async-task/tasks/ocpi/OCPICheckLocationsAsyncTask.ts @@ -35,7 +35,7 @@ export default class OCPICheckLocationsAsyncTask extends AbstractAsyncTask { } } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_CHECK_LOCATIONS, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_CHECK_LOCATIONS, error); } } } diff --git a/src/async-task/tasks/ocpi/OCPICheckSessionsAsyncTask.ts b/src/async-task/tasks/ocpi/OCPICheckSessionsAsyncTask.ts index a209e6bd01..9e81159897 100644 --- a/src/async-task/tasks/ocpi/OCPICheckSessionsAsyncTask.ts +++ b/src/async-task/tasks/ocpi/OCPICheckSessionsAsyncTask.ts @@ -35,7 +35,7 @@ export default class OCPICheckSessionsAsyncTask extends AbstractAsyncTask { } } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_CHECK_SESSIONS, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_CHECK_SESSIONS, error); } } } diff --git a/src/async-task/tasks/ocpi/OCPIPullCdrsAsyncTask.ts b/src/async-task/tasks/ocpi/OCPIPullCdrsAsyncTask.ts index 455e54ff56..2f31e395fc 100644 --- a/src/async-task/tasks/ocpi/OCPIPullCdrsAsyncTask.ts +++ b/src/async-task/tasks/ocpi/OCPIPullCdrsAsyncTask.ts @@ -35,7 +35,7 @@ export default class OCPIPullCdrsAsyncTask extends AbstractAsyncTask { } } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_EMSP_GET_CDR, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_EMSP_GET_CDR, error); } } } diff --git a/src/async-task/tasks/ocpi/OCPIPullLocationsAsyncTask.ts b/src/async-task/tasks/ocpi/OCPIPullLocationsAsyncTask.ts index 776dc047be..f1ede60d02 100644 --- a/src/async-task/tasks/ocpi/OCPIPullLocationsAsyncTask.ts +++ b/src/async-task/tasks/ocpi/OCPIPullLocationsAsyncTask.ts @@ -35,7 +35,7 @@ export default class OCPIPullLocationsAsyncTask extends AbstractAsyncTask { } } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_EMSP_GET_LOCATIONS, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_EMSP_GET_LOCATIONS, error); } } } diff --git a/src/async-task/tasks/ocpi/OCPIPullSessionsAsyncTask.ts b/src/async-task/tasks/ocpi/OCPIPullSessionsAsyncTask.ts index e670b9af5b..9e0bea587c 100644 --- a/src/async-task/tasks/ocpi/OCPIPullSessionsAsyncTask.ts +++ b/src/async-task/tasks/ocpi/OCPIPullSessionsAsyncTask.ts @@ -35,7 +35,7 @@ export default class OCPIPullSessionsAsyncTask extends AbstractAsyncTask { } } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_EMSP_GET_SESSION, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_EMSP_GET_SESSION, error); } } } diff --git a/src/async-task/tasks/ocpi/OCPIPullTokensAsyncTask.ts b/src/async-task/tasks/ocpi/OCPIPullTokensAsyncTask.ts index 2dd5c1df39..d265cb715a 100644 --- a/src/async-task/tasks/ocpi/OCPIPullTokensAsyncTask.ts +++ b/src/async-task/tasks/ocpi/OCPIPullTokensAsyncTask.ts @@ -35,7 +35,7 @@ export default class OCPIPullTokensAsyncTask extends AbstractAsyncTask { } } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_GET_TOKENS, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_GET_TOKENS, error); } } } diff --git a/src/async-task/tasks/ocpi/OCPIPushEVSEStatusesAsyncTask.ts b/src/async-task/tasks/ocpi/OCPIPushEVSEStatusesAsyncTask.ts index 5e87c3e77e..e158d70e32 100644 --- a/src/async-task/tasks/ocpi/OCPIPushEVSEStatusesAsyncTask.ts +++ b/src/async-task/tasks/ocpi/OCPIPushEVSEStatusesAsyncTask.ts @@ -35,7 +35,7 @@ export default class OCPIPushEVSEStatusesAsyncTask extends AbstractAsyncTask { } } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_UPDATE_STATUS, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_UPDATE_STATUS, error); } } } diff --git a/src/async-task/tasks/ocpi/OCPIPushTokensAsyncTask.ts b/src/async-task/tasks/ocpi/OCPIPushTokensAsyncTask.ts index ed9d850793..f2a203fdf3 100644 --- a/src/async-task/tasks/ocpi/OCPIPushTokensAsyncTask.ts +++ b/src/async-task/tasks/ocpi/OCPIPushTokensAsyncTask.ts @@ -36,7 +36,7 @@ export default class OCPIPushTokensAsyncTask extends AbstractAsyncTask { } } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_EMSP_UPDATE_TOKENS, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_EMSP_UPDATE_TOKENS, error); } } } diff --git a/src/authorization/Authorizations.ts b/src/authorization/Authorizations.ts index 8ec37c8aa6..b2116ec209 100644 --- a/src/authorization/Authorizations.ts +++ b/src/authorization/Authorizations.ts @@ -933,7 +933,7 @@ export default class Authorizations { if (remoteAuthorization && OCPIUtils.isAuthorizationValid(remoteAuthorization.timestamp)) { // Check Tag ID if (remoteAuthorization.tagId === tag.ocpiToken?.uid) { - await Logging.logDebug({ + Logging.beDebug()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action, message: `${Utils.buildConnectorInfo(connector.connectorId, transaction?.id)} Valid Remote Authorization found for Tag ID '${tag.ocpiToken.uid}'`, diff --git a/src/bootstrap/LocalCarCatalogBootstrap.ts b/src/bootstrap/LocalCarCatalogBootstrap.ts index ff4c2f1d77..87daede0d1 100644 --- a/src/bootstrap/LocalCarCatalogBootstrap.ts +++ b/src/bootstrap/LocalCarCatalogBootstrap.ts @@ -54,7 +54,7 @@ export default class LocalCarCatalogBootstrap { created++; } catch (error) { const message = `Error while importing the local Car ID '${carCatalog.id}': ${error.message as string}`; - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.UPDATE_LOCAL_CAR_CATALOGS, module: MODULE_NAME, method: 'uploadLocalCarCatalogsFromFile', @@ -66,7 +66,7 @@ export default class LocalCarCatalogBootstrap { } } catch (error) { const message = `Error while importing the local Cars: ${error.message as string}`; - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.UPDATE_LOCAL_CAR_CATALOGS, module: MODULE_NAME, method: 'uploadLocalCarCatalogsFromFile', @@ -77,7 +77,7 @@ export default class LocalCarCatalogBootstrap { // Log in the default tenant if (created > 0) { const message = `${created} local Car(s) catalog created in the default tenant`; - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.UPDATE_LOCAL_CAR_CATALOGS, message, module: MODULE_NAME, method: 'uploadLocalCarCatalogsFromFile', diff --git a/src/client/ocpi/CpoOCPIClient.ts b/src/client/ocpi/CpoOCPIClient.ts index 1dedd1245a..63752e2341 100644 --- a/src/client/ocpi/CpoOCPIClient.ts +++ b/src/client/ocpi/CpoOCPIClient.ts @@ -117,7 +117,7 @@ export default class CpoOCPIClient extends OCPIClient { } const numberOfTags = response.data.data.length as number; totalNumberOfTags += numberOfTags; - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: this.tenant.id, action: ServerAction.OCPI_CPO_GET_TOKENS, message: `${numberOfTags.toString()} Tokens retrieved from ${tokensUrl}`, @@ -162,7 +162,7 @@ export default class CpoOCPIClient extends OCPIClient { } const executionDurationLoopSecs = (new Date().getTime() - startTimeLoop) / 1000; const executionDurationTotalLoopSecs = (new Date().getTime() - startTime) / 1000; - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: this.tenant.id, action: ServerAction.OCPI_CPO_GET_TOKENS, message: `${numberOfTags.toString()} token(s) processed in ${executionDurationLoopSecs}s - Total of ${totalNumberOfTags} token(s) processed in ${executionDurationTotalLoopSecs}s`, @@ -239,7 +239,7 @@ export default class CpoOCPIClient extends OCPIClient { detailedMessages: { locationReference, authorizationInfo } }); } - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: this.tenant.id, action: ServerAction.OCPI_CPO_AUTHORIZE_TOKEN, @@ -284,7 +284,7 @@ export default class CpoOCPIClient extends OCPIClient { transaction.ocpiData = { session: ocpiSession }; - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: this.tenant.id, action: ServerAction.OCPI_CPO_START_SESSION, @@ -330,7 +330,7 @@ export default class CpoOCPIClient extends OCPIClient { 'Content-Type': 'application/json' }, }); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, action: ServerAction.OCPI_CPO_PUSH_SESSIONS, @@ -375,7 +375,7 @@ export default class CpoOCPIClient extends OCPIClient { 'Content-Type': 'application/json' }, }); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, action: ServerAction.OCPI_CPO_STOP_SESSION, @@ -441,7 +441,7 @@ export default class CpoOCPIClient extends OCPIClient { 'Content-Type': 'application/json' }, }); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, action: ServerAction.OCPI_CPO_PUSH_CDRS, @@ -451,7 +451,7 @@ export default class CpoOCPIClient extends OCPIClient { }); return true; } - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, action: ServerAction.OCPI_CPO_PUSH_CDRS, @@ -760,7 +760,7 @@ export default class CpoOCPIClient extends OCPIClient { { concurrency: Constants.OCPI_MAX_PARALLEL_REQUESTS }); const executionDurationLoopSecs = (new Date().getTime() - startTimeLoop) / 1000; const executionDurationTotalLoopSecs = (new Date().getTime() - startTime) / 1000; - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: this.tenant.id, action: ServerAction.OCPI_CPO_UPDATE_STATUS, message: `${evses.length} EVSE Status(es) processed in ${executionDurationLoopSecs}s in Location '${location.name}' - Total of ${totalNumberOfEvses} EVSE(s) processed in ${executionDurationTotalLoopSecs}s`, @@ -864,7 +864,7 @@ export default class CpoOCPIClient extends OCPIClient { 'Content-Type': 'application/json' }, }); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation as ChargingStation), tenantID: this.tenant.id, action: ServerAction.OCPI_CPO_UPDATE_STATUS, @@ -898,7 +898,7 @@ export default class CpoOCPIClient extends OCPIClient { }); // Create if it does not exit if (response.data.status_code === 3001) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, action: ServerAction.OCPI_CPO_CHECK_CDRS, @@ -920,7 +920,7 @@ export default class CpoOCPIClient extends OCPIClient { const cdr = response.data.data as OCPICdr; if (cdr) { // CDR checked - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, action: ServerAction.OCPI_CPO_CHECK_CDRS, @@ -931,7 +931,7 @@ export default class CpoOCPIClient extends OCPIClient { return true; } } - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, action: ServerAction.OCPI_CPO_CHECK_CDRS, @@ -966,7 +966,7 @@ export default class CpoOCPIClient extends OCPIClient { if (OCPIUtilsService.isSuccessResponse(response.data)) { const session = response.data.data as OCPISession; if (session) { - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, action: ServerAction.OCPI_CPO_CHECK_SESSIONS, @@ -977,7 +977,7 @@ export default class CpoOCPIClient extends OCPIClient { return true; } } - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, action: ServerAction.OCPI_CPO_CHECK_SESSIONS, @@ -1022,7 +1022,7 @@ export default class CpoOCPIClient extends OCPIClient { detailedMessages: { location, ocpiLocation } }); } - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: this.tenant.id, action: ServerAction.OCPI_CPO_CHECK_LOCATIONS, message: `Location '${location.name}' with ID '${location.id}' checked successfully`, diff --git a/src/client/ocpi/EmspOCPIClient.ts b/src/client/ocpi/EmspOCPIClient.ts index a74080de25..e761e83153 100644 --- a/src/client/ocpi/EmspOCPIClient.ts +++ b/src/client/ocpi/EmspOCPIClient.ts @@ -99,7 +99,7 @@ export default class EmspOCPIClient extends OCPIClient { currentSkip += Constants.DB_RECORD_COUNT_DEFAULT; const executionDurationLoopSecs = (new Date().getTime() - startTimeLoop) / 1000; const executionDurationTotalLoopSecs = (new Date().getTime() - startTime) / 1000; - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: this.tenant.id, action: ServerAction.OCPI_EMSP_UPDATE_TOKENS, message: `${tokens.count.toString()} token(s) pushed in ${executionDurationLoopSecs}s - Total of ${totalNumberOfTokens} token(s) pushed in ${executionDurationTotalLoopSecs}s`, @@ -188,7 +188,7 @@ export default class EmspOCPIClient extends OCPIClient { } const numberOfLocations = response.data.data.length as number; totalNumberOfLocations += numberOfLocations; - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: this.tenant.id, action: ServerAction.OCPI_CPO_GET_TOKENS, message: `${numberOfLocations.toString()} Tokens retrieved from ${locationsUrl}`, @@ -237,7 +237,7 @@ export default class EmspOCPIClient extends OCPIClient { } const executionDurationLoopSecs = (new Date().getTime() - startTimeLoop) / 1000; const executionDurationTotalLoopSecs = (new Date().getTime() - startTime) / 1000; - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: this.tenant.id, action: ServerAction.OCPI_EMSP_GET_LOCATIONS, message: `${numberOfLocations.toString()} location(s) processed in ${executionDurationLoopSecs}s - Total of ${totalNumberOfLocations} location(s) processed in ${executionDurationTotalLoopSecs}s`, @@ -471,7 +471,7 @@ export default class EmspOCPIClient extends OCPIClient { 'Content-Type': 'application/json' }, }); - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: this.tenant.id, ...LoggingHelper.getChargingStationProperties(chargingStation), action: ServerAction.OCPI_EMSP_START_SESSION, @@ -527,7 +527,7 @@ export default class EmspOCPIClient extends OCPIClient { 'Content-Type': 'application/json' }, }); - await Logging.logDebug({ + Logging.beDebug()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, action: ServerAction.OCPI_EMSP_STOP_SESSION, diff --git a/src/client/ocpi/OCPIClient.ts b/src/client/ocpi/OCPIClient.ts index 72eb7387f2..5e36abb9c2 100644 --- a/src/client/ocpi/OCPIClient.ts +++ b/src/client/ocpi/OCPIClient.ts @@ -169,7 +169,7 @@ export default abstract class OCPIClient { } public async getVersions(): Promise { - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: this.tenant.id, action: ServerAction.OCPI_GET_VERSIONS, message: `Get OCPI Versions at ${this.ocpiEndpoint.baseUrl}`, @@ -188,7 +188,7 @@ export default abstract class OCPIClient { } public async getEndpointVersions(): Promise { - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: this.tenant.id, action: ServerAction.OCPI_GET_ENDPOINT_VERSIONS, message: `Get OCPI Services at ${this.ocpiEndpoint.versionUrl}`, @@ -267,7 +267,7 @@ export default abstract class OCPIClient { private async deleteCredentials(): Promise { // Get credentials url const credentialsUrl = this.getEndpointUrl('credentials', ServerAction.OCPI_CREATE_CREDENTIALS); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: this.tenant.id, action: ServerAction.OCPI_CREATE_CREDENTIALS, message: `Delete Credentials at ${credentialsUrl}`, @@ -288,7 +288,7 @@ export default abstract class OCPIClient { // Get credentials url const credentialsUrl = this.getEndpointUrl('credentials', ServerAction.OCPI_CREATE_CREDENTIALS); const credentials = await OCPIUtils.buildOcpiCredentialObject(this.tenant, this.ocpiEndpoint.localToken, this.ocpiEndpoint.role); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: this.tenant.id, action: ServerAction.OCPI_CREATE_CREDENTIALS, message: `Post Credentials at ${credentialsUrl}`, @@ -310,7 +310,7 @@ export default abstract class OCPIClient { // Get credentials url const credentialsUrl = this.getEndpointUrl('credentials', ServerAction.OCPI_UPDATE_CREDENTIALS); const credentials = await OCPIUtils.buildOcpiCredentialObject(this.tenant, this.ocpiEndpoint.localToken, this.ocpiEndpoint.role); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: this.tenant.id, action: ServerAction.OCPI_UPDATE_CREDENTIALS, message: `Put Credentials at ${credentialsUrl}`, diff --git a/src/client/ocpi/OCPIClientFactory.ts b/src/client/ocpi/OCPIClientFactory.ts index 37084e7fc4..f2fabab363 100644 --- a/src/client/ocpi/OCPIClientFactory.ts +++ b/src/client/ocpi/OCPIClientFactory.ts @@ -22,7 +22,7 @@ export default class OCPIClientFactory { if (Utils.isTenantComponentActive(tenant, TenantComponents.OCPI)) { const ocpiSettings = await SettingStorage.getOCPISettings(tenant); if (!ocpiSettings && ocpiSettings.ocpi) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: ServerAction.OCPI_SETTINGS, module: MODULE_NAME, method: 'getOcpiClient', @@ -37,7 +37,7 @@ export default class OCPIClientFactory { return new EmspOCPIClient(tenant, ocpiSettings.ocpi, ocpiEndpoint); } } else { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: ServerAction.OCPI_SETTINGS, module: MODULE_NAME, method: 'getOcpiClient', @@ -52,7 +52,7 @@ export default class OCPIClientFactory { const client = await OCPIClientFactory.getOcpiClient(tenant, ocpiEndpoint); return client as CpoOCPIClient; } - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: ServerAction.OCPI_CLIENT_INITIALIZATION, module: MODULE_NAME, method: 'getCpoOcpiClient', @@ -65,7 +65,7 @@ export default class OCPIClientFactory { const client = await OCPIClientFactory.getOcpiClient(tenant, ocpiEndpoint); return client as EmspOCPIClient; } - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: ServerAction.OCPI_CLIENT_INITIALIZATION, module: MODULE_NAME, method: 'getEmspOcpiClient', diff --git a/src/client/ocpp/ChargingStationClientFactory.ts b/src/client/ocpp/ChargingStationClientFactory.ts index df1729fd85..1e488e9cb1 100644 --- a/src/client/ocpp/ChargingStationClientFactory.ts +++ b/src/client/ocpp/ChargingStationClientFactory.ts @@ -17,7 +17,7 @@ export default class ChargingStationClientFactory { // Json Server if (global.centralSystemJsonServer?.hasChargingStationConnected(tenant, chargingStation)) { // Get the local WS Connection Client - chargingClient = await global.centralSystemJsonServer.getChargingStationClient(tenant, chargingStation); + chargingClient = global.centralSystemJsonServer.getChargingStationClient(tenant, chargingStation); } else { // Get the Remote WS Connection Client (Rest) chargingClient = new JsonRestChargingStationClient(tenant.id, chargingStation); diff --git a/src/client/ocpp/json/JsonChargingStationClient.ts b/src/client/ocpp/json/JsonChargingStationClient.ts index b61e9c3640..85a96e510c 100644 --- a/src/client/ocpp/json/JsonChargingStationClient.ts +++ b/src/client/ocpp/json/JsonChargingStationClient.ts @@ -4,29 +4,17 @@ import ChargingStationClient from '../../ocpp/ChargingStationClient'; import { Command } from '../../../types/ChargingStation'; import JsonWSConnection from '../../../server/ocpp/json/web-socket/JsonWSConnection'; import Logging from '../../../utils/Logging'; -import { OCPPMessageType } from '../../../types/ocpp/OCPPCommon'; import OCPPUtils from '../../../server/ocpp/utils/OCPPUtils'; -import Tenant from '../../../types/Tenant'; import Utils from '../../../utils/Utils'; const MODULE_NAME = 'JsonChargingStationClient'; export default class JsonChargingStationClient extends ChargingStationClient { - private chargingStationID: string; - private siteID: string; - private siteAreaID: string; - private companyID: string; - private tenant: Tenant; private wsConnection: JsonWSConnection; - public constructor(wsConnection: JsonWSConnection, tenant: Tenant, chargingStationID: string) { + public constructor(wsConnection: JsonWSConnection) { super(); this.wsConnection = wsConnection; - this.tenant = tenant; - this.chargingStationID = chargingStationID; - this.companyID = wsConnection.getCompanyID(); - this.siteID = wsConnection.getSiteID(); - this.siteAreaID = wsConnection.getSiteAreaID(); } public getChargingStationID(): string { @@ -99,15 +87,31 @@ export default class JsonChargingStationClient extends ChargingStationClient { private async sendMessage(command: Command, params: any): Promise { // Trace - const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, this.tenant, this.chargingStationID, - OCPPUtils.buildServerActionFromOcppCommand(command), params, '<<', - { siteAreaID: this.siteAreaID, siteID: this.siteID, companyID: this.companyID }); + const performanceTracingData = await Logging.traceOcppMessageRequest( + MODULE_NAME, + this.wsConnection.getTenant(), + this.wsConnection.getChargingStationID(), + OCPPUtils.buildServerActionFromOcppCommand(command), + params, '<<', + { + siteAreaID: this.wsConnection.getSiteAreaID(), + siteID: this.wsConnection.getSiteID(), + companyID: this.wsConnection.getCompanyID() + } + ); // Execute - const result = await this.wsConnection.sendMessage(Utils.generateUUID(), OCPPMessageType.CALL_MESSAGE, command, params); + const result = await this.wsConnection.sendMessageAndWaitForResult(Utils.generateUUID(), command, params as Record); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, this.tenant, this.chargingStationID, + await Logging.traceOcppMessageResponse( + MODULE_NAME, + this.wsConnection.getTenant(), + this.wsConnection.getChargingStationID(), OCPPUtils.buildServerActionFromOcppCommand(command), params, result, '>>', - { siteAreaID: this.siteAreaID, siteID: this.siteID, companyID: this.companyID }, + { + siteAreaID: this.wsConnection.getSiteAreaID(), + siteID: this.wsConnection.getSiteID(), + companyID: this.wsConnection.getCompanyID() + }, performanceTracingData ); return result; diff --git a/src/client/ocpp/json/JsonRestChargingStationClient.ts b/src/client/ocpp/json/JsonRestChargingStationClient.ts index 7cb9e9fdbd..97fca6d27a 100644 --- a/src/client/ocpp/json/JsonRestChargingStationClient.ts +++ b/src/client/ocpp/json/JsonRestChargingStationClient.ts @@ -1,6 +1,6 @@ import ChargingStation, { Command } from '../../../types/ChargingStation'; import { OCPPCancelReservationRequest, OCPPCancelReservationResponse, OCPPChangeAvailabilityRequest, OCPPChangeAvailabilityResponse, OCPPChangeConfigurationRequest, OCPPChangeConfigurationResponse, OCPPClearCacheResponse, OCPPClearChargingProfileRequest, OCPPClearChargingProfileResponse, OCPPDataTransferRequest, OCPPDataTransferResponse, OCPPGetCompositeScheduleRequest, OCPPGetCompositeScheduleResponse, OCPPGetConfigurationRequest, OCPPGetConfigurationResponse, OCPPGetDiagnosticsRequest, OCPPGetDiagnosticsResponse, OCPPRemoteStartTransactionRequest, OCPPRemoteStartTransactionResponse, OCPPRemoteStopTransactionRequest, OCPPRemoteStopTransactionResponse, OCPPReserveNowRequest, OCPPReserveNowResponse, OCPPResetRequest, OCPPResetResponse, OCPPSetChargingProfileRequest, OCPPSetChargingProfileResponse, OCPPStatus, OCPPUnlockConnectorRequest, OCPPUnlockConnectorResponse, OCPPUpdateFirmwareRequest } from '../../../types/ocpp/OCPPClient'; -import { OCPPIncomingRequest, OCPPMessageType, OCPPOutgoingRequest } from '../../../types/ocpp/OCPPCommon'; +import { OCPPIncomingError, OCPPIncomingRequest, OCPPIncomingResponse, OCPPMessageType, OCPPOutgoingRequest } from '../../../types/ocpp/OCPPCommon'; import { ServerAction, WSServerProtocol } from '../../../types/Server'; import BackendError from '../../../exception/BackendError'; @@ -9,8 +9,8 @@ import Configuration from '../../../utils/Configuration'; import Logging from '../../../utils/Logging'; import LoggingHelper from '../../../utils/LoggingHelper'; import Utils from '../../../utils/Utils'; -import WSClient from '../../websocket/WSClient'; -import { WSClientOptions } from '../../../types/WebSocket'; +import WebSocket from 'ws'; +import { WebSocketCloseEventStatusCode } from '../../../types/WebSocket'; const MODULE_NAME = 'JsonRestChargingStationClient'; @@ -19,7 +19,7 @@ export default class JsonRestChargingStationClient extends ChargingStationClient private serverURL: string; private chargingStation: ChargingStation; private requests: { [messageUID: string]: { resolve?: (result: Record | string) => void; reject?: (error: Error|Record) => void; command: Command } }; - private wsConnection: WSClient; + private webSocket: WebSocket; private tenantID: string; public constructor(tenantID: string, chargingStation: ChargingStation) { @@ -115,11 +115,9 @@ export default class JsonRestChargingStationClient extends ChargingStationClient return this.sendMessage(this.buildRequest(Command.CANCEL_RESERVATION, params)); } - private async openConnection(request: OCPPOutgoingRequest): Promise { - // Extract Current Command - const triggeringCommand: Command = request[2]; + private async openConnection(triggeringCommand: string): Promise { // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: this.tenantID, siteID: this.chargingStation.siteID, siteAreaID: this.chargingStation.siteAreaID, @@ -127,25 +125,19 @@ export default class JsonRestChargingStationClient extends ChargingStationClient chargingStationID: this.chargingStation.id, action: ServerAction.WS_CLIENT_CONNECTION, module: MODULE_NAME, method: 'onOpen', - message: `Try to connect to '${this.serverURL}' - command: ${triggeringCommand}` + message: `${triggeringCommand} > Connecting to '${this.serverURL}'` }); // Create Promise return new Promise((resolve, reject) => { try { - // Create WS - const wsClientOptions: WSClientOptions = { - wsOptions: { - handshakeTimeout: 5000, - }, - protocols: WSServerProtocol.REST, - logTenantID: this.tenantID - }; // Create and Open the WS - this.wsConnection = new WSClient(this.serverURL, wsClientOptions); + this.webSocket = new WebSocket(this.serverURL, WSServerProtocol.REST, { + handshakeTimeout: 5000, + }); + // Opened - // eslint-disable-next-line @typescript-eslint/no-misused-promises - this.wsConnection.onopen = async () => { - await Logging.logInfo({ + this.webSocket.on('open', () => { + Logging.beInfo()?.log({ tenantID: this.tenantID, siteID: this.chargingStation.siteID, siteAreaID: this.chargingStation.siteAreaID, @@ -153,30 +145,30 @@ export default class JsonRestChargingStationClient extends ChargingStationClient chargingStationID: this.chargingStation.id, action: ServerAction.WS_CLIENT_CONNECTION_OPEN, module: MODULE_NAME, method: 'onOpen', - message: `Connection opened to '${this.serverURL}' - command: ${triggeringCommand}` + message: `${triggeringCommand} > Now connected to '${this.serverURL}'` }); // Connection is opened and ready to use resolve(); - }; + }); // Closed - // eslint-disable-next-line @typescript-eslint/no-misused-promises - this.wsConnection.onclose = async (code: number) => { - await Logging.logInfo({ - tenantID: this.tenantID, - siteID: this.chargingStation.siteID, - siteAreaID: this.chargingStation.siteAreaID, - companyID: this.chargingStation.companyID, - chargingStationID: this.chargingStation.id, - action: ServerAction.WS_CLIENT_CONNECTION_CLOSE, - module: MODULE_NAME, method: 'onClose', - message: `Connection closed to '${this.serverURL}', Message: '${Utils.getWebSocketCloseEventStatusString(code)}', Code: '${code}'`, - detailedMessages: { code } - }); - }; + this.webSocket.on('close', (code) => { + // code === 1000 + if (code !== WebSocketCloseEventStatusCode.CLOSE_NORMAL) { + Logging.beWarning()?.log({ + tenantID: this.tenantID, + siteID: this.chargingStation.siteID, + siteAreaID: this.chargingStation.siteAreaID, + companyID: this.chargingStation.companyID, + chargingStationID: this.chargingStation.id, + action: ServerAction.WS_CLIENT_CONNECTION_CLOSE, + module: MODULE_NAME, method: 'onClose', + message: `${triggeringCommand} > Connection has been closed - Code: '${code}'`, + }); + } + }); // Handle Error Message - // eslint-disable-next-line @typescript-eslint/no-misused-promises - this.wsConnection.onerror = async (error: Error) => { - await Logging.logError({ + this.webSocket.on('error', (error) => { + Logging.beError()?.log({ tenantID: this.tenantID, siteID: this.chargingStation.siteID, siteAreaID: this.chargingStation.siteAreaID, @@ -184,108 +176,144 @@ export default class JsonRestChargingStationClient extends ChargingStationClient chargingStationID: this.chargingStation.id, action: ServerAction.WS_CLIENT_CONNECTION_ERROR, module: MODULE_NAME, method: 'onError', - message: `Connection error to '${this.serverURL}: ${error?.message}`, - detailedMessages: { error: error.stack } + message: `${triggeringCommand} > Connection failed - ${error?.message}`, + detailedMessages: { + url: this.serverURL, + error: error.stack + } }); // Terminate WS in error this.terminateConnection(); - reject(new Error(`Error on opening Web Socket connection: ${error.message}'`)); - }; + reject(new Error(`${triggeringCommand} - Web Socket connection failed - ${error.message}`)); + }); // Handle Server Message - // eslint-disable-next-line @typescript-eslint/no-misused-promises - this.wsConnection.onmessage = async (message) => { + this.webSocket.on('message', (rawData: WebSocket.RawData) => { try { // Parse the message - const [messageType, messageId, command, commandPayload, errorDetails]: OCPPIncomingRequest = JSON.parse(message.data) as OCPPIncomingRequest; - // Check if this corresponds to a request - if (this.requests[messageId]) { - // Check message type - if (messageType === OCPPMessageType.CALL_ERROR_MESSAGE) { - // Error message - await Logging.logError({ - tenantID: this.tenantID, - siteID: this.chargingStation.siteID, - siteAreaID: this.chargingStation.siteAreaID, - companyID: this.chargingStation.companyID, - chargingStationID: this.chargingStation.id, - action: ServerAction.WS_CLIENT_ERROR, - module: MODULE_NAME, method: 'onMessage', - message: `${commandPayload.toString()}`, - detailedMessages: { messageType, messageId, command, commandPayload, errorDetails } - }); - // Resolve with error message - // this.requests[messageId].reject({ status: OCPPStatus.REJECTED, error: [messageType, messageId, command, commandPayload, errorDetails] }); - this.requests[messageId].reject(new Error(`${message.data as string}`)); - } else { - // Respond to the request - this.requests[messageId].resolve(command); - } - // Close WS - this.closeConnection(); + const messageData = rawData.toString(); + const ocppMessage: OCPPIncomingRequest|OCPPIncomingResponse|OCPPIncomingError = JSON.parse(messageData); + const [ messageType ] = ocppMessage; + if (messageType === OCPPMessageType.CALL_RESULT_MESSAGE) { + this.handleOcppResponse(ocppMessage as OCPPIncomingResponse); + } else if (messageType === OCPPMessageType.CALL_ERROR_MESSAGE) { + this.handleOcppError(ocppMessage as OCPPIncomingError); } else { - // Error message - await Logging.logError({ - tenantID: this.tenantID, - siteID: this.chargingStation.siteID, - siteAreaID: this.chargingStation.siteAreaID, - companyID: this.chargingStation.companyID, - chargingStationID: this.chargingStation.id, - action: ServerAction.WS_CLIENT_ERROR, - module: MODULE_NAME, method: 'onMessage', - message: 'Received unknown message', - detailedMessages: { messageType, messageId, command, commandPayload, errorDetails } - }); + this.handleOcppRequest(ocppMessage as OCPPIncomingRequest); } } catch (error) { - await Logging.logException(error as Error, ServerAction.WS_CLIENT_MESSAGE, MODULE_NAME, 'onMessage', this.tenantID); + Logging.logException(error as Error, ServerAction.WS_CLIENT_MESSAGE, MODULE_NAME, 'onMessage', this.tenantID); } - }; + }); } catch (error) { - reject(new Error(`Unexpected error on opening Web Socket connection: ${error.message as string}'`)); + reject(new Error(`Failed to open Web Socket connection - ${error.message as string}'`)); } }); } - private closeConnection() { - // Close - if (this.wsConnection) { - this.wsConnection.close(); + private handleOcppResponse(occpMessage : OCPPIncomingResponse) { + const [messageType, messageId, payload] = occpMessage; + // Respond to the request + if (this.requests[messageId]) { + this.requests[messageId].resolve(payload); + } else { + // Error message + Logging.beError()?.log({ + tenantID: this.tenantID, + siteID: this.chargingStation.siteID, + siteAreaID: this.chargingStation.siteAreaID, + companyID: this.chargingStation.companyID, + chargingStationID: this.chargingStation.id, + action: ServerAction.WS_CLIENT_ERROR, + module: MODULE_NAME, method: 'onMessage', + message: 'Unexpected OCPP Response', + detailedMessages: { messageType, messageId, payload } + }); + } + // Close WS + this.endConnection(); + } + + private handleOcppError(occpMessage : OCPPIncomingError) { + const [messageType, messageId, errorType, errorMessage, errorDetails] = occpMessage; + // Respond to the request + if (this.requests[messageId]) { + this.requests[messageId].reject(new Error(`WS Error Message - type: ${messageType} - ID: ${messageId} - message: ${errorMessage}`)); + } else { + // Error message + Logging.beError()?.log({ + tenantID: this.tenantID, + siteID: this.chargingStation.siteID, + siteAreaID: this.chargingStation.siteAreaID, + companyID: this.chargingStation.companyID, + chargingStationID: this.chargingStation.id, + action: ServerAction.WS_CLIENT_ERROR, + module: MODULE_NAME, method: 'onMessage', + message: 'Unexpected OCPP Error', + detailedMessages: { messageType, messageId, errorType, errorMessage, errorDetails } + }); + } + // Close WS + this.endConnection(); + } + + private handleOcppRequest(occpMessage : OCPPIncomingRequest) { + const [messageType, messageId, command, payload] = occpMessage; + // Should not happen + Logging.beError()?.log({ + tenantID: this.tenantID, + siteID: this.chargingStation.siteID, + siteAreaID: this.chargingStation.siteAreaID, + companyID: this.chargingStation.companyID, + chargingStationID: this.chargingStation.id, + action: ServerAction.WS_CLIENT_ERROR, + module: MODULE_NAME, method: 'onMessage', + message: 'Unexpected OCPP Request', + detailedMessages: { messageType, messageId, command, payload } + }); + // Close WS + // this.endConnection(); + } + + private endConnection() { + if (this.webSocket) { + // Gracefully Close Web Socket - WS Code 1000 + this.webSocket.close(WebSocketCloseEventStatusCode.CLOSE_NORMAL, 'Operation completed'); } - this.wsConnection = null; + this.webSocket = null; } private terminateConnection() { // Terminate - if (this.wsConnection) { - this.wsConnection.terminate(); + if (this.webSocket) { + this.webSocket.terminate(); } - this.wsConnection = null; + this.webSocket = null; } private async sendMessage(request: OCPPOutgoingRequest): Promise { + // Extract Current Command + const triggeringCommand: Command = request[2]; // Check for the lastSeen if (Date.now() - this.chargingStation.lastSeen.getTime() > Configuration.getChargingStationConfig().pingIntervalOCPPJSecs * 1000 * 2) { // Charging station is not connected to the server - let's abort the current operation - throw new Error(`Charging station is not connected to the server - request '${request[2]}' has been aborted`); + throw new Error(`Charging station is not connected to the server - command '${triggeringCommand}' has been aborted`); } - // eslint-disable-next-line @typescript-eslint/no-misused-promises, no-async-promise-executor - return new Promise(async (resolve, reject) => { - try { - // Open WS Connection - await this.openConnection(request); + return new Promise((resolve, reject) => { + // Open WS Connection + this.openConnection(triggeringCommand).then(() => { // Check if wsConnection is ready - if (this.wsConnection?.isConnectionOpen()) { + if (this.webSocket?.readyState === WebSocket.OPEN) { // Send - this.wsConnection.send(JSON.stringify(request)); + this.webSocket.send(JSON.stringify(request)); // Set the resolve function - this.requests[request[1]] = { resolve, reject, command: request[2] }; + this.requests[request[1]] = { resolve, reject, command: triggeringCommand }; } else { // Reject it - reject(new Error(`Socket is closed for message ${request[2]}`)); + reject(new Error(`Socket is closed for message ${triggeringCommand}`)); } - } catch (error) { - reject(new Error(`Unexpected error on request '${request[2]}': ${error.message}'`)); - } + }).catch((error: Error) => { + reject(new Error(`Unexpected error on request '${triggeringCommand}': ${error.message}'`)); + }); }); } diff --git a/src/client/ocpp/soap/SoapChargingStationClient.ts b/src/client/ocpp/soap/SoapChargingStationClient.ts index 73610caff9..df32e4399f 100644 --- a/src/client/ocpp/soap/SoapChargingStationClient.ts +++ b/src/client/ocpp/soap/SoapChargingStationClient.ts @@ -39,7 +39,7 @@ export default class SoapChargingStationClient extends ChargingStationClient { break; default: // Log - void Logging.logError({ + Logging.beError()?.log({ tenantID: scsc.tenant.id, action: ServerAction.CHARGING_STATION_CLIENT_INITIALIZATION, siteID: scsc.chargingStation.siteID, @@ -54,9 +54,9 @@ export default class SoapChargingStationClient extends ChargingStationClient { // Client options const options: any = {}; // Create SOAP client - soap.createClient(chargingStationWdsl, options, async (error, client) => { + soap.createClient(chargingStationWdsl, options, (error, client) => { if (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: scsc.tenant.id, action: ServerAction.CHARGING_STATION_CLIENT_INITIALIZATION, siteID: scsc.chargingStation.siteID, @@ -96,7 +96,7 @@ export default class SoapChargingStationClient extends ChargingStationClient { 'remoteStopTransactionRequest': params }); if (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.CHARGING_STATION_REMOTE_STOP_TRANSACTION, siteID: this.chargingStation.siteID, @@ -135,7 +135,7 @@ export default class SoapChargingStationClient extends ChargingStationClient { const { error, result, envelope } = await this.client.RemoteStartTransaction(params); if (error) { // Log - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.CHARGING_STATION_REMOTE_START_TRANSACTION, siteID: this.chargingStation.siteID, @@ -175,7 +175,7 @@ export default class SoapChargingStationClient extends ChargingStationClient { }); if (error) { // Log - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.CHARGING_STATION_UNLOCK_CONNECTOR, siteID: this.chargingStation.siteID, @@ -215,7 +215,7 @@ export default class SoapChargingStationClient extends ChargingStationClient { }); if (error) { // Log - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.CHARGING_STATION_RESET, siteID: this.chargingStation.siteID, @@ -253,7 +253,7 @@ export default class SoapChargingStationClient extends ChargingStationClient { const { error, result, envelope } = await this.client.ClearCache({ clearCacheRequest: {} }); if (error) { // Log - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.CHARGING_STATION_CLEAR_CACHE, siteID: this.chargingStation.siteID, @@ -300,7 +300,7 @@ export default class SoapChargingStationClient extends ChargingStationClient { const { error, result, envelope } = await this.client.GetConfiguration(request); if (error) { // Log - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.CHARGING_STATION_GET_CONFIGURATION, siteID: this.chargingStation.siteID, @@ -344,7 +344,7 @@ export default class SoapChargingStationClient extends ChargingStationClient { }); if (error) { // Log - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, siteID: this.chargingStation.siteID, siteAreaID: this.chargingStation.siteAreaID, diff --git a/src/client/oicp/CpoOICPClient.ts b/src/client/oicp/CpoOICPClient.ts index 284e30a356..f77e9b23a6 100644 --- a/src/client/oicp/CpoOICPClient.ts +++ b/src/client/oicp/CpoOICPClient.ts @@ -80,7 +80,7 @@ export default class CpoOICPClient extends OICPClient { transaction.oicpData = { session: oicpSession }; - await Logging.logDebug({ + Logging.beDebug()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, action: ServerAction.OICP_PUSH_SESSIONS, @@ -159,7 +159,7 @@ export default class CpoOICPClient extends OICPClient { // Stop if (transaction.tagID !== OICPDefaultTagId.RemoteIdentification) { const response = await this.authorizeStop(transaction); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, action: ServerAction.OICP_PUSH_SESSIONS, @@ -533,7 +533,7 @@ export default class CpoOICPClient extends OICPClient { } }); } else { - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: this.tenant.id, action: ServerAction.OICP_PUSH_EVSE_DATA, message: `${evses.length} EVSEs have been pushed successfully`, @@ -575,7 +575,7 @@ export default class CpoOICPClient extends OICPClient { requestError = error; } if (!pushEvseStatusResponse?.Result || pushEvseStatusResponse?.Result !== true) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.OICP_PUSH_EVSE_STATUSES, message: this.buildOICPChargingNotificationErrorMessage(pushEvseStatusResponse, requestError), @@ -587,7 +587,7 @@ export default class CpoOICPClient extends OICPClient { } }); } else { - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: this.tenant.id, action: ServerAction.OICP_PUSH_EVSE_STATUSES, message: `${evseStatuses.length} EVSE Statuses have been pushed successfully`, @@ -632,7 +632,7 @@ export default class CpoOICPClient extends OICPClient { requestError = error; } if (requestError) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.OICP_AUTHORIZE_START, message: this.buildOICPChargingNotificationErrorMessage(authorizeResponse, requestError), @@ -645,7 +645,7 @@ export default class CpoOICPClient extends OICPClient { }); } if (authorizeResponse?.AuthorizationStatus !== OICPAuthorizationStatus.Authorized) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.OICP_AUTHORIZE_START, module: MODULE_NAME, method: 'authorizeStart', @@ -653,7 +653,7 @@ export default class CpoOICPClient extends OICPClient { detailedMessages: { authorize: payload, response: authorizeResponse } }); } else { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: this.tenant.id, action: ServerAction.OICP_AUTHORIZE_START, message: `OICP Tag ID '${tagID}' has been authorized`, @@ -698,7 +698,7 @@ export default class CpoOICPClient extends OICPClient { requestError = error; } if (requestError) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, user: user, @@ -713,7 +713,7 @@ export default class CpoOICPClient extends OICPClient { }); } if (authorizeResponse?.AuthorizationStatus !== OICPAuthorizationStatus.Authorized) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, user: user, @@ -723,7 +723,7 @@ export default class CpoOICPClient extends OICPClient { detailedMessages: { authorize: payload, response: authorizeResponse } }); } else { - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, user: user, @@ -804,7 +804,7 @@ export default class CpoOICPClient extends OICPClient { requestError = error; } if (!pushCdrResponse?.Result || pushCdrResponse?.Result !== true) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, action: ServerAction.OICP_PUSH_CDRS, @@ -817,7 +817,7 @@ export default class CpoOICPClient extends OICPClient { } }); } else { - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, action: ServerAction.OICP_PUSH_CDRS, @@ -875,7 +875,7 @@ export default class CpoOICPClient extends OICPClient { requestError = error; } if (!notificationStartResponse?.Result || notificationStartResponse?.Result !== true) { - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, action: ServerAction.OICP_SEND_CHARGING_NOTIFICATION_START, @@ -888,7 +888,7 @@ export default class CpoOICPClient extends OICPClient { } }); } else { - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, action: ServerAction.OICP_SEND_CHARGING_NOTIFICATION_START, @@ -950,7 +950,7 @@ export default class CpoOICPClient extends OICPClient { } transaction.oicpData.session.last_progress_notification = new Date(); if (!notificationProgressResponse?.Result || notificationProgressResponse?.Result !== true) { - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, action: ServerAction.OICP_SEND_CHARGING_NOTIFICATION_PROGRESS, @@ -963,7 +963,7 @@ export default class CpoOICPClient extends OICPClient { } }); } else { - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, action: ServerAction.OICP_SEND_CHARGING_NOTIFICATION_PROGRESS, @@ -1038,7 +1038,7 @@ export default class CpoOICPClient extends OICPClient { requestError = error; } if (!notificationEndResponse?.Result || notificationEndResponse?.Result !== true) { - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, action: ServerAction.OICP_SEND_CHARGING_NOTIFICATION_END, @@ -1051,7 +1051,7 @@ export default class CpoOICPClient extends OICPClient { } }); } else { - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, action: ServerAction.OICP_SEND_CHARGING_NOTIFICATION_END, @@ -1106,7 +1106,7 @@ export default class CpoOICPClient extends OICPClient { requestError = err; } if (!notificationErrorResponse?.Result || notificationErrorResponse?.Result !== true) { - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, action: ServerAction.OICP_SEND_CHARGING_NOTIFICATION_ERROR, @@ -1146,7 +1146,7 @@ export default class CpoOICPClient extends OICPClient { } private async pingEvseEndpoint(): Promise { - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: this.tenant.id, action: ServerAction.OICP_PUSH_EVSE_DATA, message: `Ping Hubject at ${this.getEndpointUrl('evses',ServerAction.OICP_PUSH_EVSE_DATA)}`, diff --git a/src/client/oicp/OICPClientFactory.ts b/src/client/oicp/OICPClientFactory.ts index 7854998070..25a41c2432 100644 --- a/src/client/oicp/OICPClientFactory.ts +++ b/src/client/oicp/OICPClientFactory.ts @@ -20,7 +20,7 @@ export default class OICPClientFactory { if (Utils.isTenantComponentActive(tenant, TenantComponents.OICP)) { const oicpSettings = await SettingStorage.getOICPSettings(tenant); if (!oicpSettings && oicpSettings.oicp) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: ServerAction.OICP_SETTINGS, module: MODULE_NAME, method: 'getOicpClient', @@ -41,7 +41,7 @@ export default class OICPClientFactory { const client = await OICPClientFactory.getOicpClient(tenant, oicpEndpoint); return client as CpoOICPClient; } - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: ServerAction.OICP_SETTINGS, module: MODULE_NAME, method: 'getCpoOicpClient', diff --git a/src/client/websocket/WSClient.ts b/src/client/websocket/WSClient.ts index 588502d1fd..52bb7e8375 100644 --- a/src/client/websocket/WSClient.ts +++ b/src/client/websocket/WSClient.ts @@ -175,10 +175,10 @@ export default class WSClient { tenantID: this.logTenantID, module: MODULE_NAME, method: 'onClose', action: ServerAction.WS_CLIENT_CONNECTION_CLOSE, - message: `Connection closing to '${this.url}', Reason: '${reason ? reason : 'No reason given'}', Message: '${Utils.getWebSocketCloseEventStatusString(code)}', Code: '${code}'` + message: `Connection closing to '${this.url}', Reason: '${reason ? reason : 'No reason given'}', Code: '${code}'` }); } else { - !Utils.isProductionEnv() && Logging.logConsoleInfo(`WSClient connection closing to '${this.url}', Reason: '${reason ? reason : 'No reason given'}', Message: '${Utils.getWebSocketCloseEventStatusString(code)}', Code: '${code}'`); + !Utils.isProductionEnv() && Logging.logConsoleInfo(`WSClient connection closing to '${this.url}', Reason: '${reason ? reason : 'No reason given'}', Code: '${code}'`); } break; // Abnormal close @@ -188,10 +188,10 @@ export default class WSClient { tenantID: this.logTenantID, module: MODULE_NAME, method: 'onClose', action: ServerAction.WS_CLIENT_ERROR, - message: `Connection closing error to '${this.url}', Reason: '${reason ? reason : 'No reason given'}', Message: '${Utils.getWebSocketCloseEventStatusString(code)}', Code: '${code}'` + message: `Connection closing error to '${this.url}', Reason: '${reason ? reason : 'No reason given'}', Code: '${code}'` }); } else { - !Utils.isProductionEnv() && Logging.logConsoleError(`WSClient Connection closing error to '${this.url}', Reason: '${reason ? reason : 'No reason given'}', Message: '${Utils.getWebSocketCloseEventStatusString(code)}', Code: '${code}'`); + !Utils.isProductionEnv() && Logging.logConsoleError(`WSClient Connection closing error to '${this.url}', Reason: '${reason ? reason : 'No reason given'}', Code: '${code}'`); } break; } diff --git a/src/integration/asset/AssetFactory.ts b/src/integration/asset/AssetFactory.ts index e6c5dbf02b..0b55e7871f 100644 --- a/src/integration/asset/AssetFactory.ts +++ b/src/integration/asset/AssetFactory.ts @@ -45,7 +45,7 @@ export default class AssetFactory { return assetIntegrationImpl; } } - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, action: ServerAction.ASSET, module: MODULE_NAME, method: 'getAssetImpl', diff --git a/src/integration/asset/greencom/GreencomAssetIntegration.ts b/src/integration/asset/greencom/GreencomAssetIntegration.ts index f1cb4c0aa6..1b3966081d 100644 --- a/src/integration/asset/greencom/GreencomAssetIntegration.ts +++ b/src/integration/asset/greencom/GreencomAssetIntegration.ts @@ -46,7 +46,7 @@ export default class GreencomAssetIntegration extends AssetIntegration GreenCom web service has been called successfully`, diff --git a/src/integration/asset/iothink/IothinkAssetIntegration.ts b/src/integration/asset/iothink/IothinkAssetIntegration.ts index 82ae80a4c8..0ea28ea43f 100644 --- a/src/integration/asset/iothink/IothinkAssetIntegration.ts +++ b/src/integration/asset/iothink/IothinkAssetIntegration.ts @@ -48,7 +48,7 @@ export default class IothinkAssetIntegration extends AssetIntegration Iothink web service has been called successfully`, diff --git a/src/integration/asset/lacroix/LacroixAssetIntegration.ts b/src/integration/asset/lacroix/LacroixAssetIntegration.ts index eebcfdd767..4c78cf4021 100644 --- a/src/integration/asset/lacroix/LacroixAssetIntegration.ts +++ b/src/integration/asset/lacroix/LacroixAssetIntegration.ts @@ -64,7 +64,7 @@ export default class LacroixAssetIntegration extends AssetIntegration Lacroix web service has been called successfully`, diff --git a/src/integration/asset/schneider/SchneiderAssetIntegration.ts b/src/integration/asset/schneider/SchneiderAssetIntegration.ts index 1530b5f03b..9cf7328075 100644 --- a/src/integration/asset/schneider/SchneiderAssetIntegration.ts +++ b/src/integration/asset/schneider/SchneiderAssetIntegration.ts @@ -43,7 +43,7 @@ export default class SchneiderAssetIntegration extends AssetIntegration Schneider web service has been called successfully`, diff --git a/src/integration/asset/wit/WitAssetIntegration.ts b/src/integration/asset/wit/WitAssetIntegration.ts index dab98f9fbb..105a5aa7ca 100644 --- a/src/integration/asset/wit/WitAssetIntegration.ts +++ b/src/integration/asset/wit/WitAssetIntegration.ts @@ -48,7 +48,7 @@ export default class WitAssetIntegration extends AssetIntegration headers: this.buildAuthHeader(token) } ); - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: this.tenant.id, action: ServerAction.RETRIEVE_ASSET_CONSUMPTION, message: `${asset.name} > WIT web service has been called successfully`, diff --git a/src/integration/billing/BillingFacade.ts b/src/integration/billing/BillingFacade.ts index 62c20d29b1..665e93d2be 100644 --- a/src/integration/billing/BillingFacade.ts +++ b/src/integration/billing/BillingFacade.ts @@ -34,7 +34,7 @@ export default class BillingFacade { }; } catch (error) { const message = `Billing - Start Transaction failed with Transaction ID '${transaction.id}'`; - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: tenant.id, action: ServerAction.BILLING_TRANSACTION, @@ -66,7 +66,7 @@ export default class BillingFacade { } } catch (error) { const message = `Billing - Update Transaction failed with Transaction ID '${transaction.id}'`; - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: tenant.id, action: ServerAction.BILLING_TRANSACTION, @@ -92,7 +92,7 @@ export default class BillingFacade { } } catch (error) { const message = `Billing - Stop Transaction failed with Transaction ID '${transaction.id}'`; - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: tenant.id, action: ServerAction.BILLING_TRANSACTION, @@ -119,7 +119,7 @@ export default class BillingFacade { } } catch (error) { const message = `Billing - End Transaction failed with Transaction ID '${transaction.id}'`; - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: tenant.id, action: ServerAction.BILLING_TRANSACTION, diff --git a/src/integration/billing/BillingFactory.ts b/src/integration/billing/BillingFactory.ts index f4f6543fae..17c8b42981 100644 --- a/src/integration/billing/BillingFactory.ts +++ b/src/integration/billing/BillingFactory.ts @@ -26,7 +26,7 @@ export default class BillingFactory { } return billingIntegrationImpl; } - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, action: ServerAction.BILLING, module: MODULE_NAME, method: 'getBillingImpl', diff --git a/src/integration/billing/BillingIntegration.ts b/src/integration/billing/BillingIntegration.ts index 4f36a2113f..d04a49cd05 100644 --- a/src/integration/billing/BillingIntegration.ts +++ b/src/integration/billing/BillingIntegration.ts @@ -45,7 +45,7 @@ export default abstract class BillingIntegration { let billingUser: BillingUser = null; try { billingUser = await this._synchronizeUser(user); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: this.tenant.id, actionOnUser: user, action: ServerAction.BILLING_SYNCHRONIZE_USER, @@ -54,7 +54,7 @@ export default abstract class BillingIntegration { }); return billingUser; } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, actionOnUser: user, action: ServerAction.BILLING_SYNCHRONIZE_USER, @@ -71,14 +71,14 @@ export default abstract class BillingIntegration { try { billingUser = await this._synchronizeUser(user, true /* !forceMode */); if (user?.billingData?.customerID !== billingUser?.billingData?.customerID) { - await Logging.logWarning({ + Logging.beWarning()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_FORCE_SYNCHRONIZE_USER, module: MODULE_NAME, method: 'forceSynchronizeUser', message: `CustomerID has been repaired - old value ${user?.billingData?.customerID} - ${billingUser?.billingData?.customerID}` }); } - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_FORCE_SYNCHRONIZE_USER, actionOnUser: user, @@ -86,7 +86,7 @@ export default abstract class BillingIntegration { message: `Successfully forced the synchronization of user: '${user.id}' - '${user.email}'`, }); } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, actionOnUser: user, action: ServerAction.BILLING_FORCE_SYNCHRONIZE_USER, @@ -132,7 +132,7 @@ export default abstract class BillingIntegration { // Make sure to avoid trying to charge it again too soon if (!taskConfig?.forceOperation && moment(invoice.createdOn).isSame(moment(), 'day')) { actionsDone.inSuccess++; - await Logging.logWarning({ + Logging.beWarning()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_PERFORM_OPERATIONS, actionOnUser: invoice.user, @@ -146,7 +146,7 @@ export default abstract class BillingIntegration { // The new invoice may now have a different status - and this impacts the pagination skip--; // This is very important! } - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_PERFORM_OPERATIONS, actionOnUser: invoice.user, @@ -156,7 +156,7 @@ export default abstract class BillingIntegration { actionsDone.inSuccess++; } catch (error) { actionsDone.inError++; - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_PERFORM_OPERATIONS, actionOnUser: invoice.user, @@ -203,7 +203,7 @@ export default abstract class BillingIntegration { return true; } } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_TRANSACTION, actionOnUser: billingInvoice.user, @@ -315,7 +315,7 @@ export default abstract class BillingIntegration { } } catch (error) { // Catch stripe errors and send the information back to the client - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_CHARGE_INVOICE, actionOnUser: billingInvoice.user, @@ -332,7 +332,7 @@ export default abstract class BillingIntegration { if (!Utils.isDevelopmentEnv()) { const timeSpent = this.computeTimeSpentInSeconds(transaction); if (timeSpent < Constants.AFIREV_MINIMAL_DURATION_THRESHOLD /* 2 minutes */) { - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, user: transaction.userID, @@ -344,7 +344,7 @@ export default abstract class BillingIntegration { return false; } if (transaction.stop.totalConsumptionWh < Constants.AFIREV_MINIMAL_CONSUMPTION_THRESHOLD /* 0.5 kW.h */) { - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, user: transaction.userID, @@ -429,21 +429,21 @@ export default abstract class BillingIntegration { // eslint-disable-next-line @typescript-eslint/member-ordering public async clearTestData(): Promise { // await this.checkConnection(); - stripe connection is useless to cleanup test data - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_TEST_DATA_CLEANUP, module: MODULE_NAME, method: 'clearTestData', message: 'Starting test data cleanup' }); await this.clearAllInvoiceTestData(); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_TEST_DATA_CLEANUP, module: MODULE_NAME, method: 'clearTestData', message: 'Invoice Test data cleanup has been completed' }); await this.clearAllUsersTestData(); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_TEST_DATA_CLEANUP, module: MODULE_NAME, method: 'clearTestData', @@ -457,7 +457,7 @@ export default abstract class BillingIntegration { for (const invoice of invoices.result) { try { await this.clearInvoiceTestData(invoice); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_TEST_DATA_CLEANUP, actionOnUser: invoice.user, @@ -465,7 +465,7 @@ export default abstract class BillingIntegration { message: `Successfully clear test data for invoice '${invoice.id}'` }); } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_TEST_DATA_CLEANUP, actionOnUser: invoice.user, @@ -510,7 +510,7 @@ export default abstract class BillingIntegration { // Save to clear billing data await TransactionStorage.saveTransactionBillingData(this.tenant, transaction.id, transaction.billingData); } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_TEST_DATA_CLEANUP, module: MODULE_NAME, method: 'clearTransactionsTestData', @@ -527,7 +527,7 @@ export default abstract class BillingIntegration { for (const user of users) { try { await this.clearUserTestBillingData(user); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_TEST_DATA_CLEANUP, actionOnUser: user, @@ -535,7 +535,7 @@ export default abstract class BillingIntegration { message: `Successfully cleared user test data for Invoice of User ID '${user.id}'` }); } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_TEST_DATA_CLEANUP, actionOnUser: user, @@ -743,7 +743,7 @@ export default abstract class BillingIntegration { actionsDone.inSuccess++; } catch (error) { actionsDone.inError++; - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_TRANSFER_DISPATCH_FUNDS, module: MODULE_NAME, method: 'dispatchCollectedFunds', @@ -777,7 +777,7 @@ export default abstract class BillingIntegration { }; const transferID = await BillingStorage.saveTransfer(this.tenant, transferToSave); await TransactionStorage.updateTransactionsWithTransferData(this.tenant, collectedFundReport.transactionIDs, transferID); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_TRANSFER_DISPATCH_FUNDS, module: MODULE_NAME, method: 'dispatchCollectedFunds', diff --git a/src/integration/billing/stripe/StripeBillingIntegration.ts b/src/integration/billing/stripe/StripeBillingIntegration.ts index 1d099c661a..5ca81031df 100644 --- a/src/integration/billing/stripe/StripeBillingIntegration.ts +++ b/src/integration/billing/stripe/StripeBillingIntegration.ts @@ -226,7 +226,7 @@ export default class StripeBillingIntegration extends BillingIntegration { requestParams.starting_after = taxes[taxes.length - 1].id; } } while (request.has_more); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_TAXES, module: MODULE_NAME, method: 'getTaxes', @@ -234,7 +234,7 @@ export default class StripeBillingIntegration extends BillingIntegration { }); } catch (error) { // catch stripe errors and send the information back to the client - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_TAXES, module: MODULE_NAME, method: 'getTaxes', @@ -256,7 +256,7 @@ export default class StripeBillingIntegration extends BillingIntegration { } } catch (error) { // catch stripe errors and send the information back to the client - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_TAXES, module: MODULE_NAME, method: 'getTaxRate', @@ -442,7 +442,7 @@ export default class StripeBillingIntegration extends BillingIntegration { await BillingStorage.saveInvoice(this.tenant, billingInvoice); throw operationResult.error; } else { - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_CHARGE_INVOICE, actionOnUser: billingInvoice.user, @@ -539,7 +539,7 @@ export default class StripeBillingIntegration extends BillingIntegration { // Check billing data consistency const customerID = user?.billingData?.customerID; const paymentMethods: BillingPaymentMethod[] = await this.getStripePaymentMethods(user, customerID); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: this.tenant.id, user, action: ServerAction.BILLING_PAYMENT_METHODS, @@ -574,7 +574,7 @@ export default class StripeBillingIntegration extends BillingIntegration { const setupIntent: Stripe.SetupIntent = await this.stripe.setupIntents.create({ customer: customerID }); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_SETUP_PAYMENT_METHOD, module: MODULE_NAME, method: 'createSetupIntent', @@ -588,7 +588,7 @@ export default class StripeBillingIntegration extends BillingIntegration { }; } catch (error) { // catch stripe errors and send the information back to the client - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_SETUP_PAYMENT_METHOD, actionOnUser: user, @@ -617,7 +617,7 @@ export default class StripeBillingIntegration extends BillingIntegration { }; } await this.stripe.paymentMethods.update(paymentMethodId, paymentMethodUpdateParams); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_SETUP_PAYMENT_METHOD, module: MODULE_NAME, method: 'attachPaymentMethod', @@ -627,7 +627,7 @@ export default class StripeBillingIntegration extends BillingIntegration { await this.stripe.customers.update(customerID, { invoice_settings: { default_payment_method: paymentMethodId } }); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_SETUP_PAYMENT_METHOD, module: MODULE_NAME, method: 'attachPaymentMethod', @@ -640,7 +640,7 @@ export default class StripeBillingIntegration extends BillingIntegration { }; } catch (error) { // catch stripe errors and send the information back to the client - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_SETUP_PAYMENT_METHOD, actionOnUser: user, @@ -677,7 +677,7 @@ export default class StripeBillingIntegration extends BillingIntegration { } while (response.has_more); } } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_PAYMENT_METHODS, actionOnUser: user, @@ -698,7 +698,7 @@ export default class StripeBillingIntegration extends BillingIntegration { const paymentMethod = await this.stripe.paymentMethods.retrieve(paymentMethodID); return this.convertToBillingPaymentMethod(paymentMethod, asDefault); } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_PAYMENT_METHODS, module: MODULE_NAME, method: 'getStripePaymentMethod', @@ -735,7 +735,7 @@ export default class StripeBillingIntegration extends BillingIntegration { } // Detach payment method from the stripe customer const paymentMethod: Stripe.PaymentMethod = await this.stripe.paymentMethods.detach(paymentMethodId); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_DELETE_PAYMENT_METHOD, module: MODULE_NAME, method: 'detachStripePaymentMethod', @@ -748,7 +748,7 @@ export default class StripeBillingIntegration extends BillingIntegration { }; } catch (error) { // catch stripe errors and send the information back to the client - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_DELETE_PAYMENT_METHOD, module: MODULE_NAME, method: 'detachStripePaymentMethod', @@ -775,7 +775,7 @@ export default class StripeBillingIntegration extends BillingIntegration { // Well ... when in test mode we may allow to start the transaction if (!customerID) { // Not yet LIVE ... starting a transaction without a STRIPE CUSTOMER is allowed - await Logging.logWarning({ + Logging.beWarning()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_TRANSACTION, module: MODULE_NAME, method: 'startTransaction', @@ -958,7 +958,7 @@ export default class StripeBillingIntegration extends BillingIntegration { }; } if (transaction.billingData?.stop?.status === BillingStatus.BILLED) { - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_TRANSACTION, module: MODULE_NAME, method: 'endTransaction', @@ -972,7 +972,7 @@ export default class StripeBillingIntegration extends BillingIntegration { return transaction.billingData.stop; } if (!transaction.stop?.extraInactivityComputed) { - await Logging.logWarning({ + Logging.beWarning()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING_TRANSACTION, module: MODULE_NAME, method: 'endTransaction', @@ -1010,7 +1010,7 @@ export default class StripeBillingIntegration extends BillingIntegration { const customerID: string = transaction.user?.billingData?.customerID; const customer = await this.getStripeCustomer(customerID); if (customer) { - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, user: transaction.userID, @@ -1034,7 +1034,7 @@ export default class StripeBillingIntegration extends BillingIntegration { }; } } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, user: transaction.userID, @@ -1203,7 +1203,7 @@ export default class StripeBillingIntegration extends BillingIntegration { // Let's try to bill the stripe invoice using the default payment method of the customer operationResult = await this.chargeStripeInvoice(stripeInvoice.id); if (!operationResult?.succeeded && operationResult?.error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, user: user.id, action: ServerAction.BILLING_TRANSACTION, @@ -1364,7 +1364,7 @@ export default class StripeBillingIntegration extends BillingIntegration { status: BillingInvoiceStatus.OPEN, }); if (list && !Utils.isEmptyArray(list.data)) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.USER_DELETE, actionOnUser: user, @@ -1379,7 +1379,7 @@ export default class StripeBillingIntegration extends BillingIntegration { status: BillingInvoiceStatus.DRAFT, }); if (list && !Utils.isEmptyArray(list.data)) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.USER_DELETE, actionOnUser: user, @@ -1394,7 +1394,7 @@ export default class StripeBillingIntegration extends BillingIntegration { pending: true, }); if (itemsList && itemsList.data && itemsList.data.length > 0) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.USER_DELETE, actionOnUser: user, @@ -1541,7 +1541,7 @@ export default class StripeBillingIntegration extends BillingIntegration { try { await this.checkConnection(); } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, user, action: ServerAction.BILLING, module: MODULE_NAME, method: 'precheckStartTransactionPrerequisites', @@ -1554,7 +1554,7 @@ export default class StripeBillingIntegration extends BillingIntegration { try { await this.checkTaxPrerequisites(); // Checks that the taxID is still valid } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, user, action: ServerAction.BILLING, module: MODULE_NAME, method: 'precheckStartTransactionPrerequisites', @@ -1571,7 +1571,7 @@ export default class StripeBillingIntegration extends BillingIntegration { // Check whether the customer has a default payment method await this.checkStripePaymentMethod(customer); } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, user, action: ServerAction.BILLING, module: MODULE_NAME, method: 'precheckStartTransactionPrerequisites', @@ -1674,7 +1674,7 @@ export default class StripeBillingIntegration extends BillingIntegration { // This method is ONLY USED when repairing invoices - c.f.: RepairInvoiceInconsistencies migration task if (!billingInvoice.sessions) { // This should not happen - but it happened once! - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING, actionOnUser: billingInvoice.user, @@ -1706,7 +1706,7 @@ export default class StripeBillingIntegration extends BillingIntegration { } } catch (error) { // Catch stripe errors and send the information back to the client - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, action: ServerAction.BILLING, actionOnUser: billingInvoice.user, diff --git a/src/integration/car-connector/mercedes-connector/MercedesCarConnectorIntegration.ts b/src/integration/car-connector/mercedes-connector/MercedesCarConnectorIntegration.ts index 370f167a55..a4a228ee03 100644 --- a/src/integration/car-connector/mercedes-connector/MercedesCarConnectorIntegration.ts +++ b/src/integration/car-connector/mercedes-connector/MercedesCarConnectorIntegration.ts @@ -76,7 +76,7 @@ export default class MercedesCarConnectorIntegration extends CarConnectorIntegra public async createConnection(userID: string, data: any): Promise { try { - await Logging.logDebug({ + Logging.beDebug()?.log({ user: userID, tenantID: this.tenant.id, module: MODULE_NAME, method: 'createConnection', @@ -95,7 +95,7 @@ export default class MercedesCarConnectorIntegration extends CarConnectorIntegra 'Authorization': `Basic ${Buffer.from(this.connection.mercedesConnection.clientId + ':' + await Cypher.decrypt(this.tenant, this.connection.mercedesConnection.clientSecret)).toString('base64')}` }, }); - await Logging.logDebug({ + Logging.beDebug()?.log({ user: userID, tenantID: this.tenant.id, module: MODULE_NAME, method: 'createConnection', @@ -144,7 +144,7 @@ export default class MercedesCarConnectorIntegration extends CarConnectorIntegra headers: { 'Authorization': 'Bearer ' + connection.data.access_token } } ); - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: this.tenant.id, action: ServerAction.CAR_CONNECTOR, message: `${car.vin} > Mercedes web service has been called successfully`, @@ -201,7 +201,7 @@ export default class MercedesCarConnectorIntegration extends CarConnectorIntegra 'Authorization': `Basic ${Buffer.from(this.connection.mercedesConnection.clientId + ':' + await Cypher.decrypt(this.tenant, this.connection.mercedesConnection.clientSecret)).toString('base64')}` } }); - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: this.tenant.id, user: userID, action: ServerAction.CAR_CONNECTOR, diff --git a/src/integration/car-connector/targa-telematics-connector/TargaTelematicsConnector.ts b/src/integration/car-connector/targa-telematics-connector/TargaTelematicsConnector.ts index aa1e59a1b1..a8aeee9cf1 100644 --- a/src/integration/car-connector/targa-telematics-connector/TargaTelematicsConnector.ts +++ b/src/integration/car-connector/targa-telematics-connector/TargaTelematicsConnector.ts @@ -46,7 +46,7 @@ export default class TargaTelematicsCarConnectorIntegration extends CarConnector headers: { 'Authorization': 'Bearer ' + connectionToken } } ); - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: this.tenant.id, action: ServerAction.CAR_CONNECTOR, message: `${car.vin} > Targa Telematics web service has been called successfully`, diff --git a/src/integration/car-connector/tronity-connector/TronityCarConnectorIntegration.ts b/src/integration/car-connector/tronity-connector/TronityCarConnectorIntegration.ts index 177a07821a..6f71336e13 100644 --- a/src/integration/car-connector/tronity-connector/TronityCarConnectorIntegration.ts +++ b/src/integration/car-connector/tronity-connector/TronityCarConnectorIntegration.ts @@ -38,7 +38,7 @@ export default class TronityCarConnectorIntegration extends CarConnectorIntegrat public async getCurrentSoC(car: Car): Promise { if (Utils.isNullOrUndefined(car.carConnectorData.carConnectorMeterID)) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: this.tenant.id, module: MODULE_NAME, method: 'getCurrentSoC', @@ -57,7 +57,7 @@ export default class TronityCarConnectorIntegration extends CarConnectorIntegrat headers: { 'Authorization': 'Bearer ' + connectionToken } } ); - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: this.tenant.id, action: ServerAction.CAR_CONNECTOR, message: `${car.vin} > Tronity web service has been called successfully`, diff --git a/src/integration/car/CarIntegration.ts b/src/integration/car/CarIntegration.ts index f046b8fa0e..d6b4295c75 100644 --- a/src/integration/car/CarIntegration.ts +++ b/src/integration/car/CarIntegration.ts @@ -41,7 +41,7 @@ export default abstract class CarIntegration { externalCar.id = await CarStorage.saveCarCatalog(externalCar); actionsDone.inSuccess++; // Log - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.SYNCHRONIZE_CAR_CATALOGS, module: MODULE_NAME, method: 'synchronizeCarCatalogs', @@ -75,7 +75,7 @@ export default abstract class CarIntegration { await CarStorage.saveCarCatalog(externalCar); actionsDone.inSuccess++; // Log - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.SYNCHRONIZE_CAR_CATALOGS, module: MODULE_NAME, method: 'synchronizeCarCatalogs', @@ -84,7 +84,7 @@ export default abstract class CarIntegration { } } catch (error) { actionsDone.inError++; - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.SYNCHRONIZE_CAR_CATALOGS, module: MODULE_NAME, method: 'synchronizeCarCatalogs', diff --git a/src/integration/car/ev-database/EVDatabaseCarIntegration.ts b/src/integration/car/ev-database/EVDatabaseCarIntegration.ts index 6eb573d6ea..7c7917fc98 100644 --- a/src/integration/car/ev-database/EVDatabaseCarIntegration.ts +++ b/src/integration/car/ev-database/EVDatabaseCarIntegration.ts @@ -22,7 +22,7 @@ export default class EVDatabaseCarIntegration extends CarIntegration { public async getCarCatalogs(): Promise { const evDatabaseConfig = Configuration.getEVDatabaseConfig(); if (!evDatabaseConfig) { - await Logging.logWarning({ + Logging.beWarning()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, message: 'No configuration is provided to access the EVDatabase system, skipping', module: MODULE_NAME, method: 'getCarCatalogs', @@ -95,7 +95,7 @@ export default class EVDatabaseCarIntegration extends CarIntegration { const base64Image = Buffer.from(response.data).toString('base64'); image = 'data:' + response.headers['content-type'] + ';base64,' + base64Image; } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.SYNCHRONIZE_CAR_CATALOGS, module: MODULE_NAME, method: 'getCarCatalogThumb', @@ -114,7 +114,7 @@ export default class EVDatabaseCarIntegration extends CarIntegration { const encodedImage = await response.getBase64Async(imageMIME); return encodedImage; } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.SYNCHRONIZE_CAR_CATALOGS, module: MODULE_NAME, method: 'getCarCatalogImage', diff --git a/src/integration/charging-station-vendor/ChargingStationVendorIntegration.ts b/src/integration/charging-station-vendor/ChargingStationVendorIntegration.ts index 9bd13016fc..a031cfbf41 100644 --- a/src/integration/charging-station-vendor/ChargingStationVendorIntegration.ts +++ b/src/integration/charging-station-vendor/ChargingStationVendorIntegration.ts @@ -37,7 +37,7 @@ export default abstract class ChargingStationVendorIntegration { const numberOfPhases = Utils.getNumberOfConnectedPhases(chargingStation, chargePoint); const numberOfConnectors = chargePoint ? chargePoint.connectorIDs.length : chargingStation.connectors.length; if (chargePoint.excludeFromPowerLimitation) { - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.CHARGING_STATION_LIMIT_POWER, @@ -48,7 +48,7 @@ export default abstract class ChargingStationVendorIntegration { return { status: OCPPConfigurationStatus.NOT_SUPPORTED }; } if (!chargePoint.ocppParamForPowerLimitation) { - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.CHARGING_STATION_LIMIT_POWER, @@ -88,7 +88,7 @@ export default abstract class ChargingStationVendorIntegration { const ocppLimitAmpValue = this.convertLimitAmpPerPhase(chargingStation, chargePoint, 0, maxAmps * ocppParamValueMultiplier); let result: OCPPChangeConfigurationResponse; try { - await Logging.logDebug({ + Logging.beDebug()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.CHARGING_STATION_LIMIT_POWER, @@ -133,7 +133,7 @@ export default abstract class ChargingStationVendorIntegration { const connector = Utils.getConnectorFromID(chargingStation, connectorID); if (connector) { connector.amperageLimit = this.convertLimitAmpToAllPhases(chargingStation, chargePoint, connectorID, Utils.convertToInt(ocppParamValue) / ocppParamValueDivider); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.OCPP_PARAM_UPDATE, @@ -187,7 +187,7 @@ export default abstract class ChargingStationVendorIntegration { }); // Call each connector? if (result.status !== OCPPChargingProfileStatus.ACCEPTED) { - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.CHARGING_PROFILE_UPDATE, @@ -214,7 +214,7 @@ export default abstract class ChargingStationVendorIntegration { }); return result; } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.CHARGING_PROFILE_UPDATE, @@ -261,7 +261,7 @@ export default abstract class ChargingStationVendorIntegration { }); // Call each connector? if (result.status !== OCPPClearChargingProfileStatus.ACCEPTED) { - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.CHARGING_PROFILE_DELETE, @@ -288,7 +288,7 @@ export default abstract class ChargingStationVendorIntegration { }); return result; } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.CHARGING_PROFILE_DELETE, @@ -340,7 +340,7 @@ export default abstract class ChargingStationVendorIntegration { result.chargingSchedule = this.convertFromVendorChargingSchedule(chargingStation, chargePoint, result.connectorId, result.chargingSchedule); return result; } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.CHARGING_STATION_GET_COMPOSITE_SCHEDULE, @@ -437,7 +437,7 @@ export default abstract class ChargingStationVendorIntegration { limitWatts: Utils.convertAmpToWatt(chargingStation, chargePoint, connectorID, connectorLimitAmps), limitSource: ConnectorCurrentLimitSource.STATIC_LIMITATION, }; - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.GET_CONNECTOR_CURRENT_LIMIT, @@ -449,7 +449,7 @@ export default abstract class ChargingStationVendorIntegration { } } } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.GET_CONNECTOR_CURRENT_LIMIT, @@ -464,7 +464,7 @@ export default abstract class ChargingStationVendorIntegration { limitWatts: limitDefaultMaxPower, limitSource: ConnectorCurrentLimitSource.CONNECTOR }; - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.GET_CONNECTOR_CURRENT_LIMIT, @@ -613,7 +613,7 @@ export default abstract class ChargingStationVendorIntegration { limitWatts: Utils.convertAmpToWatt(chargingStation, chargePoint, connectorID, Utils.convertToInt(schedulePeriod.limit)), limitSource: ConnectorCurrentLimitSource.CHARGING_PROFILE, }; - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.GET_CONNECTOR_CURRENT_LIMIT, @@ -631,7 +631,7 @@ export default abstract class ChargingStationVendorIntegration { limitWatts: Utils.convertAmpToWatt(chargingStation, chargePoint, connectorID, Utils.convertToInt(lastButOneSchedule.limit)), limitSource: ConnectorCurrentLimitSource.CHARGING_PROFILE, }; - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.GET_CONNECTOR_CURRENT_LIMIT, @@ -650,7 +650,7 @@ export default abstract class ChargingStationVendorIntegration { limitWatts: Utils.convertAmpToWatt(chargingStation, chargePoint, connectorID, Utils.convertToInt(lastButOneSchedule.limit)), limitSource: ConnectorCurrentLimitSource.CHARGING_PROFILE, }; - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.GET_CONNECTOR_CURRENT_LIMIT, diff --git a/src/integration/pricing/PricingEngine.ts b/src/integration/pricing/PricingEngine.ts index 61913d75dc..a71b329e50 100644 --- a/src/integration/pricing/PricingEngine.ts +++ b/src/integration/pricing/PricingEngine.ts @@ -25,7 +25,7 @@ export default class PricingEngine { // pricingDefinitions.push(...await PricingEngine.getPricingDefinitions4Entity(tenant, pricingContext, PricingEntity.COMPANY, transaction.companyID)); pricingDefinitions.push(...await PricingEngine.getPricingDefinitions4Entity(tenant, pricingContext, PricingEntity.TENANT, tenant.id)); if (!pricingContext.timezone) { - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getPricingContextProperties(pricingContext), tenantID: tenant.id, module: MODULE_NAME, @@ -43,7 +43,7 @@ export default class PricingEngine { }, pricingDefinitions }; - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getPricingContextProperties(pricingContext), tenantID: tenant.id, module: MODULE_NAME, @@ -75,7 +75,7 @@ export default class PricingEngine { private static async getPricingDefinitions4Entity(tenant: Tenant, pricingContext: PricingContext, entityType: PricingEntity, entityID: string): Promise { if (!entityID) { - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getPricingContextProperties(pricingContext), tenantID: tenant.id, module: MODULE_NAME, @@ -94,7 +94,7 @@ export default class PricingEngine { ).map((pricingDefinition) => PricingEngine.shrinkPricingDefinition(pricingDefinition) ); - await Logging.logDebug({ + Logging.beDebug()?.log({ ...LoggingHelper.getPricingContextProperties(pricingContext), tenantID: tenant.id, module: MODULE_NAME, diff --git a/src/integration/pricing/simple-pricing/BuiltInPricingIntegration.ts b/src/integration/pricing/simple-pricing/BuiltInPricingIntegration.ts index a986caf383..3ba45ba0a8 100644 --- a/src/integration/pricing/simple-pricing/BuiltInPricingIntegration.ts +++ b/src/integration/pricing/simple-pricing/BuiltInPricingIntegration.ts @@ -23,7 +23,7 @@ export default class BuiltInPricingIntegration extends PricingIntegration { const pricedConsumption = await this.computePrice(transaction, consumptionData, chargingStation); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, module: MODULE_NAME, @@ -41,7 +41,7 @@ export default class BuiltInPricingIntegration extends PricingIntegration { const pricedConsumption = await this.computePrice(transaction, consumptionData, chargingStation); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, module: MODULE_NAME, @@ -55,7 +55,7 @@ export default class BuiltInPricingIntegration extends PricingIntegration { const pricedConsumption = await this.computePrice(transaction, consumptionData, chargingStation); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: this.tenant.id, module: MODULE_NAME, @@ -69,7 +69,7 @@ export default class BuiltInPricingIntegration extends PricingIntegration { if (!PricingHelper.checkContextConsistency(pricingContext)) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getPricingContextProperties(pricingContext), tenantID: this.tenant.id, module: MODULE_NAME, diff --git a/src/integration/refund/RefundFactory.ts b/src/integration/refund/RefundFactory.ts index 4877679987..37997af5a0 100644 --- a/src/integration/refund/RefundFactory.ts +++ b/src/integration/refund/RefundFactory.ts @@ -25,7 +25,7 @@ export default class RefundFactory { } return refundIntegrationImpl; } - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, action: ServerAction.REFUND, module: MODULE_NAME, diff --git a/src/integration/refund/sap-concur/SapConcurRefundIntegration.ts b/src/integration/refund/sap-concur/SapConcurRefundIntegration.ts index 14d357fcda..d0060ca091 100644 --- a/src/integration/refund/sap-concur/SapConcurRefundIntegration.ts +++ b/src/integration/refund/sap-concur/SapConcurRefundIntegration.ts @@ -106,7 +106,7 @@ export default class SapConcurRefundIntegration extends RefundIntegration { try { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: this.tenant.id, module: MODULE_NAME, method: 'createConnection', action: ServerAction.REFUND, message: `Request Concur access token for User ID '${userID}'` @@ -125,7 +125,7 @@ export default class SapConcurRefundIntegration extends RefundIntegration { - // Retry setting the cp 2 more times - for (let i = 0; i < 2; i++) { - try { - // Set Charging Profile - await OCPPUtils.setAndSaveChargingProfile(this.tenant, chargingProfile); - return true; - } catch (error) { - // Log failed - await Logging.logError({ - tenantID: this.tenant.id, - siteID: chargingProfile.chargingStation.siteID, - siteAreaID: chargingProfile.chargingStation.siteAreaID, - companyID: chargingProfile.chargingStation.companyID, - chargingStationID: chargingProfile.chargingStationID, - action: ServerAction.CHARGING_PROFILE_UPDATE, - module: MODULE_NAME, method: 'handleRefusedChargingProfile', - message: 'Setting Charging Profiles failed 3 times.', - detailedMessages: { error: error.stack } - }); - } - } - // Remove Charging Station from Smart Charging - const chargingStation = await ChargingStationStorage.getChargingStation(tenant, chargingProfile.chargingStationID); - // Remember Charging Stations which were removed from Smart Charging - this.excludedChargingStations.push(chargingStation.id); + private excludeChargingStationAndNotify(tenant: Tenant, chargingProfile: ChargingProfile, siteAreaName: string): void { + // Exclude Charging Station from this smart charging run! + this.excludedChargingStations.push(chargingProfile.chargingStationID); // Notify Admins - NotificationHandler.sendComputeAndApplyChargingProfilesFailed(tenant, chargingStation, - { chargeBoxID: chargingProfile.chargingStationID, - siteID: chargingProfile.chargingStation?.siteID, - siteAreaID: chargingProfile.chargingStation?.siteAreaID, - companyID: chargingProfile.chargingStation?.companyID, - siteAreaName: siteAreaName, - evseDashboardURL: Utils.buildEvseURL(tenant.subdomain) - } - ).catch((error) => { + NotificationHandler.sendComputeAndApplyChargingProfilesFailed(tenant, { + chargeBoxID: chargingProfile.chargingStationID, + siteID: chargingProfile.chargingStation?.siteID, + siteAreaID: chargingProfile.chargingStation?.siteAreaID, + companyID: chargingProfile.chargingStation?.companyID, + siteAreaName: siteAreaName, + evseDashboardURL: Utils.buildEvseURL(tenant.subdomain) + }).catch((error) => { Logging.logPromiseError(error, tenant?.id); }); - return false; } public abstract buildChargingProfiles(siteArea: SiteArea, excludedChargingStations?: string[]): Promise; diff --git a/src/integration/smart-charging/sap-smart-charging/SapSmartChargingIntegration.ts b/src/integration/smart-charging/sap-smart-charging/SapSmartChargingIntegration.ts index 4aa2e7fef3..b2ea2096ec 100644 --- a/src/integration/smart-charging/sap-smart-charging/SapSmartChargingIntegration.ts +++ b/src/integration/smart-charging/sap-smart-charging/SapSmartChargingIntegration.ts @@ -91,7 +91,7 @@ export default class SapSmartChargingIntegration extends SmartChargingIntegratio (chargingStation) => chargingStation.siteAreaID === siteArea.id); } } else { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: this.tenant.id, action: ServerAction.SMART_CHARGING, message: `${sourceSiteArea.name} > No charging station used, so no need to call the Smart Charging service`, @@ -126,7 +126,7 @@ export default class SapSmartChargingIntegration extends SmartChargingIntegratio const url = await this.buildOptimizerUrl(sourceSiteArea); // Check at least one car if (request.state.cars.length === 0) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: this.tenant.id, action: ServerAction.SMART_CHARGING, message: `${sourceSiteArea.name} > No car connected so no need to call the SAP Smart Charging service`, @@ -135,7 +135,7 @@ export default class SapSmartChargingIntegration extends SmartChargingIntegratio }); return; } - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: this.tenant.id, action: ServerAction.SMART_CHARGING, message: `${sourceSiteArea.name} > Call the SAP Smart Charging service...`, @@ -148,7 +148,7 @@ export default class SapSmartChargingIntegration extends SmartChargingIntegratio Accept: 'application/json', } }); - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: this.tenant.id, action: ServerAction.SMART_CHARGING, message: `${sourceSiteArea.name} > SAP Smart Charging service has been called successfully`, @@ -158,7 +158,7 @@ export default class SapSmartChargingIntegration extends SmartChargingIntegratio // Build charging profiles from result const chargingProfiles = await this.buildChargingProfilesFromOptimizerResponse( sourceSiteArea, siteAreas.result, response.data); - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: this.tenant.id, action: ServerAction.SMART_CHARGING, message: `${sourceSiteArea.name} > Charging Profiles have been built successfully`, @@ -348,7 +348,7 @@ export default class SapSmartChargingIntegration extends SmartChargingIntegratio // Transaction in progress? if (!connector.currentTransactionID) { // Should not happen - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: this.tenant.id, action: ServerAction.SMART_CHARGING, @@ -362,7 +362,7 @@ export default class SapSmartChargingIntegration extends SmartChargingIntegratio const currentTransaction = transactions.find((transaction) => transaction.id === connector.currentTransactionID); if (!currentTransaction) { // Should not happen - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: this.tenant.id, action: ServerAction.SMART_CHARGING, @@ -380,7 +380,7 @@ export default class SapSmartChargingIntegration extends SmartChargingIntegratio // Get Asset consumption const assetConsumptionInWatts = await this.getAssetConsumptionInWatts(siteArea); if (siteArea.maximumPower !== siteArea.maximumPower - assetConsumptionInWatts) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: this.tenant.id, action: ServerAction.SMART_CHARGING, message: `${siteArea.name} > limit of ${siteArea.maximumPower} W has been adjusted to ${Math.round(siteArea.maximumPower - assetConsumptionInWatts)} W due Asset Consumption`, @@ -492,7 +492,7 @@ export default class SapSmartChargingIntegration extends SmartChargingIntegratio } // Found unsupported chargers if (siteMaxAmps !== rootFuse.fusePhase1 + rootFuse.fusePhase2 + rootFuse.fusePhase3) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: this.tenant.id, action: ServerAction.SMART_CHARGING, message: `${siteArea.name} > limit of ${siteMaxAmps} Amps has been lowered to ${Math.round(rootFuse.fusePhase1 + rootFuse.fusePhase2 + rootFuse.fusePhase3)} Amps due to unsupported charging stations currently being used`, @@ -1024,7 +1024,7 @@ export default class SapSmartChargingIntegration extends SmartChargingIntegratio } } if (removedChargingProfiles > 0) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: this.tenant.id, action: ServerAction.SMART_CHARGING, message: `${siteArea.name} > ${removedChargingProfiles} Charging Profiles have been already applied and will be removed from charging profile schedule`, diff --git a/src/locking/LockingManager.ts b/src/locking/LockingManager.ts index 6101cdb430..fbea696984 100644 --- a/src/locking/LockingManager.ts +++ b/src/locking/LockingManager.ts @@ -16,7 +16,7 @@ export default class LockingManager { public static async acquire(lock: Lock, timeoutSecs = 0, retry = true): Promise { try { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: lock.tenantID, module: MODULE_NAME, method: 'acquire', action: ServerAction.LOCKING, @@ -36,7 +36,7 @@ export default class LockingManager { detailedMessages: { lock, timeoutSecs, retry } }); } - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: lock.tenantID, module: MODULE_NAME, method: 'acquire', action: ServerAction.LOCKING, @@ -50,7 +50,7 @@ export default class LockingManager { if (retry && await LockingManager.checkAndReleaseExpiredLock(lock)) { return LockingManager.acquire(lock, timeoutSecs, false); } - await Logging.logWarning({ + Logging.beWarning()?.log({ tenantID: lock.tenantID, module: MODULE_NAME, method: 'acquire', action: ServerAction.LOCKING, @@ -66,7 +66,7 @@ export default class LockingManager { // Delete const result = await LockingStorage.deleteLock(lock.id); if (!result) { - await Logging.logWarning({ + Logging.beWarning()?.log({ tenantID: lock.tenantID, module: MODULE_NAME, method: 'release', action: ServerAction.LOCKING, @@ -75,7 +75,7 @@ export default class LockingManager { }); return false; } - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: lock.tenantID, module: MODULE_NAME, method: 'release', action: ServerAction.LOCKING, @@ -156,7 +156,7 @@ export default class LockingManager { try { // Remove the lock await LockingManager.release(lockInDB); - await Logging.logWarning({ + Logging.beWarning()?.log({ tenantID: lock.tenantID, module: MODULE_NAME, method: 'acquire', action: ServerAction.LOCKING, @@ -166,7 +166,7 @@ export default class LockingManager { Utils.isDevelopmentEnv() && Logging.logConsoleWarning(`The lock '${lock.entity}' ('${lock.key}') of type '${lock.type}' in Tenant ID ${lock.tenantID} has expired and was released successfully`); return true; } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: lock.tenantID, module: MODULE_NAME, method: 'acquire', action: ServerAction.LOCKING, diff --git a/src/migration/MigrationHandler.ts b/src/migration/MigrationHandler.ts index 5bf4955c55..4eb4b2290b 100644 --- a/src/migration/MigrationHandler.ts +++ b/src/migration/MigrationHandler.ts @@ -18,7 +18,7 @@ export default class MigrationHandler { if (await LockingManager.acquire(migrationLock)) { try { const startTime = moment(); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.MIGRATION, module: MODULE_NAME, method: 'migrate', @@ -49,14 +49,14 @@ export default class MigrationHandler { } // Log Total Processing Time const totalTimeSecs = moment.duration(moment().diff(startTime)).asSeconds(); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.MIGRATION, module: MODULE_NAME, method: 'migrate', message: `The ${processAsyncTasksOnly ? 'asynchronous' : 'synchronous'} migration has been run in ${totalTimeSecs} secs` }); } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.MIGRATION, module: MODULE_NAME, method: 'migrate', @@ -80,7 +80,7 @@ export default class MigrationHandler { try { // Log Start Task let logMsg = `${currentMigrationTask.isAsynchronous() ? 'Asynchronous' : 'Synchronous'} Migration Task '${currentMigrationTask.getName()}' Version '${currentMigrationTask.getVersion()}' is running...`; - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.MIGRATION, module: MODULE_NAME, method: 'executeTask', @@ -104,7 +104,7 @@ export default class MigrationHandler { durationSecs: totalTaskTimeSecs }); logMsg = `${currentMigrationTask.isAsynchronous() ? 'Asynchronous' : 'Synchronous'} Migration Task '${currentMigrationTask.getName()}' Version '${currentMigrationTask.getVersion()}' has run with success in ${totalTaskTimeSecs} secs`; - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.MIGRATION, module: MODULE_NAME, method: 'executeTask', @@ -114,7 +114,7 @@ export default class MigrationHandler { Utils.isDevelopmentEnv() && Logging.logConsoleDebug(logMsg); } catch (error) { const logMsg = `${currentMigrationTask.isAsynchronous() ? 'Asynchronous' : 'Synchronous'} Migration Task '${currentMigrationTask.getName()}' Version '${currentMigrationTask.getVersion()}' has failed with error: ${error.message as string}`; - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.MIGRATION, module: MODULE_NAME, method: 'executeTask', diff --git a/src/migration/TenantMigrationTask.ts b/src/migration/TenantMigrationTask.ts index 578f5628d6..22c5b74e72 100644 --- a/src/migration/TenantMigrationTask.ts +++ b/src/migration/TenantMigrationTask.ts @@ -15,7 +15,7 @@ export default abstract class TenantMigrationTask extends MigrationTask { for (const tenant of tenants.result) { const tenantCorrelationID = Utils.generateShortNonUniqueID(); const startTimeInTenant = moment(); - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.MIGRATION, module: MODULE_NAME, method: 'migrate', @@ -25,7 +25,7 @@ export default abstract class TenantMigrationTask extends MigrationTask { // Migrate await this.migrateTenant(tenant); } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.MIGRATION, module: MODULE_NAME, method: 'migrate', @@ -35,7 +35,7 @@ export default abstract class TenantMigrationTask extends MigrationTask { } // Log Total Processing Time const totalTimeSecsInTenant = moment.duration(moment().diff(startTimeInTenant)).asSeconds(); - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.MIGRATION, module: MODULE_NAME, method: 'migrate', diff --git a/src/migration/tasks/AddCompanyIDToChargingStationsTask.ts b/src/migration/tasks/AddCompanyIDToChargingStationsTask.ts index 7ccaf443ec..fe310260c2 100644 --- a/src/migration/tasks/AddCompanyIDToChargingStationsTask.ts +++ b/src/migration/tasks/AddCompanyIDToChargingStationsTask.ts @@ -49,7 +49,7 @@ export default class AddCompanyIDToChargingStationsTask extends TenantMigrationT } // Log in the default tenant if (updated > 0) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, module: MODULE_NAME, method: 'migrateTenant', action: ServerAction.MIGRATION, diff --git a/src/migration/tasks/AddCompanyIDToTransactionsTask.ts b/src/migration/tasks/AddCompanyIDToTransactionsTask.ts index 0b3bed5724..f29df87978 100644 --- a/src/migration/tasks/AddCompanyIDToTransactionsTask.ts +++ b/src/migration/tasks/AddCompanyIDToTransactionsTask.ts @@ -49,7 +49,7 @@ export default class AddCompanyIDToTransactionsTask extends TenantMigrationTask } // Log in the default tenant if (updated > 0) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, module: MODULE_NAME, method: 'migrateTenant', action: ServerAction.MIGRATION, diff --git a/src/migration/tasks/AddLevelTemplateToChargingStationTemplateTask.ts b/src/migration/tasks/AddLevelTemplateToChargingStationTemplateTask.ts index 8885317dd9..d4bb559f08 100644 --- a/src/migration/tasks/AddLevelTemplateToChargingStationTemplateTask.ts +++ b/src/migration/tasks/AddLevelTemplateToChargingStationTemplateTask.ts @@ -17,7 +17,7 @@ export default class AddLevelTemplateToChargingStationTemplateTask extends Migra for (const template of templates) { if (template.template) { // skip this one as it has already ran - continue + continue; } // Put _id in id const and get template without id const { @@ -47,7 +47,7 @@ export default class AddLevelTemplateToChargingStationTemplateTask extends Migra }, ); } - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, module: MODULE_NAME, method: 'migrate', action: ServerAction.MIGRATION, diff --git a/src/migration/tasks/AddUserIDToCarsTask.ts b/src/migration/tasks/AddUserIDToCarsTask.ts index 11af90b226..562f07de48 100644 --- a/src/migration/tasks/AddUserIDToCarsTask.ts +++ b/src/migration/tasks/AddUserIDToCarsTask.ts @@ -35,7 +35,7 @@ export default class AddUserIDToCarsTask extends TenantMigrationTask { } // Log in the default tenant if (updated > 0) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, module: MODULE_NAME, method: 'migrateTenant', action: ServerAction.MIGRATION, diff --git a/src/migration/tasks/AlignEntitiesWithOrganizationIDsTask.ts b/src/migration/tasks/AlignEntitiesWithOrganizationIDsTask.ts index 55b33f3823..7ebafa767b 100644 --- a/src/migration/tasks/AlignEntitiesWithOrganizationIDsTask.ts +++ b/src/migration/tasks/AlignEntitiesWithOrganizationIDsTask.ts @@ -30,7 +30,7 @@ export default class AlignEntitiesWithOrganizationIDsTask extends TenantMigratio updated += await SiteAreaStorage.updateEntitiesWithOrganizationIDs( tenant, foundSite.companyID.toString(), siteArea.siteID.toString(), siteArea._id.toString()); } else { - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, module: MODULE_NAME, method: 'migrateTenant', action: ServerAction.MIGRATION, @@ -41,7 +41,7 @@ export default class AlignEntitiesWithOrganizationIDsTask extends TenantMigratio } // Log in the default tenant if (updated > 0) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, module: MODULE_NAME, method: 'migrateTenant', action: ServerAction.MIGRATION, diff --git a/src/migration/tasks/MigrateSimplePricing.ts b/src/migration/tasks/MigrateSimplePricing.ts index 254ad75eac..4b3aca90d3 100644 --- a/src/migration/tasks/MigrateSimplePricing.ts +++ b/src/migration/tasks/MigrateSimplePricing.ts @@ -17,7 +17,7 @@ export default class SimplePricingMigrationTask extends TenantMigrationTask { const pricingSetting = await SettingStorage.getSettingByIdentifier(tenant, TenantComponents.PRICING); if (pricingSetting?.content?.type === PricingSettingsType.SIMPLE) { await this.createDefaultPricingDefinition(tenant, pricingSetting.content.simple); - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, module: MODULE_NAME, method: 'migrateTenant', action: ServerAction.MIGRATION, diff --git a/src/migration/tasks/RemoveDuplicateTagVisualIDsTask.ts b/src/migration/tasks/RemoveDuplicateTagVisualIDsTask.ts index b30e494b9d..df35d90735 100644 --- a/src/migration/tasks/RemoveDuplicateTagVisualIDsTask.ts +++ b/src/migration/tasks/RemoveDuplicateTagVisualIDsTask.ts @@ -49,7 +49,7 @@ export default class RemoveDuplicateTagVisualIDsTask extends TenantMigrationTask } // Log in the default tenant if (updated > 0) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, module: MODULE_NAME, method: 'migrateTenant', action: ServerAction.MIGRATION, diff --git a/src/migration/tasks/RepairInvoiceInconsistencies.ts b/src/migration/tasks/RepairInvoiceInconsistencies.ts index 3dbef59364..2534ba41e2 100644 --- a/src/migration/tasks/RepairInvoiceInconsistencies.ts +++ b/src/migration/tasks/RepairInvoiceInconsistencies.ts @@ -18,7 +18,7 @@ export default class RepairInvoiceInconsistencies extends TenantMigrationTask { const billingImpl = await BillingFactory.getBillingImpl(tenant); if (billingImpl && billingImpl instanceof StripeBillingIntegration) { await this.repairInvoices(tenant, billingImpl); - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, module: MODULE_NAME, method: 'migrateTenant', action: ServerAction.MIGRATION, @@ -26,7 +26,7 @@ export default class RepairInvoiceInconsistencies extends TenantMigrationTask { }); } } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: ServerAction.BILLING_PERFORM_OPERATIONS, module: MODULE_NAME, method: 'repairInvoices', @@ -68,7 +68,7 @@ export default class RepairInvoiceInconsistencies extends TenantMigrationTask { try { // Skip invoices that are already PAID or not relevant for the current billing process if (!billingInvoice.sessions) { - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, action: ServerAction.BILLING_PERFORM_OPERATIONS, actionOnUser: billingInvoice.user, @@ -76,7 +76,7 @@ export default class RepairInvoiceInconsistencies extends TenantMigrationTask { message: `Attempt to repair invoice: '${billingInvoice.id}' - '${billingInvoice.number}' ` }); await billingImpl.repairInvoice(billingInvoice); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, action: ServerAction.BILLING_PERFORM_OPERATIONS, actionOnUser: billingInvoice.user, @@ -85,7 +85,7 @@ export default class RepairInvoiceInconsistencies extends TenantMigrationTask { }); } } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: ServerAction.BILLING_PERFORM_OPERATIONS, actionOnUser: billingInvoice.user, diff --git a/src/migration/tasks/RepairTransactionBillingData.ts b/src/migration/tasks/RepairTransactionBillingData.ts index d9855e3589..ad608bf579 100644 --- a/src/migration/tasks/RepairTransactionBillingData.ts +++ b/src/migration/tasks/RepairTransactionBillingData.ts @@ -18,7 +18,7 @@ export default class RepairTransactionBillingData extends TenantMigrationTask { const billingImpl = await BillingFactory.getBillingImpl(tenant); if (billingImpl && billingImpl instanceof StripeBillingIntegration) { await this.repairTransactionsBillingData(tenant, billingImpl); - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, module: MODULE_NAME, method: 'migrateTenant', action: ServerAction.MIGRATION, @@ -26,7 +26,7 @@ export default class RepairTransactionBillingData extends TenantMigrationTask { }); } } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: ServerAction.BILLING_PERFORM_OPERATIONS, module: MODULE_NAME, method: 'repairInvoices', @@ -66,7 +66,7 @@ export default class RepairTransactionBillingData extends TenantMigrationTask { skip += limit; for (const billingInvoice of invoices.result) { try { - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, action: ServerAction.BILLING_PERFORM_OPERATIONS, actionOnUser: billingInvoice.user, @@ -74,7 +74,7 @@ export default class RepairTransactionBillingData extends TenantMigrationTask { message: `Attempt to repair transaction's billing data for invoice: '${billingInvoice.id}' - '${billingInvoice.number}' ` }); await billingImpl.repairTransactionsBillingData(billingInvoice); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, action: ServerAction.BILLING_PERFORM_OPERATIONS, actionOnUser: billingInvoice.user, @@ -82,7 +82,7 @@ export default class RepairTransactionBillingData extends TenantMigrationTask { message: `Transaction's billing data has been repaired for invoice: '${billingInvoice.id}' - '${billingInvoice.number}' ` }); } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: ServerAction.BILLING_PERFORM_OPERATIONS, actionOnUser: billingInvoice.user, diff --git a/src/migration/tasks/RepairTransactionPricedAtZeroTask.ts b/src/migration/tasks/RepairTransactionPricedAtZeroTask.ts index 39ead9fc19..428a5b31d7 100644 --- a/src/migration/tasks/RepairTransactionPricedAtZeroTask.ts +++ b/src/migration/tasks/RepairTransactionPricedAtZeroTask.ts @@ -46,7 +46,7 @@ export default class RepairTransactionPricedAtZero extends TenantMigrationTask { await this.loadSimplePricingSettings(tenant); if (transactionsMDB.length > 0 && this.pricingSettings?.simple?.price > 0) { let message = `${transactionsMDB.length} Transaction(s) are going to be repaired in Tenant ${Utils.buildTenantName(tenant)}...`; - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.MIGRATION, module: MODULE_NAME, method: 'migrateTenant', @@ -57,7 +57,7 @@ export default class RepairTransactionPricedAtZero extends TenantMigrationTask { const numberOfProcessedTransactions = transactionsUpdated.inError + transactionsUpdated.inSuccess; if (numberOfProcessedTransactions > 0 && (numberOfProcessedTransactions % 100) === 0) { message = `> ${transactionsUpdated.inError + transactionsUpdated.inSuccess}/${transactionsMDB.length} - Transaction consumptions recomputed in Tenant ${Utils.buildTenantName(tenant)}`; - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.MIGRATION, module: MODULE_NAME, method: 'migrateTenant', @@ -78,7 +78,7 @@ export default class RepairTransactionPricedAtZero extends TenantMigrationTask { transactionsUpdated.inSuccess++; } catch (error) { transactionsUpdated.inError++; - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.MIGRATION, module: MODULE_NAME, method: 'migrateTenant', diff --git a/src/migration/tasks/RestoreDataIntegrityInSiteUsersTask.ts b/src/migration/tasks/RestoreDataIntegrityInSiteUsersTask.ts index 246bf41044..e1b88a9c48 100644 --- a/src/migration/tasks/RestoreDataIntegrityInSiteUsersTask.ts +++ b/src/migration/tasks/RestoreDataIntegrityInSiteUsersTask.ts @@ -47,7 +47,7 @@ export default class RestoreDataIntegrityInSiteUsersTask extends TenantMigration } // Log in the default tenant if (deleted > 0) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, module: MODULE_NAME, method: 'migrateTenant', action: ServerAction.MIGRATION, diff --git a/src/migration/tasks/UpdateEmailsToLowercaseTask.ts b/src/migration/tasks/UpdateEmailsToLowercaseTask.ts index 86889ca148..4cd636e746 100644 --- a/src/migration/tasks/UpdateEmailsToLowercaseTask.ts +++ b/src/migration/tasks/UpdateEmailsToLowercaseTask.ts @@ -22,7 +22,7 @@ export default class UpdateEmailsToLowercaseTask extends TenantMigrationTask { ) as UpdateResult; if (updateResult.modifiedCount > 0) { // Log in the default tenant - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, module: MODULE_NAME, method: 'migrateTenant', action: ServerAction.MIGRATION, diff --git a/src/monitoring/prometheus/PrometheusMonitoringServer.ts b/src/monitoring/prometheus/PrometheusMonitoringServer.ts index 481dd09e87..ea2814ffef 100644 --- a/src/monitoring/prometheus/PrometheusMonitoringServer.ts +++ b/src/monitoring/prometheus/PrometheusMonitoringServer.ts @@ -35,9 +35,9 @@ export default class PrometheusMonitoringServer extends MonitoringServer { app: 'e-Mobility' }); if (process.env.K8S) { - this.createGaugeMetric(Constants.WEB_SOCKET_QUEUED_REQUEST, 'The number of web sockets that are queued'); + // this.createGaugeMetric(Constants.WEB_SOCKET_QUEUED_REQUEST, 'The number of web sockets that are queued'); this.createGaugeMetric(Constants.WEB_SOCKET_RUNNING_REQUEST, 'The number of web sockets that are running'); - this.createGaugeMetric(Constants.WEB_SOCKET_RUNNING_REQUEST_RESPONSE, 'The number of web sockets request + response that are running'); + // this.createGaugeMetric(Constants.WEB_SOCKET_RUNNING_REQUEST_RESPONSE, 'The number of web sockets request + response that are running'); this.createGaugeMetric(Constants.WEB_SOCKET_CURRENT_REQUEST, 'JSON WS Requests in cache'); this.createGaugeMetric(Constants.WEB_SOCKET_OCPP_CONNECTIONS_COUNT, 'number of json web sockets'); this.createGaugeMetric(Constants.MONGODB_CONNECTION_READY, 'The number of connection that are ready'); @@ -64,9 +64,12 @@ export default class PrometheusMonitoringServer extends MonitoringServer { next(); // Trace Response Logging.traceExpressResponse(req, res, next, ServerAction.MONITORING); - - }).catch((error) => { /* */ }); - }).catch((error) => { /* */ }); + }).catch((error) => { + Logging.logPromiseError(error); + }); + }).catch((error) => { + Logging.logPromiseError(error); + }); } ); // Post init @@ -106,6 +109,7 @@ export default class PrometheusMonitoringServer extends MonitoringServer { return metric; } + public getCounterClearableMetric(prefix : string, metricName: string, metricHelp: string, labelValues: LabelValues) : CounterClearableMetric { // const labelNames = Object.keys(labelValues); const values = Object.values(labelValues).toString(); diff --git a/src/notification/NotificationHandler.ts b/src/notification/NotificationHandler.ts index f0eb1006ce..de1b222cc5 100644 --- a/src/notification/NotificationHandler.ts +++ b/src/notification/NotificationHandler.ts @@ -70,7 +70,7 @@ export default class NotificationHandler { } return false; } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.NOTIFICATION, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.NOTIFICATION, error); } } @@ -87,7 +87,7 @@ export default class NotificationHandler { ); return notifications.count > 0; } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.NOTIFICATION, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.NOTIFICATION, error); } } @@ -119,7 +119,7 @@ export default class NotificationHandler { await notificationSource.notificationTask.sendEndOfCharge(sourceData, user, tenant, NotificationSeverity.INFO); } } else { - await Logging.logDebug({ + Logging.beDebug()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'sendEndOfCharge', @@ -129,7 +129,7 @@ export default class NotificationHandler { }); } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.END_OF_CHARGE, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.END_OF_CHARGE, error); } } } @@ -164,7 +164,7 @@ export default class NotificationHandler { await notificationSource.notificationTask.sendOptimalChargeReached(sourceData, user, tenant, NotificationSeverity.INFO); } } else { - await Logging.logDebug({ + Logging.beDebug()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'sendOptimalChargeReached', @@ -174,7 +174,7 @@ export default class NotificationHandler { }); } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OPTIMAL_CHARGE_REACHED, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OPTIMAL_CHARGE_REACHED, error); } } } @@ -209,7 +209,7 @@ export default class NotificationHandler { await notificationSource.notificationTask.sendEndOfSession(sourceData, user, tenant, NotificationSeverity.INFO); } } else { - await Logging.logDebug({ + Logging.beDebug()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'sendEndOfSession', @@ -219,7 +219,7 @@ export default class NotificationHandler { }); } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.END_OF_SESSION, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.END_OF_SESSION, error); } } } @@ -254,7 +254,7 @@ export default class NotificationHandler { await notificationSource.notificationTask.sendEndOfSignedSession(sourceData, user, tenant, NotificationSeverity.INFO); } } else { - await Logging.logDebug({ + Logging.beDebug()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'sendEndOfSignedSession', @@ -264,7 +264,7 @@ export default class NotificationHandler { }); } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.END_OF_SESSION, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.END_OF_SESSION, error); } } } @@ -285,7 +285,7 @@ export default class NotificationHandler { await notificationSource.notificationTask.sendRequestPassword( sourceData, user, tenant, NotificationSeverity.INFO); } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.REQUEST_PASSWORD, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.REQUEST_PASSWORD, error); } } } @@ -309,7 +309,7 @@ export default class NotificationHandler { sourceData, user, tenant, NotificationSeverity.WARNING); } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.USER_ACCOUNT_STATUS_CHANGED, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.USER_ACCOUNT_STATUS_CHANGED, error); } } } @@ -331,7 +331,7 @@ export default class NotificationHandler { await notificationSource.notificationTask.sendNewRegisteredUser( sourceData, user, tenant, NotificationSeverity.INFO); } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.NEW_REGISTERED_USER, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.NEW_REGISTERED_USER, error); } } } @@ -352,7 +352,7 @@ export default class NotificationHandler { await notificationSource.notificationTask.sendAccountVerificationNotification( sourceData, user, tenant, NotificationSeverity.INFO); } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.USER_ACCOUNT_VERIFICATION, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.USER_ACCOUNT_VERIFICATION, error); } } } @@ -388,7 +388,7 @@ export default class NotificationHandler { sourceData, adminUser, tenant, NotificationSeverity.INFO); } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.ADMIN_ACCOUNT_VERIFICATION, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.ADMIN_ACCOUNT_VERIFICATION, error); } } } @@ -417,7 +417,7 @@ export default class NotificationHandler { await notificationSource.notificationTask.sendVerificationEmail( sourceData, user, tenant, NotificationSeverity.INFO); } else { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'sendVerificationEmail', action: ServerAction.VERIFY_EMAIL, @@ -426,7 +426,7 @@ export default class NotificationHandler { }); } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.VERIFY_EMAIL, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.VERIFY_EMAIL, error); } } } @@ -450,7 +450,7 @@ export default class NotificationHandler { await notificationSource.notificationTask.sendVerificationEmailUserImport( sourceData, user, tenant, NotificationSeverity.INFO); } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.VERIFICATION_EMAIL_USER_IMPORT, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.VERIFICATION_EMAIL_USER_IMPORT, error); } } } @@ -490,7 +490,7 @@ export default class NotificationHandler { sourceData, adminUser, tenant, NotificationSeverity.ERROR); } } else { - await Logging.logDebug({ + Logging.beDebug()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'sendChargingStationStatusError', @@ -499,7 +499,7 @@ export default class NotificationHandler { }); } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.CHARGING_STATION_STATUS_ERROR, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.CHARGING_STATION_STATUS_ERROR, error); } } } @@ -527,7 +527,7 @@ export default class NotificationHandler { sourceData, adminUser, tenant, NotificationSeverity.WARNING); } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.CHARGING_STATION_REGISTERED, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.CHARGING_STATION_REGISTERED, error); } } } @@ -555,7 +555,7 @@ export default class NotificationHandler { sourceData, adminUser, tenant, NotificationSeverity.WARNING); } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.UNKNOWN_USER_BADGED, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.UNKNOWN_USER_BADGED, error); } } } @@ -593,7 +593,7 @@ export default class NotificationHandler { sourceData, user, tenant, NotificationSeverity.INFO); } } else { - await Logging.logDebug({ + Logging.beDebug()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'sendSessionStarted', @@ -603,7 +603,7 @@ export default class NotificationHandler { }); } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.TRANSACTION_STARTED, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.TRANSACTION_STARTED, error); } } } @@ -643,7 +643,7 @@ export default class NotificationHandler { } } } else { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'sendOCPIPatchChargingStationsStatusesError', action: ServerAction.PATCH_EVSE_STATUS_ERROR, @@ -651,7 +651,7 @@ export default class NotificationHandler { }); } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.PATCH_EVSE_STATUS_ERROR, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.PATCH_EVSE_STATUS_ERROR, error); } } } @@ -687,7 +687,7 @@ export default class NotificationHandler { } } } else { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'sendOICPPatchChargingStationsStatusesError', action: ServerAction.PATCH_EVSE_STATUS_ERROR, @@ -695,7 +695,7 @@ export default class NotificationHandler { }); } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.PATCH_EVSE_STATUS_ERROR, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.PATCH_EVSE_STATUS_ERROR, error); } } } @@ -731,7 +731,7 @@ export default class NotificationHandler { } } } else { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'sendOICPPatchChargingStationsError', action: ServerAction.PATCH_EVSE_ERROR, @@ -739,7 +739,7 @@ export default class NotificationHandler { }); } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.PATCH_EVSE_ERROR, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.PATCH_EVSE_ERROR, error); } } } @@ -766,7 +766,7 @@ export default class NotificationHandler { await notificationSource.notificationTask.sendUserAccountInactivity( sourceData, user, tenant, NotificationSeverity.INFO); } else { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'sendUserAccountInactivity', action: ServerAction.USER_ACCOUNT_INACTIVITY, @@ -775,7 +775,7 @@ export default class NotificationHandler { }); } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.USER_ACCOUNT_INACTIVITY, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.USER_ACCOUNT_INACTIVITY, error); } } } @@ -810,7 +810,7 @@ export default class NotificationHandler { await notificationSource.notificationTask.sendPreparingSessionNotStarted(sourceData, user, tenant, NotificationSeverity.INFO); } } else { - await Logging.logDebug({ + Logging.beDebug()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'sendPreparingSessionNotStarted', @@ -820,7 +820,7 @@ export default class NotificationHandler { }); } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.PREPARING_SESSION_NOT_STARTED, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.PREPARING_SESSION_NOT_STARTED, error); } } } @@ -855,7 +855,7 @@ export default class NotificationHandler { } } } else { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'sendOfflineChargingStations', action: ServerAction.OFFLINE_CHARGING_STATIONS, @@ -863,7 +863,7 @@ export default class NotificationHandler { }); } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OFFLINE_CHARGING_STATIONS, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OFFLINE_CHARGING_STATIONS, error); } } } @@ -898,7 +898,7 @@ export default class NotificationHandler { } } } else { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'sendBillingSynchronizationFailed', action: ServerAction.BILLING_USER_SYNCHRONIZATION_FAILED, @@ -906,7 +906,7 @@ export default class NotificationHandler { }); } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.BILLING_USER_SYNCHRONIZATION_FAILED, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.BILLING_USER_SYNCHRONIZATION_FAILED, error); } } } @@ -941,7 +941,7 @@ export default class NotificationHandler { } } } else { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'sendBillingInvoicesSynchronizationFailed', action: ServerAction.BILLING_INVOICE_SYNCHRONIZATION_FAILED, @@ -949,7 +949,7 @@ export default class NotificationHandler { }); } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.BILLING_USER_SYNCHRONIZATION_FAILED, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.BILLING_USER_SYNCHRONIZATION_FAILED, error); } } } @@ -984,7 +984,7 @@ export default class NotificationHandler { } } } else { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'sendBillingPeriodicOperationFailed', action: ServerAction.BILLING_PERFORM_OPERATIONS, @@ -992,7 +992,7 @@ export default class NotificationHandler { }); } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.BILLING_PERFORM_OPERATIONS, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.BILLING_PERFORM_OPERATIONS, error); } } } @@ -1027,7 +1027,7 @@ export default class NotificationHandler { } } } else { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: Constants.DEFAULT_TENANT_OBJECT.id, module: MODULE_NAME, method: 'sendCarsSynchronizationFailed', action: ServerAction.CAR_CATALOG_SYNCHRONIZATION_FAILED, @@ -1035,15 +1035,14 @@ export default class NotificationHandler { }); } } catch (error) { - await Logging.logActionExceptionMessage(Constants.DEFAULT_TENANT_ID, ServerAction.CAR_CATALOG_SYNCHRONIZATION_FAILED, error); + Logging.logActionExceptionMessage(Constants.DEFAULT_TENANT_ID, ServerAction.CAR_CATALOG_SYNCHRONIZATION_FAILED, error); } } } } } - public static async sendComputeAndApplyChargingProfilesFailed(tenant: Tenant, chargingStation: ChargingStation, - sourceData: ComputeAndApplyChargingProfilesFailedNotification): Promise { + public static async sendComputeAndApplyChargingProfilesFailed(tenant: Tenant, sourceData: ComputeAndApplyChargingProfilesFailedNotification): Promise { if (tenant.id !== Constants.DEFAULT_TENANT_ID) { // Enrich with admins const adminUsers = await NotificationHandler.getAdminUsers(tenant); @@ -1061,7 +1060,7 @@ export default class NotificationHandler { if (!hasBeenNotified) { // Save await NotificationHandler.saveNotification( - tenant, notificationSource.channel, null, ServerAction.COMPUTE_AND_APPLY_CHARGING_PROFILES_FAILED, { chargingStation: chargingStation }); + tenant, notificationSource.channel, null, ServerAction.COMPUTE_AND_APPLY_CHARGING_PROFILES_FAILED); // Send for (const adminUser of adminUsers) { // Enabled? @@ -1070,17 +1069,9 @@ export default class NotificationHandler { sourceData, adminUser, tenant, NotificationSeverity.ERROR); } } - } else { - await Logging.logDebug({ - ...LoggingHelper.getChargingStationProperties(chargingStation), - tenantID: tenant.id, - module: MODULE_NAME, method: 'sendComputeAndApplyChargingProfilesFailed', - action: ServerAction.COMPUTE_AND_APPLY_CHARGING_PROFILES_FAILED, - message: `Notification via '${notificationSource.channel}' has already been sent` - }); } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.COMPUTE_AND_APPLY_CHARGING_PROFILES_FAILED, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.COMPUTE_AND_APPLY_CHARGING_PROFILES_FAILED, error); } } } @@ -1114,7 +1105,7 @@ export default class NotificationHandler { } } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.END_USER_REPORT_ERROR, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.END_USER_REPORT_ERROR, error); } } } @@ -1146,7 +1137,7 @@ export default class NotificationHandler { await notificationSource.notificationTask.sendSessionNotStarted(sourceData, sourceData.user, tenant, NotificationSeverity.INFO); } } else { - await Logging.logDebug({ + Logging.beDebug()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'sendSessionNotStarted', @@ -1155,7 +1146,7 @@ export default class NotificationHandler { }); } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.SESSION_NOT_STARTED_AFTER_AUTHORIZE, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.SESSION_NOT_STARTED_AFTER_AUTHORIZE, error); } } } @@ -1185,7 +1176,7 @@ export default class NotificationHandler { } } } else { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'sendBillingNewInvoiceNotification', action: ServerAction.BILLING_NEW_INVOICE, @@ -1194,7 +1185,7 @@ export default class NotificationHandler { }); } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.BILLING_NEW_INVOICE, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.BILLING_NEW_INVOICE, error); } } } @@ -1216,7 +1207,7 @@ export default class NotificationHandler { await notificationSource.notificationTask.sendBillingAccountCreationLink( sourceData, user, tenant, NotificationSeverity.INFO); } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.BILLING_ACCOUNT_CREATE, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.BILLING_ACCOUNT_CREATE, error); } } } @@ -1238,7 +1229,7 @@ export default class NotificationHandler { await notificationSource.notificationTask.sendBillingAccountActivationNotification( sourceData, user, tenant, NotificationSeverity.INFO); } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.BILLING_ACCOUNT_ACTIVATE, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.BILLING_ACCOUNT_ACTIVATE, error); } } } @@ -1260,7 +1251,7 @@ export default class NotificationHandler { // Success if (extraParams.user) { // User - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, siteID: extraParams.chargingStation?.siteID, siteAreaID: extraParams.chargingStation?.siteAreaID, @@ -1273,7 +1264,7 @@ export default class NotificationHandler { }); } else { // Admin - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, siteID: extraParams.chargingStation?.siteID, siteAreaID: extraParams.chargingStation?.siteAreaID, diff --git a/src/notification/email/EMailNotificationTask.ts b/src/notification/email/EMailNotificationTask.ts index c7cc61d204..59005394a7 100644 --- a/src/notification/email/EMailNotificationTask.ts +++ b/src/notification/email/EMailNotificationTask.ts @@ -231,7 +231,7 @@ export default class EMailNotificationTask implements NotificationTask { // Email configuration sanity checks if (!this.smtpMainClientInstance) { // No suitable main SMTP server configuration found to send the email - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, siteID: data?.siteID, siteAreaID: data?.siteAreaID, @@ -257,7 +257,7 @@ export default class EMailNotificationTask implements NotificationTask { }); if (Utils.isDevelopmentEnv()) { // Do not send mail in Dev mode - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id ? tenant.id : Constants.DEFAULT_TENANT_ID, action: ServerAction.EMAIL_NOTIFICATION, module: MODULE_NAME, method: 'sendEmail', @@ -278,7 +278,7 @@ export default class EMailNotificationTask implements NotificationTask { // Send the message const messageSent: Message = await smtpClient.sendAsync(messageToSend); // Email sent successfully - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id ? tenant.id : Constants.DEFAULT_TENANT_ID, siteID: data?.siteID, siteAreaID: data?.siteAreaID, @@ -295,7 +295,7 @@ export default class EMailNotificationTask implements NotificationTask { } }); } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id ? tenant.id : Constants.DEFAULT_TENANT_ID, siteID: data?.siteID, siteAreaID: data?.siteAreaID, @@ -372,7 +372,7 @@ export default class EMailNotificationTask implements NotificationTask { html: emailContent.html, }; } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, ...LoggingHelper.getSourceDataProperties(sourceData), action: ServerAction.EMAIL_NOTIFICATION, diff --git a/src/notification/remote-push-notification/RemotePushNotificationTask.ts b/src/notification/remote-push-notification/RemotePushNotificationTask.ts index 992cce7b16..1b2a89a2fc 100644 --- a/src/notification/remote-push-notification/RemotePushNotificationTask.ts +++ b/src/notification/remote-push-notification/RemotePushNotificationTask.ts @@ -66,7 +66,7 @@ export default class RemotePushNotificationTask implements NotificationTask { } RemotePushNotificationTask.initialized = true; } catch (error) { - void Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.REMOTE_PUSH_NOTIFICATION, module: MODULE_NAME, method: 'constructor', @@ -491,17 +491,6 @@ export default class RemotePushNotificationTask implements NotificationTask { // Do it startTime = Logging.traceNotificationStart(); if (!user?.mobileData?.mobileToken) { - // await Logging.logDebug({ - // tenantID: tenant.id, - // siteID: data?.siteID, - // siteAreaID: data?.siteAreaID, - // companyID: data?.companyID, - // chargingStationID: data?.chargeBoxID, - // action: ServerAction.REMOTE_PUSH_NOTIFICATION, - // module: MODULE_NAME, method: 'sendRemotePushNotificationToUsers', - // message: `'${notificationType}': No mobile token found for this User`, - // actionOnUser: user.id, - // }); // Send nothing return Promise.resolve(); } @@ -528,7 +517,7 @@ export default class RemotePushNotificationTask implements NotificationTask { ); // Error if (response.failureCount > 0) { - Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, siteID: data?.siteID, siteAreaID: data?.siteAreaID, @@ -539,25 +528,14 @@ export default class RemotePushNotificationTask implements NotificationTask { message: `Notification: '${notificationType}' - Error code: '${response.results[0]?.error?.code}'`, actionOnUser: user.id, detailedMessages: { response, mobileData: user.mobileData } - }).catch((error) => Logging.logPromiseError(error)); + }); // Success } else { // Stop sending notification notificationSent = true; - // Logging.logDebug({ - // tenantID: tenant.id, - // siteID: data?.siteID, - // siteAreaID: data?.siteAreaID, - // companyID: data?.companyID, - // chargingStationID: data?.chargeBoxID, - // action: ServerAction.REMOTE_PUSH_NOTIFICATION, - // module: MODULE_NAME, method: 'sendRemotePushNotificationToUsers', - // message: `Notification Sent: '${notificationType}' - '${title}'`, - // actionOnUser: user.id, - // }).catch((error) => Logging.logPromiseError(error)); } } catch (error) { - Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, siteID: data?.siteID, siteAreaID: data?.siteAreaID, @@ -568,7 +546,7 @@ export default class RemotePushNotificationTask implements NotificationTask { message: `Notification: '${notificationType}' - '${error.message as string}'`, actionOnUser: user.id, detailedMessages: { error: error.stack } - }).catch((error2) => Logging.logPromiseError(error2)); + }); } } } finally { diff --git a/src/scheduler/SchedulerManager.ts b/src/scheduler/SchedulerManager.ts index a9510707a8..cb370074c1 100644 --- a/src/scheduler/SchedulerManager.ts +++ b/src/scheduler/SchedulerManager.ts @@ -42,7 +42,7 @@ export default class SchedulerManager { // Keep the conf SchedulerManager.schedulerConfig = schedulerConfig; // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.SCHEDULER, module: MODULE_NAME, method: 'init', @@ -52,7 +52,7 @@ export default class SchedulerManager { for (const task of SchedulerManager.schedulerConfig.tasks) { // Active? if (!task.active) { - await Logging.logWarning({ + Logging.beWarning()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.SCHEDULER, module: MODULE_NAME, method: 'init', @@ -64,7 +64,7 @@ export default class SchedulerManager { if (schedulerTask) { // Register task to cron engine cron.schedule(task.periodicity, () => SchedulerManager.runTask(schedulerTask, task)); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.SCHEDULER, module: MODULE_NAME, method: 'init', @@ -143,7 +143,7 @@ export default class SchedulerManager { case 'DispatchCollectedFundsTask': return new DispatchCollectedFundsTask(); default: - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.SCHEDULER, module: MODULE_NAME, method: 'createTask', diff --git a/src/scheduler/SchedulerTask.ts b/src/scheduler/SchedulerTask.ts index 8410143fd6..6ff7e3db8b 100644 --- a/src/scheduler/SchedulerTask.ts +++ b/src/scheduler/SchedulerTask.ts @@ -21,7 +21,7 @@ export default abstract class SchedulerTask { if (scheduledTaskLock) { try { const startTime = moment(); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.SCHEDULER, module: MODULE_NAME, method: 'run', @@ -35,7 +35,7 @@ export default abstract class SchedulerTask { // Hook await this.afterTaskRun(config); } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.SCHEDULER, module: MODULE_NAME, method: 'run', @@ -45,7 +45,7 @@ export default abstract class SchedulerTask { } // Log Total Processing Time const totalTimeSecs = moment.duration(moment().diff(startTime)).asSeconds(); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.SCHEDULER, module: MODULE_NAME, method: 'run', diff --git a/src/scheduler/TenantSchedulerTask.ts b/src/scheduler/TenantSchedulerTask.ts index ffee0dbd70..1a1f2014a8 100644 --- a/src/scheduler/TenantSchedulerTask.ts +++ b/src/scheduler/TenantSchedulerTask.ts @@ -23,7 +23,7 @@ export default abstract class TenantSchedulerTask extends SchedulerTask { (taskSettings.task.disableAllTasks || !Utils.isEmptyArray(taskSettings.task.disableTasksInEnv) && taskSettings.task.disableTasksInEnv.includes(currentTaskEnv))) { // Tasks are disabled for this environment isTaskExecutionDisabled = true; - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.SCHEDULER, module: MODULE_NAME, method: 'processTask', @@ -43,7 +43,7 @@ export default abstract class TenantSchedulerTask extends SchedulerTask { } // Check if tenant task needs to run on a specific environment if (tenant.taskExecutionEnv && tenant.taskExecutionEnv !== currentTaskEnv) { - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.SCHEDULER, module: MODULE_NAME, method: 'processTask', @@ -54,13 +54,13 @@ export default abstract class TenantSchedulerTask extends SchedulerTask { } const tenantCorrelationID = Utils.generateShortNonUniqueID(); const startTimeInTenant = moment(); - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.SCHEDULER, module: MODULE_NAME, method: 'processTask', message: `The Task '${this.getName()}~${this.getCorrelationID()}~${tenantCorrelationID}' is running for Tenant ${Utils.buildTenantName(tenant)}...` }); - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, action: ServerAction.SCHEDULER, module: MODULE_NAME, method: 'processTask', @@ -74,14 +74,14 @@ export default abstract class TenantSchedulerTask extends SchedulerTask { // Hook await this.afterProcessTenant(tenant, config); } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.SCHEDULER, module: MODULE_NAME, method: 'processTask', message: `Error while running the Task '${this.getName()}~${this.getCorrelationID()}~${tenantCorrelationID}' for Tenant ${Utils.buildTenantName(tenant)}: ${error.message as string}`, detailedMessages: { error: error.stack } }); - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: ServerAction.SCHEDULER, module: MODULE_NAME, method: 'processTask', @@ -91,13 +91,13 @@ export default abstract class TenantSchedulerTask extends SchedulerTask { } // Log Total Processing Time in Tenant const totalTimeSecsInTenant = moment.duration(moment().diff(startTimeInTenant)).asSeconds(); - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.SCHEDULER, module: MODULE_NAME, method: 'processTask', message: `The Task '${this.getName()}~${this.getCorrelationID()}~${tenantCorrelationID}' has been run successfully in ${totalTimeSecsInTenant} secs for Tenant ${Utils.buildTenantName(tenant)}` }); - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, action: ServerAction.SCHEDULER, module: MODULE_NAME, method: 'processTask', diff --git a/src/scheduler/tasks/AssetGetConsumptionTask.ts b/src/scheduler/tasks/AssetGetConsumptionTask.ts index 8344dae8d2..214d2e081b 100644 --- a/src/scheduler/tasks/AssetGetConsumptionTask.ts +++ b/src/scheduler/tasks/AssetGetConsumptionTask.ts @@ -89,7 +89,7 @@ export default class AssetGetConsumptionTask extends TenantSchedulerTask { } } catch (error) { // Log error - await Logging.logActionExceptionMessage(tenant.id, ServerAction.RETRIEVE_ASSET_CONSUMPTION, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.RETRIEVE_ASSET_CONSUMPTION, error); } finally { // Release the lock await LockingManager.release(assetLock); diff --git a/src/scheduler/tasks/BillingPeriodicOperationTask.ts b/src/scheduler/tasks/BillingPeriodicOperationTask.ts index 3910b3653e..0ddf82fc38 100644 --- a/src/scheduler/tasks/BillingPeriodicOperationTask.ts +++ b/src/scheduler/tasks/BillingPeriodicOperationTask.ts @@ -34,7 +34,7 @@ export default class BillingPeriodicOperationTask extends TenantSchedulerTask { } } catch (error) { // Log error - await Logging.logActionExceptionMessage(tenant.id, ServerAction.BILLING_PERFORM_OPERATIONS, error as Error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.BILLING_PERFORM_OPERATIONS, error as Error); } finally { // Release the lock await LockingManager.release(billingLock); diff --git a/src/scheduler/tasks/CheckAndComputeSmartChargingTask.ts b/src/scheduler/tasks/CheckAndComputeSmartChargingTask.ts index 8b7d4e92b9..37bfccf9d1 100644 --- a/src/scheduler/tasks/CheckAndComputeSmartChargingTask.ts +++ b/src/scheduler/tasks/CheckAndComputeSmartChargingTask.ts @@ -29,7 +29,7 @@ export default class CheckAndComputeSmartChargingTask extends TenantSchedulerTas const smartCharging = await SmartChargingFactory.getSmartChargingImpl(tenant); if (!smartCharging) { // Log - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processTenant', action: ServerAction.CHECK_AND_APPLY_SMART_CHARGING, @@ -40,7 +40,7 @@ export default class CheckAndComputeSmartChargingTask extends TenantSchedulerTas await smartCharging.computeAndApplyChargingProfiles(siteArea); } catch (error) { // Log error - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processTenant', action: ServerAction.CHECK_AND_APPLY_SMART_CHARGING, @@ -53,7 +53,7 @@ export default class CheckAndComputeSmartChargingTask extends TenantSchedulerTas } } } - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, module: MODULE_NAME, method: 'processTenant', action: ServerAction.CHECK_AND_APPLY_SMART_CHARGING, diff --git a/src/scheduler/tasks/CheckChargingStationTemplateTask.ts b/src/scheduler/tasks/CheckChargingStationTemplateTask.ts index a618d0877e..b5906eeeeb 100644 --- a/src/scheduler/tasks/CheckChargingStationTemplateTask.ts +++ b/src/scheduler/tasks/CheckChargingStationTemplateTask.ts @@ -22,7 +22,7 @@ export default class CheckChargingStationTemplateTask extends TenantSchedulerTas await this.applyTemplateToChargingStations(tenant); } catch (error) { // Log error - await Logging.logActionExceptionMessage(tenant.id, ServerAction.UPDATE_CHARGING_STATION_WITH_TEMPLATE, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.UPDATE_CHARGING_STATION_WITH_TEMPLATE, error); } finally { // Release the lock await LockingManager.release(checkChargingStationTemplateLock); @@ -62,7 +62,7 @@ export default class CheckChargingStationTemplateTask extends TenantSchedulerTas updated++; } } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.UPDATE_CHARGING_STATION_WITH_TEMPLATE, @@ -74,7 +74,7 @@ export default class CheckChargingStationTemplateTask extends TenantSchedulerTas } } if (updated > 0) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, action: ServerAction.UPDATE_CHARGING_STATION_WITH_TEMPLATE, module: MODULE_NAME, method: 'applyTemplateToChargingStations', diff --git a/src/scheduler/tasks/CheckOfflineChargingStationsTask.ts b/src/scheduler/tasks/CheckOfflineChargingStationsTask.ts index 68651c1551..27a47e7c9b 100644 --- a/src/scheduler/tasks/CheckOfflineChargingStationsTask.ts +++ b/src/scheduler/tasks/CheckOfflineChargingStationsTask.ts @@ -45,7 +45,7 @@ export default class CheckOfflineChargingStationsTask extends TenantSchedulerTas } // Charging Station is still connected: ignore it if (ocppHeartbeatConfiguration) { - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.OFFLINE_CHARGING_STATION, @@ -81,7 +81,7 @@ export default class CheckOfflineChargingStationsTask extends TenantSchedulerTas } } catch (error) { // Log error - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OFFLINE_CHARGING_STATION, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OFFLINE_CHARGING_STATION, error); } finally { // Release the lock await LockingManager.release(offlineChargingStationLock); diff --git a/src/scheduler/tasks/CheckPreparingSessionNotStartedTask.ts b/src/scheduler/tasks/CheckPreparingSessionNotStartedTask.ts index afbe7a6203..7fbfa3c80b 100644 --- a/src/scheduler/tasks/CheckPreparingSessionNotStartedTask.ts +++ b/src/scheduler/tasks/CheckPreparingSessionNotStartedTask.ts @@ -52,7 +52,7 @@ export default class CheckPreparingSessionNotStartedTask extends TenantScheduler } } catch (error) { // Log error - await Logging.logActionExceptionMessage(tenant.id, ServerAction.PREPARING_SESSION_NOT_STARTED, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.PREPARING_SESSION_NOT_STARTED, error); } finally { // Release the lock await LockingManager.release(sessionNotStartedLock); diff --git a/src/scheduler/tasks/CheckSessionNotStartedAfterAuthorizeTask.ts b/src/scheduler/tasks/CheckSessionNotStartedAfterAuthorizeTask.ts index 3260ce8b0c..56a22ff60d 100644 --- a/src/scheduler/tasks/CheckSessionNotStartedAfterAuthorizeTask.ts +++ b/src/scheduler/tasks/CheckSessionNotStartedAfterAuthorizeTask.ts @@ -39,7 +39,7 @@ export default class CheckSessionNotStartedAfterAuthorizeTask extends TenantSche } } catch (error) { // Log error - await Logging.logActionExceptionMessage(tenant.id, ServerAction.PREPARING_SESSION_NOT_STARTED, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.PREPARING_SESSION_NOT_STARTED, error); } finally { // Release the lock await LockingManager.release(sessionNotStartedLock); diff --git a/src/scheduler/tasks/CheckUserAccountInactivityTask.ts b/src/scheduler/tasks/CheckUserAccountInactivityTask.ts index 5456695b93..ce6876c95c 100644 --- a/src/scheduler/tasks/CheckUserAccountInactivityTask.ts +++ b/src/scheduler/tasks/CheckUserAccountInactivityTask.ts @@ -42,7 +42,7 @@ export default class CheckUserAccountInactivityTask extends TenantSchedulerTask } } catch (error) { // Log error - await Logging.logActionExceptionMessage(tenant.id, ServerAction.USER_ACCOUNT_INACTIVITY, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.USER_ACCOUNT_INACTIVITY, error); } finally { // Release the lock await LockingManager.release(accountInactivityLock); diff --git a/src/scheduler/tasks/CloseTransactionsInProgressTask.ts b/src/scheduler/tasks/CloseTransactionsInProgressTask.ts index 3e507392bf..dbab7a2e65 100644 --- a/src/scheduler/tasks/CloseTransactionsInProgressTask.ts +++ b/src/scheduler/tasks/CloseTransactionsInProgressTask.ts @@ -44,7 +44,7 @@ export default class CloseTransactionsInProgressTask extends TenantSchedulerTask // Soft stop transaction await ocppService.softStopTransaction(tenant, transaction, transaction.chargeBox, transaction.siteArea); result.inSuccess++; - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: tenant.id, actionOnUser: transaction.userID, @@ -57,7 +57,7 @@ export default class CloseTransactionsInProgressTask extends TenantSchedulerTask }); } catch (error) { result.inError++; - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: tenant.id, action: ServerAction.TRANSACTION_SOFT_STOP, @@ -79,7 +79,7 @@ export default class CloseTransactionsInProgressTask extends TenantSchedulerTask `No Transaction have been soft stopped in ${executionDurationSecs}s in Tenant ${Utils.buildTenantName(tenant)}` ); } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.TRANSACTION_SOFT_STOP, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.TRANSACTION_SOFT_STOP, error); } finally { // Release the lock await LockingManager.release(transactionsCloseLock); diff --git a/src/scheduler/tasks/DispatchCollectedFundsTask.ts b/src/scheduler/tasks/DispatchCollectedFundsTask.ts index c3c5006f2f..ed9a967c18 100644 --- a/src/scheduler/tasks/DispatchCollectedFundsTask.ts +++ b/src/scheduler/tasks/DispatchCollectedFundsTask.ts @@ -34,7 +34,7 @@ export default class DispatchCollectedFundsTask extends TenantSchedulerTask { } } catch (error) { // Log error - await Logging.logActionExceptionMessage(tenant.id, ServerAction.BILLING_TRANSFER_DISPATCH_FUNDS, error as Error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.BILLING_TRANSFER_DISPATCH_FUNDS, error as Error); } finally { // Release the lock await LockingManager.release(billingLock); diff --git a/src/scheduler/tasks/LoggingDatabaseTableCleanupTask.ts b/src/scheduler/tasks/LoggingDatabaseTableCleanupTask.ts index b4e5bd2022..a22598b055 100644 --- a/src/scheduler/tasks/LoggingDatabaseTableCleanupTask.ts +++ b/src/scheduler/tasks/LoggingDatabaseTableCleanupTask.ts @@ -47,14 +47,14 @@ export default class LoggingDatabaseTableCleanupTask extends TenantSchedulerTask // Delete const result = await LogStorage.deleteLogs(tenant, deleteUpToDate); if (result.acknowledged) { - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, action: ServerAction.LOGS_CLEANUP, module: MODULE_NAME, method: 'deleteLogs', message: `${result.deletedCount} Log(s) have been deleted before '${moment(deleteUpToDate).format('DD/MM/YYYY h:mm A')}'` }); } else { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: ServerAction.LOGS_CLEANUP, module: MODULE_NAME, method: 'deleteLogs', @@ -63,7 +63,7 @@ export default class LoggingDatabaseTableCleanupTask extends TenantSchedulerTask }); } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.LOGS_CLEANUP, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.LOGS_CLEANUP, error); } finally { await LockingManager.release(logsCleanUpLock); } @@ -90,14 +90,14 @@ export default class LoggingDatabaseTableCleanupTask extends TenantSchedulerTask // Delete Logs const result = await PerformanceStorage.deletePerformanceRecords({ deleteUpToDate }); if (result.acknowledged) { - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, action: ServerAction.PERFORMANCES_CLEANUP, module: MODULE_NAME, method: 'deletePerformanceRecords', message: `${result.deletedCount} Performance Record(s) have been deleted before '${moment(deleteUpToDate).format('DD/MM/YYYY h:mm A')}'` }); } else { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: ServerAction.PERFORMANCES_CLEANUP, module: MODULE_NAME, method: 'deletePerformanceRecords', @@ -106,7 +106,7 @@ export default class LoggingDatabaseTableCleanupTask extends TenantSchedulerTask }); } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.PERFORMANCES_CLEANUP, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.PERFORMANCES_CLEANUP, error); } finally { // Release the lock await LockingManager.release(performanceCleanUpLock); diff --git a/src/scheduler/tasks/SynchronizeCarsTask.ts b/src/scheduler/tasks/SynchronizeCarsTask.ts index a57c0b5ac8..df7a8ebce4 100644 --- a/src/scheduler/tasks/SynchronizeCarsTask.ts +++ b/src/scheduler/tasks/SynchronizeCarsTask.ts @@ -30,7 +30,7 @@ export default class SynchronizeCarsTask extends SchedulerTask { } } catch (error) { // Log error - await Logging.logActionExceptionMessage(Constants.DEFAULT_TENANT_ID, ServerAction.SYNCHRONIZE_CAR_CATALOGS, error); + Logging.logActionExceptionMessage(Constants.DEFAULT_TENANT_ID, ServerAction.SYNCHRONIZE_CAR_CATALOGS, error); } finally { // Release the lock await LockingManager.release(syncCarCatalogLock); diff --git a/src/scheduler/tasks/SynchronizeRefundTransactionsTask.ts b/src/scheduler/tasks/SynchronizeRefundTransactionsTask.ts index 98e49ed8ab..7847be165b 100644 --- a/src/scheduler/tasks/SynchronizeRefundTransactionsTask.ts +++ b/src/scheduler/tasks/SynchronizeRefundTransactionsTask.ts @@ -17,7 +17,7 @@ const MODULE_NAME = 'SynchronizeRefundTransactionsTask'; export default class SynchronizeRefundTransactionsTask extends TenantSchedulerTask { public async processTenant(tenant: Tenant, config: TaskConfig): Promise { if (!Utils.isTenantComponentActive(tenant, TenantComponents.REFUND)) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, action: ServerAction.SYNCHRONIZE_REFUND, module: MODULE_NAME, method: 'run', @@ -28,7 +28,7 @@ export default class SynchronizeRefundTransactionsTask extends TenantSchedulerTa // Get Concur Settings const refundConnector = await RefundFactory.getRefundImpl(tenant); if (!refundConnector) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, action: ServerAction.SYNCHRONIZE_REFUND, module: MODULE_NAME, method: 'run', @@ -46,7 +46,7 @@ export default class SynchronizeRefundTransactionsTask extends TenantSchedulerTa { ...Constants.DB_PARAMS_MAX_LIMIT, sort: { 'userID': 1, 'refundData.reportId': 1 } }); if (!Utils.isEmptyArray(transactions.result)) { // Process them - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, action: ServerAction.SYNCHRONIZE_REFUND, module: MODULE_NAME, method: 'processTenant', @@ -74,11 +74,11 @@ export default class SynchronizeRefundTransactionsTask extends TenantSchedulerTa } } catch (error) { actionsDone.error++; - await Logging.logActionExceptionMessage(tenant.id, ServerAction.SYNCHRONIZE_REFUND, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.SYNCHRONIZE_REFUND, error); } } // Log result - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, action: ServerAction.SYNCHRONIZE_REFUND, module: MODULE_NAME, method: 'processTenant', @@ -86,7 +86,7 @@ export default class SynchronizeRefundTransactionsTask extends TenantSchedulerTa }); } else { // Process them - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, action: ServerAction.SYNCHRONIZE_REFUND, module: MODULE_NAME, method: 'processTenant', @@ -95,7 +95,7 @@ export default class SynchronizeRefundTransactionsTask extends TenantSchedulerTa } } catch (error) { // Log error - await Logging.logActionExceptionMessage(tenant.id, ServerAction.SYNCHRONIZE_REFUND, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.SYNCHRONIZE_REFUND, error); } finally { // Release the lock await LockingManager.release(refundLock); diff --git a/src/scheduler/tasks/ocpi/OCPICheckCdrsTask.ts b/src/scheduler/tasks/ocpi/OCPICheckCdrsTask.ts index 76027bc2eb..dae33530e9 100644 --- a/src/scheduler/tasks/ocpi/OCPICheckCdrsTask.ts +++ b/src/scheduler/tasks/ocpi/OCPICheckCdrsTask.ts @@ -29,7 +29,7 @@ export default class OCPICheckCdrsTask extends TenantSchedulerTask { } } catch (error) { // Log error - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_CHECK_CDRS, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_CHECK_CDRS, error); } } @@ -40,7 +40,7 @@ export default class OCPICheckCdrsTask extends TenantSchedulerTask { try { // Check if OCPI endpoint is registered if (ocpiEndpoint.status !== OCPIRegistrationStatus.REGISTERED) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOCPIEndpoint', action: ServerAction.OCPI_CPO_CHECK_CDRS, @@ -49,7 +49,7 @@ export default class OCPICheckCdrsTask extends TenantSchedulerTask { return; } if (!ocpiEndpoint.backgroundPatchJob) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOCPIEndpoint', action: ServerAction.OCPI_CPO_CHECK_CDRS, @@ -57,7 +57,7 @@ export default class OCPICheckCdrsTask extends TenantSchedulerTask { }); return; } - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOCPIEndpoint', action: ServerAction.OCPI_CPO_CHECK_CDRS, @@ -67,7 +67,7 @@ export default class OCPICheckCdrsTask extends TenantSchedulerTask { const ocpiClient = await OCPIClientFactory.getCpoOcpiClient(tenant, ocpiEndpoint); // Check CDRs const result = await ocpiClient.checkCdrs(); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOCPIEndpoint', action: ServerAction.OCPI_CPO_CHECK_CDRS, @@ -75,7 +75,7 @@ export default class OCPICheckCdrsTask extends TenantSchedulerTask { detailedMessages: { result } }); } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_CHECK_CDRS, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_CHECK_CDRS, error); } finally { await LockingManager.release(ocpiLock); } diff --git a/src/scheduler/tasks/ocpi/OCPICheckLocationsTask.ts b/src/scheduler/tasks/ocpi/OCPICheckLocationsTask.ts index f9f97eb453..bf30916b88 100644 --- a/src/scheduler/tasks/ocpi/OCPICheckLocationsTask.ts +++ b/src/scheduler/tasks/ocpi/OCPICheckLocationsTask.ts @@ -29,7 +29,7 @@ export default class OCPICheckLocationsTask extends TenantSchedulerTask { } } catch (error) { // Log error - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_CHECK_SESSIONS, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_CHECK_SESSIONS, error); } } @@ -40,7 +40,7 @@ export default class OCPICheckLocationsTask extends TenantSchedulerTask { try { // Check if OCPI endpoint is registered if (ocpiEndpoint.status !== OCPIRegistrationStatus.REGISTERED) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOCPIEndpoint', action: ServerAction.OCPI_CPO_CHECK_SESSIONS, @@ -49,7 +49,7 @@ export default class OCPICheckLocationsTask extends TenantSchedulerTask { return; } if (!ocpiEndpoint.backgroundPatchJob) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOCPIEndpoint', action: ServerAction.OCPI_CPO_CHECK_SESSIONS, @@ -57,7 +57,7 @@ export default class OCPICheckLocationsTask extends TenantSchedulerTask { }); return; } - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOCPIEndpoint', action: ServerAction.OCPI_CPO_CHECK_SESSIONS, @@ -67,7 +67,7 @@ export default class OCPICheckLocationsTask extends TenantSchedulerTask { const ocpiClient = await OCPIClientFactory.getCpoOcpiClient(tenant, ocpiEndpoint); // Check Locations const result = await ocpiClient.checkLocations(); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOCPIEndpoint', action: ServerAction.OCPI_CPO_CHECK_SESSIONS, @@ -75,7 +75,7 @@ export default class OCPICheckLocationsTask extends TenantSchedulerTask { detailedMessages: { result } }); } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_CHECK_LOCATIONS, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_CHECK_LOCATIONS, error); } finally { await LockingManager.release(ocpiLock); } diff --git a/src/scheduler/tasks/ocpi/OCPICheckSessionsTask.ts b/src/scheduler/tasks/ocpi/OCPICheckSessionsTask.ts index 1cc32f4389..944ef33f63 100644 --- a/src/scheduler/tasks/ocpi/OCPICheckSessionsTask.ts +++ b/src/scheduler/tasks/ocpi/OCPICheckSessionsTask.ts @@ -29,7 +29,7 @@ export default class OCPICheckSessionsTask extends TenantSchedulerTask { } } catch (error) { // Log error - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_CHECK_SESSIONS, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_CHECK_SESSIONS, error); } } @@ -40,7 +40,7 @@ export default class OCPICheckSessionsTask extends TenantSchedulerTask { try { // Check if OCPI endpoint is registered if (ocpiEndpoint.status !== OCPIRegistrationStatus.REGISTERED) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOCPIEndpoint', action: ServerAction.OCPI_CPO_CHECK_SESSIONS, @@ -49,7 +49,7 @@ export default class OCPICheckSessionsTask extends TenantSchedulerTask { return; } if (!ocpiEndpoint.backgroundPatchJob) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOCPIEndpoint', action: ServerAction.OCPI_CPO_CHECK_SESSIONS, @@ -57,7 +57,7 @@ export default class OCPICheckSessionsTask extends TenantSchedulerTask { }); return; } - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOCPIEndpoint', action: ServerAction.OCPI_CPO_CHECK_SESSIONS, @@ -67,7 +67,7 @@ export default class OCPICheckSessionsTask extends TenantSchedulerTask { const ocpiClient = await OCPIClientFactory.getCpoOcpiClient(tenant, ocpiEndpoint); // Check Sessions const result = await ocpiClient.checkSessions(); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOCPIEndpoint', action: ServerAction.OCPI_CPO_CHECK_SESSIONS, @@ -75,7 +75,7 @@ export default class OCPICheckSessionsTask extends TenantSchedulerTask { detailedMessages: { result } }); } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_CHECK_SESSIONS, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_CHECK_SESSIONS, error); } finally { await LockingManager.release(ocpiLock); } diff --git a/src/scheduler/tasks/ocpi/OCPIPullCdrsTask.ts b/src/scheduler/tasks/ocpi/OCPIPullCdrsTask.ts index 26aafb2278..a8cacb6987 100644 --- a/src/scheduler/tasks/ocpi/OCPIPullCdrsTask.ts +++ b/src/scheduler/tasks/ocpi/OCPIPullCdrsTask.ts @@ -29,7 +29,7 @@ export default class OCPIPullCdrsTask extends TenantSchedulerTask { } } catch (error) { // Log error - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_EMSP_GET_CDRS, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_EMSP_GET_CDRS, error); } } @@ -41,7 +41,7 @@ export default class OCPIPullCdrsTask extends TenantSchedulerTask { try { // Check if OCPI endpoint is registered if (ocpiEndpoint.status !== OCPIRegistrationStatus.REGISTERED) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, action: ServerAction.OCPI_EMSP_GET_CDRS, module: MODULE_NAME, method: 'processOCPIEndpoint', @@ -50,7 +50,7 @@ export default class OCPIPullCdrsTask extends TenantSchedulerTask { return; } if (!ocpiEndpoint.backgroundPatchJob) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, action: ServerAction.OCPI_EMSP_GET_CDRS, module: MODULE_NAME, method: 'processOCPIEndpoint', @@ -58,7 +58,7 @@ export default class OCPIPullCdrsTask extends TenantSchedulerTask { }); return; } - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, action: ServerAction.OCPI_EMSP_GET_CDRS, module: MODULE_NAME, method: 'processOCPIEndpointatch', @@ -68,7 +68,7 @@ export default class OCPIPullCdrsTask extends TenantSchedulerTask { const ocpiClient = await OCPIClientFactory.getEmspOcpiClient(tenant, ocpiEndpoint); // Pull CDRs const result = await ocpiClient.pullCdrs(true); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, action: ServerAction.OCPI_EMSP_GET_CDRS, module: MODULE_NAME, method: 'processOCPIEndpoint', @@ -76,7 +76,7 @@ export default class OCPIPullCdrsTask extends TenantSchedulerTask { detailedMessages: { result } }); } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_EMSP_GET_CDRS, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_EMSP_GET_CDRS, error); } finally { await LockingManager.release(ocpiLock); } diff --git a/src/scheduler/tasks/ocpi/OCPIPullLocationsTask.ts b/src/scheduler/tasks/ocpi/OCPIPullLocationsTask.ts index fad3084a51..72ef8cb1ab 100644 --- a/src/scheduler/tasks/ocpi/OCPIPullLocationsTask.ts +++ b/src/scheduler/tasks/ocpi/OCPIPullLocationsTask.ts @@ -29,7 +29,7 @@ export default class OCPIPullLocationsTask extends TenantSchedulerTask { } } catch (error) { // Log error - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_EMSP_GET_LOCATIONS, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_EMSP_GET_LOCATIONS, error); } } @@ -40,7 +40,7 @@ export default class OCPIPullLocationsTask extends TenantSchedulerTask { try { // Check if OCPI endpoint is registered if (ocpiEndpoint.status !== OCPIRegistrationStatus.REGISTERED) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, action: ServerAction.OCPI_EMSP_GET_LOCATIONS, module: MODULE_NAME, method: 'processOCPIEndpoint', @@ -49,7 +49,7 @@ export default class OCPIPullLocationsTask extends TenantSchedulerTask { return; } if (!ocpiEndpoint.backgroundPatchJob) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, action: ServerAction.OCPI_EMSP_GET_LOCATIONS, module: MODULE_NAME, method: 'processOCPIEndpoint', @@ -57,7 +57,7 @@ export default class OCPIPullLocationsTask extends TenantSchedulerTask { }); return; } - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, action: ServerAction.OCPI_EMSP_GET_LOCATIONS, module: MODULE_NAME, method: 'processOCPIEndpoint', @@ -67,7 +67,7 @@ export default class OCPIPullLocationsTask extends TenantSchedulerTask { const ocpiClient = await OCPIClientFactory.getEmspOcpiClient(tenant, ocpiEndpoint); // Pull Locations const result = await ocpiClient.pullLocations(config.partial); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, action: ServerAction.OCPI_EMSP_GET_LOCATIONS, module: MODULE_NAME, method: 'processOCPIEndpoint', @@ -75,7 +75,7 @@ export default class OCPIPullLocationsTask extends TenantSchedulerTask { detailedMessages: { result } }); } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_EMSP_GET_LOCATIONS, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_EMSP_GET_LOCATIONS, error); } finally { await LockingManager.release(ocpiLock); } diff --git a/src/scheduler/tasks/ocpi/OCPIPullSessionsTask.ts b/src/scheduler/tasks/ocpi/OCPIPullSessionsTask.ts index d0e1ddfaa9..03c7772858 100644 --- a/src/scheduler/tasks/ocpi/OCPIPullSessionsTask.ts +++ b/src/scheduler/tasks/ocpi/OCPIPullSessionsTask.ts @@ -29,7 +29,7 @@ export default class OCPIPullSessionsTask extends TenantSchedulerTask { } } catch (error) { // Log error - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_EMSP_GET_SESSION, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_EMSP_GET_SESSION, error); } } @@ -40,7 +40,7 @@ export default class OCPIPullSessionsTask extends TenantSchedulerTask { try { // Check if OCPI endpoint is registered if (ocpiEndpoint.status !== OCPIRegistrationStatus.REGISTERED) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOCPIEndpoint', action: ServerAction.OCPI_EMSP_GET_SESSION, @@ -49,7 +49,7 @@ export default class OCPIPullSessionsTask extends TenantSchedulerTask { return; } if (!ocpiEndpoint.backgroundPatchJob) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOCPIEndpoint', action: ServerAction.OCPI_EMSP_GET_SESSION, @@ -57,7 +57,7 @@ export default class OCPIPullSessionsTask extends TenantSchedulerTask { }); return; } - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOCPIEndpoint', action: ServerAction.OCPI_EMSP_GET_SESSION, @@ -67,7 +67,7 @@ export default class OCPIPullSessionsTask extends TenantSchedulerTask { const ocpiClient = await OCPIClientFactory.getEmspOcpiClient(tenant, ocpiEndpoint); // Pull Sessions const result = await ocpiClient.pullSessions(true); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOCPIEndpoint', action: ServerAction.OCPI_EMSP_GET_SESSION, @@ -75,7 +75,7 @@ export default class OCPIPullSessionsTask extends TenantSchedulerTask { detailedMessages: { result } }); } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_EMSP_GET_SESSION, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_EMSP_GET_SESSION, error); } finally { await LockingManager.release(ocpiLock); } diff --git a/src/scheduler/tasks/ocpi/OCPIPullTokensTask.ts b/src/scheduler/tasks/ocpi/OCPIPullTokensTask.ts index a453172eee..04076b174e 100644 --- a/src/scheduler/tasks/ocpi/OCPIPullTokensTask.ts +++ b/src/scheduler/tasks/ocpi/OCPIPullTokensTask.ts @@ -29,7 +29,7 @@ export default class OCPIPullTokensTask extends TenantSchedulerTask { } } catch (error) { // Log error - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_GET_TOKENS, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_GET_TOKENS, error); } } @@ -40,7 +40,7 @@ export default class OCPIPullTokensTask extends TenantSchedulerTask { try { // Check if OCPI endpoint is registered if (ocpiEndpoint.status !== OCPIRegistrationStatus.REGISTERED) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOCPIEndpoint', action: ServerAction.OCPI_CPO_GET_TOKENS, @@ -49,7 +49,7 @@ export default class OCPIPullTokensTask extends TenantSchedulerTask { return; } if (!ocpiEndpoint.backgroundPatchJob) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOCPIEndpoint', action: ServerAction.OCPI_CPO_GET_TOKENS, @@ -57,7 +57,7 @@ export default class OCPIPullTokensTask extends TenantSchedulerTask { }); return; } - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOCPIEndpoint', action: ServerAction.OCPI_CPO_GET_TOKENS, @@ -67,7 +67,7 @@ export default class OCPIPullTokensTask extends TenantSchedulerTask { const ocpiClient = await OCPIClientFactory.getCpoOcpiClient(tenant, ocpiEndpoint); // Pull Tokens const result = await ocpiClient.pullTokens(config.partial); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOCPIEndpoint', action: ServerAction.OCPI_CPO_GET_TOKENS, @@ -75,7 +75,7 @@ export default class OCPIPullTokensTask extends TenantSchedulerTask { detailedMessages: { result } }); } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_GET_TOKENS, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_GET_TOKENS, error); } finally { await LockingManager.release(ocpiLock); } diff --git a/src/scheduler/tasks/ocpi/OCPIPushCdrsTask.ts b/src/scheduler/tasks/ocpi/OCPIPushCdrsTask.ts index 92e1c95a8b..214354068f 100644 --- a/src/scheduler/tasks/ocpi/OCPIPushCdrsTask.ts +++ b/src/scheduler/tasks/ocpi/OCPIPushCdrsTask.ts @@ -46,7 +46,7 @@ export default class OCPIPushCdrsTask extends TenantSchedulerTask { } ]).toArray(); if (!Utils.isEmptyArray(transactionsMDB)) { - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, action: ServerAction.OCPI_CPO_PUSH_CDRS, module: MODULE_NAME, method: 'processTenant', @@ -60,7 +60,7 @@ export default class OCPIPushCdrsTask extends TenantSchedulerTask { // Get Transaction const transaction = await TransactionStorage.getTransaction(tenant, transactionMDB._id, { withUser: true }); if (!transaction) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: ServerAction.OCPI_CPO_PUSH_CDRS, module: MODULE_NAME, method: 'processTenant', @@ -69,7 +69,7 @@ export default class OCPIPushCdrsTask extends TenantSchedulerTask { continue; } if (transaction.ocpiData?.cdr) { - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, action: ServerAction.OCPI_CPO_PUSH_CDRS, module: MODULE_NAME, method: 'processTenant', @@ -80,7 +80,7 @@ export default class OCPIPushCdrsTask extends TenantSchedulerTask { // Get Charging Station const chargingStation = await ChargingStationStorage.getChargingStation(tenant, transaction.chargeBoxID, { withSiteArea: true }); if (!chargingStation) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: ServerAction.OCPI_CPO_PUSH_CDRS, module: MODULE_NAME, method: 'processTenant', @@ -91,7 +91,7 @@ export default class OCPIPushCdrsTask extends TenantSchedulerTask { // Get Tag const tag = await TagStorage.getTag(tenant, transaction.tagID); if (!tag) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: ServerAction.OCPI_CPO_PUSH_CDRS, module: MODULE_NAME, method: 'processTenant', @@ -103,7 +103,7 @@ export default class OCPIPushCdrsTask extends TenantSchedulerTask { await OCPIFacade.processEndTransaction(tenant, transaction, chargingStation, chargingStation.siteArea, transaction.user, ServerAction.OCPI_CPO_PUSH_CDRS); // Save await TransactionStorage.saveTransactionOcpiData(tenant, transaction.id, transaction.ocpiData); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, action: ServerAction.OCPI_CPO_PUSH_CDRS, actionOnUser: (transaction.user ? transaction.user : null), @@ -112,7 +112,7 @@ export default class OCPIPushCdrsTask extends TenantSchedulerTask { detailedMessages: { cdr: transaction.ocpiData.cdr } }); } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: ServerAction.OCPI_CPO_PUSH_CDRS, module: MODULE_NAME, method: 'processTenant', @@ -131,7 +131,7 @@ export default class OCPIPushCdrsTask extends TenantSchedulerTask { } } } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_PUSH_CDRS, error as Error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_PUSH_CDRS, error as Error); } } } diff --git a/src/scheduler/tasks/ocpi/OCPIPushEVSEStatusesTask.ts b/src/scheduler/tasks/ocpi/OCPIPushEVSEStatusesTask.ts index 6e8fb59dc3..3b2183b1d2 100644 --- a/src/scheduler/tasks/ocpi/OCPIPushEVSEStatusesTask.ts +++ b/src/scheduler/tasks/ocpi/OCPIPushEVSEStatusesTask.ts @@ -29,7 +29,7 @@ export default class OCPIPushEVSEStatusesTask extends TenantSchedulerTask { } } catch (error) { // Log error - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_PUSH_EVSE_STATUSES, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_PUSH_EVSE_STATUSES, error); } } @@ -40,7 +40,7 @@ export default class OCPIPushEVSEStatusesTask extends TenantSchedulerTask { try { // Check if OCPI endpoint is registered if (ocpiEndpoint.status !== OCPIRegistrationStatus.REGISTERED) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOCPIEndpoint', action: ServerAction.OCPI_CPO_PUSH_EVSE_STATUSES, @@ -49,7 +49,7 @@ export default class OCPIPushEVSEStatusesTask extends TenantSchedulerTask { return; } if (!ocpiEndpoint.backgroundPatchJob) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOCPIEndpoint', action: ServerAction.OCPI_CPO_PUSH_EVSE_STATUSES, @@ -57,7 +57,7 @@ export default class OCPIPushEVSEStatusesTask extends TenantSchedulerTask { }); return; } - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOCPIEndpoint', action: ServerAction.OCPI_CPO_PUSH_EVSE_STATUSES, @@ -67,14 +67,14 @@ export default class OCPIPushEVSEStatusesTask extends TenantSchedulerTask { const ocpiClient = await OCPIClientFactory.getCpoOcpiClient(tenant, ocpiEndpoint); // Push EVSE statuses const sendResult = await ocpiClient.pushChargingStationStatuses(config.partial); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOCPIEndpoint', action: ServerAction.OCPI_CPO_PUSH_EVSE_STATUSES, message: `Push of Locations process for endpoint '${ocpiEndpoint.name}' is completed (Success: ${sendResult.success} / Failure: ${sendResult.failure})` }); } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_PUSH_EVSE_STATUSES, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_CPO_PUSH_EVSE_STATUSES, error); } finally { await LockingManager.release(ocpiLock); } diff --git a/src/scheduler/tasks/ocpi/OCPIPushTokensTask.ts b/src/scheduler/tasks/ocpi/OCPIPushTokensTask.ts index 54a864ebaa..d4b2f1f2b9 100644 --- a/src/scheduler/tasks/ocpi/OCPIPushTokensTask.ts +++ b/src/scheduler/tasks/ocpi/OCPIPushTokensTask.ts @@ -29,7 +29,7 @@ export default class OCPIPushTokensTask extends TenantSchedulerTask { } } catch (error) { // Log error - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_EMSP_UPDATE_TOKENS, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_EMSP_UPDATE_TOKENS, error); } } @@ -40,7 +40,7 @@ export default class OCPIPushTokensTask extends TenantSchedulerTask { try { // Check if OCPI endpoint is registered if (ocpiEndpoint.status !== OCPIRegistrationStatus.REGISTERED) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, action: ServerAction.OCPI_EMSP_UPDATE_TOKENS, module: MODULE_NAME, method: 'processOCPIEndpoint', @@ -49,7 +49,7 @@ export default class OCPIPushTokensTask extends TenantSchedulerTask { return; } if (!ocpiEndpoint.backgroundPatchJob) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, action: ServerAction.OCPI_EMSP_UPDATE_TOKENS, module: MODULE_NAME, method: 'processOCPIEndpoint', @@ -57,7 +57,7 @@ export default class OCPIPushTokensTask extends TenantSchedulerTask { }); return; } - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, action: ServerAction.OCPI_EMSP_UPDATE_TOKENS, module: MODULE_NAME, method: 'processOCPIEndpoint', @@ -67,7 +67,7 @@ export default class OCPIPushTokensTask extends TenantSchedulerTask { const ocpiClient = await OCPIClientFactory.getEmspOcpiClient(tenant, ocpiEndpoint); // Push Tokens const result = await ocpiClient.pushTokens(config.partial); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, action: ServerAction.OCPI_EMSP_UPDATE_TOKENS, module: MODULE_NAME, method: 'processOCPIEndpoint', @@ -75,7 +75,7 @@ export default class OCPIPushTokensTask extends TenantSchedulerTask { detailedMessages: { result } }); } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_EMSP_UPDATE_TOKENS, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OCPI_EMSP_UPDATE_TOKENS, error); } finally { await LockingManager.release(ocpiLock); } diff --git a/src/scheduler/tasks/oicp/OICPPushEvseDataTask.ts b/src/scheduler/tasks/oicp/OICPPushEvseDataTask.ts index 0ebec59080..15b9a21932 100644 --- a/src/scheduler/tasks/oicp/OICPPushEvseDataTask.ts +++ b/src/scheduler/tasks/oicp/OICPPushEvseDataTask.ts @@ -29,7 +29,7 @@ export default class OICPPushEvseDataTask extends TenantSchedulerTask { } } catch (error) { // Log error - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OICP_PUSH_EVSE_DATA, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OICP_PUSH_EVSE_DATA, error); } } @@ -40,7 +40,7 @@ export default class OICPPushEvseDataTask extends TenantSchedulerTask { try { // Check if OICP endpoint is registered if (oicpEndpoint.status !== OICPRegistrationStatus.REGISTERED) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOICPEndpoint', action: ServerAction.OICP_PUSH_EVSE_DATA, @@ -49,7 +49,7 @@ export default class OICPPushEvseDataTask extends TenantSchedulerTask { return; } if (!oicpEndpoint.backgroundPatchJob) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOICPEndpoint', action: ServerAction.OICP_PUSH_EVSE_DATA, @@ -57,7 +57,7 @@ export default class OICPPushEvseDataTask extends TenantSchedulerTask { }); return; } - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOICPEndpoint', action: ServerAction.OICP_PUSH_EVSE_DATA, @@ -67,7 +67,7 @@ export default class OICPPushEvseDataTask extends TenantSchedulerTask { const oicpClient = await OICPClientFactory.getCpoOicpClient(tenant, oicpEndpoint); // Send EVSEs const sendEVSEDataResult = await oicpClient.sendEVSEs(!Utils.isUndefined(config.partial) ? config.partial : false); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOICPEndpoint', action: ServerAction.OICP_PUSH_EVSE_DATA, @@ -75,7 +75,7 @@ export default class OICPPushEvseDataTask extends TenantSchedulerTask { }); } catch (error) { // Log error - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OICP_PUSH_EVSE_DATA, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OICP_PUSH_EVSE_DATA, error); } finally { // Release the lock await LockingManager.release(oicpLock); diff --git a/src/scheduler/tasks/oicp/OICPPushEvseStatusTask.ts b/src/scheduler/tasks/oicp/OICPPushEvseStatusTask.ts index b118cad2a4..90b698fd48 100644 --- a/src/scheduler/tasks/oicp/OICPPushEvseStatusTask.ts +++ b/src/scheduler/tasks/oicp/OICPPushEvseStatusTask.ts @@ -29,7 +29,7 @@ export default class OICPPushEvseStatusTask extends TenantSchedulerTask { } } catch (error) { // Log error - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OICP_PUSH_EVSE_STATUSES, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OICP_PUSH_EVSE_STATUSES, error); } } @@ -40,7 +40,7 @@ export default class OICPPushEvseStatusTask extends TenantSchedulerTask { try { // Check if OICP endpoint is registered if (oicpEndpoint.status !== OICPRegistrationStatus.REGISTERED) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOICPEndpoint', action: ServerAction.OICP_PUSH_EVSE_STATUSES, @@ -49,7 +49,7 @@ export default class OICPPushEvseStatusTask extends TenantSchedulerTask { return; } if (!oicpEndpoint.backgroundPatchJob) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOICPEndpoint', action: ServerAction.OICP_PUSH_EVSE_STATUSES, @@ -57,7 +57,7 @@ export default class OICPPushEvseStatusTask extends TenantSchedulerTask { }); return; } - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOICPEndpoint', action: ServerAction.OICP_PUSH_EVSE_STATUSES, @@ -67,7 +67,7 @@ export default class OICPPushEvseStatusTask extends TenantSchedulerTask { const oicpClient = await OICPClientFactory.getCpoOicpClient(tenant, oicpEndpoint); // Send EVSE statuses const sendEVSEStatusResult = await oicpClient.sendEVSEStatuses(config.partial); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'processOICPEndpoint', action: ServerAction.OICP_PUSH_EVSE_STATUSES, @@ -75,7 +75,7 @@ export default class OICPPushEvseStatusTask extends TenantSchedulerTask { }); } catch (error) { // Log error - await Logging.logActionExceptionMessage(tenant.id, ServerAction.OICP_PUSH_EVSE_STATUSES, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.OICP_PUSH_EVSE_STATUSES, error); } finally { // Release the lock await LockingManager.release(oicpLock); diff --git a/src/server/ExpressUtils.ts b/src/server/ExpressUtils.ts index 09bd913c4a..3ea9cf3d11 100644 --- a/src/server/ExpressUtils.ts +++ b/src/server/ExpressUtils.ts @@ -1,3 +1,4 @@ +import FeatureToggles, { Feature } from '../utils/FeatureToggles'; import express, { Application, NextFunction, Request, Response } from 'express'; import Constants from '../utils/Constants'; @@ -51,7 +52,7 @@ export default class ExpressUtils { limit: bodyLimit })); // Health Check Handling - app.get(Constants.HEALTH_CHECK_ROUTE, ExpressUtils.healthCheckService.bind(this)); + app.get(Constants.HEALTH_CHECK_ROUTE, (req: Request, res: Response, next: NextFunction) => ExpressUtils.healthCheckService(req, res, next)); // Use app.use(locale(Constants.SUPPORTED_LOCALES)); return app; @@ -62,14 +63,19 @@ export default class ExpressUtils { expressApplication.use(Logging.traceExpressError.bind(this)); } + // eslint-disable-next-line @typescript-eslint/no-unused-vars private static healthCheckService(req: Request, res: Response, next: NextFunction): void { - // TODO - Find another metric to check the health - res.sendStatus(StatusCodes.OK); - // const pingSuccess = await global.database.ping(); - // if (pingSuccess) { - // res.sendStatus(StatusCodes.OK); - // } else { - // res.sendStatus(StatusCodes.INTERNAL_SERVER_ERROR); - // } + if (FeatureToggles.isFeatureActive(Feature.HEALTH_CHECK_PING_DATABASE)) { + global.database.ping().then((pingSuccess) => { + if (pingSuccess) { + res.sendStatus(StatusCodes.OK); + } else { + res.sendStatus(StatusCodes.INTERNAL_SERVER_ERROR); + } + }).catch(() => { /* Intentional */ }); + } else { + // TODO - FIND ANOTHER METRIC TO CHECK THE READINESS and LIVENESS PROBE + res.sendStatus(StatusCodes.OK); + } } } diff --git a/src/server/ServerUtils.ts b/src/server/ServerUtils.ts index 62b246a69b..c4191c1d37 100644 --- a/src/server/ServerUtils.ts +++ b/src/server/ServerUtils.ts @@ -12,7 +12,7 @@ export class ServerUtils { protocol: ServerProtocol, hostname: string, port: number): Promise { const logMsg = `${serverType} Server listening on '${protocol}://${hostname}:${port}'`; // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, module: serverModuleName, method: methodName, action: ServerAction.STARTUP, diff --git a/src/server/ocpi/OCPIFacade.ts b/src/server/ocpi/OCPIFacade.ts index 4e6b00da07..efaf620828 100644 --- a/src/server/ocpi/OCPIFacade.ts +++ b/src/server/ocpi/OCPIFacade.ts @@ -52,7 +52,7 @@ export default class OCPIFacade { // Update OCPI Session await ocpiClient.updateSession(transaction); } catch (error) { - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: tenant.id, action, module: MODULE_NAME, method: 'processUpdateTransaction', @@ -120,7 +120,7 @@ export default class OCPIFacade { } } } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'updateConnectorStatus', diff --git a/src/server/ocpi/OCPIServer.ts b/src/server/ocpi/OCPIServer.ts index af22dbb1a5..1cf4e996b6 100644 --- a/src/server/ocpi/OCPIServer.ts +++ b/src/server/ocpi/OCPIServer.ts @@ -44,7 +44,7 @@ export default class OCPIServer { message: `Endpoint '${req.path}' not implemented`, ocpiError: OCPIStatusCode.CODE_3000_GENERIC_SERVER_ERROR }); - void Logging.logActionExceptionMessage(req.tenant?.id ?? Constants.DEFAULT_TENANT_ID, error.params?.action ?? ServerAction.OCPI_ENDPOINT, error); + Logging.logActionExceptionMessage(req.tenant?.id ?? Constants.DEFAULT_TENANT_ID, error.params?.action ?? ServerAction.OCPI_ENDPOINT, error); res.status(HTTPError.NOT_IMPLEMENTED_ERROR).json(OCPIUtils.toErrorResponse(error)); } }); @@ -135,7 +135,7 @@ export default class OCPIServer { } next(); } catch (error) { - await Logging.logActionExceptionMessage(req.tenant?.id ?? Constants.DEFAULT_TENANT_ID, error.params?.action ?? ServerAction.OCPI_ENDPOINT, error); + Logging.logActionExceptionMessage(req.tenant?.id ?? Constants.DEFAULT_TENANT_ID, error.params?.action ?? ServerAction.OCPI_ENDPOINT, error); res.status(error.params?.errorCode ?? HTTPError.GENERAL_ERROR).json(OCPIUtils.toErrorResponse(error)); } } diff --git a/src/server/ocpi/OCPIUtils.ts b/src/server/ocpi/OCPIUtils.ts index 25888d112b..e0f93fae69 100644 --- a/src/server/ocpi/OCPIUtils.ts +++ b/src/server/ocpi/OCPIUtils.ts @@ -239,7 +239,7 @@ export default class OCPIUtils { try { await OCPIUtils.updateCreateChargingStationWithEmspLocation(tenant, location, site, siteArea, evse, action); } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action, module: MODULE_NAME, method: 'processEMSPLocationChargingStations', message: `Error while processing the EVSE UID '${evse.uid}' (ID '${evse.evse_id}') in Location '${location.name}'`, @@ -265,7 +265,7 @@ export default class OCPIUtils { // Delete Charging Station if (currentChargingStation && evse.status === OCPIEvseStatus.REMOVED) { await ChargingStationStorage.deleteChargingStation(tenant, currentChargingStation.id); - await Logging.logDebug({ + Logging.beDebug()?.log({ ...LoggingHelper.getChargingStationProperties(currentChargingStation), tenantID: tenant.id, action, module: MODULE_NAME, method: 'processEMSPLocationChargingStation', @@ -278,7 +278,7 @@ export default class OCPIUtils { currentChargingStation, evse, location, site, siteArea, action); await ChargingStationStorage.saveChargingStation(tenant, chargingStation); await ChargingStationStorage.saveChargingStationOcpiData(tenant, chargingStation.id, chargingStation.ocpiData); - await Logging.logDebug({ + Logging.beDebug()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action, module: MODULE_NAME, method: 'processEMSPLocationChargingStation', diff --git a/src/server/ocpi/service/OCPIUtilsService.ts b/src/server/ocpi/service/OCPIUtilsService.ts index 1461dfdf93..79eef7f0c4 100644 --- a/src/server/ocpi/service/OCPIUtilsService.ts +++ b/src/server/ocpi/service/OCPIUtilsService.ts @@ -321,7 +321,7 @@ export default class OCPIUtilsService { } // Check the CDR if (transaction?.ocpiData?.cdr?.id) { - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: tenant.id, actionOnUser: transaction.userID, @@ -333,7 +333,7 @@ export default class OCPIUtilsService { } // Check the Session Status if (transaction?.ocpiData?.session?.status === OCPISessionStatus.COMPLETED) { - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: tenant.id, actionOnUser: transaction.userID, @@ -445,7 +445,7 @@ export default class OCPIUtilsService { } // Session in the past if (moment(session.last_updated).isBefore(transaction.lastConsumption.timestamp)) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: tenant.id, actionOnUser: transaction.userID, diff --git a/src/server/ocpi/service/common/v2.1.1/CPOEMSPCredentialsService.ts b/src/server/ocpi/service/common/v2.1.1/CPOEMSPCredentialsService.ts index 7de3403615..43e7c1bc55 100644 --- a/src/server/ocpi/service/common/v2.1.1/CPOEMSPCredentialsService.ts +++ b/src/server/ocpi/service/common/v2.1.1/CPOEMSPCredentialsService.ts @@ -25,7 +25,7 @@ export default class CPOEMSPCredentialsService { token = req.headers.authorization.split(' ')[1]; } // Log body - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'handleDeleteCredentials', action, message: 'Received OCPI unregister endpoint', @@ -52,7 +52,7 @@ export default class CPOEMSPCredentialsService { const { tenant, ocpiEndpoint } = req; // Get payload const credential = req.body as OCPICredential; - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'handleUpdateCreateCredentials', action, message: 'Received credential object', @@ -73,7 +73,7 @@ export default class CPOEMSPCredentialsService { token = req.headers.authorization.split(' ')[1]; } // Log body - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'handleUpdateCreateCredentials', action, message: 'Received token', @@ -86,7 +86,7 @@ export default class CPOEMSPCredentialsService { ocpiEndpoint.partyId = credential.party_id; ocpiEndpoint.businessDetails = credential.business_details; // Log updated ocpi endpoint - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'handleUpdateCreateCredentials', action, message: 'OCPI Server found and updated with credential object', @@ -102,7 +102,7 @@ export default class CPOEMSPCredentialsService { }, }); // Log available OCPI Versions - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'handleUpdateCreateCredentials', action, message: 'Available OCPI Versions', @@ -125,7 +125,7 @@ export default class CPOEMSPCredentialsService { ocpiEndpoint.version = version.version; ocpiEndpoint.versionUrl = version.url; // Log correct OCPI service found - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'handleUpdateCreateCredentials', action, message: 'Correct OCPI version found', @@ -149,7 +149,7 @@ export default class CPOEMSPCredentialsService { } }); // Log available OCPI services - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'handleUpdateCreateCredentials', action, message: 'Available OCPI services', @@ -184,7 +184,7 @@ export default class CPOEMSPCredentialsService { // Build credential object const respCredential = await OCPIUtils.buildOcpiCredentialObject(tenant, ocpiEndpoint.localToken, ocpiEndpoint.role, versionUrl); // Log available OCPI Versions - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'handleUpdateCreateCredentials', action, message: 'Response with credential object', diff --git a/src/server/ocpi/service/cpo/v2.1.1/CPOCommandsService.ts b/src/server/ocpi/service/cpo/v2.1.1/CPOCommandsService.ts index 35e3a31544..ff911b51ea 100644 --- a/src/server/ocpi/service/cpo/v2.1.1/CPOCommandsService.ts +++ b/src/server/ocpi/service/cpo/v2.1.1/CPOCommandsService.ts @@ -92,7 +92,7 @@ export default class CPOCommandsService { localToken = await OCPIUtilsService.updateCreateTagWithEmspToken(tenant, startSession.token, localToken, emspUser, action); } if (!localToken?.active || !localToken.ocpiToken?.valid) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'remoteStartSession', action, message: `Token ID '${startSession.token.uid}' is either not active or invalid`, @@ -101,7 +101,7 @@ export default class CPOCommandsService { return CPOCommandsService.buildOCPIResponse(OCPICommandResponseType.REJECTED); } if (Utils.isNullOrUndefined(localToken.user) || localToken.user?.issuer) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'remoteStartSession', action, message: `Invalid user associated to Token ID '${startSession.token.uid}'`, @@ -113,7 +113,7 @@ export default class CPOCommandsService { const chargingStation = await ChargingStationStorage.getChargingStationByOcpiLocationEvseUid( tenant, startSession.location_id, startSession.evse_uid); if (!chargingStation) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'remoteStartSession', action, message: `Charging Station with EVSE ID '${startSession.evse_uid}' and Location ID '${startSession.location_id}' does not exist`, @@ -125,7 +125,7 @@ export default class CPOCommandsService { const connectorID = Utils.convertToInt(OCPIUtils.getConnectorIDFromEvseID(startSession.evse_uid)); const connector = Utils.getConnectorFromID(chargingStation, connectorID); if (!connector) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'remoteStartSession', action, @@ -135,7 +135,7 @@ export default class CPOCommandsService { return CPOCommandsService.buildOCPIResponse(OCPICommandResponseType.REJECTED); } if (!chargingStation.issuer || !chargingStation.public) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'remoteStartSession', action, @@ -146,7 +146,7 @@ export default class CPOCommandsService { } if (connector.status !== ChargePointStatus.AVAILABLE && connector.status !== ChargePointStatus.PREPARING) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'remoteStartSession', action, @@ -162,7 +162,7 @@ export default class CPOCommandsService { (authorization) => authorization.connectorId === connector.connectorId); if (existingAuthorization) { if (OCPIUtils.isAuthorizationValid(existingAuthorization.timestamp)) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'remoteStartSession', action, @@ -203,7 +203,7 @@ export default class CPOCommandsService { } const transaction = await TransactionStorage.getOCPITransactionBySessionID(tenant, stopSession.session_id); if (!transaction) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'remoteStopSession', action, message: `Transaction with Session ID '${stopSession.session_id}' does not exists`, @@ -212,7 +212,7 @@ export default class CPOCommandsService { return CPOCommandsService.buildOCPIResponse(OCPICommandResponseType.REJECTED); } if (!transaction.issuer) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: tenant.id, module: MODULE_NAME, method: 'remoteStopSession', action, @@ -222,7 +222,7 @@ export default class CPOCommandsService { return CPOCommandsService.buildOCPIResponse(OCPICommandResponseType.REJECTED); } if (transaction.stop) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: tenant.id, module: MODULE_NAME, method: 'remoteStopSession', action, @@ -233,7 +233,7 @@ export default class CPOCommandsService { } const chargingStation = await ChargingStationStorage.getChargingStation(tenant, transaction.chargeBoxID); if (!chargingStation) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: tenant.id, module: MODULE_NAME, method: 'remoteStopSession', action, @@ -278,7 +278,7 @@ export default class CPOCommandsService { try { const chargingStationClient = await ChargingStationClientFactory.getChargingStationClient(tenant, chargingStation); if (!chargingStationClient) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'remoteStartTransaction', action, @@ -296,7 +296,7 @@ export default class CPOCommandsService { await CPOCommandsService.sendCommandResponse(tenant, action, startSession.response_url, OCPICommandResponseType.REJECTED, ocpiEndpoint); } } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'remoteStartTransaction', action, @@ -311,7 +311,7 @@ export default class CPOCommandsService { try { const chargingStationClient = await ChargingStationClientFactory.getChargingStationClient(tenant, chargingStation); if (!chargingStationClient) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'remoteStopTransaction', action, @@ -328,7 +328,7 @@ export default class CPOCommandsService { await CPOCommandsService.sendCommandResponse(tenant, action, stopSession.response_url, OCPICommandResponseType.REJECTED, ocpiEndpoint); } } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'remoteStopTransaction', action, @@ -343,7 +343,7 @@ export default class CPOCommandsService { const payload: OCPICommandResponse = { result: responseType }; - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'sendCommandResponse', action, message: `Post command response at ${responseUrl}`, diff --git a/src/server/ocpi/service/emsp/v2.1.1/EMSPCommandsService.ts b/src/server/ocpi/service/emsp/v2.1.1/EMSPCommandsService.ts index 6f70ce7f35..4e9002357d 100644 --- a/src/server/ocpi/service/emsp/v2.1.1/EMSPCommandsService.ts +++ b/src/server/ocpi/service/emsp/v2.1.1/EMSPCommandsService.ts @@ -39,7 +39,7 @@ export default class EMSPCommandsService { case OCPICommandType.RESERVE_NOW: case OCPICommandType.UNLOCK_CONNECTOR: if (req.body?.result !== OCPICommandResponseType.ACCEPTED) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: EMSPCommandsService.getAction(command), message: `OCPI Callback '${req.body?.result as string}' received for Command '${command}' with ID '${commandId}'`, @@ -47,7 +47,7 @@ export default class EMSPCommandsService { detailedMessages: { response: req.body } }); } else { - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, action: EMSPCommandsService.getAction(command), message: `OCPI Callback '${req.body?.result as string}' received for Command '${command}' with ID '${commandId}'`, diff --git a/src/server/ocpp/json/JsonOCPPServer.ts b/src/server/ocpp/json/JsonOCPPServer.ts index 8eec822d86..da2c583836 100644 --- a/src/server/ocpp/json/JsonOCPPServer.ts +++ b/src/server/ocpp/json/JsonOCPPServer.ts @@ -1,6 +1,8 @@ import * as uWS from 'uWebSockets.js'; import { App, HttpRequest, HttpResponse, WebSocket, us_socket_context_t } from 'uWebSockets.js'; +import FeatureToggles, { Feature } from '../../../utils/FeatureToggles'; +import { OCPPIncomingError, OCPPIncomingRequest, OCPPIncomingResponse } from '../../../types/ocpp/OCPPCommon'; import { ServerAction, ServerType, WSServerProtocol } from '../../../types/Server'; import { WebSocketAction, WebSocketCloseEventStatusCode, WebSocketPingResult } from '../../../types/WebSocket'; @@ -8,13 +10,13 @@ import CentralSystemConfiguration from '../../../types/configuration/CentralSyst import ChargingStation from '../../../types/ChargingStation'; import ChargingStationClient from '../../../client/ocpp/ChargingStationClient'; import ChargingStationConfiguration from '../../../types/configuration/ChargingStationConfiguration'; +import ChargingStationStorage from '../../../storage/mongodb/ChargingStationStorage'; import Configuration from '../../../utils/Configuration'; import Constants from '../../../utils/Constants'; import JsonRestWSConnection from './web-socket/JsonRestWSConnection'; import JsonWSConnection from './web-socket/JsonWSConnection'; import Logging from '../../../utils/Logging'; import LoggingHelper from '../../../utils/LoggingHelper'; -import { OCPPMessageType } from '../../../types/ocpp/OCPPCommon'; import OCPPServer from '../OCPPServer'; import Tenant from '../../../types/Tenant'; import Utils from '../../../utils/Utils'; @@ -23,102 +25,99 @@ import WSWrapper from './web-socket/WSWrapper'; import global from '../../../types/GlobalType'; import sizeof from 'object-sizeof'; +// import wtfnode from 'wtfnode'; + const MODULE_NAME = 'JsonOCPPServer'; export default class JsonOCPPServer extends OCPPServer { - private waitingWSMessages = 0; private runningWSMessages = 0; - private runningWSRequestsMessages: Record = {}; private jsonWSConnections: Map = new Map(); private jsonRestWSConnections: Map = new Map(); + private lastUpdatedChargingStationsLastSeen = new Date(); public constructor(centralSystemConfig: CentralSystemConfiguration, chargingStationConfig: ChargingStationConfiguration) { super(centralSystemConfig, chargingStationConfig); - // Start job to clean WS connections - this.checkAndCleanupAllWebSockets(); + if (FeatureToggles.isFeatureActive(Feature.WS_SEND_PING_AUTOMATICALLY)) { + // Nothing to do - the uWS layer takes care to ping the WS for us! + } else { + // Start job to ping and clean WS connections (if necessary) + this.checkAndCleanupAllWebSockets(); + } // Monitor WS activity this.monitorWSConnections(); + // Start 15 secs after ping checks + setTimeout(() => this.massUpdateChargingStationsLastSeen(), 15 * 1000); } public start(): void { // Keep it global global.centralSystemJsonServer = this; + // uWS can send pings automatically before the idleTimeout is reached + let idleTimeout: number; + const sendPingsAutomatically = FeatureToggles.isFeatureActive(Feature.WS_SEND_PING_AUTOMATICALLY); + if (sendPingsAutomatically) { + idleTimeout = 1 * 60; // 1 minute - Maintains the web socket live - impact visible with the number of pongs! + // idleTimeout = 5 * 60; // 5 minutes - too long - some chargers are closing their web socket with error code 1006 - no reason! + } else { + // idleTimeout = 3600; // 1 hour of inactivity ==> close + idleTimeout = 0; // Never close Web Sockets + } // Start the WS server Logging.logConsoleDebug(`Starting ${ServerType.JSON_SERVER} Server...`); App({}).ws('/*', { compression: uWS.SHARED_COMPRESSOR, maxPayloadLength: 64 * 1024, // 64 KB per request - idleTimeout: 1 * 3600, // 1 hour of inactivity => Close - // eslint-disable-next-line @typescript-eslint/no-misused-promises - upgrade: async (res: HttpResponse, req: HttpRequest, context: us_socket_context_t) => { + idleTimeout, + sendPingsAutomatically, // keeps the connection alive - uWS sends ping automatically before reaching the idleTimeout + upgrade: (res: HttpResponse, req: HttpRequest, context: us_socket_context_t) => { // Delegate - await this.onUpgrade(res, req, context); + this.onUpgrade(res, req, context); }, - // eslint-disable-next-line @typescript-eslint/no-misused-promises - open: async (ws: WebSocket) => { + open: (ws: WebSocket) => { // Delegate - await this.onOpen(ws); + this.onOpen(ws); + }, + drain: (ws: WebSocket) => { + this.onDrain(ws); }, - // eslint-disable-next-line @typescript-eslint/no-misused-promises - message: async (ws: WebSocket, message: ArrayBuffer, isBinary: boolean) => { + message: (ws: WebSocket, message: ArrayBuffer, isBinary: boolean) => { // Delegate const messageStr = Utils.convertBufferArrayToString(message); - await this.onMessage(ws, messageStr, isBinary); + this.onMessage(ws, messageStr, isBinary).catch(() => { /* Intentional */ }); }, - // eslint-disable-next-line @typescript-eslint/no-misused-promises - close: async (ws: WebSocket, code: number, message: ArrayBuffer) => { - // Convert right away + close: (ws: WebSocket, code: number, message: ArrayBuffer) => { const reason = Utils.convertBufferArrayToString(message); - const wsWrapper = ws.wsWrapper as WSWrapper; - // Close - wsWrapper.closed = true; - await this.logWSConnectionClosed(wsWrapper, ServerAction.WS_SERVER_CONNECTION_CLOSE, code, - `${WebSocketAction.CLOSE} > WS Connection ID '${wsWrapper.guid}' closed by charging station with code '${code}', reason: '${!Utils.isNullOrEmptyString(reason) ? reason : 'No reason given'}'`); - // Remove connection - await this.removeWSWrapper(WebSocketAction.CLOSE, ServerAction.WS_SERVER_CONNECTION_CLOSE, wsWrapper); + this.onClose(ws, code, reason); }, - // eslint-disable-next-line @typescript-eslint/no-misused-promises - ping: async (ws: WebSocket, message: ArrayBuffer) => { - // Convert + ping: (ws: WebSocket, message: ArrayBuffer) => { + // Convert right away (sometimes not working in the method) const ocppMessage = Utils.convertBufferArrayToString(message); - // Update - if (ws.wsWrapper) { - (ws.wsWrapper as WSWrapper).lastPingDate = new Date(); - } - // Get the WS - if (ws.wsWrapper.wsConnection) { - await ws.wsWrapper.wsConnection.onPing(ocppMessage); - } + this.onPing(ws, ocppMessage); }, - // eslint-disable-next-line @typescript-eslint/no-misused-promises - pong: async (ws: WebSocket, message: ArrayBuffer) => { - // Convert + pong: (ws: WebSocket, message: ArrayBuffer) => { + // Convert right away (sometimes not working in the method) const ocppMessage = Utils.convertBufferArrayToString(message); - // Update - if (ws.wsWrapper) { - (ws.wsWrapper as WSWrapper).lastPongDate = new Date(); - } - // Get the WS - if (ws.wsWrapper.wsConnection) { - await ws.wsWrapper.wsConnection.onPong(ocppMessage); - } + this.onPong(ws, ocppMessage); } - // eslint-disable-next-line @typescript-eslint/no-misused-promises }).any(Constants.HEALTH_CHECK_ROUTE, (res: HttpResponse) => { - // TODO - Find another metric to check the health - res.end('OK'); - // res.onAborted(() => { - // res.aborted = true; - // }); - // const pingSuccess = await global.database.ping(); - // if (!res.aborted) { - // if (pingSuccess) { - // res.end('OK'); - // } else { - // res.writeStatus('500'); - // res.end('KO'); - // } - // } + res.onAborted(() => { + res.aborted = true; + }); + if (FeatureToggles.isFeatureActive(Feature.HEALTH_CHECK_PING_DATABASE)) { + global.database.ping().then((pingSuccess) => { + if (!res.aborted) { + if (pingSuccess) { + res.end('OK'); + } else { + res.writeStatus('500'); + res.end('KO'); + } + } + }).catch(() => { /* Intentional */ }); + } else { + // TODO - FIND ANOTHER METRIC TO CHECK THE READINESS and LIVENESS PROBE + res.end('OK'); + } }).any('/*', (res: HttpResponse) => { res.writeStatus('404'); res.end(); @@ -133,18 +132,18 @@ export default class JsonOCPPServer extends OCPPServer { }); } - public async getChargingStationClient(tenant: Tenant, chargingStation: ChargingStation): Promise { + public getChargingStationClient(tenant: Tenant, chargingStation: ChargingStation): ChargingStationClient { // Get the Json Web Socket const jsonWebSocket = this.jsonWSConnections.get(`${tenant.id}~${chargingStation.id}`); if (!jsonWebSocket) { const message = 'No opened Web Socket connection found'; - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'getChargingStationClient', action: ServerAction.WS_SERVER_CONNECTION, message }); - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, chargingStationID: chargingStation.id, module: MODULE_NAME, method: 'getChargingStationClient', @@ -160,18 +159,23 @@ export default class JsonOCPPServer extends OCPPServer { return this.jsonWSConnections.has(`${tenant.id}~${chargingStation.id}`); } - private async onUpgrade(res: uWS.HttpResponse, req: uWS.HttpRequest, context: uWS.us_socket_context_t) { - // Check for WS connection over HTTP + private onUpgrade(res: uWS.HttpResponse, req: uWS.HttpRequest, context: uWS.us_socket_context_t) { + /* Keep track of abortions */ + const upgradeAborted = { aborted: false }; + // Copy data here because access to 'req' object no longer valid after an 'await' call const url = req.getUrl(); + const secWebSocketKey = req.getHeader('sec-websocket-key'); + const secWebSocketProtocol = req.getHeader('sec-websocket-protocol'); + const secWebSocketExtensions = req.getHeader('sec-websocket-extensions'); try { // You MUST register an abort handler to know if the upgrade was aborted by peer res.onAborted(() => { - // If no handler here, it crashes!!! + upgradeAborted.aborted = true; }); // INFO: Cannot use Logging in this method as uWebSocket will fail in using req/res objects :S // Check URI (/OCPP16/// or /REST///) if (!url.startsWith('/OCPP16') && !url.startsWith('/REST')) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, module: MODULE_NAME, method: 'onUpgrade', action: ServerAction.WS_SERVER_CONNECTION, @@ -183,7 +187,7 @@ export default class JsonOCPPServer extends OCPPServer { // Check Protocol (ocpp1.6 / rest) const protocol = req.getHeader('sec-websocket-protocol'); if (url.startsWith('/OCPP16') && (protocol !== WSServerProtocol.OCPP16)) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, module: MODULE_NAME, method: 'onUpgrade', action: ServerAction.WS_SERVER_CONNECTION, @@ -194,7 +198,7 @@ export default class JsonOCPPServer extends OCPPServer { return; } if (url.startsWith('/REST') && (protocol !== WSServerProtocol.REST)) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, module: MODULE_NAME, method: 'onUpgrade', action: ServerAction.WS_SERVER_CONNECTION, @@ -204,19 +208,39 @@ export default class JsonOCPPServer extends OCPPServer { res.close(); return; } - res.upgrade( - { url }, - req.getHeader('sec-websocket-key'), - req.getHeader('sec-websocket-protocol'), - req.getHeader('sec-websocket-extensions'), - context - ); + // Check and Create WSWrapper without WebSocket + const wsWrapper = new WSWrapper(url); + // Create Json connection + this.createAndKeepJsonConnection(wsWrapper).then(() => { + // Upgrade to WS + if (!upgradeAborted.aborted) { + res.upgrade( + { url }, + secWebSocketKey, + secWebSocketProtocol, + secWebSocketExtensions, + context + ); + } + }).catch((error) => { + // Wrapper creation failed + const message = `${WebSocketAction.UPGRADE} > New WS Connection with URL '${url}' failed with error: ${error.message as string}`; + res.writeStatus('500'); + res.end(message); + this.isDebug() && Logging.logConsoleDebug(message); + Logging.beError()?.log({ + tenantID: Constants.DEFAULT_TENANT_ID, + action: ServerAction.WS_SERVER_CONNECTION, + module: MODULE_NAME, method: 'onUpgrade', + message, detailedMessages: { error: error.stack } + }); + }); } catch (error) { const message = `${WebSocketAction.UPGRADE} > New WS Connection with URL '${url}' failed with error: ${error.message as string}`; res.writeStatus('500'); res.end(message); this.isDebug() && Logging.logConsoleDebug(message); - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.WS_SERVER_CONNECTION, module: MODULE_NAME, method: 'onUpgrade', @@ -225,173 +249,267 @@ export default class JsonOCPPServer extends OCPPServer { } } - private async onOpen(ws: uWS.WebSocket) { - // Create WS Wrapper - const wsWrapper = new WSWrapper(ws); - // Keep it on the ws - ws.wsWrapper = wsWrapper; - // Lock incoming WS messages - await this.acquireLockForWSRequest(WebSocketAction.OPEN, ServerAction.WS_SERVER_CONNECTION_OPEN, wsWrapper); - try { - this.runningWSMessages++; - // Path must contain /OCPP16 or /REST as it is already checked during the Upgrade process - // Check OCPP16 connection - if (wsWrapper.url.startsWith('/OCPP16')) { - // Create and Initialize WS Connection - await this.checkAndStoreWSOpenedConnection(WSServerProtocol.OCPP16, wsWrapper); - } - // Check REST connection - if (wsWrapper.url.startsWith('/REST')) { - // Create and Initialize WS Connection - await this.checkAndStoreWSOpenedConnection(WSServerProtocol.REST, wsWrapper); + private resolveAndGetWSWrapper(ws: WebSocket): WSWrapper { + const wsWrapper = ws['wsWrapper'] as WSWrapper; + if (wsWrapper) { + if (!wsWrapper.isClosed()) { + return wsWrapper; } - } catch (error) { - await Logging.logException(error as Error, ServerAction.WS_SERVER_CONNECTION_OPEN, MODULE_NAME, 'onOpen', Constants.DEFAULT_TENANT_ID); - if (wsWrapper.tenantID) { - await Logging.logException(error as Error, ServerAction.WS_SERVER_CONNECTION_OPEN, MODULE_NAME, 'onOpen', wsWrapper.tenantID); + return; + } + // Find the WS Wrapper (only done the first time, next it is attached to the uWS) + const url = ws['url'] as string; + let wsConnections: IterableIterator; + if (url.startsWith('/OCPP16')) { + wsConnections = this.jsonWSConnections.values(); + } + if (url.startsWith('/REST')) { + wsConnections = this.jsonRestWSConnections.values(); + } + // Search for already registered Wrapper set by in the 'onUpgrade' method + if (wsConnections) { + for (const wsConnection of wsConnections) { + if (wsConnection.getOriginalURL() === url) { + // Attach it to the Web Socket + const foundWSWrapper = wsConnection.getWS(); + ws['wsWrapper'] = foundWSWrapper; + foundWSWrapper.setWebSocket(ws); + return foundWSWrapper; + } } - // Close WS - await this.closeWebSocket(WebSocketAction.OPEN, ServerAction.WS_SERVER_CONNECTION_OPEN, wsWrapper, WebSocketCloseEventStatusCode.CLOSE_ABNORMAL, - `${WebSocketAction.OPEN} > WS Connection ID '${wsWrapper.guid}' has been rejected and closed by server due to an exception: ${error.message as string}`); - } finally { - this.runningWSMessages--; - this.releaseLockForWSMessageRequest(wsWrapper); } + // No found: close the connection + ws.end(WebSocketCloseEventStatusCode.CLOSE_ABNORMAL, 'Connection rejected by the backend'); } - private async checkAndStoreWSOpenedConnection(protocol: WSServerProtocol, wsWrapper: WSWrapper): Promise { + private async createAndKeepJsonConnection(wsWrapper: WSWrapper): Promise { let wsConnection: WSConnection; const timeStart = Date.now(); - // Set the protocol - wsWrapper.protocol = protocol; - // Create a WebSocket connection object - if (protocol === WSServerProtocol.OCPP16) { - wsConnection = new JsonWSConnection(wsWrapper); - } - if (protocol === WSServerProtocol.REST) { - wsConnection = new JsonRestWSConnection(wsWrapper); - } - await Logging.logDebug({ - tenantID: Constants.DEFAULT_TENANT_ID, - action: ServerAction.WS_SERVER_CONNECTION_OPEN, module: MODULE_NAME, method: 'checkAndStoreWSOpenedConnection', - message: `${WebSocketAction.OPEN} > WS Connection ID '${wsWrapper.guid}' is being checked ('${wsWrapper.url}')`, - detailedMessages: { wsWrapper: this.getWSWrapperData(wsWrapper) } - }); - // Initialize (check of Tenant, Token, Charging Station -> Can take time) - await wsConnection.initialize(); - // Check if WS is still opened (long time initialization when thousand of WS are connecting at the same time) - if (!wsWrapper.closed) { + try { + // Create a WebSocket connection object + if (wsWrapper.protocol === WSServerProtocol.OCPP16) { + wsConnection = new JsonWSConnection(wsWrapper); + } + if (wsWrapper.protocol === WSServerProtocol.REST) { + wsConnection = new JsonRestWSConnection(wsWrapper); + } + Logging.beDebug()?.log({ + tenantID: wsConnection.getTenantID(), + ...LoggingHelper.getWSConnectionProperties(wsConnection), + action: ServerAction.WS_SERVER_CONNECTION_OPEN, module: MODULE_NAME, method: 'createAndKeepJsonConnection', + message: `${WebSocketAction.OPEN} > WS Connection ID '${wsWrapper.guid}' is being checked ('${wsWrapper.url}')`, + detailedMessages: { + wsWrapper: wsWrapper.toJson() + } + }); + // Initialize (check of Tenant, Token, Charging Station -> Can take time) + await wsConnection.initialize(); // Keep common data (Set here to get Tenant info in case of exception in Logs) - wsWrapper.key = wsConnection.getID(); - wsWrapper.chargingStationID = wsConnection.getChargingStationID(); - wsWrapper.tenantID = wsConnection.getTenantID(); - wsWrapper.tokenID = wsConnection.getTokenID(); - wsWrapper.siteID = wsConnection.getSiteID(); - wsWrapper.siteAreaID = wsConnection.getSiteAreaID(); - wsWrapper.companyID = wsConnection.getCompanyID(); - // Check already existing WS Connection - await this.checkAndCloseIdenticalOpenedWSConnection(wsWrapper, wsConnection); - const message = `${WebSocketAction.OPEN} > WS Connection ID '${wsWrapper.guid}' has been accepted in ${Utils.computeTimeDurationSecs(timeStart)} secs`; - await Logging.logInfo({ - tenantID: Constants.DEFAULT_TENANT_ID, - chargingStationID: wsWrapper.chargingStationID, - action: ServerAction.WS_SERVER_CONNECTION_OPEN, module: MODULE_NAME, method: 'checkAndStoreWSOpenedConnection', - message, detailedMessages: { wsWrapper: this.getWSWrapperData(wsWrapper) } + wsWrapper.setConnection(wsConnection); + // Keep WS connection in cache + if (wsWrapper.protocol === WSServerProtocol.OCPP16) { + this.closePreviousWebSocketConnection(wsConnection); + await wsConnection.updateChargingStationRuntimeData(); + this.jsonWSConnections.set(wsConnection.getID(), wsConnection as JsonWSConnection); + } else if (wsWrapper.protocol === WSServerProtocol.REST) { + this.jsonRestWSConnections.set(wsConnection.getID(), wsConnection as JsonRestWSConnection); + } + Logging.beInfo()?.log({ + ...LoggingHelper.getWSWrapperProperties(wsWrapper), + tenantID: wsWrapper.wsConnection?.getTenantID(), + action: ServerAction.WS_SERVER_CONNECTION_OPEN, module: MODULE_NAME, method: 'createAndKeepJsonConnection', + message: `${WebSocketAction.OPEN} > WS ID '${wsWrapper.guid}' is valid (processed in ${Utils.computeTimeDurationSecs(timeStart)} secs)`, + detailedMessages: { wsWrapper: wsWrapper.toJson() } }); - await Logging.logInfo({ + } catch (error) { + wsWrapper.unsetConnection(); + Logging.beError()?.log({ ...LoggingHelper.getWSWrapperProperties(wsWrapper), - action: ServerAction.WS_SERVER_CONNECTION_OPEN, module: MODULE_NAME, method: 'checkAndStoreWSOpenedConnection', - message, detailedMessages: { wsWrapper: this.getWSWrapperData(wsWrapper) } + tenantID: wsWrapper.wsConnection?.getTenantID(), + action: ServerAction.WS_SERVER_CONNECTION_OPEN, module: MODULE_NAME, method: 'createAndKeepJsonConnection', + message: `${WebSocketAction.OPEN} > WS ID '${wsWrapper.guid}' is invalid (processed in ${Utils.computeTimeDurationSecs(timeStart)} secs)`, + detailedMessages: { wsWrapper: wsWrapper.toJson() } }); - // Keep WS connection in cache - await this.setWSConnection(WebSocketAction.OPEN, ServerAction.WS_SERVER_CONNECTION_OPEN, wsConnection, wsWrapper); - if (Utils.isMonitoringEnabled() && (protocol === WSServerProtocol.OCPP16)) { - wsWrapper.ocppOpenWebSocketMetricCounter.inc(); - } - } else { - await this.logWSConnectionClosed(wsWrapper, ServerAction.WS_SERVER_CONNECTION_OPEN, WebSocketCloseEventStatusCode.CLOSE_ABNORMAL, - `${WebSocketAction.OPEN} > WS Connection ID '${wsWrapper.guid}' has been closed during initialization in ${Utils.computeTimeDurationSecs(timeStart)} secs ('${wsWrapper.url}')`); } } - private async checkAndCloseIdenticalOpenedWSConnection(wsWrapper: WSWrapper, wsConnection: WSConnection): Promise { - // Get connection - const existingWSConnection = - this.getWSConnectionFromProtocolAndID(wsConnection.getWS().protocol, wsConnection.getID()); - // Found existing WS Connection? + private closePreviousWebSocketConnection(wsConnection: WSConnection) { + const currentWSWrapper = wsConnection.getWS(); + if (currentWSWrapper.protocol === WSServerProtocol.REST) { + // REST WS are closed by the web socket client! + return; + } + // Make sure the charging station does not open tons of web sockets! + const existingWSConnection = this.jsonWSConnections.get(wsConnection.getID()); if (existingWSConnection) { // Still opened WS? const existingWSWrapper = existingWSConnection.getWS(); - if (!existingWSWrapper.closed) { - // Ping WS - const result = await this.pingWebSocket(existingWSWrapper); - if (result.ok) { - // Close the old WS and keep the new incoming one - await Logging.logWarning({ - tenantID: Constants.DEFAULT_TENANT_ID, - chargingStationID: wsWrapper.chargingStationID, - action: ServerAction.WS_SERVER_CONNECTION, module: MODULE_NAME, method: 'checkAndCloseIdenticalOpenedWSConnection', - message: `${WebSocketAction.OPEN} > Existing WS Connection ID '${existingWSWrapper.guid}' will be closed and replaced by new incoming one with ID '${wsWrapper.guid}'`, - detailedMessages: { wsWrapper: this.getWSWrapperData(wsWrapper) } + if (!existingWSWrapper.isClosed()) { + try { + Logging.beDebug()?.log({ + tenantID: existingWSConnection.getTenantID(), + chargingStationID: existingWSConnection.getChargingStationID(), + action: ServerAction.WS_SERVER_CONNECTION_CLOSE, module: MODULE_NAME, method: 'closePreviousWebSocketConnection', + message: `Forcefully close WS - previous WS ID '${existingWSWrapper.guid}' - new WS ID '${currentWSWrapper.guid}` + }); + existingWSWrapper.end(WebSocketCloseEventStatusCode.CLOSE_PROTOCOL_ERROR, 'WebSocket kicked out by a new one'); + } catch (error) { + Logging.beError()?.log({ + tenantID: existingWSConnection.getTenantID(), + chargingStationID: existingWSConnection.getChargingStationID(), + action: ServerAction.WS_SERVER_CONNECTION_CLOSE, module: MODULE_NAME, method: 'closePreviousWebSocketConnection', + message: `Failed to forcefully close WS - previous WS ID '${existingWSWrapper.guid}' - new WS ID '${currentWSWrapper.guid}`, + detailedMessages: { + rootCause: error.message + } }); - await this.closeWebSocket(WebSocketAction.OPEN, ServerAction.WS_SERVER_CONNECTION_OPEN, existingWSConnection.getWS(), WebSocketCloseEventStatusCode.CLOSE_ABNORMAL, - `${WebSocketAction.OPEN} > Existing WS Connection ID '${existingWSWrapper.guid}' has been closed successfully by the server`); } } } } - private async acquireLockForWSRequest(wsAction: WebSocketAction, action: ServerAction, wsWrapper: WSWrapper, ocppMessageType?: OCPPMessageType): Promise { - // Only lock requests, not responses - if (ocppMessageType && ocppMessageType !== OCPPMessageType.CALL_MESSAGE) { - return; + private onOpen(ws: uWS.WebSocket) { + // Init WS + this.resolveAndGetWSWrapper(ws); + } + + private onDrain(ws: WebSocket) { + // Do not try to resolve the WSWrapper + const wsWrapper = ws['wsWrapper'] as WSWrapper ?? new WSWrapper(ws['url'] as string); + // Just log draining + Logging.beWarning()?.log({ + ...LoggingHelper.getWSWrapperProperties(wsWrapper), + tenantID: Constants.DEFAULT_TENANT_ID, + action: ServerAction.WS_SERVER_CONNECTION_CLOSE, + module: MODULE_NAME, method: 'drain', + message: 'Web Socket drain method called', + detailedMessages: { + wsWrapper: wsWrapper?.toJson() + } + }); + } + + private onClose(ws: WebSocket, code: number, reason: string): void { + // Do not try to resolve the WSWrapper, just get it from the uWS + const wsWrapper = ws['wsWrapper'] as WSWrapper; + if (wsWrapper) { + if (wsWrapper.wsConnection) { + if (wsWrapper.protocol === WSServerProtocol.REST) { + // Cleanup WS Connection map + this.jsonRestWSConnections.delete(wsWrapper.wsConnection.getID()); + } else { + // Cleanup WS Connection map + this.jsonWSConnections.delete(wsWrapper.wsConnection.getID()); + // if (code !== WebSocketCloseEventStatusCode.CLOSE_NORMAL) { + // // Only count abnormal close events + // wsWrapper.ocppClosedWebSocketMetricCounter?.inc(); + // } + // Only log OCPP close events + this.logWSConnectionClosed(wsWrapper, ServerAction.WS_SERVER_CONNECTION_CLOSE, code, + `${WebSocketAction.CLOSE} > WS ID '${wsWrapper?.guid}' - onClose - code '${code}', reason: '${reason || ''}'`); + } + } else { + Logging.beError()?.log({ + tenantID: Constants.DEFAULT_TENANT_ID, + action: ServerAction.WS_SERVER_CONNECTION_CLOSE, + module: MODULE_NAME, method: 'onClose', + message: `${WebSocketAction.CLOSE} > Unexpected situation - onClose received for an unknown connection - WS ID '${wsWrapper?.guid}'`, + detailedMessages: { code, reason } + }); + } + } else { + Logging.beError()?.log({ + tenantID: Constants.DEFAULT_TENANT_ID, + action: ServerAction.WS_SERVER_CONNECTION_CLOSE, + module: MODULE_NAME, method: 'onClose', + message: `${WebSocketAction.CLOSE} > Unexpected situation - onClose received for an unknown web socket`, + detailedMessages: { code, reason } + }); } - // Wait for Init (avoid WS connection with same URL), ocppMessageType only provided when a WS Message is received - await this.waitForWSLockToRelease(wsAction, action, wsWrapper); - // Lock - this.runningWSRequestsMessages[wsWrapper.url] = true; } - private releaseLockForWSMessageRequest(wsWrapper: WSWrapper, ocppMessageType?: OCPPMessageType): void { - // Only lock requests, not responses - if (ocppMessageType && (ocppMessageType !== OCPPMessageType.CALL_MESSAGE)) { - return; + private onPing(ws: WebSocket, ocppMessage: string): void { + const wsWrapper = this.resolveAndGetWSWrapper(ws); + if (wsWrapper) { + wsWrapper.lastPingDate = new Date(); + // Get the WS + if (wsWrapper.wsConnection) { + wsWrapper.wsConnection.onPing(ocppMessage); + } + } + } + + private onPong(ws: WebSocket, ocppMessage: string): void { + const wsWrapper = this.resolveAndGetWSWrapper(ws); + if (wsWrapper) { + wsWrapper.lastPongDate = new Date(); + // Get the WS + if (wsWrapper.wsConnection) { + wsWrapper.wsConnection.onPong(ocppMessage); + } } - // Unlock - delete this.runningWSRequestsMessages[wsWrapper.url]; } private async onMessage(ws: uWS.WebSocket, message: string, isBinary: boolean): Promise { - const wsWrapper: WSWrapper = ws.wsWrapper; + const wsWrapper = this.resolveAndGetWSWrapper(ws); + if (!wsWrapper) { + Logging.beError()?.log({ + action: ServerAction.WS_SERVER_MESSAGE, + module: MODULE_NAME, method: 'onMessage', + message: `${WebSocketAction.MESSAGE} > WS Connection not found ('${ws['url'] as string}')`, + detailedMessages: { message, isBinary } + }); + ws.end(WebSocketCloseEventStatusCode.CLOSE_ABNORMAL, 'Connection rejected by the backend: No WS Wrapper found'); + return; + } + if (wsWrapper.isClosed()) { + Logging.beError()?.log({ + ...LoggingHelper.getWSWrapperProperties(wsWrapper), + action: ServerAction.WS_SERVER_MESSAGE, + module: MODULE_NAME, method: 'onMessage', + message: `${WebSocketAction.MESSAGE} > WS Connection ID '${wsWrapper.guid}' is already closed ('${wsWrapper.url}')`, + detailedMessages: { message, isBinary, wsWrapper: wsWrapper.toJson() } + }); + return; + } + if (!wsWrapper.isValid()) { + Logging.beError()?.log({ + ...LoggingHelper.getWSWrapperProperties(wsWrapper), + action: ServerAction.WS_SERVER_MESSAGE, + module: MODULE_NAME, method: 'onMessage', + message: `${WebSocketAction.MESSAGE} > WS Connection ID '${wsWrapper.guid}' is invalid ('${wsWrapper.url}')`, + detailedMessages: { message, isBinary, wsWrapper: wsWrapper.toJson() } + }); + wsWrapper.end(WebSocketCloseEventStatusCode.CLOSE_ABNORMAL, 'Connection rejected by the backend'); + return; + } + // Keep last date + wsWrapper.lastMessageDate = new Date(); + // Process Message try { // Extract the OCPP Message Type - const [ocppMessageType]: [OCPPMessageType] = JSON.parse(message); - // Lock incoming WS messages - await this.acquireLockForWSRequest(WebSocketAction.MESSAGE, ServerAction.WS_SERVER_MESSAGE, wsWrapper, ocppMessageType); + const ocppMessage: OCPPIncomingRequest|OCPPIncomingResponse|OCPPIncomingError = JSON.parse(message); try { this.runningWSMessages++; - // Check if connection is available in Map - await this.checkWSConnectionFromOnMessage(wsWrapper); // OCPP Request? - if (ocppMessageType === OCPPMessageType.CALL_MESSAGE) { - if (!wsWrapper.closed) { - // Process the message - if (wsWrapper.wsConnection) { - await wsWrapper.wsConnection.receivedMessage(message, isBinary); - } - } - // Process the message - } else if (wsWrapper.wsConnection) { - await wsWrapper.wsConnection.receivedMessage(message, isBinary); + if (wsWrapper.wsConnection) { + await wsWrapper.wsConnection.handleIncomingOcppMessage(wsWrapper, ocppMessage); + } else { + Logging.beError()?.log({ + ...LoggingHelper.getWSWrapperProperties(wsWrapper), + action: ServerAction.WS_SERVER_MESSAGE, + module: MODULE_NAME, method: 'onMessage', + message: 'Unexpected situation - message is received but wsConnection is not set', + detailedMessages: { message, isBinary, wsWrapper: this.getWSWrapperData(wsWrapper) } + }); } } finally { this.runningWSMessages--; - this.releaseLockForWSMessageRequest(wsWrapper, ocppMessageType); } } catch (error) { const logMessage = `${WebSocketAction.MESSAGE} > WS Connection ID '${wsWrapper.guid}' got error while processing WS Message: ${error.message as string}`; - if (wsWrapper?.tenantID) { - await Logging.logError({ + if (wsWrapper?.wsConnection?.getTenantID()) { + Logging.beError()?.log({ ...LoggingHelper.getWSWrapperProperties(wsWrapper), action: ServerAction.WS_SERVER_MESSAGE, module: MODULE_NAME, method: 'onMessage', @@ -399,153 +517,40 @@ export default class JsonOCPPServer extends OCPPServer { detailedMessages: { message, isBinary, wsWrapper: this.getWSWrapperData(wsWrapper), error: error.stack } }); } - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, - chargingStationID: wsWrapper.chargingStationID, + ...LoggingHelper.getWSWrapperProperties(wsWrapper), action: ServerAction.WS_SERVER_MESSAGE, module: MODULE_NAME, method: 'onMessage', - message: logMessage + ` - tenant: ${wsWrapper?.tenantID}`, + message: logMessage + ` - tenant: ${wsWrapper?.wsConnection?.getTenantID()}`, detailedMessages: { message, isBinary, wsWrapper: this.getWSWrapperData(wsWrapper), error: error.stack } }); } } - private async checkWSConnectionFromOnMessage(wsWrapper: WSWrapper) { - // Get WS Connection - const wsConnection = wsWrapper.wsConnection; - if (wsWrapper.closed) { - // Current message is from a charger which should not reach us! - // e.g.: Websocket has been closed during the onOpen because the tenant does not exist - throw new Error('Websocket is already closed'); - } - // Get WS Connection from cache - const wsExistingConnection = - this.getWSConnectionFromProtocolAndID(wsWrapper.protocol, wsWrapper.key); - if (!wsExistingConnection) { - await Logging.logError({ - tenantID: Constants.DEFAULT_TENANT_ID, - chargingStationID: wsWrapper.chargingStationID, - action: ServerAction.WS_SERVER_MESSAGE, - module: MODULE_NAME, method: 'checkWSConnectionFromOnMessage', - message: `${WebSocketAction.MESSAGE} > WS Connection ID '${wsWrapper.guid}' has sent a WS Message on an unreferenced WS Connection, it will be then added in the WS cache`, - detailedMessages: { wsWrapper: this.getWSWrapperData(wsWrapper) } - }); - // Add WS connection from OnMessage in cache - await this.setWSConnection(WebSocketAction.MESSAGE, ServerAction.WS_SERVER_MESSAGE, wsConnection, wsWrapper); - return; - } - // Should have the same GUID - const wsExistingWrapper = wsExistingConnection.getWS(); - if (wsExistingWrapper.guid !== wsWrapper.guid) { - await Logging.logError({ - tenantID: Constants.DEFAULT_TENANT_ID, - chargingStationID: wsWrapper.chargingStationID, - action: ServerAction.WS_SERVER_MESSAGE, - module: MODULE_NAME, method: 'checkWSConnectionFromOnMessage', - message: `${WebSocketAction.MESSAGE} > WS Connection ID '${wsWrapper.guid}' has sent a WS Message on an already referenced WS Connection ID '${wsExistingWrapper.guid}' in WS cache, ping will be performed...`, - detailedMessages: { wsWrapper: this.getWSWrapperData(wsWrapper), wsExistingWrapper: this.getWSWrapperData(wsExistingWrapper) } - }); - // Ping - const result = await this.pingWebSocket(wsExistingWrapper); - if (result.ok) { - await Logging.logError({ - tenantID: Constants.DEFAULT_TENANT_ID, - chargingStationID: wsWrapper.chargingStationID, - action: ServerAction.WS_SERVER_MESSAGE, - module: MODULE_NAME, method: 'checkWSConnectionFromOnMessage', - message: `${WebSocketAction.MESSAGE} > Existing WS Connection ID '${wsExistingWrapper.guid}' ping succeeded meaning multiple WS connections are opened by the same charging station, existing one will be closed and replaced by new one with ID '${wsWrapper.guid}'`, - detailedMessages: { wsExistingWrapper: this.getWSWrapperData(wsExistingWrapper), wsWrapper: this.getWSWrapperData(wsWrapper) } - }); - // Close WS - await this.closeWebSocket(WebSocketAction.MESSAGE, ServerAction.WS_SERVER_MESSAGE, wsExistingWrapper, - WebSocketCloseEventStatusCode.CLOSE_ABNORMAL, `${WebSocketAction.MESSAGE} > Existing WS Connection ID '${wsExistingWrapper.guid}' has been closed successfully by server (duplicate WS Connection)`); - } else { - await Logging.logWarning({ - tenantID: Constants.DEFAULT_TENANT_ID, - chargingStationID: wsWrapper.chargingStationID, - action: ServerAction.WS_SERVER_MESSAGE, - module: MODULE_NAME, method: 'checkWSConnectionFromOnMessage', - message: `${WebSocketAction.MESSAGE} > Existing WS Connection ID '${wsExistingWrapper.guid}' ping failed, new WS Connection ID '${wsWrapper.guid}' will be then added in the WS cache`, - detailedMessages: { wsExistingWrapper: this.getWSWrapperData(wsExistingWrapper), wsWrapper: this.getWSWrapperData(wsWrapper) } - }); - } - // Keep WS connection in cache - await this.setWSConnection(WebSocketAction.MESSAGE, ServerAction.WS_SERVER_MESSAGE, wsConnection, wsWrapper); - } - } - - private async logWSConnectionClosed(wsWrapper: WSWrapper, action: ServerAction, code: number, message: string): Promise { + private logWSConnectionClosed(wsWrapper: WSWrapper, action: ServerAction, code: number, message: string): void { this.isDebug() && Logging.logConsoleDebug(message); - if (wsWrapper.tenantID) { - await Logging.logInfo({ + const tenantID = wsWrapper?.wsConnection?.getTenantID(); + if (tenantID) { + Logging.beInfo()?.log({ + tenantID, ...LoggingHelper.getWSWrapperProperties(wsWrapper), action, module: MODULE_NAME, method: 'logWSConnectionClosed', message: message, detailedMessages: { code, message, wsWrapper: this.getWSWrapperData(wsWrapper) } }); } - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, - chargingStationID: wsWrapper.chargingStationID, + ...LoggingHelper.getWSWrapperProperties(wsWrapper), action, module: MODULE_NAME, method: 'logWSConnectionClosed', message: message, detailedMessages: { code, message, wsWrapper: this.getWSWrapperData(wsWrapper) } }); } - private async waitForWSLockToRelease(wsAction: WebSocketAction, action: ServerAction, wsWrapper: WSWrapper): Promise { - // Wait for init to handle multiple same WS Connection - if (this.runningWSRequestsMessages[wsWrapper.url]) { - const maxNumberOfTrials = 10; - let numberOfTrials = 0; - const timeStart = Date.now(); - await Logging.logWarning({ - tenantID: Constants.DEFAULT_TENANT_ID, - chargingStationID: wsWrapper.chargingStationID, - action, module: MODULE_NAME, method: 'waitForWSLockToRelease', - message: `${wsAction} > WS Connection ID '${wsWrapper.guid}' - Lock is taken: Wait and try to acquire the lock after ${Constants.WS_LOCK_TIME_OUT_MILLIS} ms...`, - detailedMessages: { wsWrapper: this.getWSWrapperData(wsWrapper) } - }); - this.waitingWSMessages++; - // eslint-disable-next-line no-constant-condition - while (true) { - // Wait - await Utils.sleep(Constants.WS_LOCK_TIME_OUT_MILLIS); - numberOfTrials++; - // Message has been processed - if (!this.runningWSRequestsMessages[wsWrapper.url]) { - await Logging.logInfo({ - tenantID: Constants.DEFAULT_TENANT_ID, - chargingStationID: wsWrapper.chargingStationID, - action, module: MODULE_NAME, method: 'waitForWSLockToRelease', - message: `${wsAction} > WS Connection ID '${wsWrapper.guid}' - Lock has been acquired successfully after ${numberOfTrials} trial(s) and ${Utils.computeTimeDurationSecs(timeStart)} secs`, - detailedMessages: { wsWrapper: this.getWSWrapperData(wsWrapper) } - }); - // Free the lock - this.waitingWSMessages--; - break; - } - // Handle remaining trial - if (numberOfTrials >= maxNumberOfTrials) { - // Abnormal situation: The lock should not be taken for so long! - await Logging.logError({ - tenantID: Constants.DEFAULT_TENANT_ID, - chargingStationID: wsWrapper.chargingStationID, - action, module: MODULE_NAME, method: 'waitForWSLockToRelease', - message: `${wsAction} > WS Connection ID '${wsWrapper.guid}' - Cannot acquire the lock after ${numberOfTrials} trial(s) and ${Utils.computeTimeDurationSecs(timeStart)} secs - Lock will be forced to be released`, - detailedMessages: { wsWrapper: this.getWSWrapperData(wsWrapper) } - }); - // Free the lock - this.waitingWSMessages--; - break; - } - } - } - return true; - } - - private async pingWebSocket(wsWrapper: WSWrapper): Promise { + private pingWebSocket(wsWrapper: WSWrapper): WebSocketPingResult { try { // Ping the WS - wsWrapper.ping(); + wsWrapper.ping('OCPPJ Ping'); // Reset wsWrapper.nbrPingFailed = 0; return { @@ -555,19 +560,19 @@ export default class JsonOCPPServer extends OCPPServer { wsWrapper.nbrPingFailed++; // Close WS if (wsWrapper.nbrPingFailed >= Constants.WS_MAX_NBR_OF_FAILED_PINGS) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, - chargingStationID: wsWrapper.chargingStationID, + ...LoggingHelper.getWSWrapperProperties(wsWrapper), action: ServerAction.WS_SERVER_CONNECTION_PING, module: MODULE_NAME, method: 'pingWebSocket', message: `${WebSocketAction.PING} > Failed to ping the WS Connection ID '${wsWrapper.guid}' after ${wsWrapper.nbrPingFailed} trial(s), will be removed from WS cache`, detailedMessages: { wsWrapper: this.getWSWrapperData(wsWrapper), error: error.stack } }); - await this.closeWebSocket(WebSocketAction.PING, ServerAction.WS_SERVER_CONNECTION_PING, wsWrapper, + this.closeWebSocket(WebSocketAction.PING, ServerAction.WS_SERVER_CONNECTION_PING, wsWrapper, WebSocketCloseEventStatusCode.CLOSE_ABNORMAL, `${WebSocketAction.PING} > WS Connection ID '${wsWrapper.guid}' has been closed by server after ${wsWrapper.nbrPingFailed} failed ping`); } else { - await Logging.logWarning({ + Logging.beWarning()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, - chargingStationID: wsWrapper.chargingStationID, + ...LoggingHelper.getWSWrapperProperties(wsWrapper), action: ServerAction.WS_SERVER_CONNECTION_PING, module: MODULE_NAME, method: 'pingWebSocket', message: `${WebSocketAction.PING} > Failed to ping the WS Connection ID '${wsWrapper.guid}' after ${wsWrapper.nbrPingFailed} trial(s) (${Constants.WS_MAX_NBR_OF_FAILED_PINGS - wsWrapper.nbrPingFailed} remaining)`, detailedMessages: { wsWrapper: this.getWSWrapperData(wsWrapper), error: error.stack } @@ -581,17 +586,17 @@ export default class JsonOCPPServer extends OCPPServer { } } - private async closeWebSocket(wsAction: WebSocketAction, action: ServerAction, wsWrapper: WSWrapper, code: WebSocketCloseEventStatusCode, message: string): Promise { + private closeWebSocket(wsAction: WebSocketAction, action: ServerAction, wsWrapper: WSWrapper, code: WebSocketCloseEventStatusCode, message: string): void { // Close WS - if (!wsWrapper.closed) { + if (!wsWrapper.isClosed()) { try { - wsWrapper.close(code, message); - await this.logWSConnectionClosed(wsWrapper, action, code, message); + wsWrapper.end(code, message); + this.logWSConnectionClosed(wsWrapper, action, code, message); } catch (error) { // Just log and ignore issue - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, - chargingStationID: wsWrapper.chargingStationID, + ...LoggingHelper.getWSWrapperProperties(wsWrapper), action, module: MODULE_NAME, method: 'closeWebSocket', message: `${wsAction} > Failed to close WS Connection ID '${wsWrapper.guid}': ${error.message as string}`, detailedMessages: { error: error.stack, wsWrapper: this.getWSWrapperData(wsWrapper) } @@ -599,55 +604,20 @@ export default class JsonOCPPServer extends OCPPServer { } } // Remove connection - await this.removeWSWrapper(wsAction, action, wsWrapper); - } - - private async setWSConnection(wsAction: WebSocketAction, action: ServerAction, wsConnection: WSConnection, wsWrapper: WSWrapper) { - // Reference a Json WebSocket connection object - if (wsWrapper.protocol === WSServerProtocol.OCPP16) { - this.jsonWSConnections.set(wsConnection.getID(), wsConnection as JsonWSConnection); - await Logging.logDebug({ - tenantID: Constants.DEFAULT_TENANT_ID, - chargingStationID: wsWrapper.chargingStationID, - action, module: MODULE_NAME, method: 'setWSConnection', - message: `${wsAction} > WS Connection ID '${wsWrapper.guid}' has been added in the WS cache`, - detailedMessages: { wsWrapper: this.getWSWrapperData(wsWrapper) } - }); - } - if (wsWrapper.protocol === WSServerProtocol.REST) { - this.jsonRestWSConnections.set(wsConnection.getID(), wsConnection as JsonRestWSConnection); - await Logging.logDebug({ - tenantID: Constants.DEFAULT_TENANT_ID, - chargingStationID: wsWrapper.chargingStationID, - action, module: MODULE_NAME, method: 'setWSConnection', - message: `${wsAction} > WS Connection ID '${wsWrapper.guid}' has been added in the WS cache`, - detailedMessages: { wsWrapper: this.getWSWrapperData(wsWrapper) } - }); - } - wsWrapper.wsConnection = wsConnection; - } - - private getWSConnectionFromProtocolAndID(protocol: WSServerProtocol, wsConnectionID: string): WSConnection { - if (protocol === WSServerProtocol.OCPP16) { - return this.jsonWSConnections.get(wsConnectionID); - } - if (protocol === WSServerProtocol.REST) { - return this.jsonRestWSConnections.get(wsConnectionID); - } + this.removeWSWrapper(wsAction, action, wsWrapper); } - private async removeWSWrapper(wsAction: WebSocketAction, action: ServerAction, wsWrapper: WSWrapper): Promise { + private removeWSWrapper(wsAction: WebSocketAction, action: ServerAction, wsWrapper: WSWrapper): void { if (wsWrapper.protocol === WSServerProtocol.OCPP16) { - await this.removeWSConnection( + this.removeWSConnection( wsAction, action, wsWrapper.wsConnection, this.jsonWSConnections); - } - if (wsWrapper.protocol === WSServerProtocol.REST) { - await this.removeWSConnection( + } else if (wsWrapper.protocol === WSServerProtocol.REST) { + this.removeWSConnection( wsAction, action, wsWrapper.wsConnection, this.jsonRestWSConnections); } } - private async removeWSConnection(wsAction: WebSocketAction, action: ServerAction, wsConnection: WSConnection, wsConnections: Map): Promise { + private removeWSConnection(wsAction: WebSocketAction, action: ServerAction, wsConnection: WSConnection, wsConnections: Map): void { if (wsConnection) { const wsWrapper = wsConnection.getWS(); const existingWsConnection = wsConnections.get(wsConnection.getID()); @@ -656,22 +626,19 @@ export default class JsonOCPPServer extends OCPPServer { // Check id same WS Connection if (existingWsWrapper.guid === wsWrapper.guid) { // Remove from WS Cache - if ((Utils.isMonitoringEnabled()) && (wsWrapper.protocol === WSServerProtocol.OCPP16)){ - wsWrapper.ocppClosedWebSocketMetricCounter.inc(); - } wsConnections.delete(wsConnection.getID()); - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, - chargingStationID: wsWrapper.chargingStationID, + ...LoggingHelper.getWSWrapperProperties(wsWrapper), action, module: MODULE_NAME, method: 'setWSConnection', message: `${wsAction} > WS Connection ID '${wsWrapper.guid}' has been removed from the WS cache`, detailedMessages: { wsWrapper: this.getWSWrapperData(wsWrapper) } }); } else { // WS Connection not identical - await Logging.logWarning({ + Logging.beWarning()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, - chargingStationID: wsWrapper.chargingStationID, + ...LoggingHelper.getWSWrapperProperties(wsWrapper), action, module: MODULE_NAME, method: 'removeWSConnection', message: `${wsAction} > Failed to remove WS Connection ID '${wsWrapper.guid}' from WS cache due to an already existing WS with different ID '${existingWsWrapper.guid}'`, detailedMessages: { wsWrapper: this.getWSWrapperData(wsWrapper), existingWsWrapper: this.getWSWrapperData(existingWsWrapper) } @@ -679,9 +646,9 @@ export default class JsonOCPPServer extends OCPPServer { } } else { // WS Connection not found - await Logging.logWarning({ + Logging.beWarning()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, - chargingStationID: wsWrapper.chargingStationID, + ...LoggingHelper.getWSWrapperProperties(wsWrapper), action, module: MODULE_NAME, method: 'removeWSConnection', message: `${wsAction} > Failed to remove WS Connection ID '${wsWrapper.guid}' from WS cache as it does not exist anymore in it`, detailedMessages: { wsWrapper: this.getWSWrapperData(wsWrapper) } @@ -695,59 +662,69 @@ export default class JsonOCPPServer extends OCPPServer { } private monitorWSConnections() { + // Do it once at startup - wait a bit to have some charger already connected + Utils.sleep(5000).then(() => { + this._monitorWSConnections(); + }).catch(() => { /* Intentional */ }); + // Then do it again from time to time setInterval(() => { - try { - // Log size of WS Json Connections (track leak) - let sizeOfCurrentRequestsBytes = 0, numberOfCurrentRequests = 0; - for (const jsonWSConnection of Array.from(this.jsonWSConnections.values())) { - const currentOcppRequests = jsonWSConnection.getCurrentOcppRequests(); - sizeOfCurrentRequestsBytes += sizeof(currentOcppRequests); - numberOfCurrentRequests += Object.keys(currentOcppRequests).length; - } - // Log Stats on number of WS Connections - Logging.logDebug({ - tenantID: Constants.DEFAULT_TENANT_ID, - action: ServerAction.WS_SERVER_CONNECTION, module: MODULE_NAME, method: 'monitorWSConnections', - message: `${this.jsonWSConnections.size} WS connections, ${this.jsonRestWSConnections.size} REST connections, ${this.runningWSMessages} Messages, ${Object.keys(this.runningWSRequestsMessages).length} Requests, ${this.waitingWSMessages} queued WS Message(s)`, - detailedMessages: [ - `${numberOfCurrentRequests} JSON WS Requests cached`, - `${sizeOfCurrentRequestsBytes / 1000} kB used in JSON WS cache` - ] - }).catch(() => { /* Intentional */ }); - if (Utils.isMonitoringEnabled()) { - global.monitoringServer.getGauge(Constants.WEB_SOCKET_RUNNING_REQUEST_RESPONSE).set(this.runningWSMessages); - global.monitoringServer.getGauge(Constants.WEB_SOCKET_OCPP_CONNECTIONS_COUNT).set(this.jsonWSConnections.size); - global.monitoringServer.getGauge(Constants.WEB_SOCKET_REST_CONNECTIONS_COUNT).set(this.jsonRestWSConnections.size); - global.monitoringServer.getGauge(Constants.WEB_SOCKET_CURRENT_REQUEST).set(numberOfCurrentRequests); - global.monitoringServer.getGauge(Constants.WEB_SOCKET_RUNNING_REQUEST).set(Object.keys(this.runningWSRequestsMessages).length); - global.monitoringServer.getGauge(Constants.WEB_SOCKET_QUEUED_REQUEST).set(this.waitingWSMessages); - } - if (this.isDebug()) { - Logging.logConsoleDebug('====================================='); - Logging.logConsoleDebug(`** ${this.jsonWSConnections.size} JSON Connection(s)`); - Logging.logConsoleDebug(`** ${numberOfCurrentRequests} JSON WS Requests in cache with a size of ${sizeOfCurrentRequestsBytes / 1000} kB`); - Logging.logConsoleDebug(`** ${this.jsonRestWSConnections.size} REST Connection(s)`); - Logging.logConsoleDebug(`** ${Object.keys(this.runningWSRequestsMessages).length} running WS Requests`); - Logging.logConsoleDebug(`** ${this.runningWSMessages} running WS Messages (Requests + Responses)`); - Logging.logConsoleDebug(`** ${this.waitingWSMessages} queued WS Message(s)`); - Logging.logConsoleDebug('====================================='); - } - } catch (error) { - /* Intentional */ - } + this._monitorWSConnections(); }, Configuration.getChargingStationConfig().monitoringIntervalOCPPJSecs * 1000); } + private _monitorWSConnections() { + try { + // Log size of WS Json Connections (track leak) + let sizeOfPendingCommands = 0, numberOfPendingCommands = 0; + for (const jsonWSConnection of Array.from(this.jsonWSConnections.values())) { + const pendingCommands = jsonWSConnection.getPendingOccpCommands(); + sizeOfPendingCommands += sizeof(pendingCommands); + numberOfPendingCommands += Object.keys(pendingCommands).length; + } + // Log Stats on number of WS Connections + Logging.beDebug()?.log({ + tenantID: Constants.DEFAULT_TENANT_ID, + action: ServerAction.WS_SERVER_CONNECTION, module: MODULE_NAME, method: 'monitorWSConnections', + message: `${this.jsonWSConnections.size} WS connections, ${this.jsonRestWSConnections.size} REST connections, ${this.runningWSMessages} Messages, ${numberOfPendingCommands} pending OCPP commands`, + detailedMessages: [ + `${numberOfPendingCommands} pending OCPP commands - ${sizeOfPendingCommands / 1000} kB` + ] + }); + if (Utils.isMonitoringEnabled()) { + global.monitoringServer.getGauge(Constants.WEB_SOCKET_RUNNING_REQUEST).set(this.runningWSMessages); + global.monitoringServer.getGauge(Constants.WEB_SOCKET_OCPP_CONNECTIONS_COUNT).set(this.jsonWSConnections.size); + global.monitoringServer.getGauge(Constants.WEB_SOCKET_REST_CONNECTIONS_COUNT).set(this.jsonRestWSConnections.size); + global.monitoringServer.getGauge(Constants.WEB_SOCKET_CURRENT_REQUEST).set(numberOfPendingCommands); + // global.monitoringServer.getGauge(Constants.WEB_SOCKET_RUNNING_REQUEST).set(Object.keys(this.runningWSRequestsMessages).length); + // global.monitoringServer.getGauge(Constants.WEB_SOCKET_QUEUED_REQUEST).set(this.waitingWSMessages); + } + if (this.isDebug()) { + Logging.logConsoleDebug('====================================='); + Logging.logConsoleDebug(`** ${this.jsonWSConnections.size} JSON Connection(s)`); + Logging.logConsoleDebug(`** ${numberOfPendingCommands} pending OCPP commands - Size: ${sizeOfPendingCommands / 1000} kB`); + Logging.logConsoleDebug(`** ${this.jsonRestWSConnections.size} REST Connection(s)`); + Logging.logConsoleDebug(`** ${this.runningWSMessages} running WS Messages (Requests + Responses)`); + Logging.logConsoleDebug('====================================='); + } + } catch (error) { + /* Intentional */ + } + } + private checkAndCleanupAllWebSockets() { setInterval(() => { - // Check Json connections - this.checkAndCleanupWebSockets(this.jsonWSConnections, 'CS').catch(() => { /* Intentional */ }); - // Check Rest connections - this.checkAndCleanupWebSockets(this.jsonRestWSConnections, 'REST').catch(() => { /* Intentional */ }); + try { + // Check Json connections + this.checkAndCleanupWebSockets(this.jsonWSConnections, 'CS'); + // Check Rest connections + this.checkAndCleanupWebSockets(this.jsonRestWSConnections, 'REST'); + } catch (error) { + /* Intentional */ + } }, Configuration.getChargingStationConfig().pingIntervalOCPPJSecs * 1000); } - private async checkAndCleanupWebSockets(wsConnections: Map, type: 'CS'|'REST') { + private checkAndCleanupWebSockets(wsConnections: Map, type: 'CS'|'REST'): void { const validConnections: Record[] = [], invalidConnections: Record[] = []; const timeStart = Date.now(); const wsConnectionKeys = Array.from(wsConnections.keys()); @@ -758,7 +735,7 @@ export default class JsonOCPPServer extends OCPPServer { // Get the WS const wsWrapper = wsConnection.getWS(); // Check WS - const result = await this.pingWebSocket(wsWrapper); + const result = this.pingWebSocket(wsWrapper); if (result.ok) { validConnections.push(this.getWSWrapperData(wsWrapper)); } else { @@ -770,14 +747,14 @@ export default class JsonOCPPServer extends OCPPServer { const message = `Total of ${wsConnectionKeys.length} ${type} WS connection(s) pinged in ${Utils.computeTimeDurationSecs(timeStart)} secs: ${validConnections.length} valid, ${invalidConnections.length} invalid`; this.isDebug() && Logging.logConsoleDebug(message); if (invalidConnections.length) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, module: MODULE_NAME, method: 'checkAndCleanupWebSockets', action: ServerAction.WS_SERVER_CONNECTION_PING, - message, detailedMessages: { invalidConnections, /* validConnections */ } + message, /* detailedMessages: { invalidConnections, validConnections } */ }); } else { - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, module: MODULE_NAME, method: 'checkAndCleanupWebSockets', action: ServerAction.WS_SERVER_CONNECTION_PING, @@ -790,18 +767,15 @@ export default class JsonOCPPServer extends OCPPServer { private getWSWrapperData(wsWrapper: WSWrapper): Record { return { - key: wsWrapper.key, + tenantID: wsWrapper.wsConnection?.getTenantID(), + key: wsWrapper.wsConnection?.getID(), guid: wsWrapper.guid, nbrPingFailed: wsWrapper.nbrPingFailed, - siteID: wsWrapper.siteID, - siteAreaID: wsWrapper.siteAreaID, - companyID: wsWrapper.companyID, - chargingStationID: wsWrapper.chargingStationID, - tenantID: wsWrapper.tenantID, tokenID: wsWrapper.tokenID, + ...LoggingHelper.getWSConnectionProperties(wsWrapper.wsConnection), url: wsWrapper.url, clientIP: wsWrapper.clientIP, - closed: wsWrapper.closed, + closed: wsWrapper.isClosed(), protocol: wsWrapper.protocol, remoteAddress: wsWrapper.remoteAddress, firstConnectionDate: wsWrapper.firstConnectionDate, @@ -810,4 +784,97 @@ export default class JsonOCPPServer extends OCPPServer { lastPongDate: wsWrapper.lastPongDate, }; } + + private massUpdateChargingStationsLastSeen() { + setInterval(() => { + this._massUpdateChargingStationsLastSeen().catch((error) => { + Logging.logPromiseError(error); + }); + }, (Configuration.getChargingStationConfig().pingIntervalOCPPJSecs / 3) * 1000); + } + + private async _massUpdateChargingStationsLastSeen() { + const lastUpdatedChargingStationsLastSeen = new Date(); + const lastSeenChargingStationsMap = new Map(); + let numberOfUpdatedChargingStations = 0; + try { + for (const jsonWSConnection of this.jsonWSConnections.values()) { + const wsWrapper = jsonWSConnection.getWS(); + let lastSeenDate: Date; + // Check Ping date + if (wsWrapper.lastPingDate) { + lastSeenDate = wsWrapper.lastPingDate; + } + // Check Pong date + if ((!lastSeenDate && wsWrapper.lastPongDate) || + (lastSeenDate && wsWrapper.lastPongDate && lastSeenDate.getTime() < wsWrapper.lastPongDate.getTime())) { + lastSeenDate = wsWrapper.lastPongDate; + } + // Check Last Message date + if ((!lastSeenDate && wsWrapper.lastMessageDate) || + (lastSeenDate && wsWrapper.lastMessageDate && lastSeenDate.getTime() < wsWrapper.lastMessageDate.getTime())) { + lastSeenDate = wsWrapper.lastMessageDate; + } + // Process lastSeen? + if (lastSeenDate && lastSeenDate.getTime() > this.lastUpdatedChargingStationsLastSeen.getTime()) { + // Round last seen for mass update + lastSeenDate.setMilliseconds(0); + lastSeenDate.setSeconds(lastSeenDate.getSeconds() - (lastSeenDate.getSeconds() % 10)); // Round seconds down + // Keep them for later mass update + const lastSeenChargingStationsKey = `${wsWrapper.wsConnection.getTenantID()}-${lastSeenDate.getTime()}`; + const lastSeenChargingStation = lastSeenChargingStationsMap.get(lastSeenChargingStationsKey); + if (!lastSeenChargingStation) { + // Create the entry and add Charging Station to update + lastSeenChargingStationsMap.set(lastSeenChargingStationsKey, { + tenant: jsonWSConnection.getTenant(), + lastSeenDate: lastSeenDate, + chargingStationIDs: [wsWrapper.wsConnection.getChargingStationID()], + }); + } else { + // Add Charging Station to update + lastSeenChargingStation.chargingStationIDs.push( + wsWrapper.wsConnection.getChargingStationID()); + } + } + } + // Process mass update lastSeen field + for (const lastSeenChargingStation of lastSeenChargingStationsMap.values()) { + await ChargingStationStorage.saveChargingStationsLastSeen( + lastSeenChargingStation.tenant, + lastSeenChargingStation.chargingStationIDs, + lastSeenChargingStation.lastSeenDate + ); + numberOfUpdatedChargingStations += lastSeenChargingStation.chargingStationIDs.length; + } + // Next round + this.lastUpdatedChargingStationsLastSeen = lastUpdatedChargingStationsLastSeen; + Logging.beInfo()?.log({ + tenantID: Constants.DEFAULT_TENANT_ID, + action: ServerAction.WS_SERVER_CONNECTION_LAST_SEEN, + module: MODULE_NAME, method: 'massUpdateChargingStationsLastSeen', + message: `${numberOfUpdatedChargingStations} Charging Stations have been updated successfully (${lastSeenChargingStationsMap.size} grouped updates)`, + detailedMessages: { lastSeenChargingStations: Array.from(lastSeenChargingStationsMap.values()) + .map((lastSeenChargingStation) => + ({ + tenant: { + id: lastSeenChargingStation.tenant.id, + subdomain: lastSeenChargingStation.tenant.subdomain, + }, + lastSeen: lastSeenChargingStation.lastSeenDate.toISOString(), + chargingStationIDs: lastSeenChargingStation.chargingStationIDs, + }) + ) + } + }); + } catch (error) { + Logging.beError()?.log({ + tenantID: Constants.DEFAULT_TENANT_ID, + action: ServerAction.WS_SERVER_CONNECTION_LAST_SEEN, + module: MODULE_NAME, method: 'massUpdateChargingStationsLastSeen', + message: 'Failed to update Charging Station\'s Last Seen', + detailedMessages: { error: error.stack } + }); + } + } + } diff --git a/src/server/ocpp/json/services/JsonChargingStationService.ts b/src/server/ocpp/json/services/JsonChargingStationService.ts index 05ce8fbd8e..e1116bbbad 100644 --- a/src/server/ocpp/json/services/JsonChargingStationService.ts +++ b/src/server/ocpp/json/services/JsonChargingStationService.ts @@ -45,9 +45,9 @@ export default class JsonChargingStationService { } public async handleBootNotification(headers: OCPPHeader, payload: OCPPBootNotificationRequest): Promise { - const { chargeBoxIdentity, tenant } = headers; - const keyString = `${tenant.subdomain}:${chargeBoxIdentity}`; - await this.checkRateLimiters(tenant, chargeBoxIdentity, this.limitersBootNotifs, keyString); + const { chargeBoxIdentity, connectionContext } = headers; + const keyString = `${connectionContext.tenant.subdomain}:${chargeBoxIdentity}`; + await this.checkRateLimiters(connectionContext.tenant, chargeBoxIdentity, this.limitersBootNotifs, keyString); const result = await this.handle(Command.BOOT_NOTIFICATION, headers, payload); return { currentTime: result.currentTime, @@ -93,7 +93,8 @@ export default class JsonChargingStationService { } public async handleStartTransaction(headers: OCPPHeader, payload: OCPPStartTransactionRequest): Promise { - const { chargingStation, tenant } = headers; + const { connectionContext } = headers; + const { chargingStation, tenant } = connectionContext; const key = { connector: payload.connectorId, tenant: tenant.subdomain, chargingStation: chargingStation.id } ; const keyString = `${key.connector}:${key.tenant}:${key.chargingStation}`; await this.checkRateLimiters(tenant, chargingStation.id, this.limitersStartStopTransaction, keyString); @@ -114,7 +115,8 @@ export default class JsonChargingStationService { } public async handleStopTransaction(headers: OCPPHeader, payload: OCPPStopTransactionRequest): Promise { - const { chargingStation, tenant } = headers; + const { connectionContext } = headers; + const { chargingStation, tenant } = connectionContext; const key = { tenant: tenant.subdomain, chargingStation: chargingStation.id } ; const keyString = `${key.tenant}:${key.chargingStation}`; await this.checkRateLimiters(tenant, chargingStation.id, this.limitersStartStopTransaction, keyString); @@ -126,11 +128,11 @@ export default class JsonChargingStationService { }; } - private async handle(command: Command, headers: OCPPHeader, payload) { + private async handle(command: Command, headers: OCPPHeader, payload): Promise { try { - return this.chargingStationService[`handle${command}`](headers, payload); + return this.chargingStationService[`handle${command}`](headers, payload) as Promise; } catch (error) { - await Logging.logException(error, OCPPUtils.buildServerActionFromOcppCommand(command), MODULE_NAME, command, headers.tenantID); + Logging.logException(error as Error, OCPPUtils.buildServerActionFromOcppCommand(command), MODULE_NAME, command, headers.rawConnectionData?.tenantID); throw error; } } diff --git a/src/server/ocpp/json/web-socket/JsonRestWSConnection.ts b/src/server/ocpp/json/web-socket/JsonRestWSConnection.ts index c4af0cc70f..fdad588fb7 100644 --- a/src/server/ocpp/json/web-socket/JsonRestWSConnection.ts +++ b/src/server/ocpp/json/web-socket/JsonRestWSConnection.ts @@ -1,6 +1,7 @@ import BackendError from '../../../../exception/BackendError'; import ChargingStationStorage from '../../../../storage/mongodb/ChargingStationStorage'; import { Command } from '../../../../types/ChargingStation'; +import LoggingHelper from '../../../../utils/LoggingHelper'; import OCPPUtils from '../../utils/OCPPUtils'; import WSConnection from './WSConnection'; import WSWrapper from './WSWrapper'; @@ -23,10 +24,7 @@ export default class JsonRestWSConnection extends WSConnection { // Check Command if (!this.isValidOcppClientCommand(command)) { throw new BackendError({ - chargingStationID: this.getChargingStationID(), - siteID: this.getSiteID(), - siteAreaID: this.getSiteAreaID(), - companyID: this.getCompanyID(), + ...LoggingHelper.getWSConnectionProperties(this), module: MODULE_NAME, method: 'handleRequest', message: `Command '${command}' is not allowed from REST server`, @@ -37,10 +35,7 @@ export default class JsonRestWSConnection extends WSConnection { const chargingStation = await ChargingStationStorage.getChargingStation(this.getTenant(), this.getChargingStationID()); if (!chargingStation) { throw new BackendError({ - chargingStationID: this.getChargingStationID(), - siteID: this.getSiteID(), - siteAreaID: this.getSiteAreaID(), - companyID: this.getCompanyID(), + ...LoggingHelper.getWSConnectionProperties(this), module: MODULE_NAME, method: 'handleRequest', message: 'Charging Station not found', @@ -48,13 +43,10 @@ export default class JsonRestWSConnection extends WSConnection { }); } // Get the client from JSON Server - const chargingStationClient = await global.centralSystemJsonServer.getChargingStationClient(this.getTenant(), chargingStation); + const chargingStationClient = global.centralSystemJsonServer.getChargingStationClient(this.getTenant(), chargingStation); if (!chargingStationClient) { throw new BackendError({ - chargingStationID: this.getChargingStationID(), - siteID: this.getSiteID(), - siteAreaID: this.getSiteAreaID(), - companyID: this.getCompanyID(), + ...LoggingHelper.getWSConnectionProperties(this), module: MODULE_NAME, method: 'handleRequest', message: 'Charging Station is not connected to the backend', @@ -69,10 +61,7 @@ export default class JsonRestWSConnection extends WSConnection { result = await chargingStationClient[actionMethod](commandPayload); } else { throw new BackendError({ - chargingStationID: this.getChargingStationID(), - siteID: this.getSiteID(), - siteAreaID: this.getSiteAreaID(), - companyID: this.getCompanyID(), + ...LoggingHelper.getWSConnectionProperties(this), module: MODULE_NAME, method: 'handleRequest', message: `'${actionMethod}' is not implemented`, @@ -82,10 +71,14 @@ export default class JsonRestWSConnection extends WSConnection { return result; } - public async onPing(message: string): Promise { + public onPing(message: string): void { } - public async onPong(message: string): Promise { + public onPong(message: string): void { + } + + public async updateChargingStationRuntimeData(): Promise { + // Do not update Charging Station when called by REST server } private isValidOcppClientCommand(command: Command): boolean { diff --git a/src/server/ocpp/json/web-socket/JsonWSConnection.ts b/src/server/ocpp/json/web-socket/JsonWSConnection.ts index ae2f1dc8da..197e462312 100644 --- a/src/server/ocpp/json/web-socket/JsonWSConnection.ts +++ b/src/server/ocpp/json/web-socket/JsonWSConnection.ts @@ -1,20 +1,21 @@ -import ChargingStation, { Command } from '../../../../types/ChargingStation'; import { OCPPProtocol, OCPPVersion } from '../../../../types/ocpp/OCPPServer'; import BackendError from '../../../../exception/BackendError'; import ChargingStationClient from '../../../../client/ocpp/ChargingStationClient'; import ChargingStationStorage from '../../../../storage/mongodb/ChargingStationStorage'; -import { PerformanceRecordGroup } from '../../../../types/Performance'; +import { Command } from '../../../../types/ChargingStation'; import Configuration from '../../../../utils/Configuration'; import Constants from '../../../../utils/Constants'; import JsonChargingStationClient from '../../../../client/ocpp/json/JsonChargingStationClient'; -import Utils from '../../../../utils/Utils'; import JsonChargingStationService from '../services/JsonChargingStationService'; import Logging from '../../../../utils/Logging'; +import LoggingHelper from '../../../../utils/LoggingHelper'; import OCPPError from '../../../../exception/OcppError'; import { OCPPErrorType } from '../../../../types/ocpp/OCPPCommon'; import { OCPPHeader } from '../../../../types/ocpp/OCPPHeader'; import OCPPUtils from '../../utils/OCPPUtils'; +import { ServerAction } from '../../../../types/Server'; +import Utils from '../../../../utils/Utils'; import WSConnection from './WSConnection'; import WSWrapper from './WSWrapper'; @@ -23,8 +24,6 @@ const MODULE_NAME = 'JsonWSConnection'; export default class JsonWSConnection extends WSConnection { private chargingStationClient: JsonChargingStationClient; private chargingStationService: JsonChargingStationService; - private headers: OCPPHeader; - private lastSeen: Date; public constructor(ws: WSWrapper) { super(ws); @@ -33,25 +32,8 @@ export default class JsonWSConnection extends WSConnection { public async initialize(): Promise { // Init parent await super.initialize(); - // Initialize the default Headers - this.headers = { - chargeBoxIdentity: this.getChargingStationID(), - ocppVersion: (this.getWS().protocol.startsWith('ocpp') ? this.getWS().protocol.replace('ocpp', '') : this.getWS().protocol) as OCPPVersion, - ocppProtocol: OCPPProtocol.JSON, - chargingStationURL: Configuration.getJsonEndpointConfig().baseSecureUrl, - tenantID: this.getTenantID(), - tokenID: this.getTokenID(), - From: { - Address: this.getClientIP() - } - }; - if (Utils.isMonitoringEnabled()) { - const labelValues = { tenant: this.getTenant().subdomain }; - this.getWS().ocppOpenWebSocketMetricCounter = global.monitoringServer.getCounterClearableMetric(PerformanceRecordGroup.OCPP, 'OpenedWebSocket', 'Opened web sockets', labelValues); - this.getWS().ocppClosedWebSocketMetricCounter = global.monitoringServer.getCounterClearableMetric(PerformanceRecordGroup.OCPP, 'ClosedWebSocket', 'Closed web sockets', labelValues); - } // Create the Json Client - this.chargingStationClient = new JsonChargingStationClient(this, this.getTenant(), this.getChargingStationID()); + this.chargingStationClient = new JsonChargingStationClient(this); // Create the Json Server Service this.chargingStationService = new JsonChargingStationService(); } @@ -75,15 +57,26 @@ export default class JsonWSConnection extends WSConnection { const methodName = `handle${command}`; // Check if method exist in the service if (typeof this.chargingStationService[methodName] === 'function') { - this.headers.currentIPAddress = this.getClientIP(); - // Check the Charging Station - const { tenant, chargingStation, token } = await OCPPUtils.checkAndGetChargingStationConnectionData( - OCPPUtils.buildServerActionFromOcppCommand(command), - this.getTenantID(), this.getChargingStationID(), this.getTokenID()); + // Initialize the default Headers + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const headers: OCPPHeader = { + chargeBoxIdentity: this.getChargingStationID(), + ocppVersion: (this.getWS().protocol.startsWith('ocpp') ? this.getWS().protocol.replace('ocpp', '') : this.getWS().protocol) as OCPPVersion, + ocppProtocol: OCPPProtocol.JSON, + chargingStationURL: Configuration.getJsonEndpointConfig().baseSecureUrl, + rawConnectionData: { + tenantID: this.getTenantID(), + tokenID: this.getTokenID(), + chargingStationID: this.getChargingStationID() + }, + From: { + Address: this.getClientIP() + } + }; + headers.currentIPAddress = this.getClientIP(); // Set the header - this.headers.tenant = tenant; - this.headers.chargingStation = chargingStation; - this.headers.token = token; + headers.connectionContext = await OCPPUtils.checkAndGetChargingStationConnectionData( + OCPPUtils.buildServerActionFromOcppCommand(command), this.rawConnectionData); // Trace const performanceTracingData = await Logging.traceOcppMessageRequest(Constants.MODULE_JSON_OCPP_SERVER_16, this.getTenant(), this.getChargingStationID(), OCPPUtils.buildServerActionFromOcppCommand(command), commandPayload, '>>', @@ -91,13 +84,8 @@ export default class JsonWSConnection extends WSConnection { ); try { // Call it - result = await this.chargingStationService[methodName](this.headers, commandPayload); + result = await this.chargingStationService[methodName](headers, commandPayload); } finally { - // TODO - to be clarified - why should we clear the header here? - // Clean the header - // delete this.headers.chargingStation; - // delete this.headers.tenant; - // delete this.headers.token; // Trace await Logging.traceOcppMessageResponse(Constants.MODULE_JSON_OCPP_SERVER_16, this.getTenant(), this.getChargingStationID(), OCPPUtils.buildServerActionFromOcppCommand(command), commandPayload, result, '<<', @@ -107,10 +95,7 @@ export default class JsonWSConnection extends WSConnection { } else { // Throw Exception throw new OCPPError({ - chargingStationID: this.getChargingStationID(), - siteID: this.getSiteID(), - siteAreaID: this.getSiteAreaID(), - companyID: this.getCompanyID(), + ...LoggingHelper.getWSConnectionProperties(this), module: MODULE_NAME, method: 'handleRequest', code: OCPPErrorType.NOT_IMPLEMENTED, @@ -124,30 +109,46 @@ export default class JsonWSConnection extends WSConnection { return this.chargingStationClient; } - public setChargingStation(chargingStation: ChargingStation): void { - super.setChargingStation(chargingStation); - } - - public async onPing(message: string): Promise { - await this.updateChargingStationLastSeen(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars + public onPing(message: string): void { + // this.updateChargingStationLastSeen().catch(() => { /* Intentional */ }); + Logging.beDebug()?.log({ + ...LoggingHelper.getWSConnectionProperties(this), + tenantID: this.getTenantID(), + action: ServerAction.WS_CLIENT_CONNECTION_PING, + module: MODULE_NAME, method: 'onPing', + message: `Ping received from WS ID '${this.getWS()?.guid}'` + }); } - public async onPong(message: string): Promise { - await this.updateChargingStationLastSeen(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars + public onPong(message: string): void { + // this.updateChargingStationLastSeen().catch(() => { /* Intentional */ }); + Logging.beDebug()?.log({ + ...LoggingHelper.getWSConnectionProperties(this), + tenantID: this.getTenantID(), + action: ServerAction.WS_CLIENT_CONNECTION_PONG, + module: MODULE_NAME, method: 'onPong', + message: `Pong received from WS ID '${this.getWS()?.guid}'` + }); } - private async updateChargingStationLastSeen(): Promise { - // Update once every ping interval / 2 - if (!this.lastSeen || - (Date.now() - this.lastSeen.getTime()) > (Configuration.getChargingStationConfig().pingIntervalOCPPJSecs * 1000 / 2)) { - // Update last seen - this.lastSeen = new Date(); - const chargingStation = await ChargingStationStorage.getChargingStation(this.getTenant(), - this.getChargingStationID(), { issuer: true }, ['id']); - if (chargingStation) { - await ChargingStationStorage.saveChargingStationRuntimeData(this.getTenant(), this.getChargingStationID(), - { lastSeen: this.lastSeen }); - } + public async updateChargingStationRuntimeData() { + // Update Charging Station info + const chargingStation = this.getChargingStation(); + // First time the charging station connects, it does not yet exist + if (chargingStation) { + chargingStation.lastSeen = new Date(); + chargingStation.tokenID = this.getTokenID(); + chargingStation.cloudHostIP = Utils.getHostIP(); + chargingStation.cloudHostName = Utils.getHostName(); + // Save Charging Station runtime data + await ChargingStationStorage.saveChargingStationRuntimeData(this.getTenant(), chargingStation.id, { + lastSeen: chargingStation.lastSeen, + tokenID: chargingStation.tokenID, + cloudHostIP: chargingStation.cloudHostIP, + cloudHostName: chargingStation.cloudHostName, + }); } } diff --git a/src/server/ocpp/json/web-socket/WSConnection.ts b/src/server/ocpp/json/web-socket/WSConnection.ts index 5aac196863..b6a8ee2695 100644 --- a/src/server/ocpp/json/web-socket/WSConnection.ts +++ b/src/server/ocpp/json/web-socket/WSConnection.ts @@ -1,10 +1,13 @@ +/* eslint-disable @typescript-eslint/member-ordering */ import ChargingStation, { Command } from '../../../../types/ChargingStation'; -import { FctOCPPReject, FctOCPPResponse, OCPPErrorType, OCPPIncomingRequest, OCPPIncomingResponse, OCPPMessageType, OCPPRequest } from '../../../../types/ocpp/OCPPCommon'; +import { FctOCPPReject, FctOCPPResponse, OCPPErrorType, OCPPIncomingError, OCPPIncomingRequest, OCPPIncomingResponse, OCPPMessageType, OCPPPayload } from '../../../../types/ocpp/OCPPCommon'; +import { OcppConnectionContext, OcppRawConnectionData } from '../../../../types/ocpp/OCPPHeader'; import { ServerAction, WSServerProtocol } from '../../../../types/Server'; import BackendError from '../../../../exception/BackendError'; import Constants from '../../../../utils/Constants'; import Logging from '../../../../utils/Logging'; +import LoggingHelper from '../../../../utils/LoggingHelper'; import OCPPError from '../../../../exception/OcppError'; import OCPPUtils from '../../utils/OCPPUtils'; import Tenant from '../../../../types/Tenant'; @@ -13,311 +16,353 @@ import WSWrapper from './WSWrapper'; const MODULE_NAME = 'WSConnection'; +export class OcppPendingCommand { + private command: Command; + private resolveCallback: FctOCPPResponse; + private rejectCallback: FctOCPPReject; + private timer: NodeJS.Timeout; + + public constructor(command: Command, resolveCallback: FctOCPPResponse, rejectCallback: FctOCPPReject, timer: NodeJS.Timeout) { + this.command = command; + this.resolveCallback = resolveCallback; + this.rejectCallback = rejectCallback; + this.timer = timer; + } + + public getCommand(): Command { + return this.command; + } + + public resolve(payload: Record | string): void { + this.clearTimer(); + this.resolveCallback(payload); + } + + public reject(error: OCPPError): void { + this.clearTimer(); + this.rejectCallback(error); + } + + private clearTimer() { + const timer = this.timer; + if (timer) { + this.timer = null; + clearTimeout(timer); + } + } +} + export default abstract class WSConnection { - private siteID: string; - private siteAreaID: string; - private companyID: string; - private chargingStationID: string; - private tenantID: string; - private tenant: Tenant; - private tenantSubdomain: string; - private tokenID: string; + protected rawConnectionData: OcppRawConnectionData; + private connectionContext: OcppConnectionContext; + // private chargingStation: ChargingStation; + // private tenant: Tenant; private url: string; - private clientIP: string | string[]; - private ws: WSWrapper; - private ocppRequests: Record = {}; + private wsWrapper: WSWrapper; + private pendingOcppCommands: Record = {}; - public constructor(ws: WSWrapper) { + public constructor(wsWrapper: WSWrapper) { // Init - this.url = ws.url.trim().replace(/\b(\?|&).*/, ''); // Filter trailing URL parameters - this.ws = ws; - this.clientIP = ws.getRemoteAddress(); + this.wsWrapper = wsWrapper; + this.url = wsWrapper.url.trim().replace(/\b(\?|&).*/, ''); // Filter trailing URL parameters // Check mandatory fields - this.checkMandatoryFieldsInRequest(); + this.rawConnectionData = this.checkMandatoryFieldsInRequest(); } public async initialize(): Promise { // Do not update the lastSeen when the caller is the REST server! - const updateChargingStationData = (this.ws.protocol !== WSServerProtocol.REST); + const updateChargingStationData = (this.wsWrapper.protocol !== WSServerProtocol.REST); // Check and Get Charging Station data - const { tenant, chargingStation } = await OCPPUtils.checkAndGetChargingStationConnectionData( - ServerAction.WS_SERVER_CONNECTION, - this.getTenantID(), - this.getChargingStationID(), this.getTokenID(), - updateChargingStationData); - // Set - this.setTenant(tenant); - this.setChargingStation(chargingStation); + this.connectionContext = await OCPPUtils.checkAndGetChargingStationConnectionData(ServerAction.WS_SERVER_CONNECTION, this.rawConnectionData, updateChargingStationData); + // TBC - Avoid this reference + this.wsWrapper.setConnection(this); } - public async sendResponse(messageID: string, command: Command, response: Record): Promise> { - return this.sendMessage(messageID, OCPPMessageType.CALL_RESULT_MESSAGE, command, response); + public sendResponse(messageID: string, command: Command, initialPayload: OCPPPayload, response: OCPPPayload): void { + // Build Message + const messageType = OCPPMessageType.CALL_RESULT_MESSAGE; + const messageToSend = JSON.stringify([messageType, messageID, response]); + Utils.isDevelopmentEnv() && Logging.logConsoleDebug(`Send Response ${messageToSend} for '${this.wsWrapper.url }'`); + this.sendMessageInternal(messageToSend, command, initialPayload); } - public async sendError(messageID: string, error: OCPPError): Promise { - return this.sendMessage(messageID, OCPPMessageType.CALL_ERROR_MESSAGE, null, null, error); + public sendError(messageID: string, + initialCommand: Command, + initialPayload: OCPPPayload, + error: any): void { + // Build Error Message + const messageType = OCPPMessageType.CALL_ERROR_MESSAGE; + const errorCode = error.code ?? OCPPErrorType.GENERIC_ERROR; + const errorMessage = error.message ? error.message : ''; + const errorDetail = error.details ? error.details : {}; + const messageToSend = JSON.stringify([messageType, messageID, errorCode, errorMessage, errorDetail]); + Utils.isDevelopmentEnv() && Logging.logConsoleDebug(`Send Error ${messageToSend} for '${this.wsWrapper.url}'`); + this.sendMessageInternal(messageToSend, initialCommand, initialPayload); } - public async sendMessage(messageID: string, messageType: OCPPMessageType, command?: Command, data?: Record, error?: OCPPError): Promise { - // Create a promise - return new Promise((resolve, reject) => { - let messageToSend: string; - let messageProcessed = false; - let requestTimeout: NodeJS.Timer; + public async sendMessageAndWaitForResult(messageID: string, command: Command, dataToSend: OCPPPayload): Promise { + // Create a pending promise + const pendingPromise = new Promise((resolve, reject) => { + // Send the message to the charging station + const messageType = OCPPMessageType.CALL_MESSAGE; + const messageToSend = JSON.stringify([messageType, messageID, command, dataToSend]); // Function that will receive the request's response - const responseCallback = (payload?: Record | string): void => { - if (!messageProcessed) { - if (requestTimeout) { - clearTimeout(requestTimeout); - } - // Send response - messageProcessed = true; - delete this.ocppRequests[messageID]; - resolve(payload); - } + const responseCallback = (payload?: OCPPPayload | string): void => { + resolve(payload); }; // Function that will receive the request's rejection - const rejectCallback = (reason: string | OCPPError): void => { - if (!messageProcessed) { - if (requestTimeout) { - clearTimeout(requestTimeout); - } - // Send error - messageProcessed = true; - delete this.ocppRequests[messageID]; - const ocppError = reason instanceof OCPPError ? reason : new Error(reason); - reject(ocppError); - } + const rejectCallback = (error: OCPPError): void => { + reject(error); }; - // Type of message - switch (messageType) { - // Request - case OCPPMessageType.CALL_MESSAGE: - // Store Promise callback - this.ocppRequests[messageID] = [responseCallback, rejectCallback, command]; - // Build request - messageToSend = JSON.stringify([messageType, messageID, command, data]); - break; - // Response - case OCPPMessageType.CALL_RESULT_MESSAGE: - // Build response - messageToSend = JSON.stringify([messageType, messageID, data]); - break; - // Error Message - case OCPPMessageType.CALL_ERROR_MESSAGE: - // Build Error Message - messageToSend = JSON.stringify([messageType, messageID, error.code ?? OCPPErrorType.GENERIC_ERROR, error.message ? error.message : '', error.details ? error.details : {}]); - break; + // Make sure to reject automatically if we do not receive anything after 10 seconds + const timeout = setTimeout(() => { + // Remove it from the cache + this.consumePendingOcppCommands(messageID); + // Send some feedback + const timeoutError = new Error(`Timeout after ${Constants.OCPP_SOCKET_TIMEOUT_MILLIS / 1000} secs for Message ID '${messageID}' with content '${messageToSend} - (${this.getTenantSubDomain()})`); + reject(timeoutError); + }, Constants.OCPP_SOCKET_TIMEOUT_MILLIS); + // Let's send it + Utils.isDevelopmentEnv() && Logging.logConsoleDebug(`Send Message ${messageToSend} for '${this.wsWrapper.url }'`); + // Keep track of the pending promise + this.pendingOcppCommands[messageID] = new OcppPendingCommand(command, responseCallback, rejectCallback, timeout); + // Send the message + if (!this.sendMessageInternal(messageToSend)) { + // Well - we have not been able to send the message - Remove the pending promise from the cache + this.consumePendingOcppCommands(messageID); + // send some feedback + const unexpectedError = new Error(`Unexpected situation - Failed to send Message ID '${messageID}' with content '${messageToSend} - (${this.getTenantSubDomain()})`); + reject(unexpectedError); } - Utils.isDevelopmentEnv() && Logging.logConsoleDebug(`Send Message ${messageToSend} for '${this.ws.url }'`); - try { - // Send Message - if (!this.ws.send(messageToSend)) { - // Not always an error with uWebSocket: check BackPressure example - const message = `Error when sending message '${messageToSend}' to Web Socket`; - void Logging.logError({ - tenantID: this.tenantID, - chargingStationID: this.chargingStationID, - companyID: this.companyID, - siteID: this.siteID, - siteAreaID: this.siteAreaID, - module: MODULE_NAME, method: 'sendMessage', - action: ServerAction.WS_SERVER_CONNECTION_ERROR, - message, detailedMessages: { message: messageToSend } - }); - Utils.isDevelopmentEnv() && Logging.logConsoleError(message); - } - } catch (wsError) { - // Invalid Web Socket - const message = `Error when sending message '${messageToSend}' to Web Socket: ${wsError?.message as string}`; - void Logging.logError({ - tenantID: this.tenantID, - chargingStationID: this.chargingStationID, - companyID: this.companyID, - siteID: this.siteID, - siteAreaID: this.siteAreaID, - module: MODULE_NAME, method: 'sendMessage', + }); + // This promise is pending and will be resolved as soon as we get a response/error from the charging station + return pendingPromise; + } + + private sendMessageInternal( + messageToSend: string, + initialCommand: Command = null, + initialCommandPayload: OCPPPayload = null): boolean { + + // Extract raw connection data + const { tenantID, chargingStationID } = this.rawConnectionData; + let sent = false ; + try { + // Send Message + if (this.wsWrapper.send(messageToSend, initialCommand, initialCommandPayload)) { + sent = true; + } else { + // Not always an error with uWebSocket: check BackPressure example + const message = `Error when sending error '${messageToSend}' to Web Socket`; + Logging.beError()?.log({ + ...LoggingHelper.getChargingStationProperties(this.connectionContext.chargingStation), + tenantID, + chargingStationID, + module: MODULE_NAME, method: 'sendMessageInternal', action: ServerAction.WS_SERVER_CONNECTION_ERROR, - message, detailedMessages: { message: messageToSend, error: wsError?.stack } + message, detailedMessages: { + message: messageToSend + } }); Utils.isDevelopmentEnv() && Logging.logConsoleError(message); } - // Response? - if (messageType !== OCPPMessageType.CALL_MESSAGE) { - responseCallback(); + } catch (wsError) { + // Invalid Web Socket + const message = `Error when sending message '${messageToSend}' to Web Socket: ${wsError?.message as string}`; + Logging.beError()?.log({ + ...LoggingHelper.getChargingStationProperties(this.connectionContext.chargingStation), + tenantID, + chargingStationID, + module: MODULE_NAME, method: 'sendMessageInternal', + action: ServerAction.WS_SERVER_CONNECTION_ERROR, + message, detailedMessages: { + message: messageToSend, + error: wsError?.stack + } + }); + Utils.isDevelopmentEnv() && Logging.logConsoleError(message); + } + return sent; + } + + public async handleIncomingOcppMessage(wsWrapper: WSWrapper, ocppMessage: OCPPIncomingRequest|OCPPIncomingResponse|OCPPIncomingError): Promise { + const ocppMessageType = ocppMessage[0]; + // Extract raw connection data + const { tenantID, chargingStationID } = this.rawConnectionData; + try { + if (ocppMessageType === OCPPMessageType.CALL_MESSAGE) { + await wsWrapper.wsConnection.handleIncomingOcppRequest(wsWrapper, ocppMessage as OCPPIncomingRequest); + } else if (ocppMessageType === OCPPMessageType.CALL_RESULT_MESSAGE) { + wsWrapper.wsConnection.handleIncomingOcppResponse(ocppMessage as OCPPIncomingResponse); + } else if (ocppMessageType === OCPPMessageType.CALL_ERROR_MESSAGE) { + wsWrapper.wsConnection.handleIncomingOcppError(ocppMessage as OCPPIncomingError); } else { - // Trigger timeout - requestTimeout = setTimeout(() => { - rejectCallback(`Timeout after ${Constants.OCPP_SOCKET_TIMEOUT_MILLIS / 1000} secs for Message ID '${messageID}' with content '${messageToSend} (${this.tenantSubdomain})`); - }, Constants.OCPP_SOCKET_TIMEOUT_MILLIS); + Logging.beError()?.log({ + ...LoggingHelper.getChargingStationProperties(this.connectionContext.chargingStation), + tenantID, + chargingStationID, + action: ServerAction.UNKNOWN_ACTION, + message: `Wrong OCPP Message Type in '${JSON.stringify(ocppMessage)}'`, + module: MODULE_NAME, method: 'handleIncomingOcppMessage', + }); } - }); + } catch (error) { + Logging.beError()?.log({ + ...LoggingHelper.getChargingStationProperties(this.connectionContext.chargingStation), + tenantID, + chargingStationID, + action: ServerAction.UNKNOWN_ACTION, + message: `${error.message as string}`, + module: MODULE_NAME, method: 'handleIncomingOcppMessage', + detailedMessages: { data: JSON.stringify(ocppMessage), error: error.stack } + }); + } } - public async receivedMessage(message: string, isBinary: boolean): Promise { - let responseCallback: FctOCPPResponse; - let rejectCallback: FctOCPPReject; - let command: Command, commandPayload: Record, errorDetails: Record; - // Parse the data - const ocppMessage: OCPPIncomingRequest|OCPPIncomingResponse = JSON.parse(message); - const [messageType, messageID] = ocppMessage; - let result: any; + public async handleIncomingOcppRequest(wsWrapper: WSWrapper, ocppMessage: OCPPIncomingRequest): Promise { + // Extract raw connection data + const { tenantID, chargingStationID } = this.rawConnectionData; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const [messageType, messageID, command, commandPayload] = ocppMessage; try { - // Check the Type of message - switch (messageType) { - // Received Ocpp Request - case OCPPMessageType.CALL_MESSAGE: - // Get the data - [,,command,commandPayload] = ocppMessage as OCPPIncomingRequest; - try { - // Process the call - result = await this.handleRequest(command, commandPayload); - } catch (error) { - // Send Error Response - await this.sendError(messageID, error); - throw error; - } - // Send Response - await this.sendResponse(messageID, command, result); - break; - // Response to an OCPP Request - case OCPPMessageType.CALL_RESULT_MESSAGE: - // Get the data - [,,commandPayload] = ocppMessage as OCPPIncomingResponse; - // Respond - if (Array.isArray(this.ocppRequests[messageID])) { - [responseCallback,,command] = this.ocppRequests[messageID]; - } - if (!responseCallback) { - throw new BackendError({ - chargingStationID: this.getChargingStationID(), - siteID: this.getSiteID(), - siteAreaID: this.getSiteAreaID(), - companyID: this.getCompanyID(), - module: MODULE_NAME, method: 'onMessage', - message: `Unknown OCPP Request: '${message.toString()}'`, - }); - } - responseCallback(commandPayload); - break; - // Error Response to an OCPP Request - case OCPPMessageType.CALL_ERROR_MESSAGE: - [,,commandPayload,errorDetails] = ocppMessage as OCPPIncomingResponse; - if (Array.isArray(this.ocppRequests[messageID])) { - [,rejectCallback,command] = this.ocppRequests[messageID]; - } - if (!rejectCallback) { - throw new BackendError({ - chargingStationID: this.getChargingStationID(), - siteID: this.getSiteID(), - siteAreaID: this.getSiteAreaID(), - companyID: this.getCompanyID(), - module: MODULE_NAME, method: 'onMessage', - message: `Unknown OCPP Request: '${message.toString()}'`, - detailedMessages: { messageType, messageID, commandPayload, errorDetails } - }); - } - rejectCallback(new OCPPError({ - chargingStationID: this.getChargingStationID(), - siteID: this.getSiteID(), - siteAreaID: this.getSiteAreaID(), - companyID: this.getCompanyID(), - module: MODULE_NAME, method: 'onMessage', - code: command, - message: message.toString(), - })); - break; - default: - throw new BackendError({ - chargingStationID: this.getChargingStationID(), - siteID: this.getSiteID(), - siteAreaID: this.getSiteAreaID(), - companyID: this.getCompanyID(), - action: OCPPUtils.buildServerActionFromOcppCommand(command), - module: MODULE_NAME, method: 'onMessage', - message: `Wrong OCPP Message Type '${messageType as string}' for '${message.toString()}'`, - }); - } + // Process the call + const result = await this.handleRequest(command, commandPayload); + // Send Response + this.sendResponse(messageID, command, commandPayload, result as Record); } catch (error) { - await Logging.logError({ - tenantID: this.tenantID, - siteID: this.siteID, - siteAreaID: this.siteAreaID, - companyID: this.companyID, - chargingStationID: this.chargingStationID, + // Send Error Response + this.sendError(messageID, command, commandPayload, error); + Logging.beError()?.log({ + ...LoggingHelper.getChargingStationProperties(this.connectionContext.chargingStation), + tenantID, + chargingStationID, action: OCPPUtils.buildServerActionFromOcppCommand(command), message: `${error.message as string}`, + module: MODULE_NAME, method: 'handleIncomingOcppRequest', + detailedMessages: { data: ocppMessage, error: error.stack } + }); + } + } + + private consumePendingOcppCommands(messageID: string) { + const pendingOcppCommand = this.pendingOcppCommands[messageID]; + if (pendingOcppCommand) { + // It can be consumed only once - so we remove it from the cache + delete this.pendingOcppCommands[messageID]; + } + return pendingOcppCommand; + } + + public handleIncomingOcppResponse(ocppMessage: OCPPIncomingResponse): void { + let done = false; + // Parse the data + const [messageType, messageID, commandPayload] = ocppMessage as OCPPIncomingResponse; + // Consume the pending OCPP command matching the current OCPP error? + const ocppPendingCommand = this.consumePendingOcppCommands(messageID); + if (ocppPendingCommand) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + ocppPendingCommand.resolve(commandPayload); + done = true; + } + if (!done) { + // No OCPP request found ??? + // Is there anything to cleanup? + throw new BackendError({ + ...LoggingHelper.getWSConnectionProperties(this), + module: MODULE_NAME, method: 'handleIncomingOcppResponse', + message: `OCPP Request not found for a response to messageID: '${messageID}'`, + detailedMessages: { messageType, messageID, commandPayload } + }); + } + } + + public handleIncomingOcppError(ocppMessage: OCPPIncomingError): void { + let done = false; + const [messageType, messageID, message, errorDetails] = ocppMessage; + // Consume the pending OCPP command matching the current OCPP error? + const ocppPendingCommand = this.consumePendingOcppCommands(messageID); + if (ocppPendingCommand) { + ocppPendingCommand.reject(new OCPPError({ + ...LoggingHelper.getWSConnectionProperties(this), module: MODULE_NAME, method: 'onMessage', - detailedMessages: { data: message, error: error.stack } + code: ocppPendingCommand.getCommand(), + message: JSON.stringify(ocppMessage), + })); + done = true; + } + if (!done) { + // No OCPP request found ??? + // Is there anything to cleanup? + throw new BackendError({ + ...LoggingHelper.getWSConnectionProperties(this), + module: MODULE_NAME, method: 'handleIncomingOcppError', + message: `OCPP Request not found for an error response to messageID: '${messageID}'`, + detailedMessages: { messageType, messageID, message, errorDetails } }); } } public getWS(): WSWrapper { - return this.ws; + return this.wsWrapper; } public getURL(): string { return this.url; } + public getOriginalURL(): string { + return this.wsWrapper.url; + } + public getClientIP(): string | string[] { - return this.clientIP; + return this.wsWrapper.getRemoteAddress(); } - public setChargingStation(chargingStation: ChargingStation): void { - this.siteID = chargingStation?.siteID; - this.siteAreaID = chargingStation?.siteAreaID; - this.companyID = chargingStation?.companyID; + public getChargingStation(): ChargingStation { + return this.connectionContext?.chargingStation ; } public getSiteID(): string { - return this.siteID; + return this.connectionContext?.chargingStation?.siteID; } public getSiteAreaID(): string { - return this.siteAreaID; + return this.connectionContext?.chargingStation?.siteAreaID; } public getCompanyID(): string { - return this.companyID; + return this.connectionContext?.chargingStation?.companyID; } public getChargingStationID(): string { - return this.chargingStationID; + return this.rawConnectionData.chargingStationID; } public getTenantID(): string { - return this.tenantID; + return this.rawConnectionData.tenantID; } - public setTenant(tenant: Tenant): void { - this.tenantID = tenant.id; - this.tenantSubdomain = tenant.subdomain; - // Keep the minimum - this.tenant = { - id: this.tenantID, - subdomain: this.tenantSubdomain - } as Tenant; + public getTenantSubDomain(): string { + return this.connectionContext?.tenant.subdomain; } public getTenant(): Tenant { - return this.tenant; + return this.connectionContext?.tenant; } public getTokenID(): string { - return this.tokenID; + return this.rawConnectionData.tokenID; } public getID(): string { return `${this.getTenantID()}~${this.getChargingStationID()}`; } - public getCurrentOcppRequests(): Record { - return this.ocppRequests; + public getPendingOccpCommands(): Record { + return this.pendingOcppCommands; } - private checkMandatoryFieldsInRequest() { + private checkMandatoryFieldsInRequest(): OcppRawConnectionData { // Check URL: remove starting and trailing '/' if (this.url.endsWith('/')) { // Remove '/' @@ -327,8 +372,9 @@ export default abstract class WSConnection { // Remove '/' this.url = this.url.substring(1, this.url.length); } - // Parse URL: should be like /OCPPxx/TENANTID/TOKEN/CHARGEBOXID - // Note in order to override the CS name the url would look like /OCPPxx/TENANTID/TOKEN//CHARGEBOXID + // Parse URL - Expected formats: + // 1 - /OCPP/// + // 2 - /OCPP//// - specific use-case for charger forcing a stupid charge name const splittedURL = this.getURL().split('/'); if (splittedURL.length < 4) { throw new BackendError({ @@ -336,18 +382,23 @@ export default abstract class WSConnection { message: `Wrong number of arguments in URL '/${this.url}'` }); } - // URL /OCPPxx/TENANTID/TOKEN/CHARGEBOXID - this.tenantID = splittedURL[1]; - this.tokenID = splittedURL[2]; - this.chargingStationID = splittedURL[3]; + const rawConnectionData = { + tenantID: splittedURL[1], + tokenID: splittedURL[2], + chargingStationID: splittedURL[3] + }; // Check parameters - OCPPUtils.checkChargingStationConnectionData( - ServerAction.WS_SERVER_CONNECTION, this.tenantID, this.tokenID, this.chargingStationID); + OCPPUtils.checkChargingStationConnectionData(ServerAction.WS_SERVER_CONNECTION, rawConnectionData); + // Return the validated raw data + return rawConnectionData; } public abstract handleRequest(command: Command, commandPayload: Record | string): Promise; - public abstract onPing(message: string): Promise; + public abstract onPing(message: string): void; + + public abstract onPong(message: string): void; + + public abstract updateChargingStationRuntimeData(): Promise; - public abstract onPong(message: string): Promise; } diff --git a/src/server/ocpp/json/web-socket/WSWrapper.ts b/src/server/ocpp/json/web-socket/WSWrapper.ts index 686f9f8377..635fccca56 100644 --- a/src/server/ocpp/json/web-socket/WSWrapper.ts +++ b/src/server/ocpp/json/web-socket/WSWrapper.ts @@ -1,70 +1,227 @@ -import { LabelValues } from 'prom-client'; import { RecognizedString, WebSocket } from 'uWebSockets.js'; -import { CounterClearableMetric } from '../../../../monitoring/CounterClearableMetric'; +import { ServerAction, WSServerProtocol } from '../../../../types/Server'; +import { WebSocketAction, WebSocketCloseEventStatusCode } from '../../../../types/WebSocket'; +import { Command } from '../../../../types/ChargingStation'; +import Constants from '../../../../utils/Constants'; +import { CounterClearableMetric } from '../../../../monitoring/CounterClearableMetric'; +import Logging from '../../../../utils/Logging'; +import LoggingHelper from '../../../../utils/LoggingHelper'; +import { OCPPPayload } from '../../../../types/ocpp/OCPPCommon'; +import { PerformanceRecordGroup } from '../../../../types/Performance'; import Utils from '../../../../utils/Utils'; import WSConnection from './WSConnection'; -import { WSServerProtocol } from '../../../../types/Server'; -import { WebSocketAction } from '../../../../types/WebSocket'; + +const MODULE_NAME = 'WSWrapper'; export default class WSWrapper { - public key: string; public guid: string; - public siteID: string; - public siteAreaID: string; - public companyID: string; - public chargingStationID: string; - public tenantID: string; public tokenID: string; public url: string; public clientIP: string | string[]; - public closed: boolean; public protocol: WSServerProtocol; - public wsConnection: WSConnection; public remoteAddress: string; + public wsConnection: WSConnection; public firstConnectionDate: Date; public nbrPingFailed: number; + public lastMessageDate: Date; public lastPingDate: Date; public lastPongDate: Date; - public ocppOpenWebSocketMetricCounter : CounterClearableMetric; - public ocppClosedWebSocketMetricCounter : CounterClearableMetric; - private ws: WebSocket; + private ws: WebSocket; + private _closed: boolean; + private _ocppOpenWebSocketMetricCounter: CounterClearableMetric; + private _ocppClosedWebSocketMetricCounter: CounterClearableMetric; + private _ocppKilledWebSocketMetricCounter: CounterClearableMetric; - public constructor(ws: WebSocket) { + public constructor(url: string) { + this.url = url; this.guid = Utils.generateShortNonUniqueID(); - this.ws = ws; - this.url = ws.url; - this.remoteAddress = Utils.convertBufferArrayToString(ws.getRemoteAddressAsText()).toString(); this.firstConnectionDate = new Date(); this.nbrPingFailed = 0; - this.closed = false; + this._closed = false; + if (this.url.startsWith('/OCPP16')) { + this.protocol = WSServerProtocol.OCPP16; + } else if (this.url.startsWith('/REST')) { + this.protocol = WSServerProtocol.REST; + } + } + + public isClosed(): boolean { + return this._closed; + } + + public isValid(): boolean { + return !!this.wsConnection; + } + + public setWebSocket(ws: WebSocket) { + this.ws = ws; + this.remoteAddress = Utils.convertBufferArrayToString(ws.getRemoteAddressAsText()).toString(); + } + + public setConnection(wsConnection: WSConnection) { + this.wsConnection = wsConnection; + if (this.protocol !== WSServerProtocol.REST && Utils.isMonitoringEnabled()) { + // Initialize Metrics + const labelValues = { tenant: wsConnection.getTenant().subdomain }; + this._ocppOpenWebSocketMetricCounter = global.monitoringServer.getCounterClearableMetric(PerformanceRecordGroup.OCPP, 'OpenedWebSocket', 'Opened web sockets', labelValues); + this._ocppClosedWebSocketMetricCounter = global.monitoringServer.getCounterClearableMetric(PerformanceRecordGroup.OCPP, 'ClosedWebSocket', 'Closed web sockets', labelValues); + this._ocppKilledWebSocketMetricCounter = global.monitoringServer.getCounterClearableMetric(PerformanceRecordGroup.OCPP, 'KilledWebSocket', 'Killed web sockets', labelValues); + // Increment counter + this._ocppOpenWebSocketMetricCounter?.inc(); + } + } + + public unsetConnection(): void { + this.wsConnection = null; + } + + public send(messageToSend: string, initialCommand: Command, initialCommandPayload?: OCPPPayload, isBinary?: boolean, compress?: boolean): boolean { + let sent = false ; + if (this.canSendMessage(WebSocketAction.MESSAGE, messageToSend, initialCommand, initialCommandPayload)) { + // Sends a message. + // Returns + // - 1 for success, + // - 2 for dropped due to backpressure limit, + // - 0 for built up backpressure that will drain over time. + // Todo: check backpressure before or after sending by calling getBufferedAmount() + const returnedCode = this.ws.send(messageToSend, isBinary, compress); + if (typeof returnedCode === 'boolean') { + // Returns a boolean in production - to be clarified + return returnedCode; + } + // Handle back pressure + if (returnedCode === 1) { + sent = true; + } else { + Logging.beWarning()?.log({ + ...LoggingHelper.getWSWrapperProperties(this), + tenantID: Constants.DEFAULT_TENANT_ID, + action: ServerAction.WS_SERVER_MESSAGE, + module: MODULE_NAME, method: 'send', + message: `WS Message returned a backpressure code '${returnedCode}'`, + detailedMessages: { + message: messageToSend, + returnedCode, + wsWrapper: this.toJson() + } + }); + } + } + return sent; } - public send(message: RecognizedString, isBinary?: boolean, compress?: boolean): boolean { - this.checkWSClosed(WebSocketAction.MESSAGE); - return this.ws.send(message, isBinary, compress) === 1; + public close(): void { + if (!this._closed) { + this._closed = true; + // Local ref to the Web Socket + const ws = this.ws; + if (ws) { + try { + // Clear the reference to the WebSocket! + this.ws = null; + // Forcefully closes this WebSocket. Immediately calls the close handler. + ws.close(); + } catch (error) { + // Do nothing + } finally { + // Increment specific counter to detect WS forcefully closed + this._ocppKilledWebSocketMetricCounter?.inc(); + } + } + } } - public close(code: number, shortMessage: RecognizedString): void { - if (!this.closed) { - this.closed = true; - this.ws.end(code, shortMessage); + public end(code: number, shortMessage: RecognizedString): void { + if (!this._closed) { + this._closed = true; + // Local ref to the Web Socket + const ws = this.ws; + if (ws) { + try { + // Clear the reference to the WebSocket! + this.ws = null; + // Close WS + ws.end(code, shortMessage); + } catch (error) { + // Do nothing + } finally { + if (code !== WebSocketCloseEventStatusCode.CLOSE_NORMAL) { + // Increment counter close counter when code is an error + this._ocppClosedWebSocketMetricCounter?.inc(); + } + } + } } } - public ping(message?: RecognizedString) : boolean { - this.checkWSClosed(WebSocketAction.PING); - return this.ws.ping(message) === 1; + public ping(message: RecognizedString) : boolean { + if (this._closed) { + return false; + } + const returnedCode = this.ws.ping(message); + // Return a boolean in production + if (typeof returnedCode === 'boolean') { + return returnedCode; + } + // Handle back pressure + if (returnedCode !== 1) { + Logging.beWarning()?.log({ + ...LoggingHelper.getWSWrapperProperties(this), + tenantID: Constants.DEFAULT_TENANT_ID, + action: ServerAction.WS_SERVER_CONNECTION_PING, + module: MODULE_NAME, method: 'ping', + message: `WS Ping returned a backpressure code '${returnedCode}'`, + detailedMessages: { + message, + returnedCode, + wsWrapper: this.toJson() + } + }); + } + return true; } public getRemoteAddress(): string { return this.remoteAddress; } - private checkWSClosed(wsAction: WebSocketAction): void { - if (this.closed) { - throw new Error(`${wsAction} > WS Connection ID '${this.guid}' is already closed ('${this.url}'), cannot perform action`); + public toJson(): Record { + return { + key: this.wsConnection?.getID(), + guid: this.guid, + nbrPingFailed: this.nbrPingFailed, + ...LoggingHelper.getWSConnectionProperties(this.wsConnection), + tokenID: this.tokenID, + url: this.url, + clientIP: this.clientIP, + closed: this._closed, + protocol: this.protocol, + remoteAddress: this.remoteAddress, + firstConnectionDate: this.firstConnectionDate, + durationSecs: Utils.computeTimeDurationSecs(new Date(this.firstConnectionDate).getTime()), + lastMessageDate: this.lastMessageDate, + lastPingDate: this.lastPingDate, + lastPongDate: this.lastPongDate, + }; + } + + private canSendMessage(wsAction: WebSocketAction, messageToSend: string, initialCommand?: Command, initialCommandPayload?: OCPPPayload): boolean { + if (this._closed) { + Logging.beWarning()?.log({ + ...LoggingHelper.getWSWrapperProperties(this), + tenantID: Constants.DEFAULT_TENANT_ID, + action: ServerAction.WS_SERVER_MESSAGE, + module: MODULE_NAME, method: 'canSendMessage', + message: `'${wsAction}' > Cannot send message '${messageToSend}', WS Connection ID '${this.guid}' is already closed ('${this.url}'`, + detailedMessages: { + initialCommand, + initialCommandPayload + } + }); + return false; } + return true; } } diff --git a/src/server/ocpp/services/OCPPService.ts b/src/server/ocpp/services/OCPPService.ts index 2b8cc9c010..0cdd922a67 100644 --- a/src/server/ocpp/services/OCPPService.ts +++ b/src/server/ocpp/services/OCPPService.ts @@ -58,8 +58,9 @@ export default class OCPPService { public async handleBootNotification(headers: OCPPHeader, bootNotification: OCPPBootNotificationRequestExtended): Promise { try { - const { tenant } = headers; - let { chargingStation } = headers; + const { connectionContext } = headers; + const { tenant } = connectionContext; + let { chargingStation } = connectionContext; OCPPValidator.getInstance().validateBootNotification(headers, bootNotification); // Enrich Boot Notification this.enrichBootNotification(headers, bootNotification); @@ -84,11 +85,12 @@ export default class OCPPService { // Notify this.notifyBootNotification(tenant, chargingStation); // Request OCPP configuration - // eslint-disable-next-line @typescript-eslint/no-misused-promises - setTimeout(async () => { - await OCPPCommon.requestAndSaveChargingStationOcppParameters(tenant, chargingStation); + setTimeout(() => { + OCPPCommon.requestAndSaveChargingStationOcppParameters(tenant, chargingStation).catch((error) => { + Logging.logPromiseError(error, tenant?.id); + }); }, Constants.DELAY_CHANGE_CONFIGURATION_EXECUTION_MILLIS); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.OCPP_BOOT_NOTIFICATION, @@ -104,7 +106,7 @@ export default class OCPPService { }; } catch (error) { this.addChargingStationToException(error, headers.chargeBoxIdentity); - await Logging.logActionExceptionMessage(headers.tenantID, ServerAction.OCPP_BOOT_NOTIFICATION, error, { bootNotification }); + Logging.logActionExceptionMessage(headers.rawConnectionData?.tenantID, ServerAction.OCPP_BOOT_NOTIFICATION, error as Error, { bootNotification }); // Reject return { status: RegistrationStatus.REJECTED, @@ -117,18 +119,21 @@ export default class OCPPService { public async handleHeartbeat(headers: OCPPHeader, heartbeat: OCPPHeartbeatRequestExtended): Promise { try { // Get the header infos - const { chargingStation, tenant } = headers; + const { connectionContext } = headers; + const { tenant, chargingStation } = connectionContext; if (!heartbeat) { heartbeat = {} as OCPPHeartbeatRequestExtended; } - OCPPValidator.getInstance().validateHeartbeat(heartbeat); - // Set Heart Beat Object - heartbeat.chargeBoxID = chargingStation.id; - heartbeat.timestamp = new Date(); - heartbeat.timezone = Utils.getTimezone(chargingStation.coordinates); - // Save Heart Beat - await OCPPStorage.saveHeartbeat(tenant, heartbeat); - await Logging.logInfo({ + if (FeatureToggles.isFeatureActive(Feature.OCPP_STORE_HEARTBEATS)) { + OCPPValidator.getInstance().validateHeartbeat(heartbeat); + // Set Heart Beat Object + heartbeat.chargeBoxID = chargingStation.id; + heartbeat.timestamp = new Date(); + heartbeat.timezone = Utils.getTimezone(chargingStation.coordinates); + // Save Heart Beat + await OCPPStorage.saveHeartbeat(tenant, heartbeat); + } + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'handleHeartbeat', @@ -136,29 +141,27 @@ export default class OCPPService { message: 'Heartbeat saved', detailedMessages: { heartbeat } }); - return { - currentTime: new Date().toISOString() - }; } catch (error) { this.addChargingStationToException(error, headers.chargeBoxIdentity); - await Logging.logActionExceptionMessage(headers.tenantID, ServerAction.OCPP_HEARTBEAT, error, { heartbeat }); - return { - currentTime: new Date().toISOString() - }; + Logging.logActionExceptionMessage(headers.rawConnectionData?.tenantID, ServerAction.OCPP_HEARTBEAT, error as Error, { heartbeat }); } + return { + currentTime: new Date().toISOString() + }; } public async handleStatusNotification(headers: OCPPHeader, statusNotification: OCPPStatusNotificationRequestExtended): Promise { try { // Get the header infos - const { chargingStation, tenant } = headers; + const { connectionContext } = headers; + const { tenant, chargingStation } = connectionContext; // Check props OCPPValidator.getInstance().validateStatusNotification(statusNotification); // Set Header this.enrichOCPPRequest(chargingStation, statusNotification, false); // Skip connectorId = 0 case if (statusNotification.connectorId <= 0) { - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.OCPP_STATUS_NOTIFICATION, @@ -170,25 +173,25 @@ export default class OCPPService { // Update only the given Connector ID await this.processConnectorFromStatusNotification(tenant, chargingStation, statusNotification); } - return {}; } catch (error) { this.addChargingStationToException(error, headers.chargeBoxIdentity); - await Logging.logActionExceptionMessage(headers.tenantID, ServerAction.OCPP_STATUS_NOTIFICATION, error, { statusNotification }); - return {}; + Logging.logActionExceptionMessage(headers.rawConnectionData?.tenantID, ServerAction.OCPP_STATUS_NOTIFICATION, error, { statusNotification }); } + return {}; } public async handleMeterValues(headers: OCPPHeader, meterValues: OCPPMeterValuesRequestExtended): Promise { try { // Get the header infos - const { chargingStation, tenant } = headers; - await OCPPValidator.getInstance().validateMeterValues(tenant.id, chargingStation, meterValues); + const { connectionContext } = headers; + const { tenant, chargingStation } = connectionContext; + OCPPValidator.getInstance().validateMeterValues(tenant.id, chargingStation, meterValues); // Normalize Meter Values const normalizedMeterValues = this.normalizeMeterValues(chargingStation, meterValues); // Handle Charging Station's specificities this.filterMeterValuesOnSpecificChargingStations(tenant, chargingStation, normalizedMeterValues); if (Utils.isEmptyArray(normalizedMeterValues.values)) { - await Logging.logDebug({ + Logging.beDebug()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'handleMeterValues', @@ -255,7 +258,7 @@ export default class OCPPService { // Yes: Trigger Smart Charging await this.triggerSmartCharging(tenant, chargingStation.siteArea); } - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.OCPP_METER_VALUES, @@ -266,7 +269,7 @@ export default class OCPPService { }); } catch (error) { this.addChargingStationToException(error, headers.chargeBoxIdentity); - await Logging.logActionExceptionMessage(headers.tenantID, ServerAction.OCPP_METER_VALUES, error, { meterValues }); + Logging.logActionExceptionMessage(headers.rawConnectionData?.tenantID, ServerAction.OCPP_METER_VALUES, error as Error, { meterValues }); } return {}; } @@ -274,7 +277,8 @@ export default class OCPPService { public async handleAuthorize(headers: OCPPHeader, authorize: OCPPAuthorizeRequestExtended): Promise { try { // Get the header infos - const { chargingStation, tenant } = headers; + const { connectionContext } = headers; + const { tenant, chargingStation } = connectionContext; // Check props OCPPValidator.getInstance().validateAuthorize(authorize); const { user } = await CommonUtilsService.isAuthorizedOnChargingStation(tenant, chargingStation, @@ -285,7 +289,7 @@ export default class OCPPService { this.enrichAuthorize(user, chargingStation, headers, authorize); // Save await OCPPStorage.saveAuthorize(tenant, authorize); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'handleAuthorize', @@ -301,7 +305,7 @@ export default class OCPPService { }; } catch (error) { this.addChargingStationToException(error, headers.chargeBoxIdentity); - await Logging.logActionExceptionMessage(headers.tenantID, ServerAction.OCPP_AUTHORIZE, error, { authorize }); + Logging.logActionExceptionMessage(headers.rawConnectionData?.tenantID, ServerAction.OCPP_AUTHORIZE, error as Error, { authorize }); // Rejected return { idTagInfo: { @@ -314,7 +318,8 @@ export default class OCPPService { public async handleDiagnosticsStatusNotification(headers: OCPPHeader, diagnosticsStatusNotification: OCPPDiagnosticsStatusNotificationRequestExtended): Promise { // Get the header infos - const { chargingStation, tenant } = headers; + const { connectionContext } = headers; + const { tenant, chargingStation } = connectionContext; try { // Check props OCPPValidator.getInstance().validateDiagnosticsStatusNotification(diagnosticsStatusNotification); @@ -322,7 +327,7 @@ export default class OCPPService { this.enrichOCPPRequest(chargingStation, diagnosticsStatusNotification); // Save it await OCPPStorage.saveDiagnosticsStatusNotification(tenant, diagnosticsStatusNotification); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.OCPP_DIAGNOSTICS_STATUS_NOTIFICATION, @@ -333,7 +338,7 @@ export default class OCPPService { return {}; } catch (error) { this.addChargingStationToException(error, headers.chargeBoxIdentity); - await Logging.logActionExceptionMessage(headers.tenantID, ServerAction.OCPP_DIAGNOSTICS_STATUS_NOTIFICATION, error, { diagnosticsStatusNotification }); + Logging.logActionExceptionMessage(headers.rawConnectionData?.tenantID, ServerAction.OCPP_DIAGNOSTICS_STATUS_NOTIFICATION, error as Error, { diagnosticsStatusNotification }); return {}; } } @@ -341,7 +346,8 @@ export default class OCPPService { public async handleFirmwareStatusNotification(headers: OCPPHeader, firmwareStatusNotification: OCPPFirmwareStatusNotificationRequestExtended): Promise { // Get the header infos - const { chargingStation, tenant } = headers; + const { connectionContext } = headers; + const { tenant, chargingStation } = connectionContext; try { // Check props OCPPValidator.getInstance().validateFirmwareStatusNotification(chargingStation, firmwareStatusNotification); @@ -351,7 +357,7 @@ export default class OCPPService { await ChargingStationStorage.saveChargingStationFirmwareStatus(tenant, chargingStation.id, firmwareStatusNotification.status); // Save it await OCPPStorage.saveFirmwareStatusNotification(tenant, firmwareStatusNotification); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'handleFirmwareStatusNotification', @@ -362,7 +368,7 @@ export default class OCPPService { return {}; } catch (error) { this.addChargingStationToException(error, headers.chargeBoxIdentity); - await Logging.logActionExceptionMessage(headers.tenantID, ServerAction.OCPP_FIRMWARE_STATUS_NOTIFICATION, error, { firmwareStatusNotification }); + Logging.logActionExceptionMessage(headers.rawConnectionData?.tenantID, ServerAction.OCPP_FIRMWARE_STATUS_NOTIFICATION, error as Error, { firmwareStatusNotification }); return {}; } } @@ -370,7 +376,8 @@ export default class OCPPService { public async handleStartTransaction(headers: OCPPHeader, startTransaction: OCPPStartTransactionRequestExtended): Promise { try { // Get the header infos - const { chargingStation, tenant } = headers; + const { connectionContext } = headers; + const { tenant, chargingStation } = connectionContext; // Check props OCPPValidator.getInstance().validateStartTransaction(chargingStation, startTransaction); // Enrich @@ -408,7 +415,7 @@ export default class OCPPService { await ChargingStationStorage.saveChargingStation(tenant, chargingStation); // Notify NotificationHelper.notifyStartTransaction(tenant, newTransaction, chargingStation, user); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'handleStartTransaction', @@ -425,7 +432,7 @@ export default class OCPPService { }; } catch (error) { this.addChargingStationToException(error, headers.chargeBoxIdentity); - await Logging.logActionExceptionMessage(headers.tenantID, ServerAction.OCPP_START_TRANSACTION, error, { startTransaction }); + Logging.logActionExceptionMessage(headers.rawConnectionData?.tenantID, ServerAction.OCPP_START_TRANSACTION, error, { startTransaction }); // Invalid return { transactionId: 0, @@ -439,14 +446,15 @@ export default class OCPPService { public async handleDataTransfer(headers: OCPPHeader, dataTransfer: OCPPDataTransferRequestExtended): Promise { try { // Get the header infos - const { chargingStation, tenant } = headers; + const { connectionContext } = headers; + const { tenant, chargingStation } = connectionContext; // Check props OCPPValidator.getInstance().validateDataTransfer(chargingStation, dataTransfer); // Enrich this.enrichOCPPRequest(chargingStation, dataTransfer); // Save it await OCPPStorage.saveDataTransfer(tenant, dataTransfer); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'handleDataTransfer', @@ -459,7 +467,7 @@ export default class OCPPService { }; } catch (error) { this.addChargingStationToException(error, headers.chargeBoxIdentity); - await Logging.logActionExceptionMessage(headers.tenantID, ServerAction.CHARGING_STATION_DATA_TRANSFER, error, { dataTransfer }); + Logging.logActionExceptionMessage(headers.rawConnectionData?.tenantID, ServerAction.CHARGING_STATION_DATA_TRANSFER, error as Error, { dataTransfer }); // Rejected return { status: OCPPDataTransferStatus.REJECTED @@ -471,13 +479,14 @@ export default class OCPPService { isSoftStop = false, isStoppedByCentralSystem = false): Promise { try { // Get the header infos - const { chargingStation, tenant } = headers; + const { connectionContext } = headers; + const { tenant, chargingStation } = connectionContext; // Check props OCPPValidator.getInstance().validateStopTransaction(chargingStation, stopTransaction); // Set header this.enrichOCPPRequest(chargingStation, stopTransaction, false); // Bypass Stop Transaction? - if (await this.bypassStopTransaction(tenant, chargingStation, stopTransaction)) { + if (this.bypassStopTransaction(tenant, chargingStation, stopTransaction)) { return { idTagInfo: { status: OCPPAuthorizationStatus.ACCEPTED @@ -517,7 +526,7 @@ export default class OCPPService { await this.triggerSmartChargingStopTransaction(tenant, chargingStation, transaction); // Check Connector Status await this.checkConnectorStatusOnStopTransaction(tenant, chargingStation, transaction, connector); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'handleStopTransaction', @@ -535,7 +544,7 @@ export default class OCPPService { }; } catch (error) { this.addChargingStationToException(error, headers.chargeBoxIdentity); - await Logging.logActionExceptionMessage(headers.tenantID, ServerAction.OCPP_STOP_TRANSACTION, error, { stopTransaction }); + Logging.logActionExceptionMessage(headers.rawConnectionData?.tenantID, ServerAction.OCPP_STOP_TRANSACTION, error as Error, { stopTransaction }); // Invalid return { idTagInfo: { @@ -584,18 +593,27 @@ export default class OCPPService { } // Set chargingStation.siteArea = siteArea; - // Stop Transaction - const result = await this.handleStopTransaction( - { // OCPP Header - tenant: tenant, + // OCPP Header + const ocppHeader: OCPPHeader = { + chargeBoxIdentity: chargingStation.id, + companyID: transaction.companyID, + siteID: transaction.siteID, + siteAreaID: transaction.siteAreaID, + rawConnectionData: { tenantID: tenant.id, - chargingStation: chargingStation, - chargeBoxIdentity: chargingStation.id, - companyID: transaction.companyID, - siteID: transaction.siteID, - siteAreaID: transaction.siteAreaID, + chargingStationID: chargingStation.id, + tokenID: null, }, - { // OCPP Stop Transaction + connectionContext: { + tenant, + chargingStation + } + }; + // Stop Transaction + const result = await this.handleStopTransaction( + ocppHeader, + { + // OCPP Stop Transaction transactionId: transaction.id, chargeBoxID: transaction.chargeBoxID, idTag: transaction.tagID, @@ -707,13 +725,9 @@ export default class OCPPService { // Delete TxProfile if any await this.deleteAllTransactionTxProfile(tenant, transaction); // Call async because the Transaction ID on the connector should be cleared - // eslint-disable-next-line @typescript-eslint/no-misused-promises - setTimeout(async () => { - try { - // Trigger Smart Charging - await this.triggerSmartCharging(tenant, chargingStation.siteArea); - } catch (error) { - await Logging.logError({ + setTimeout(() => { + this.triggerSmartCharging(tenant, chargingStation.siteArea).catch((error) => { + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'triggerSmartChargingStopTransaction', @@ -721,7 +735,7 @@ export default class OCPPService { message: `${Utils.buildConnectorInfo(transaction.connectorId, transaction.id)} Smart Charging exception occurred`, detailedMessages: { error: error.stack, transaction, chargingStation } }); - } + }); }, Constants.DELAY_SMART_CHARGING_EXECUTION_MILLIS); } } @@ -737,7 +751,7 @@ export default class OCPPService { for (const chargingProfile of chargingProfiles.result) { try { await OCPPUtils.clearAndDeleteChargingProfile(tenant, chargingProfile); - await Logging.logDebug({ + Logging.beDebug()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: tenant.id, action: ServerAction.CHARGING_PROFILE_DELETE, @@ -746,7 +760,7 @@ export default class OCPPService { detailedMessages: { chargingProfile } }); } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: tenant.id, action: ServerAction.CHARGING_PROFILE_DELETE, @@ -810,7 +824,7 @@ export default class OCPPService { await ChargingStationStorage.saveChargingStation(tenant, chargingStation); // Process Smart Charging await this.processSmartChargingFromStatusNotification(tenant, chargingStation, connector, previousStatus); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'processConnectorStatusNotification', @@ -819,7 +833,7 @@ export default class OCPPService { detailedMessages: { statusNotification, connector } }); // Notify Users - await this.notifyStatusNotification(tenant, chargingStation, connector, statusNotification); + this.notifyStatusNotification(tenant, chargingStation, connector, statusNotification); } } @@ -832,7 +846,7 @@ export default class OCPPService { // Trigger Smart Charging await this.triggerSmartCharging(tenant, chargingStation.siteArea); } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'processSmartChargingStatusNotification', @@ -874,16 +888,18 @@ export default class OCPPService { // Enrich Charging Station's Connector await OCPPUtils.enrichChargingStationConnectorWithTemplate(tenant, chargingStation, connector); // Same Status Notification? - } else if (Utils.objectAllPropertiesAreEqual(statusNotification, connector, ['status', 'info', 'errorCode', 'vendorErrorCode'])) { - ignoreStatusNotification = true; - await Logging.logWarning({ - ...LoggingHelper.getChargingStationProperties(chargingStation), - tenantID: tenant.id, - action: ServerAction.OCPP_STATUS_NOTIFICATION, - module: MODULE_NAME, method: 'handleStatusNotification', - message: `${this.buildStatusNotification(statusNotification)} has not changed and will be ignored`, - detailedMessages: { connector, statusNotification } - }); + } else if (FeatureToggles.isFeatureActive(Feature.OCPP_IGNORE_UNCHANGED_STATUS)) { + if (Utils.objectAllPropertiesAreEqual(statusNotification, connector, ['status', 'info', 'errorCode', 'vendorErrorCode'])) { + ignoreStatusNotification = true; + Logging.beWarning()?.log({ + ...LoggingHelper.getChargingStationProperties(chargingStation), + tenantID: tenant.id, + action: ServerAction.OCPP_STATUS_NOTIFICATION, + module: MODULE_NAME, method: 'handleStatusNotification', + message: `${this.buildStatusNotification(statusNotification)} has not changed and will be ignored`, + detailedMessages: { connector, statusNotification } + }); + } } return { connector, ignoreStatusNotification }; } @@ -903,7 +919,7 @@ export default class OCPPService { await this.finalizeTransaction(tenant, chargingStation, lastTransaction, connector, statusNotification); } else { // Unexpected situation - This should not happen - The connector is AVAILABLE before stopping the transaction - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'checkAndUpdateLastCompletedTransactionFromStatusNotification', @@ -915,7 +931,7 @@ export default class OCPPService { // Clear Connector Runtime Data OCPPUtils.clearChargingStationConnectorRuntimeData(chargingStation, lastTransaction.connectorId); } catch (error) { - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getTransactionProperties(lastTransaction), tenantID: tenant.id, module: MODULE_NAME, method: 'checkAndUpdateLastCompletedTransactionFromStatusNotification', @@ -969,7 +985,7 @@ export default class OCPPService { Utils.createDecimal(currentStatusNotifTimestamp.getTime()).minus(transactionStopTimestamp.getTime()).div(1000).floor().toNumber(); // Negative inactivity if (transaction.stop.extraInactivitySecs < 0) { - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'checkAndComputeTransactionExtraInactivityFromStatusNotification', @@ -987,7 +1003,7 @@ export default class OCPPService { ); // Build extra inactivity consumption await OCPPUtils.buildAndPriceExtraConsumptionInactivity(tenant, user, chargingStation, transaction); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, user: transaction.userID, @@ -999,7 +1015,7 @@ export default class OCPPService { } } else { // No extra inactivity - connector status is not set to FINISHING - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, user: transaction.userID, @@ -1028,12 +1044,12 @@ export default class OCPPService { return transactionUpdated; } - private async notifyStatusNotification(tenant: Tenant, chargingStation: ChargingStation, connector: Connector, statusNotification: OCPPStatusNotificationRequestExtended) { + private notifyStatusNotification(tenant: Tenant, chargingStation: ChargingStation, connector: Connector, statusNotification: OCPPStatusNotificationRequestExtended): void { // Faulted? if (connector.status !== ChargePointStatus.AVAILABLE && connector.status !== ChargePointStatus.FINISHING && // TODO: To remove after fix of ABB bug having Finishing status with an Error Code to avoid spamming Admins connector.errorCode !== ChargePointErrorCode.NO_ERROR) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.OCPP_STATUS_NOTIFICATION, @@ -1263,10 +1279,10 @@ export default class OCPPService { if (chargingStation.chargePointVendor !== ChargerVendor.ABB || chargingStation.ocppVersion !== OCPPVersion.VERSION_15) { // Filter Sample.Clock meter value for all chargers except ABB using OCPP 1.5 - meterValues.values = meterValues.values.filter(async (meterValue) => { + meterValues.values = meterValues.values.filter((meterValue) => { // Remove Sample Clock if (meterValue.attribute && meterValue.attribute.context === OCPPReadingContext.SAMPLE_CLOCK) { - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'filterMeterValuesOnSpecificChargingStations', @@ -1357,76 +1373,6 @@ export default class OCPPService { }; } - private async processExistingTransaction(tenant: Tenant, chargingStation: ChargingStation, connectorId: number) { - let activeTransaction: Transaction, lastCheckedTransactionID: number; - do { - // Check if the charging station has already a transaction - activeTransaction = await TransactionStorage.getActiveTransaction(tenant, chargingStation.id, connectorId); - // Exists already? - if (activeTransaction) { - // Avoid infinite Loop - if (lastCheckedTransactionID === activeTransaction.id) { - return; - } - // Has consumption? - if (activeTransaction.currentTotalConsumptionWh <= 0) { - // No consumption: delete - await Logging.logWarning({ - ...LoggingHelper.getChargingStationProperties(chargingStation), - tenantID: tenant.id, - module: MODULE_NAME, method: 'stopOrDeleteActiveTransactions', - action: ServerAction.CLEANUP_TRANSACTION, - actionOnUser: activeTransaction.user, - message: `${Utils.buildConnectorInfo(activeTransaction.connectorId, activeTransaction.id)} Transaction with no consumption has been deleted` - }); - // Delete - await TransactionStorage.deleteTransaction(tenant, activeTransaction.id); - // Clear connector - OCPPUtils.clearChargingStationConnectorRuntimeData(chargingStation, activeTransaction.connectorId); - } else { - // Simulate a Stop Transaction - const result = await this.handleStopTransaction({ - tenantID: tenant.id, - chargeBoxIdentity: activeTransaction.chargeBoxID, - companyID: activeTransaction.companyID, - siteID: activeTransaction.siteID, - siteAreaID: activeTransaction.siteAreaID, - }, { - chargeBoxID: activeTransaction.chargeBoxID, - transactionId: activeTransaction.id, - meterStop: (activeTransaction.lastConsumption ? activeTransaction.lastConsumption.value : activeTransaction.meterStart), - timestamp: Utils.convertToDate(activeTransaction.lastConsumption ? activeTransaction.lastConsumption.timestamp : activeTransaction.timestamp).toISOString(), - }, false, true); - if (result.idTagInfo.status === OCPPAuthorizationStatus.INVALID) { - // Cannot stop it - await Logging.logError({ - ...LoggingHelper.getChargingStationProperties(chargingStation), - tenantID: tenant.id, - module: MODULE_NAME, method: 'stopOrDeleteActiveTransactions', - action: ServerAction.CLEANUP_TRANSACTION, - actionOnUser: activeTransaction.userID, - message: `${Utils.buildConnectorInfo(activeTransaction.connectorId, activeTransaction.id)} Pending transaction cannot be stopped`, - detailedMessages: { result } - }); - } else { - // Stopped - await Logging.logWarning({ - ...LoggingHelper.getChargingStationProperties(chargingStation), - tenantID: tenant.id, - module: MODULE_NAME, method: 'stopOrDeleteActiveTransactions', - action: ServerAction.CLEANUP_TRANSACTION, - actionOnUser: activeTransaction.userID, - message: `${Utils.buildConnectorInfo(activeTransaction.connectorId, activeTransaction.id)} Pending transaction has been stopped`, - detailedMessages: { result } - }); - } - } - // Keep last Transaction ID - lastCheckedTransactionID = activeTransaction.id; - } - } while (activeTransaction); - } - private getStopTransactionTagId(stopTransaction: OCPPStopTransactionRequestExtended, transaction: Transaction): string { // Stopped Remotely? if (transaction.remotestop) { @@ -1629,15 +1575,17 @@ export default class OCPPService { // Update props newChargingStation.createdOn = new Date(); newChargingStation.issuer = true; - newChargingStation.tokenID = headers.tokenID; + newChargingStation.tokenID = headers.rawConnectionData.tokenID; newChargingStation.powerLimitUnit = ChargingRateUnitType.AMPERE; + const { token } = headers.connectionContext; + // Assign to Site Area - if (headers.token.siteAreaID) { - const siteArea = await SiteAreaStorage.getSiteArea(tenant, headers.token.siteAreaID, { withSite: true }); + if (token.siteAreaID) { + const siteArea = await SiteAreaStorage.getSiteArea(tenant, token.siteAreaID, { withSite: true }); if (siteArea) { newChargingStation.companyID = siteArea.site?.companyID; newChargingStation.siteID = siteArea.siteID; - newChargingStation.siteAreaID = headers.token.siteAreaID; + newChargingStation.siteAreaID = token.siteAreaID; // Set coordinates if (siteArea.address?.coordinates?.length === 2) { newChargingStation.coordinates = siteArea.address.coordinates; @@ -1774,11 +1722,11 @@ export default class OCPPService { } } - private async bypassStopTransaction(tenant: Tenant, chargingStation: ChargingStation, - stopTransaction: OCPPStopTransactionRequestExtended): Promise { + private bypassStopTransaction(tenant: Tenant, chargingStation: ChargingStation, + stopTransaction: OCPPStopTransactionRequestExtended): boolean { // Ignore it (DELTA bug)? if (stopTransaction.transactionId === 0) { - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'bypassStopTransaction', @@ -1806,7 +1754,9 @@ export default class OCPPService { tenant, meterValues.transactionId, { withUser: true, withTag: true, withCar: true }); if (!transaction) { // Abort the ongoing Transaction - await this.abortOngoingTransactionInMeterValues(tenant, chargingStation, meterValues); + if (FeatureToggles.isFeatureActive(Feature.OCPP_METER_VALUE_ABORT_GHOST_TRANSACTION)) { + await this.abortOngoingTransactionInMeterValues(tenant, chargingStation, meterValues); + } // Unknown Transaction throw new BackendError({ ...LoggingHelper.getChargingStationProperties(chargingStation), @@ -1817,9 +1767,11 @@ export default class OCPPService { }); } // Transaction finished - if (transaction?.stop) { + if (transaction.stop) { // Abort the ongoing Transaction - await this.abortOngoingTransactionInMeterValues(tenant, chargingStation, meterValues); + if (FeatureToggles.isFeatureActive(Feature.OCPP_METER_VALUE_ABORT_GHOST_TRANSACTION)) { + await this.abortOngoingTransactionInMeterValues(tenant, chargingStation, meterValues); + } throw new BackendError({ ...LoggingHelper.getChargingStationProperties(chargingStation), module: MODULE_NAME, method: 'getTransactionFromMeterValues', @@ -1830,7 +1782,7 @@ export default class OCPPService { } // Received Meter Values after the Transaction End Meter Value if (transaction.transactionEndReceived) { - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'getTransactionFromMeterValues', @@ -1846,7 +1798,7 @@ export default class OCPPService { // Get the OCPP Client const chargingStationClient = await ChargingStationClientFactory.getChargingStationClient(tenant, chargingStation); if (!chargingStationClient) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'abortOngoingTransactionInMeterValues', @@ -1860,7 +1812,7 @@ export default class OCPPService { transactionId: meterValues.transactionId }); if (result.status === OCPPRemoteStartStopStatus.ACCEPTED) { - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'abortOngoingTransactionInMeterValues', @@ -1869,7 +1821,7 @@ export default class OCPPService { detailedMessages: { meterValues } }); } else { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'abortOngoingTransactionInMeterValues', @@ -1930,7 +1882,7 @@ export default class OCPPService { } else if (transaction.lastConsumption) { // The consumption should be the same if (transaction.lastConsumption.value !== stopTransaction.meterStop) { - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.OCPP_STOP_TRANSACTION, diff --git a/src/server/ocpp/soap/SoapOCPPServer.ts b/src/server/ocpp/soap/SoapOCPPServer.ts index 997ecbce44..76ce42f3b6 100644 --- a/src/server/ocpp/soap/SoapOCPPServer.ts +++ b/src/server/ocpp/soap/SoapOCPPServer.ts @@ -72,7 +72,7 @@ export default class SoapOCPPServer extends OCPPServer { } private async handleSoapServerMessage(ocppVersion: OCPPVersion, request: any, methodName: string) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, module: MODULE_NAME, method: 'handleSoapServerMessage', action: ServerAction.EXPRESS_SERVER, @@ -84,7 +84,7 @@ export default class SoapOCPPServer extends OCPPServer { private async handleSoapServerLog(ocppVersion: OCPPVersion, type: string, data: any) { // Do not log 'Info' if (type === 'replied') { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, module: MODULE_NAME, method: 'handleSoapServerLog', action: ServerAction.EXPRESS_SERVER, diff --git a/src/server/ocpp/soap/services/SoapCentralSystemService15.ts b/src/server/ocpp/soap/services/SoapCentralSystemService15.ts index 112a93b85e..9e90d26fbe 100644 --- a/src/server/ocpp/soap/services/SoapCentralSystemService15.ts +++ b/src/server/ocpp/soap/services/SoapCentralSystemService15.ts @@ -15,10 +15,11 @@ export default { /* Services */ CentralSystemServiceSoap12: { /* Methods */ Authorize: function(args, callback, headers: OCPPHeader, req): void { const request = { ...headers, ...args }; + // const { tenant } = headers.connectionContext; // Check SOAP params OCPPUtils.checkChargingStationAndEnrichSoapOcppHeaders(Command.AUTHORIZE, headers, req).then(async () => { // Trace - const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_AUTHORIZE, request, '>>', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -33,7 +34,7 @@ export default { /* Services */ }; callback(response); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_AUTHORIZE, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID }, performanceTracingData @@ -48,10 +49,10 @@ export default { /* Services */ }; callback(response); // Log - await Logging.logException(error, ServerAction.OCPP_AUTHORIZE, - MODULE_NAME, 'Authorize', headers.tenantID ?? Constants.DEFAULT_TENANT_ID); + Logging.logException(error, ServerAction.OCPP_AUTHORIZE, + MODULE_NAME, 'Authorize', headers.rawConnectionData?.tenantID ?? Constants.DEFAULT_TENANT_ID); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_AUTHORIZE, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -60,10 +61,11 @@ export default { /* Services */ StartTransaction: function(args, callback, headers: OCPPHeader, req): void { const request = { ...headers, ...args }; + // const { tenant } = headers.connectionContext;BootNotification // Check SOAP params OCPPUtils.checkChargingStationAndEnrichSoapOcppHeaders(Command.START_TRANSACTION, headers, req).then(async () => { // Trace - const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_START_TRANSACTION, request, '>>', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -79,7 +81,7 @@ export default { /* Services */ }; callback(response); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_START_TRANSACTION, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID }, performanceTracingData @@ -95,10 +97,10 @@ export default { /* Services */ }; callback(response); // Log - await Logging.logException(error, ServerAction.OCPP_START_TRANSACTION, - MODULE_NAME, 'StartTransaction', headers.tenantID ?? Constants.DEFAULT_TENANT_ID); + Logging.logException(error, ServerAction.OCPP_START_TRANSACTION, + MODULE_NAME, 'StartTransaction', headers.rawConnectionData?.tenantID ?? Constants.DEFAULT_TENANT_ID); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_START_TRANSACTION, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -107,10 +109,11 @@ export default { /* Services */ StopTransaction: function(args, callback, headers: OCPPHeader, req): void { const request = { ...headers, ...args }; + // const { tenant } = headers.connectionContext;BootNotification // Check SOAP params OCPPUtils.checkChargingStationAndEnrichSoapOcppHeaders(Command.STOP_TRANSACTION, headers, req).then(async () => { // Trace - const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_STOP_TRANSACTION, request, '>>', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -125,7 +128,7 @@ export default { /* Services */ }; callback(response); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_STOP_TRANSACTION, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID }, performanceTracingData @@ -140,10 +143,10 @@ export default { /* Services */ }; callback(response); // Log - await Logging.logException(error, ServerAction.OCPP_STOP_TRANSACTION, - MODULE_NAME, 'StopTransaction', headers.tenantID ?? Constants.DEFAULT_TENANT_ID); + Logging.logException(error, ServerAction.OCPP_STOP_TRANSACTION, + MODULE_NAME, 'StopTransaction', headers.rawConnectionData?.tenantID ?? Constants.DEFAULT_TENANT_ID); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_STOP_TRANSACTION, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -152,10 +155,11 @@ export default { /* Services */ Heartbeat: function(args, callback, headers: OCPPHeader, req): void { const request = { ...headers, ...args }; + // const { tenant } = headers.connectionContext;BootNotification // Check SOAP params OCPPUtils.checkChargingStationAndEnrichSoapOcppHeaders(Command.HEARTBEAT, headers, req).then(async () => { // Trace - const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_HEARTBEAT, request, '>>', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -168,7 +172,7 @@ export default { /* Services */ }; callback(response); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_HEARTBEAT, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID }, performanceTracingData @@ -181,10 +185,10 @@ export default { /* Services */ }; callback(response); // Log - await Logging.logException(error, ServerAction.OCPP_HEARTBEAT, - MODULE_NAME, 'Heartbeat', headers.tenantID ?? Constants.DEFAULT_TENANT_ID); + Logging.logException(error, ServerAction.OCPP_HEARTBEAT, + MODULE_NAME, 'Heartbeat', headers.rawConnectionData?.tenantID ?? Constants.DEFAULT_TENANT_ID); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_HEARTBEAT, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -193,10 +197,11 @@ export default { /* Services */ MeterValues: function(args, callback, headers: OCPPHeader, req): void { const request = { ...headers, ...args }; + // const { tenant } = headers.connectionContext;BootNotification // Check SOAP params OCPPUtils.checkChargingStationAndEnrichSoapOcppHeaders(Command.METER_VALUES, headers, req).then(async () => { // Trace - const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_METER_VALUES, request, '>>', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -207,7 +212,7 @@ export default { /* Services */ }; callback(response); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_METER_VALUES, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID }, performanceTracingData @@ -218,10 +223,10 @@ export default { /* Services */ }; callback(response); // Log - await Logging.logException(error, ServerAction.OCPP_METER_VALUES, - MODULE_NAME, 'MeterValues', headers.tenantID ?? Constants.DEFAULT_TENANT_ID); + Logging.logException(error, ServerAction.OCPP_METER_VALUES, + MODULE_NAME, 'MeterValues', headers.rawConnectionData?.tenantID ?? Constants.DEFAULT_TENANT_ID); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_METER_VALUES, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -230,13 +235,14 @@ export default { /* Services */ BootNotification: function(args, callback, headers: OCPPHeader, req): void { const request = { ...headers, ...args }; + // const { tenant } = headers.connectionContext;BootNotification // Add OCPP Version headers.ocppVersion = OCPPVersion.VERSION_15; headers.ocppProtocol = OCPPProtocol.SOAP; // Check SOAP params OCPPUtils.checkChargingStationAndEnrichSoapOcppHeaders(Command.BOOT_NOTIFICATION, headers, req).then(async () => { // Trace - const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_BOOT_NOTIFICATION, request, '>>', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -251,7 +257,7 @@ export default { /* Services */ }; callback(response); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_BOOT_NOTIFICATION, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID }, performanceTracingData @@ -266,10 +272,10 @@ export default { /* Services */ }; callback(response); // Log - await Logging.logException(error, ServerAction.OCPP_BOOT_NOTIFICATION, - MODULE_NAME, 'BootNotification', headers.tenantID ?? Constants.DEFAULT_TENANT_ID); + Logging.logException(error, ServerAction.OCPP_BOOT_NOTIFICATION, + MODULE_NAME, 'BootNotification', headers.rawConnectionData?.tenantID ?? Constants.DEFAULT_TENANT_ID); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_BOOT_NOTIFICATION, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -278,10 +284,11 @@ export default { /* Services */ StatusNotification: function(args, callback, headers: OCPPHeader, req): void { const request = { ...headers, ...args }; + // const { tenant } = headers.connectionContext;BootNotification // Check SOAP params OCPPUtils.checkChargingStationAndEnrichSoapOcppHeaders(Command.STATUS_NOTIFICATION, headers, req).then(async () => { // Trace - const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_STATUS_NOTIFICATION, request, '>>', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -292,7 +299,7 @@ export default { /* Services */ }; callback(response); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_STATUS_NOTIFICATION, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID }, performanceTracingData @@ -303,10 +310,10 @@ export default { /* Services */ }; callback(response); // Log - await Logging.logException(error, ServerAction.OCPP_STATUS_NOTIFICATION, - MODULE_NAME, 'StatusNotification', headers.tenantID ?? Constants.DEFAULT_TENANT_ID); + Logging.logException(error, ServerAction.OCPP_STATUS_NOTIFICATION, + MODULE_NAME, 'StatusNotification', headers.rawConnectionData?.tenantID ?? Constants.DEFAULT_TENANT_ID); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_STATUS_NOTIFICATION, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -315,10 +322,11 @@ export default { /* Services */ FirmwareStatusNotification: function(args, callback, headers: OCPPHeader, req): void { const request = { ...headers, ...args }; + // const { tenant } = headers.connectionContext;BootNotification // Check SOAP params OCPPUtils.checkChargingStationAndEnrichSoapOcppHeaders(Command.FIRMWARE_STATUS_NOTIFICATION, headers, req).then(async () => { // Trace - const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_FIRMWARE_STATUS_NOTIFICATION, request, '>>', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -329,7 +337,7 @@ export default { /* Services */ }; callback(response); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_FIRMWARE_STATUS_NOTIFICATION, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID }, performanceTracingData @@ -340,10 +348,10 @@ export default { /* Services */ }; callback(response); // Log - await Logging.logException(error, ServerAction.OCPP_FIRMWARE_STATUS_NOTIFICATION, - MODULE_NAME, 'FirmwareStatusNotification', headers.tenantID ?? Constants.DEFAULT_TENANT_ID); + Logging.logException(error, ServerAction.OCPP_FIRMWARE_STATUS_NOTIFICATION, + MODULE_NAME, 'FirmwareStatusNotification', headers.rawConnectionData?.tenantID ?? Constants.DEFAULT_TENANT_ID); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_FIRMWARE_STATUS_NOTIFICATION, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -352,10 +360,11 @@ export default { /* Services */ DiagnosticsStatusNotification: function(args, callback, headers: OCPPHeader, req): void { const request = { ...headers, ...args }; + // const { tenant } = headers.connectionContext;BootNotification // Check SOAP params OCPPUtils.checkChargingStationAndEnrichSoapOcppHeaders(Command.DIAGNOSTICS_STATUS_NOTIFICATION, headers, req).then(async () => { // Trace - const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_DIAGNOSTICS_STATUS_NOTIFICATION, request, '>>', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -366,7 +375,7 @@ export default { /* Services */ }; callback(response); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_DIAGNOSTICS_STATUS_NOTIFICATION, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID }, performanceTracingData @@ -377,10 +386,10 @@ export default { /* Services */ }; callback(response); // Log - await Logging.logException(error, ServerAction.OCPP_DIAGNOSTICS_STATUS_NOTIFICATION, - MODULE_NAME, 'DiagnosticsStatusNotification', headers.tenantID ?? Constants.DEFAULT_TENANT_ID); + Logging.logException(error, ServerAction.OCPP_DIAGNOSTICS_STATUS_NOTIFICATION, + MODULE_NAME, 'DiagnosticsStatusNotification', headers.rawConnectionData?.tenantID ?? Constants.DEFAULT_TENANT_ID); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_DIAGNOSTICS_STATUS_NOTIFICATION, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -389,10 +398,11 @@ export default { /* Services */ DataTransfer: function(args, callback, headers: OCPPHeader, req): void { const request = { ...headers, ...args }; + // const { tenant } = headers.connectionContext;BootNotification // Check SOAP params OCPPUtils.checkChargingStationAndEnrichSoapOcppHeaders(Command.DATA_TRANSFER, headers, req).then(async () => { // Trace - const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.CHARGING_STATION_DATA_TRANSFER, request, '>>', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -405,7 +415,7 @@ export default { /* Services */ }; callback(response); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.CHARGING_STATION_DATA_TRANSFER, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID }, performanceTracingData @@ -418,10 +428,10 @@ export default { /* Services */ }; callback(response); // Log - await Logging.logException(error, ServerAction.CHARGING_STATION_DATA_TRANSFER, - MODULE_NAME, 'DataTransfer', headers.tenantID ?? Constants.DEFAULT_TENANT_ID); + Logging.logException(error, ServerAction.CHARGING_STATION_DATA_TRANSFER, + MODULE_NAME, 'DataTransfer', headers.rawConnectionData?.tenantID ?? Constants.DEFAULT_TENANT_ID); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.CHARGING_STATION_DATA_TRANSFER, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); diff --git a/src/server/ocpp/soap/services/SoapCentralSystemService16.ts b/src/server/ocpp/soap/services/SoapCentralSystemService16.ts index 4360ee24f4..b5a40f999b 100644 --- a/src/server/ocpp/soap/services/SoapCentralSystemService16.ts +++ b/src/server/ocpp/soap/services/SoapCentralSystemService16.ts @@ -15,10 +15,11 @@ export default { /* Services */ CentralSystemServiceSoap12: { /* Methods */ Authorize: function(args, callback, headers: OCPPHeader, req): void { const request = { ...headers, ...args }; + // const { tenant } = headers.connectionContext;BootNotification // Check SOAP params OCPPUtils.checkChargingStationAndEnrichSoapOcppHeaders(Command.AUTHORIZE, headers, req).then(async () => { // Trace - const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_AUTHORIZE, request, '>>', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -33,7 +34,7 @@ export default { /* Services */ }; callback(response); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_AUTHORIZE, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID }, performanceTracingData @@ -48,10 +49,10 @@ export default { /* Services */ }; callback(response); // Log - await Logging.logException(error, ServerAction.OCPP_AUTHORIZE, - MODULE_NAME, 'Authorize', headers.tenantID ?? Constants.DEFAULT_TENANT_ID); + Logging.logException(error as Error, ServerAction.OCPP_AUTHORIZE, + MODULE_NAME, 'Authorize', headers.rawConnectionData?.tenantID ?? Constants.DEFAULT_TENANT_ID); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_AUTHORIZE, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -63,10 +64,11 @@ export default { /* Services */ // Add OCPP Version headers.ocppVersion = OCPPVersion.VERSION_16; headers.ocppProtocol = OCPPProtocol.SOAP; + // const { tenant } = headers.connectionContext;BootNotification // Check SOAP params OCPPUtils.checkChargingStationAndEnrichSoapOcppHeaders(Command.BOOT_NOTIFICATION, headers, req).then(async () => { // Trace - const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_BOOT_NOTIFICATION, request, '>>', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -81,7 +83,7 @@ export default { /* Services */ }; callback(response); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_BOOT_NOTIFICATION, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID }, performanceTracingData @@ -96,10 +98,10 @@ export default { /* Services */ }; callback(response); // Log - await Logging.logException(error, ServerAction.OCPP_BOOT_NOTIFICATION, - MODULE_NAME, 'BootNotification', headers.tenantID ?? Constants.DEFAULT_TENANT_ID); + Logging.logException(error as Error, ServerAction.OCPP_BOOT_NOTIFICATION, + MODULE_NAME, 'BootNotification', headers.rawConnectionData?.tenantID ?? Constants.DEFAULT_TENANT_ID); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_BOOT_NOTIFICATION, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -108,10 +110,11 @@ export default { /* Services */ DataTransfer: function(args, callback, headers: OCPPHeader, req): void { const request = { ...headers, ...args }; + // const { tenant } = headers.connectionContext;BootNotification // Check SOAP params OCPPUtils.checkChargingStationAndEnrichSoapOcppHeaders(Command.DATA_TRANSFER, headers, req).then(async () => { // Trace - const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.CHARGING_STATION_DATA_TRANSFER, request, '>>', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -124,7 +127,7 @@ export default { /* Services */ }; callback(response); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.CHARGING_STATION_DATA_TRANSFER, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID }, performanceTracingData @@ -137,10 +140,10 @@ export default { /* Services */ }; callback(response); // Log - await Logging.logException(error, ServerAction.CHARGING_STATION_DATA_TRANSFER, - MODULE_NAME, 'DataTransfer', headers.tenantID ?? Constants.DEFAULT_TENANT_ID); + Logging.logException(error, ServerAction.CHARGING_STATION_DATA_TRANSFER, + MODULE_NAME, 'DataTransfer', headers.rawConnectionData?.tenantID ?? Constants.DEFAULT_TENANT_ID); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.CHARGING_STATION_DATA_TRANSFER, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -149,10 +152,11 @@ export default { /* Services */ DiagnosticsStatusNotification: function(args, callback, headers: OCPPHeader, req): void { const request = { ...headers, ...args }; + // const { tenant } = headers.connectionContext;BootNotification // Check SOAP params OCPPUtils.checkChargingStationAndEnrichSoapOcppHeaders(Command.DIAGNOSTICS_STATUS_NOTIFICATION, headers, req).then(async () => { // Trace - const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_DIAGNOSTICS_STATUS_NOTIFICATION, request, '>>', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -163,7 +167,7 @@ export default { /* Services */ }; callback(response); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_DIAGNOSTICS_STATUS_NOTIFICATION, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID }, performanceTracingData @@ -174,10 +178,10 @@ export default { /* Services */ }; callback(response); // Log - await Logging.logException(error, ServerAction.OCPP_DIAGNOSTICS_STATUS_NOTIFICATION, - MODULE_NAME, 'DiagnosticsStatusNotification', headers.tenantID ?? Constants.DEFAULT_TENANT_ID); + Logging.logException(error, ServerAction.OCPP_DIAGNOSTICS_STATUS_NOTIFICATION, + MODULE_NAME, 'DiagnosticsStatusNotification', headers.rawConnectionData?.tenantID ?? Constants.DEFAULT_TENANT_ID); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_DIAGNOSTICS_STATUS_NOTIFICATION, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -186,10 +190,11 @@ export default { /* Services */ FirmwareStatusNotification: function(args, callback, headers: OCPPHeader, req): void { const request = { ...headers, ...args }; + // const { tenant } = headers.connectionContext;BootNotification // Check SOAP params OCPPUtils.checkChargingStationAndEnrichSoapOcppHeaders(Command.FIRMWARE_STATUS_NOTIFICATION, headers, req).then(async () => { // Trace - const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_FIRMWARE_STATUS_NOTIFICATION, request, '>>', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -200,7 +205,7 @@ export default { /* Services */ }; callback(response); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_FIRMWARE_STATUS_NOTIFICATION, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID }, performanceTracingData @@ -211,10 +216,10 @@ export default { /* Services */ }; callback(response); // Log - await Logging.logException(error, ServerAction.OCPP_FIRMWARE_STATUS_NOTIFICATION, - MODULE_NAME, 'FirmwareStatusNotification', headers.tenantID ?? Constants.DEFAULT_TENANT_ID); + Logging.logException(error, ServerAction.OCPP_FIRMWARE_STATUS_NOTIFICATION, + MODULE_NAME, 'FirmwareStatusNotification', headers.rawConnectionData?.tenantID ?? Constants.DEFAULT_TENANT_ID); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_FIRMWARE_STATUS_NOTIFICATION, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -223,10 +228,11 @@ export default { /* Services */ Heartbeat: function(args, callback, headers: OCPPHeader, req): void { const request = { ...headers, ...args }; + // const { tenant } = headers.connectionContext;BootNotification // Check SOAP params OCPPUtils.checkChargingStationAndEnrichSoapOcppHeaders(Command.HEARTBEAT, headers, req).then(async () => { // Trace - const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_HEARTBEAT, request, '>>', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -239,7 +245,7 @@ export default { /* Services */ }; callback(response); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_HEARTBEAT, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID }, performanceTracingData @@ -252,10 +258,10 @@ export default { /* Services */ }; callback(response); // Log - await Logging.logException(error, ServerAction.OCPP_HEARTBEAT, - MODULE_NAME, 'Heartbeat', headers.tenantID ?? Constants.DEFAULT_TENANT_ID); + Logging.logException(error, ServerAction.OCPP_HEARTBEAT, + MODULE_NAME, 'Heartbeat', headers.rawConnectionData?.tenantID ?? Constants.DEFAULT_TENANT_ID); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_HEARTBEAT, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -264,10 +270,11 @@ export default { /* Services */ MeterValues: function(args, callback, headers: OCPPHeader, req): void { const request = { ...headers, ...args }; + // const { tenant } = headers.connectionContext;BootNotification // Check SOAP params OCPPUtils.checkChargingStationAndEnrichSoapOcppHeaders(Command.METER_VALUES, headers, req).then(async () => { // Trace - const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_METER_VALUES, request, '>>', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -278,7 +285,7 @@ export default { /* Services */ }; callback(response); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_METER_VALUES, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID }, performanceTracingData @@ -289,10 +296,10 @@ export default { /* Services */ }; callback(response); // Log - await Logging.logException(error, ServerAction.OCPP_METER_VALUES, - MODULE_NAME, 'MeterValues', headers.tenantID ?? Constants.DEFAULT_TENANT_ID); + Logging.logException(error, ServerAction.OCPP_METER_VALUES, + MODULE_NAME, 'MeterValues', headers.rawConnectionData?.tenantID ?? Constants.DEFAULT_TENANT_ID); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_METER_VALUES, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -301,10 +308,11 @@ export default { /* Services */ StartTransaction: function(args, callback, headers: OCPPHeader, req): void { const request = { ...headers, ...args }; + // const { tenant } = headers.connectionContext;BootNotification // Check SOAP params OCPPUtils.checkChargingStationAndEnrichSoapOcppHeaders(Command.START_TRANSACTION, headers, req).then(async () => { // Trace - const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_START_TRANSACTION, request, '>>', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -320,7 +328,7 @@ export default { /* Services */ }; callback(response); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_START_TRANSACTION, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID }, performanceTracingData @@ -336,10 +344,10 @@ export default { /* Services */ }; callback(response); // Log - await Logging.logException(error, ServerAction.OCPP_START_TRANSACTION, - MODULE_NAME, 'StartTransaction', headers.tenantID ?? Constants.DEFAULT_TENANT_ID); + Logging.logException(error, ServerAction.OCPP_START_TRANSACTION, + MODULE_NAME, 'StartTransaction', headers.rawConnectionData?.tenantID ?? Constants.DEFAULT_TENANT_ID); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_START_TRANSACTION, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -348,10 +356,11 @@ export default { /* Services */ StatusNotification: function(args, callback, headers: OCPPHeader, req): void { const request = { ...headers, ...args }; + // const { tenant } = headers.connectionContext;BootNotification // Check SOAP params OCPPUtils.checkChargingStationAndEnrichSoapOcppHeaders(Command.STATUS_NOTIFICATION, headers, req).then(async () => { // Trace - const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_STATUS_NOTIFICATION, request, '>>', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -362,7 +371,7 @@ export default { /* Services */ }; callback(response); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_STATUS_NOTIFICATION, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID }, performanceTracingData @@ -373,10 +382,10 @@ export default { /* Services */ }; callback(response); // Log - await Logging.logException(error, ServerAction.OCPP_STATUS_NOTIFICATION, - MODULE_NAME, 'StatusNotification', headers.tenantID ?? Constants.DEFAULT_TENANT_ID); + Logging.logException(error, ServerAction.OCPP_STATUS_NOTIFICATION, + MODULE_NAME, 'StatusNotification', headers.rawConnectionData?.tenantID ?? Constants.DEFAULT_TENANT_ID); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_STATUS_NOTIFICATION, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -385,10 +394,11 @@ export default { /* Services */ StopTransaction: function(args, callback, headers: OCPPHeader, req): void { const request = { ...headers, ...args }; + // const { tenant } = headers.connectionContext;BootNotification // Check SOAP params OCPPUtils.checkChargingStationAndEnrichSoapOcppHeaders(Command.STOP_TRANSACTION, headers, req).then(async () => { // Trace - const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + const performanceTracingData = await Logging.traceOcppMessageRequest(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_STOP_TRANSACTION, request, '>>', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); @@ -403,7 +413,7 @@ export default { /* Services */ }; callback(response); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_STOP_TRANSACTION, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID }, performanceTracingData @@ -418,10 +428,10 @@ export default { /* Services */ }; callback(response); // Log - await Logging.logException(error, ServerAction.OCPP_STOP_TRANSACTION, - MODULE_NAME, 'StopTransaction', headers.tenantID ?? Constants.DEFAULT_TENANT_ID); + Logging.logException(error, ServerAction.OCPP_STOP_TRANSACTION, + MODULE_NAME, 'StopTransaction', headers.rawConnectionData?.tenantID ?? Constants.DEFAULT_TENANT_ID); // Trace - await Logging.traceOcppMessageResponse(MODULE_NAME, headers.tenant, headers.chargeBoxIdentity, + await Logging.traceOcppMessageResponse(MODULE_NAME, headers.connectionContext.tenant, headers.chargeBoxIdentity, ServerAction.OCPP_STOP_TRANSACTION, request, response, '<<', { siteID: headers.siteID, siteAreaID: headers.siteAreaID, companyID: headers.companyID } ); diff --git a/src/server/ocpp/utils/OCPPCommon.ts b/src/server/ocpp/utils/OCPPCommon.ts index bad25b8252..cb6ad77719 100644 --- a/src/server/ocpp/utils/OCPPCommon.ts +++ b/src/server/ocpp/utils/OCPPCommon.ts @@ -35,7 +35,7 @@ export default class OCPPCommon { await OCPPCommon.requestAndSaveChargingStationOcppParameters(tenant, chargingStation); } if (triggerConditionalReset && result.status === OCPPConfigurationStatus.REBOOT_REQUIRED) { - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.CHARGING_STATION_CHANGE_CONFIGURATION, @@ -52,7 +52,7 @@ export default class OCPPCommon { try { // Get the OCPP Configuration const ocppConfiguration = await OCPPCommon.requestChargingStationOcppParameters(tenant, chargingStation, {}); - await Logging.logDebug({ + Logging.beDebug()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.CHARGING_STATION_CHANGE_CONFIGURATION, @@ -90,7 +90,7 @@ export default class OCPPCommon { } // Save configuration await ChargingStationStorage.saveOcppParameters(tenant, chargingStationOcppParameters); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.CHARGING_STATION_CHANGE_CONFIGURATION, @@ -99,7 +99,7 @@ export default class OCPPCommon { }); return { status: OCPPConfigurationStatus.ACCEPTED }; } catch (error) { - await Logging.logActionExceptionMessage(tenant.id, ServerAction.CHARGING_STATION_CHANGE_CONFIGURATION, error); + Logging.logActionExceptionMessage(tenant.id, ServerAction.CHARGING_STATION_CHANGE_CONFIGURATION, error); return { status: OCPPConfigurationStatus.REJECTED }; } } @@ -118,7 +118,7 @@ export default class OCPPCommon { } let resetResult = await chargingStationClient.reset({ type: resetType }); if (resetResult.status === OCPPResetStatus.REJECTED) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.CHARGING_STATION_RESET, @@ -126,7 +126,7 @@ export default class OCPPCommon { message: `Error at ${resetType} Rebooting charging station`, }); if (hardResetFallback && resetType !== OCPPResetType.HARD) { - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.CHARGING_STATION_RESET, @@ -135,7 +135,7 @@ export default class OCPPCommon { }); resetResult = await chargingStationClient.reset({ type: OCPPResetType.HARD }); if (resetResult.status === OCPPResetStatus.REJECTED) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.CHARGING_STATION_RESET, diff --git a/src/server/ocpp/utils/OCPPUtils.ts b/src/server/ocpp/utils/OCPPUtils.ts index b237414fcc..d062f865c2 100644 --- a/src/server/ocpp/utils/OCPPUtils.ts +++ b/src/server/ocpp/utils/OCPPUtils.ts @@ -1,6 +1,7 @@ import { ChargingProfile, ChargingProfilePurposeType } from '../../../types/ChargingProfile'; import ChargingStation, { ChargingStationCapabilities, ChargingStationTemplate, ChargingStationTemplateConnector, Command, Connector, ConnectorCurrentLimitSource, CurrentType, OcppParameter, SiteAreaLimitSource, StaticLimitAmps, TemplateUpdateResult } from '../../../types/ChargingStation'; import { OCPPChangeConfigurationResponse, OCPPChargingProfileStatus, OCPPConfigurationStatus } from '../../../types/ocpp/OCPPClient'; +import { OCPPHeader, OcppConnectionContext, OcppRawConnectionData } from '../../../types/ocpp/OCPPHeader'; import { OCPPLocation, OCPPMeasurand, OCPPNormalizedMeterValue, OCPPPhase, OCPPReadingContext, OCPPStopTransactionRequestExtended, OCPPUnitOfMeasure, OCPPValueFormat } from '../../../types/ocpp/OCPPServer'; import Tenant, { TenantComponents } from '../../../types/Tenant'; import Transaction, { InactivityStatus } from '../../../types/Transaction'; @@ -17,7 +18,6 @@ import DatabaseUtils from '../../../storage/mongodb/DatabaseUtils'; import Logging from '../../../utils/Logging'; import LoggingHelper from '../../../utils/LoggingHelper'; import OCPPCommon from './OCPPCommon'; -import { OCPPHeader } from '../../../types/ocpp/OCPPHeader'; import PricingFacade from '../../../integration/pricing/PricingFacade'; import { PricingSettingsType } from '../../../types/Setting'; import { Promise } from 'bluebird'; @@ -482,7 +482,7 @@ export default class OCPPUtils { // Meter Value is in the past if (transaction.lastConsumption?.timestamp && meterValue.timestamp && moment(meterValue?.timestamp).isBefore(moment(transaction?.lastConsumption?.timestamp))) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'createConsumptionsFromMeterValues', @@ -772,7 +772,7 @@ export default class OCPPUtils { for (const filter in chargingStationTemplate.template.extraFilters) { if (Utils.objectHasProperty(chargingStation, filter)) { const filterValue: string = chargingStationTemplate.template.extraFilters[filter]; - if (!(new RegExp(filterValue).test(chargingStation[filter]))) { + if (!(new RegExp(filterValue).test(chargingStation[filter] as string))) { foundTemplate = null; break; } @@ -795,7 +795,7 @@ export default class OCPPUtils { // Add unknown Connector ID chargingStation.chargePoints[0].connectorIDs.push(connector.connectorId); } - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.UPDATE_CHARGING_STATION_WITH_TEMPLATE, @@ -824,7 +824,7 @@ export default class OCPPUtils { } // Not found but not master/salve if (!foundTemplateConnector) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.UPDATE_CHARGING_STATION_WITH_TEMPLATE, @@ -877,7 +877,7 @@ export default class OCPPUtils { await OCPPUtils.setConnectorPhaseAssignment(tenant, chargingStation, connector, numberOfPhases); } // Success - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.UPDATE_CHARGING_STATION_WITH_TEMPLATE, @@ -887,7 +887,7 @@ export default class OCPPUtils { return true; } // No Connector in Template - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.UPDATE_CHARGING_STATION_WITH_TEMPLATE, @@ -901,7 +901,7 @@ export default class OCPPUtils { return false; } // No Template - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.UPDATE_CHARGING_STATION_WITH_TEMPLATE, @@ -928,7 +928,7 @@ export default class OCPPUtils { } public static async applyTemplateOcppParametersToChargingStation(tenant: Tenant, chargingStation: ChargingStation): Promise { - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.UPDATE_CHARGING_STATION_WITH_TEMPLATE, @@ -940,7 +940,7 @@ export default class OCPPUtils { Constants.DELAY_CHANGE_CONFIGURATION_EXECUTION_MILLIS, OCPPCommon.requestAndSaveChargingStationOcppParameters(tenant, chargingStation), `Time out error (${Constants.DELAY_CHANGE_CONFIGURATION_EXECUTION_MILLIS} ms): Cannot update Charging Station with Template's OCPP Parameters`); if (result.status !== OCPPConfigurationStatus.ACCEPTED) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.UPDATE_CHARGING_STATION_WITH_TEMPLATE, @@ -953,7 +953,7 @@ export default class OCPPUtils { Constants.DELAY_CHANGE_CONFIGURATION_EXECUTION_MILLIS, OCPPUtils.updateChargingStationOcppParametersWithTemplate(tenant, chargingStation), `Time out error (${Constants.DELAY_CHANGE_CONFIGURATION_EXECUTION_MILLIS} ms): Cannot update Charging Station with Template's OCPP Parameters`); if (result.status === OCPPConfigurationStatus.ACCEPTED) { - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.UPDATE_CHARGING_STATION_WITH_TEMPLATE, @@ -961,7 +961,7 @@ export default class OCPPUtils { message: 'Charging Station has been successfully updated with Template\'s OCPP Parameters', }); } else { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.UPDATE_CHARGING_STATION_WITH_TEMPLATE, @@ -992,7 +992,7 @@ export default class OCPPUtils { await this.clearAndDeleteChargingProfile(tenant, chargingProfile); actionsResponse.inSuccess++; } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, siteID: chargingProfile.chargingStation?.siteID, siteAreaID: chargingProfile.chargingStation?.siteAreaID, @@ -1047,7 +1047,7 @@ export default class OCPPUtils { try { await chargingStationVendor.clearChargingProfile(tenant, chargingStation, chargingProfile); } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.CHARGING_PROFILE_DELETE, @@ -1059,7 +1059,7 @@ export default class OCPPUtils { } // Delete from database await ChargingStationStorage.deleteChargingProfile(tenant, chargingProfile.id); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.CHARGING_PROFILE_DELETE, @@ -1069,7 +1069,7 @@ export default class OCPPUtils { }); } - public static async checkChargingStationAndEnrichSoapOcppHeaders(command: Command, headers: OCPPHeader, req: any): Promise { + public static async checkChargingStationAndEnrichSoapOcppHeaders(command: Command, headers: OCPPHeader, req: any): Promise { // Normalize OCPPUtils.normalizeOneSOAPParam(headers, 'chargeBoxIdentity'); OCPPUtils.normalizeOneSOAPParam(headers, 'Action'); @@ -1080,16 +1080,14 @@ export default class OCPPUtils { headers.currentIPAddress = Utils.getRequestIP(req); // Parse the request (lower case for fucking charging station DBT URL registration) const urlParts = url.parse(decodeURIComponent(req.url.toLowerCase()), true); - headers.tenantID = urlParts.query.tenantid as string; - headers.tokenID = urlParts.query.token as string; - // Get all the necessary entities - const { tenant, chargingStation, token } = await OCPPUtils.checkAndGetChargingStationConnectionData( - OCPPUtils.buildServerActionFromOcppCommand(command), headers.tenantID, headers.chargeBoxIdentity, headers.tokenID); - // Set - headers.tenant = tenant; - headers.chargingStation = chargingStation; - headers.token = token; - return Promise.resolve(); + headers.rawConnectionData = { + tenantID: urlParts.query.tenantid as string, + tokenID: urlParts.query.token as string, + chargingStationID: headers.chargeBoxIdentity, + }; + // Set connection context + headers.connectionContext = await OCPPUtils.checkAndGetChargingStationConnectionData(OCPPUtils.buildServerActionFromOcppCommand(command), headers.rawConnectionData); + return Promise.resolve(headers); } public static async setAndSaveChargingProfile(tenant: Tenant, chargingProfile: ChargingProfile): Promise { @@ -1144,7 +1142,7 @@ export default class OCPPUtils { } // Save const chargingProfileID = await ChargingStationStorage.saveChargingProfile(tenant, chargingProfile); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.CHARGING_PROFILE_UPDATE, @@ -1197,39 +1195,40 @@ export default class OCPPUtils { meterValue.attribute.context === OCPPReadingContext.SAMPLE_PERIODIC); } - public static checkChargingStationConnectionData(action: ServerAction, tenantID: string, tokenID: string, chargingStationID: string): void { + public static checkChargingStationConnectionData(action: ServerAction, rawConnectionData: OcppRawConnectionData): void { // Check Charging Station - if (!chargingStationID) { + if (!rawConnectionData.chargingStationID) { throw new BackendError({ action, module: MODULE_NAME, method: 'checkChargingStationOcppParameters', message: 'The Charging Station ID is mandatory!' }); } - if (!Utils.isChargingStationIDValid(chargingStationID)) { + const chargingStationID = rawConnectionData.chargingStationID; + if (!Utils.isChargingStationIDValid(rawConnectionData.chargingStationID)) { throw new BackendError({ action, chargingStationID, module: MODULE_NAME, method: 'checkChargingStationOcppParameters', - message: `The Charging Station ID '${chargingStationID}' is invalid!` + message: `The Charging Station ID '${rawConnectionData.chargingStationID}' is invalid!` }); } // Check Tenant - if (!tenantID) { + if (!rawConnectionData.tenantID) { throw new BackendError({ action, chargingStationID, module: MODULE_NAME, method: 'checkChargingStationOcppParameters', message: 'The Tenant ID is mandatory!' }); } - if (!DatabaseUtils.isObjectID(tenantID)) { + if (!DatabaseUtils.isObjectID(rawConnectionData.tenantID)) { throw new BackendError({ action, chargingStationID, module: MODULE_NAME, method: 'checkChargingStationOcppParameters', - message: `The Tenant ID '${tenantID}' is invalid!` + message: `The Tenant ID '${rawConnectionData.tenantID}' is invalid!` }); } // Check Token - if (!tokenID) { + if (!rawConnectionData.tokenID) { throw new BackendError({ action, chargingStationID, module: MODULE_NAME, method: 'checkChargingStationOcppParameters', @@ -1238,11 +1237,11 @@ export default class OCPPUtils { } } - public static async checkAndGetChargingStationConnectionData(action: ServerAction, tenantID: string, chargingStationID: string, - tokenID: string, updateChargingStationData = true): Promise<{ tenant: Tenant; chargingStation?: ChargingStation; token?: RegistrationToken }> { + public static async checkAndGetChargingStationConnectionData(action: ServerAction, rawConnectionData: OcppRawConnectionData, updateChargingStationData = true): Promise { + const { tenantID, chargingStationID, tokenID = null } = rawConnectionData; // Check parameters OCPPUtils.checkChargingStationConnectionData( - ServerAction.WS_SERVER_CONNECTION, tenantID, tokenID, chargingStationID); + ServerAction.WS_SERVER_CONNECTION, rawConnectionData); // Get Tenant const tenant = await TenantStorage.getTenantFromCache(tenantID); if (!tenant) { @@ -1252,10 +1251,17 @@ export default class OCPPUtils { message: `Tenant ID '${tenantID}' does not exist!` }); } + // Check consistency + if (!tenant?.id || !tenant?.components) { + throw new BackendError({ + chargingStationID, + module: MODULE_NAME, method: 'checkAndGetChargingStationData', + message: `Tenant ID '${tenantID}' data is not consistent - sounds like the database is under pressure!` + }); + } // Get the Charging Station let token: RegistrationToken; - const chargingStation = await ChargingStationStorage.getChargingStation( - tenant, chargingStationID, { withSiteArea: true, issuer: true }); + const chargingStation = await ChargingStationStorage.getChargingStation(tenant, chargingStationID, { withSiteArea: true, issuer: true }); if (!chargingStation) { // Must have a valid connection Token token = await OCPPUtils.ensureChargingStationHasValidConnectionToken(action, tenant, chargingStationID, tokenID); @@ -1269,14 +1275,17 @@ export default class OCPPUtils { message: 'Charging Station does not exist!' }); } - return { tenant, token }; + const ocppConnectionData = { + tenant, token, chargingStation: null + }; + return ocppConnectionData; } // Same Token? if (chargingStation.tokenID !== tokenID) { // Must have a valid connection Token token = await OCPPUtils.ensureChargingStationHasValidConnectionToken(action, tenant, chargingStationID, tokenID); // Ok, set it - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action, module: MODULE_NAME, method: 'checkAndGetChargingStationData', @@ -1316,7 +1325,10 @@ export default class OCPPUtils { cloudHostName: chargingStation.cloudHostName, }); } - return { tenant, chargingStation, token }; + const ocppConnectionData = { + tenant, chargingStation, token + }; + return ocppConnectionData; } public static async updateChargingStationOcppParametersWithTemplate(tenant: Tenant, chargingStation: ChargingStation): Promise { @@ -1330,7 +1342,7 @@ export default class OCPPUtils { const currentOcppParameters = (await ChargingStationStorage.getOcppParameters(tenant, chargingStation.id)).result; if (Utils.isEmptyArray(chargingStation.ocppStandardParameters) && Utils.isEmptyArray(chargingStation.ocppVendorParameters)) { - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.CHARGING_STATION_CHANGE_CONFIGURATION, @@ -1350,7 +1362,7 @@ export default class OCPPUtils { // Check Value if (currentOcppParam && currentOcppParam.value === ocppParameter.value) { // Ok: Already the good value - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.CHARGING_STATION_CHANGE_CONFIGURATION, @@ -1366,7 +1378,7 @@ export default class OCPPUtils { }, false); if (result.status === OCPPConfigurationStatus.ACCEPTED) { updatedOcppParameters.inSuccess++; - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.CHARGING_STATION_CHANGE_CONFIGURATION, @@ -1376,7 +1388,7 @@ export default class OCPPUtils { } else if (result.status === OCPPConfigurationStatus.REBOOT_REQUIRED) { updatedOcppParameters.inSuccess++; rebootRequired = true; - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.CHARGING_STATION_CHANGE_CONFIGURATION, @@ -1385,7 +1397,7 @@ export default class OCPPUtils { }); } else { updatedOcppParameters.inError++; - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.CHARGING_STATION_CHANGE_CONFIGURATION, @@ -1395,7 +1407,7 @@ export default class OCPPUtils { } } catch (error) { updatedOcppParameters.inError++; - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.CHARGING_STATION_CHANGE_CONFIGURATION, @@ -1443,7 +1455,7 @@ export default class OCPPUtils { // Log const instantPower = Utils.truncTo(Utils.createDecimal(connector.currentInstantWatts).div(1000).toNumber(), 3); const totalConsumption = Utils.truncTo(Utils.createDecimal(connector.currentTotalConsumptionWh).div(1000).toNumber(), 3); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'updateChargingStationConnectorRuntimeDataWithTransaction', @@ -1523,7 +1535,7 @@ export default class OCPPUtils { }; // Do not apply template if manual configured if (chargingStation.manualConfiguration) { - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.UPDATE_CHARGING_STATION_WITH_TEMPLATE, @@ -1540,7 +1552,7 @@ export default class OCPPUtils { if (chargingStationTemplate) { // Already updated? if (chargingStation.templateHash !== chargingStationTemplate.hash) { - await Logging.logDebug({ + Logging.beDebug()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.UPDATE_CHARGING_STATION_WITH_TEMPLATE, @@ -1552,17 +1564,17 @@ export default class OCPPUtils { OCPPUtils.enrichChargingStationWithTemplateTechnicalParams(chargingStation, chargingStationTemplate); // Check Capabilities templateUpdateResult.capabilitiesUpdated = - await OCPPUtils.enrichChargingStationWithTemplateCapabilities(tenant, chargingStation, chargingStationTemplate); + OCPPUtils.enrichChargingStationWithTemplateCapabilities(tenant, chargingStation, chargingStationTemplate); // Check Ocpp Standard parameters templateUpdateResult.ocppStandardUpdated = - await OCPPUtils.enrichChargingStationWithTemplateOcppStandardParams(tenant, chargingStation, chargingStationTemplate); + OCPPUtils.enrichChargingStationWithTemplateOcppStandardParams(tenant, chargingStation, chargingStationTemplate); // Check Ocpp Vendor parameters templateUpdateResult.ocppVendorUpdated = - await OCPPUtils.enrichChargingStationWithTemplateOcppVendorParams(tenant, chargingStation, chargingStationTemplate); + OCPPUtils.enrichChargingStationWithTemplateOcppVendorParams(tenant, chargingStation, chargingStationTemplate); // Update chargingStation.templateHash = chargingStationTemplate.hash; templateUpdateResult.chargingStationUpdated = true; - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.UPDATE_CHARGING_STATION_WITH_TEMPLATE, @@ -1581,7 +1593,7 @@ export default class OCPPUtils { } } } else { - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.UPDATE_CHARGING_STATION_WITH_TEMPLATE, @@ -1596,8 +1608,8 @@ export default class OCPPUtils { return templateUpdateResult; } - private static async enrichChargingStationWithTemplateOcppStandardParams(tenant: Tenant, chargingStation: ChargingStation, - chargingStationTemplate: ChargingStationTemplate): Promise { + private static enrichChargingStationWithTemplateOcppStandardParams(tenant: Tenant, chargingStation: ChargingStation, + chargingStationTemplate: ChargingStationTemplate): boolean { // Already updated? if (chargingStation.templateHashOcppStandard !== chargingStationTemplate.hashOcppStandard) { chargingStation.templateHashOcppStandard = chargingStationTemplate.hashOcppStandard; @@ -1605,8 +1617,8 @@ export default class OCPPUtils { } } - private static async enrichChargingStationWithTemplateOcppVendorParams(tenant: Tenant, chargingStation: ChargingStation, - chargingStationTemplate: ChargingStationTemplate): Promise { + private static enrichChargingStationWithTemplateOcppVendorParams(tenant: Tenant, chargingStation: ChargingStation, + chargingStationTemplate: ChargingStationTemplate): boolean { // Already updated? if (chargingStation.templateHashOcppVendor !== chargingStationTemplate.hashOcppVendor) { chargingStation.templateHashOcppVendor = chargingStationTemplate.hashOcppVendor; @@ -1614,8 +1626,8 @@ export default class OCPPUtils { } } - private static async enrichChargingStationWithTemplateOcppParams(tenant: Tenant, chargingStation: ChargingStation, chargingStationTemplate: ChargingStationTemplate, - ocppProperty: 'ocppStandardParameters'|'ocppVendorParameters'): Promise { + private static enrichChargingStationWithTemplateOcppParams(tenant: Tenant, chargingStation: ChargingStation, chargingStationTemplate: ChargingStationTemplate, + ocppProperty: 'ocppStandardParameters'|'ocppVendorParameters'): boolean { // Handle OCPP Standard Parameters chargingStation[ocppProperty] = []; if (chargingStationTemplate.template?.[ocppProperty]) { @@ -1641,7 +1653,7 @@ export default class OCPPUtils { if (matchFirmware && matchOcpp) { for (const parameter in ocppParameters.parameters) { if (OCPPUtils.isOcppParamForPowerLimitationKey(parameter, chargingStation)) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.UPDATE_CHARGING_STATION_WITH_TEMPLATE, @@ -1654,7 +1666,7 @@ export default class OCPPUtils { continue; } if (Constants.OCPP_HEARTBEAT_KEYS.includes(parameter)) { - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.UPDATE_CHARGING_STATION_WITH_TEMPLATE, @@ -1675,7 +1687,7 @@ export default class OCPPUtils { } } // Not found - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.UPDATE_CHARGING_STATION_WITH_TEMPLATE, @@ -1689,8 +1701,8 @@ export default class OCPPUtils { } } - private static async enrichChargingStationWithTemplateCapabilities(tenant: Tenant, chargingStation: ChargingStation, - chargingStationTemplate: ChargingStationTemplate): Promise { + private static enrichChargingStationWithTemplateCapabilities(tenant: Tenant, chargingStation: ChargingStation, + chargingStationTemplate: ChargingStationTemplate): boolean { // Already updated? if (chargingStation.templateHashCapabilities !== chargingStationTemplate.hashCapabilities) { // Handle capabilities @@ -1725,7 +1737,7 @@ export default class OCPPUtils { } } // Not found - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.UPDATE_CHARGING_STATION_WITH_TEMPLATE, diff --git a/src/server/ocpp/validator/OCPPValidator.ts b/src/server/ocpp/validator/OCPPValidator.ts index d04285ee24..dc24219d15 100644 --- a/src/server/ocpp/validator/OCPPValidator.ts +++ b/src/server/ocpp/validator/OCPPValidator.ts @@ -106,13 +106,13 @@ export default class OCPPValidator extends SchemaValidator { } } - public async validateMeterValues(tenantID: string, chargingStation: ChargingStation, meterValues: OCPPMeterValuesRequestExtended): Promise { + public validateMeterValues(tenantID: string, chargingStation: ChargingStation, meterValues: OCPPMeterValuesRequestExtended): void { // Always integer this.validate(this.meterValueRequest, meterValues); // Check Connector ID if (meterValues.connectorId === 0) { // KEBA: Connector ID must be > 0 according to OCPP - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenantID, module: MODULE_NAME, method: 'validateMeterValues', @@ -125,7 +125,7 @@ export default class OCPPValidator extends SchemaValidator { // Check if the transaction ID matches with the one on the Connector const foundConnector = Utils.getConnectorFromID(chargingStation, meterValues.connectorId); if (!foundConnector) { - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenantID, module: MODULE_NAME, method: 'validateMeterValues', @@ -140,7 +140,7 @@ export default class OCPPValidator extends SchemaValidator { if (meterValues.transactionId === 0 && foundConnector.currentTransactionID > 0) { // Reuse Transaction ID from Connector meterValues.transactionId = foundConnector.currentTransactionID; - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenantID, module: MODULE_NAME, method: 'validateMeterValues', diff --git a/src/server/odata/ODataRestAdapter.ts b/src/server/odata/ODataRestAdapter.ts index 648f0d7378..078bd3633c 100644 --- a/src/server/odata/ODataRestAdapter.ts +++ b/src/server/odata/ODataRestAdapter.ts @@ -97,7 +97,7 @@ export default class ODataRestAdapter { } } catch (error) { // Add logging - await Logging.logError({ + Logging.beError()?.log({ tenantID: req.user.tenantID, module: MODULE_NAME, method: 'query', action: ServerAction.ODATA_SERVER, diff --git a/src/server/odata/odata-schema/ODataSchema.ts b/src/server/odata/odata-schema/ODataSchema.ts index e41221636a..a00c038c71 100644 --- a/src/server/odata/odata-schema/ODataSchema.ts +++ b/src/server/odata/odata-schema/ODataSchema.ts @@ -42,7 +42,7 @@ export default class ODataSchema { } } catch (error) { // Add logging: login info - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, module: MODULE_NAME, method: 'getSchema', action: ServerAction.ODATA_SERVER, diff --git a/src/server/oicp/AbstractOICPService.ts b/src/server/oicp/AbstractOICPService.ts index 246baa4acf..d223870c95 100644 --- a/src/server/oicp/AbstractOICPService.ts +++ b/src/server/oicp/AbstractOICPService.ts @@ -103,7 +103,7 @@ export default abstract class AbstractOICPService { // Handle request action (endpoint) const endpoint = registeredEndpoints.get(endpointName); if (endpoint) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: endpointName, message: `>> OICP Request ${req.method} ${req.originalUrl}`, @@ -112,7 +112,7 @@ export default abstract class AbstractOICPService { }); const response = await endpoint.process(req, res, next, tenant); if (response) { - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: endpointName, message: `<< OICP Response ${req.method} ${req.originalUrl}`, @@ -121,7 +121,7 @@ export default abstract class AbstractOICPService { }); res.json(response); } else { - await Logging.logWarning({ + Logging.beWarning()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: endpointName, message: `<< OICP Endpoint ${req.method} ${req.originalUrl} not implemented`, @@ -139,14 +139,14 @@ export default abstract class AbstractOICPService { }); } } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: req.user && req.user.tenantID ? req.user.tenantID : Constants.DEFAULT_TENANT_ID, module: MODULE_NAME, method: endpointName, message: `<< OICP Response Error ${req.method} ${req.originalUrl}`, action: ServerAction.OICP_ENDPOINT, detailedMessages: { error: error.stack } }); - await Logging.logActionExceptionMessage(req.user && req.user.tenantID ? req.user.tenantID : Constants.DEFAULT_TENANT_ID, ServerAction.OICP_ENDPOINT, error); + Logging.logActionExceptionMessage(req.user && req.user.tenantID ? req.user.tenantID : Constants.DEFAULT_TENANT_ID, ServerAction.OICP_ENDPOINT, error); let errorCode: any = {}; if (error instanceof AppError || error instanceof AppAuthError) { errorCode = error.params.errorCode; diff --git a/src/server/oicp/OICPFacade.ts b/src/server/oicp/OICPFacade.ts index 3204ac2d68..19f48244fc 100644 --- a/src/server/oicp/OICPFacade.ts +++ b/src/server/oicp/OICPFacade.ts @@ -58,7 +58,7 @@ export default class OICPFacade { // Update OICP Session await oicpClient.updateSession(transaction); } catch (error) { - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: tenant.id, action, module: MODULE_NAME, method: 'processUpdateTransaction', @@ -128,7 +128,7 @@ export default class OICPFacade { } } } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, module: MODULE_NAME, method: 'updateConnectorStatus', diff --git a/src/server/oicp/oicp-services-impl/oicp-2.3.0/CPORemoteAuthorizationsEndpoint.ts b/src/server/oicp/oicp-services-impl/oicp-2.3.0/CPORemoteAuthorizationsEndpoint.ts index 876a6dc5a5..1a63f5fa9a 100644 --- a/src/server/oicp/oicp-services-impl/oicp-2.3.0/CPORemoteAuthorizationsEndpoint.ts +++ b/src/server/oicp/oicp-services-impl/oicp-2.3.0/CPORemoteAuthorizationsEndpoint.ts @@ -61,7 +61,7 @@ export default class CPORemoteAuthorizationsEndpoint extends AbstractEndpoint { const connector = chargingStationConnector.connector; const chargingStation = chargingStationConnector.chargingStation; if (!chargingStation) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: ServerAction.OICP_AUTHORIZE_REMOTE_START, message: `Charging Station ID '${authorizeRemoteStart.EvseID}' not found`, @@ -70,7 +70,7 @@ export default class CPORemoteAuthorizationsEndpoint extends AbstractEndpoint { return OICPUtils.noSuccess(session, `EVSE for EvseID '${authorizeRemoteStart.EvseID}' not found`); } if (!connector) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: ServerAction.OICP_AUTHORIZE_REMOTE_START, message: `Connector for Charging Station ID '${authorizeRemoteStart.EvseID}' not found`, @@ -79,7 +79,7 @@ export default class CPORemoteAuthorizationsEndpoint extends AbstractEndpoint { return OICPUtils.noSuccess(session, `EVSE for EvseID '${authorizeRemoteStart.EvseID}' not found`); } if (!chargingStation.issuer || !chargingStation.public) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: ServerAction.OICP_AUTHORIZE_REMOTE_START, message: `Charging Station ID '${authorizeRemoteStart.EvseID}' cannot be used with OICP`, @@ -88,7 +88,7 @@ export default class CPORemoteAuthorizationsEndpoint extends AbstractEndpoint { return OICPUtils.noSuccess(session, `EVSE '${authorizeRemoteStart.EvseID}' cannot be used with OICP`); } if (connector.status !== ChargePointStatus.AVAILABLE && connector.status !== ChargePointStatus.PREPARING) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: ServerAction.OICP_AUTHORIZE_REMOTE_START, message: `Charging Station ID '${authorizeRemoteStart.EvseID}' is not available`, @@ -108,7 +108,7 @@ export default class CPORemoteAuthorizationsEndpoint extends AbstractEndpoint { // Check if authorization of different user is valid if (OICPUtils.isAuthorizationValid(existingAuthorization.timestamp)) { // Current remote authorization fails due to valid remote authorization of different user - await Logging.logDebug({ + Logging.beDebug()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.OICP_AUTHORIZE_REMOTE_START, @@ -155,7 +155,7 @@ export default class CPORemoteAuthorizationsEndpoint extends AbstractEndpoint { session.providerID = authorizeRemoteStop.ProviderID; const transaction = await TransactionStorage.getOICPTransactionBySessionID(tenant, authorizeRemoteStop.SessionID); if (!transaction) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: ServerAction.OICP_AUTHORIZE_REMOTE_STOP, message: `OICP Transaction ID '${authorizeRemoteStop.SessionID}' does not exists`, @@ -164,7 +164,7 @@ export default class CPORemoteAuthorizationsEndpoint extends AbstractEndpoint { return OICPUtils.noSuccess(session, `Transaction with OICP Transaction ID '${authorizeRemoteStop.SessionID}' does not exists`); } if (!transaction.issuer) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: ServerAction.OICP_AUTHORIZE_REMOTE_STOP, message: `OICP Transaction ID '${authorizeRemoteStop.SessionID}' has been issued locally`, @@ -173,7 +173,7 @@ export default class CPORemoteAuthorizationsEndpoint extends AbstractEndpoint { return OICPUtils.noSuccess(session, `Transaction with OICP Transaction ID '${authorizeRemoteStop.SessionID}' has been issued locally`); } if (transaction.stop) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: ServerAction.OICP_AUTHORIZE_REMOTE_STOP, message: `OICP Transaction ID '${authorizeRemoteStop.SessionID}' is already stopped`, @@ -183,7 +183,7 @@ export default class CPORemoteAuthorizationsEndpoint extends AbstractEndpoint { } const chargingStation = await ChargingStationStorage.getChargingStation(tenant, transaction.chargeBoxID); if (!chargingStation) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: tenant.id, action: ServerAction.OICP_AUTHORIZE_REMOTE_STOP, @@ -204,7 +204,7 @@ export default class CPORemoteAuthorizationsEndpoint extends AbstractEndpoint { connector: Connector, authorizeRemoteStart: OICPAuthorizeRemoteStartCpoReceive): Promise { const chargingStationClient = await ChargingStationClientFactory.getChargingStationClient(tenant, chargingStation); if (!chargingStationClient) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.OICP_AUTHORIZE_REMOTE_START, @@ -222,7 +222,7 @@ export default class CPORemoteAuthorizationsEndpoint extends AbstractEndpoint { private async remoteStopTransaction(tenant: Tenant, chargingStation: ChargingStation, transactionId: number): Promise { const chargingStationClient = await ChargingStationClientFactory.getChargingStationClient(tenant, chargingStation); if (!chargingStationClient) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action: ServerAction.OICP_AUTHORIZE_REMOTE_STOP, diff --git a/src/server/rest/RestServerService.ts b/src/server/rest/RestServerService.ts index 8c25795ee9..e79ea3846b 100644 --- a/src/server/rest/RestServerService.ts +++ b/src/server/rest/RestServerService.ts @@ -253,7 +253,7 @@ export default class RestServerService { try { // Parse the action const action = req.params.action as ServerAction; - await Logging.logWarning({ + Logging.beWarning()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, message: `REST Endpoint 'restServiceUtil' should not be used for action '${action}'`, action: ServerAction.DEPRECATED_REST_ENDPOINT, @@ -311,7 +311,7 @@ export default class RestServerService { // Parse the action const action = req.params.action as ServerAction; // Old endpoint: should not be used - await Logging.logWarning({ + Logging.beWarning()?.log({ tenantID: req.tenant?.id, message: `REST Endpoint 'restServiceSecured' should not be used for action '${action}'`, action: ServerAction.DEPRECATED_REST_ENDPOINT, @@ -319,7 +319,7 @@ export default class RestServerService { }); // Check HTTP Verbs if (!['POST', 'GET', 'PUT', 'DELETE'].includes(req.method)) { - await Logging.logActionExceptionMessageAndSendResponse( + Logging.logActionExceptionMessageAndSendResponse( null, new Error(`Unsupported request method ${req.method}`), req, res, next); return; } diff --git a/src/server/rest/v1/service/AssetService.ts b/src/server/rest/v1/service/AssetService.ts index 574f7a6f04..b5875c8ab9 100644 --- a/src/server/rest/v1/service/AssetService.ts +++ b/src/server/rest/v1/service/AssetService.ts @@ -166,7 +166,7 @@ export default class AssetService { res.json(Object.assign({ connectionIsValid: true }, Constants.REST_RESPONSE_SUCCESS)); } catch (error) { // KO - await Logging.logError({ + Logging.beError()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleCheckAssetConnection', @@ -292,7 +292,7 @@ export default class AssetService { // Delete await AssetStorage.deleteAsset(req.tenant, asset.id); // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getAssetProperties(asset), tenantID: req.tenant.id, user: req.user, @@ -422,7 +422,7 @@ export default class AssetService { // Save newAsset.id = await AssetStorage.saveAsset(req.tenant, newAsset); // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getAssetProperties(newAsset), tenantID: req.tenant.id, user: req.user, @@ -469,7 +469,7 @@ export default class AssetService { asset.lastChangedOn = new Date(); await AssetStorage.saveAsset(req.tenant, asset); // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getAssetProperties(asset), tenantID: req.tenant.id, user: req.user, diff --git a/src/server/rest/v1/service/AuthService.ts b/src/server/rest/v1/service/AuthService.ts index 51aa07dc8d..f15ae13045 100644 --- a/src/server/rest/v1/service/AuthService.ts +++ b/src/server/rest/v1/service/AuthService.ts @@ -77,7 +77,7 @@ export default class AuthService { // Yes: Check date to reset pass if (user.passwordBlockedUntil && moment(user.passwordBlockedUntil).isBefore(moment())) { // Time elapsed: activate the account again - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.user.tenantID, actionOnUser: user, module: MODULE_NAME, method: 'handleLogIn', action: action, @@ -199,7 +199,7 @@ export default class AuthService { }; await TagStorage.saveTag(req.tenant, tag); } - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: newUser, action: action, module: MODULE_NAME, @@ -251,7 +251,7 @@ export default class AuthService { const resetHash = Utils.generateUUID(); // Init Password info await UserStorage.saveUserPassword(tenant, user.id, { passwordResetHash: resetHash }); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, user: user, action: action, module: MODULE_NAME, @@ -299,7 +299,7 @@ export default class AuthService { if (user.status === UserStatus.LOCKED) { await UserStorage.saveUserStatus(tenant, user.id, UserStatus.ACTIVE); } - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, user: user, action: action, module: MODULE_NAME, @@ -444,7 +444,7 @@ export default class AuthService { // Save User Verification Account await UserStorage.saveUserAccountVerification(req.tenant, user.id, { verificationToken: null, verifiedAt: new Date() }); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: user, action: action, module: MODULE_NAME, method: 'handleVerifyEmail', @@ -523,7 +523,7 @@ export default class AuthService { // Get existing verificationToken verificationToken = user.verificationToken; } - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: user, action: action, @@ -598,7 +598,7 @@ export default class AuthService { public static async userLoginSucceeded(action: ServerAction, tenant: Tenant, user: User, req: Request, res: Response, next: NextFunction): Promise { // Password / Login OK - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: tenant.id, user: user, module: MODULE_NAME, method: 'checkUserLogin', diff --git a/src/server/rest/v1/service/BillingService.ts b/src/server/rest/v1/service/BillingService.ts index 0681971ef9..2a2c784060 100644 --- a/src/server/rest/v1/service/BillingService.ts +++ b/src/server/rest/v1/service/BillingService.ts @@ -59,7 +59,7 @@ export default class BillingService { res.json(operationResult); } catch (error) { // Ko - await Logging.logError({ + Logging.beError()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleClearBillingTestData', @@ -96,7 +96,7 @@ export default class BillingService { res.json(Object.assign({ connectionIsValid: true }, Constants.REST_RESPONSE_SUCCESS)); } catch (error) { // Ko - await Logging.logError({ + Logging.beError()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleCheckBillingConnection', @@ -296,7 +296,7 @@ export default class BillingService { const user: User = await UtilsService.checkAndGetUserAuthorization(req.tenant, req.user, filteredRequest.userID, Action.READ, action); // Invoke the billing implementation const paymentMethods: BillingPaymentMethod[] = await billingImpl.getPaymentMethods(user); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user, action: ServerAction.BILLING_PAYMENT_METHODS, @@ -339,7 +339,7 @@ export default class BillingService { // Invoke the billing implementation const operationResult: BillingOperationResult = await billingImpl.deletePaymentMethod(user, filteredRequest.paymentMethodId); // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleDeleteSite', message: `Payment Method '${filteredRequest.paymentMethodId}' has been deleted successfully`, diff --git a/src/server/rest/v1/service/CarService.ts b/src/server/rest/v1/service/CarService.ts index a589055a5d..b5d5d5d16b 100644 --- a/src/server/rest/v1/service/CarService.ts +++ b/src/server/rest/v1/service/CarService.ts @@ -242,7 +242,7 @@ export default class CarService { }; // Save newCar.id = await CarStorage.saveCar(req.tenant, newCar); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, ...LoggingHelper.getCarProperties(newCar), user: req.user, module: MODULE_NAME, method: 'handleCreateCar', @@ -323,7 +323,7 @@ export default class CarService { if (setDefaultCarToOldUserID) { await CarService.setDefaultCarForUser(req.tenant, setDefaultCarToOldUserID); } - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, ...LoggingHelper.getCarProperties(car), user: req.user, module: MODULE_NAME, method: 'handleUpdateCar', @@ -405,7 +405,7 @@ export default class CarService { if (car.default) { await CarService.setDefaultCarForUser(req.tenant, car.userID); } - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getCarProperties(car), tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleDeleteCar', diff --git a/src/server/rest/v1/service/ChargingStationService.ts b/src/server/rest/v1/service/ChargingStationService.ts index ef0e856f7a..eedb7b6ee8 100644 --- a/src/server/rest/v1/service/ChargingStationService.ts +++ b/src/server/rest/v1/service/ChargingStationService.ts @@ -87,7 +87,7 @@ export default class ChargingStationService { // Check and Apply Charging Station templates await ChargingStationService.checkAndApplyChargingStationTemplate( action, req.tenant, chargingStation, req.user, resetAndApplyTemplate); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, action, user: req.user, module: MODULE_NAME, method: 'handleUpdateChargingStationParams', @@ -164,7 +164,7 @@ export default class ChargingStationService { detailedMessages: { result }, }); } - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: req.tenant.id, action, user: req.user, @@ -397,7 +397,7 @@ export default class ChargingStationService { // Delete physically await ChargingStationStorage.deleteChargingStation(req.tenant, chargingStation.id); } - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleDeleteChargingStation', message: `Charging Station '${chargingStation.id}' has been deleted successfully`, @@ -873,7 +873,7 @@ export default class ChargingStationService { } // OCPP Command with status if (Utils.objectHasProperty(result, 'status') && ![OCPPStatus.ACCEPTED, OCPPUnlockStatus.UNLOCKED].includes(result.status)) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: req.tenant.id, user: req.user, @@ -883,7 +883,7 @@ export default class ChargingStationService { }); } else { // OCPP Command with no status - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: req.tenant.id, user: req.user, @@ -1331,7 +1331,7 @@ export default class ChargingStationService { result.status === OCPPConfigurationStatus.REBOOT_REQUIRED) { // Reboot? if (result.status === OCPPConfigurationStatus.REBOOT_REQUIRED) { - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: req.tenant.id, action, user: req.user, @@ -1399,7 +1399,7 @@ export default class ChargingStationService { await ocpiClient.patchChargingStationStatus(chargingStation, status); } } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'updateChargingStationRoaming', action, @@ -1431,7 +1431,7 @@ export default class ChargingStationService { site, chargingStation.siteArea, chargingStation, options), actionType); } } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'updateChargingStationRoaming', action, @@ -1463,7 +1463,7 @@ export default class ChargingStationService { site, siteArea, chargingStation, options), OICPActionType.DELETE); } } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'deactivateChargingStationRoaming', action, @@ -1700,7 +1700,7 @@ export default class ChargingStationService { detailedMessages: { result: chargingProfiles[index] } }); } - await Logging.logWarning({ + Logging.beWarning()?.log({ ...LoggingHelper.getChargingStationProperties(chargingStation), tenantID: tenant.id, action, user, diff --git a/src/server/rest/v1/service/ChargingStationTemplateService.ts b/src/server/rest/v1/service/ChargingStationTemplateService.ts index e749391ed3..c464c7b424 100644 --- a/src/server/rest/v1/service/ChargingStationTemplateService.ts +++ b/src/server/rest/v1/service/ChargingStationTemplateService.ts @@ -34,7 +34,7 @@ export default class ChargingStationTemplateService { } }; newChargingStationTemplate.id = await ChargingStationTemplateStorage.saveChargingStationTemplate(newChargingStationTemplate); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleCreateChargingStationTemplate', message: `ChargingStationTemplate '${newChargingStationTemplate.id}' has been created successfully`, @@ -99,7 +99,7 @@ export default class ChargingStationTemplateService { const chargingStationTemplate = await UtilsService.checkAndGetChargingStationTemplateAuthorization(req.tenant, req.user, chargingStationTemplateID, Action.DELETE, action); // Delete await ChargingStationTemplateStorage.deleteChargingStationTemplate(req.tenant, chargingStationTemplate.id); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleDeleteChargingStationTemplate', message: `Charging Station Template'${chargingStationTemplate.id}' has been deleted successfully`, @@ -129,7 +129,7 @@ export default class ChargingStationTemplateService { chargingStationTemplate.lastChangedOn = new Date(); // Save await ChargingStationTemplateStorage.saveChargingStationTemplate(chargingStationTemplate); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleUpdateChargingStationTemplate', message: `'${chargingStationTemplate.id}' has been updated successfully`, diff --git a/src/server/rest/v1/service/CompanyService.ts b/src/server/rest/v1/service/CompanyService.ts index daceb2b644..136f92a69d 100644 --- a/src/server/rest/v1/service/CompanyService.ts +++ b/src/server/rest/v1/service/CompanyService.ts @@ -30,7 +30,7 @@ export default class CompanyService { req.tenant, req.user, companyID, Action.DELETE, action); // Delete await CompanyStorage.deleteCompany(req.tenant, company.id); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleDeleteCompany', message: `Company '${company.name}' has been deleted successfully`, @@ -163,7 +163,7 @@ export default class CompanyService { } // Save newCompany.id = await CompanyStorage.saveCompany(req.tenant, newCompany); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleCreateCompany', message: `Company '${newCompany.id}' has been created successfully`, @@ -203,7 +203,7 @@ export default class CompanyService { company.lastChangedOn = new Date(); // Update Company await CompanyStorage.saveCompany(req.tenant, company, Utils.objectHasProperty(filteredRequest, 'logo') ? true : false); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleUpdateCompany', message: `Company '${company.name}' has been updated successfully`, diff --git a/src/server/rest/v1/service/ConnectionService.ts b/src/server/rest/v1/service/ConnectionService.ts index 7f12d1f2fa..aff28cd8d6 100644 --- a/src/server/rest/v1/service/ConnectionService.ts +++ b/src/server/rest/v1/service/ConnectionService.ts @@ -104,7 +104,7 @@ export default class ConnectionService { if (!Utils.isNullOrUndefined(integrationConnector)) { // Create const connection: Connection = await integrationConnector.createConnection(filteredRequest.userId, filteredRequest.data); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleCreateConnection', message: `Connection to '${connection.connectorId}' has been created successfully`, @@ -141,7 +141,7 @@ export default class ConnectionService { // Delete await ConnectionStorage.deleteConnectionById(req.tenant, connection.id); // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, actionOnUser: connection.userId, diff --git a/src/server/rest/v1/service/OCPIEndpointService.ts b/src/server/rest/v1/service/OCPIEndpointService.ts index e1b9f77b0d..4ac50d04c3 100644 --- a/src/server/rest/v1/service/OCPIEndpointService.ts +++ b/src/server/rest/v1/service/OCPIEndpointService.ts @@ -34,7 +34,7 @@ export default class OCPIEndpointService { const ocpiEndpoint = await UtilsService.checkAndGetOCPIEndpointAuthorization(req.tenant, req.user, filteredRequest.ID, Action.DELETE, action); // Delete await OCPIEndpointStorage.deleteOcpiEndpoint(req.tenant, ocpiEndpoint.id); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleDeleteOcpiEndpoint', message: `Ocpi Endpoint '${ocpiEndpoint.name}' has been deleted successfully`, @@ -108,7 +108,7 @@ export default class OCPIEndpointService { status: OCPIRegistrationStatus.NEW } as OCPIEndpoint; const endpointID = await OCPIEndpointStorage.saveOcpiEndpoint(req.tenant, ocpiEndpoint); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleCreateOcpiEndpoint', message: `Ocpi Endpoint '${filteredRequest.name}' has been created successfully`, @@ -132,7 +132,7 @@ export default class OCPIEndpointService { ocpiEndpoint.lastChangedOn = new Date(); // Update OcpiEndpoint await OCPIEndpointStorage.saveOcpiEndpoint(req.tenant, { ...ocpiEndpoint, ...filteredRequest }); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleUpdateOcpiEndpoint', message: `Ocpi Endpoint '${ocpiEndpoint.name}' has been updated successfully`, @@ -157,7 +157,7 @@ export default class OCPIEndpointService { const result = await ocpiClient.ping(); // Check ping result if (result.statusCode === StatusCodes.OK) { - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handlePingOcpiEndpoint', message: `Ocpi Endpoint '${filteredRequest.name}' can be reached successfully`, @@ -543,7 +543,7 @@ export default class OCPIEndpointService { const result = await ocpiClient.updateCredentials(); // Check ping result if (result.statusCode === StatusCodes.OK) { - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleUpdateCredentialsOcpiEndpoint', message: `Ocpi Endpoint '${ocpiEndpoint.name}' can be reached successfully`, @@ -585,7 +585,7 @@ export default class OCPIEndpointService { const result = await ocpiClient.unregister(); // Check ping result if (result.statusCode === StatusCodes.OK) { - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleUnregisterOcpiEndpoint', message: `Ocpi Endpoint '${ocpiEndpoint.name}' can be reached successfully`, @@ -627,7 +627,7 @@ export default class OCPIEndpointService { const result = await ocpiClient.register(); // Check ping result if (result.statusCode === StatusCodes.OK) { - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleRegisterOcpiEndpoint', message: `Ocpi Endpoint '${ocpiEndpoint.name}' can be reached successfully`, @@ -663,7 +663,7 @@ export default class OCPIEndpointService { await AuthorizationService.checkAndGetOCPIEndpointsAuthorizations(req.tenant, req.user, Action.GENERATE_LOCAL_TOKEN); // Generate endpoint const localToken = OCPIUtils.generateLocalToken(req.tenant.subdomain); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleGenerateLocalTokenOcpiEndpoint', message: 'Local Token for Ocpi Endpoint has been generated successfully', diff --git a/src/server/rest/v1/service/OICPEndpointService.ts b/src/server/rest/v1/service/OICPEndpointService.ts index 7934c640a0..887b2c7d9b 100644 --- a/src/server/rest/v1/service/OICPEndpointService.ts +++ b/src/server/rest/v1/service/OICPEndpointService.ts @@ -44,7 +44,7 @@ export default class OICPEndpointService { // Delete await OICPEndpointStorage.deleteOicpEndpoint(req.tenant, oicpEndpoint.id); // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleDeleteOicpEndpoint', message: `Oicp Endpoint '${oicpEndpoint.name}' has been deleted successfully`, @@ -91,7 +91,7 @@ export default class OICPEndpointService { } as OICPEndpoint; const endpointID = await OICPEndpointStorage.saveOicpEndpoint(req.tenant, oicpEndpoint); // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleCreateOicpEndpoint', message: `Oicp Endpoint '${filteredRequest.name}' has been created successfully`, @@ -128,7 +128,7 @@ export default class OICPEndpointService { // Update OicpEndpoint await OICPEndpointStorage.saveOicpEndpoint(req.tenant, { ...oicpEndpoint, ...filteredRequest }); // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleUpdateOicpEndpoint', message: `Oicp Endpoint '${oicpEndpoint.name}' has been updated successfully`, @@ -293,7 +293,7 @@ export default class OICPEndpointService { // Check ping result if (pingResult.statusCode === OICPStatusCode.Code000) { // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handlePingOicpEndpoint', message: `Oicp Endpoint '${oicpEndpoint.name}' can be reached successfully`, @@ -303,7 +303,7 @@ export default class OICPEndpointService { res.json(Object.assign(pingResult, Constants.REST_RESPONSE_SUCCESS)); } else { // Log - await Logging.logError({ + Logging.beError()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handlePingOicpEndpoint', message: `Oicp Endpoint '${oicpEndpoint.name}' cannot be reached`, @@ -341,7 +341,7 @@ export default class OICPEndpointService { // Check ping result if (result.statusCode === StatusCodes.OK) { // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleUnregisterOicpEndpoint', message: `Oicp Endpoint '${oicpEndpoint.name}' can be reached successfully`, @@ -351,7 +351,7 @@ export default class OICPEndpointService { res.json(Object.assign(result, Constants.REST_RESPONSE_SUCCESS)); } else { // Log - await Logging.logError({ + Logging.beError()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleUnregisterOicpEndpoint', message: `Oicp Endpoint '${oicpEndpoint.name}' cannot be reached`, @@ -389,7 +389,7 @@ export default class OICPEndpointService { // Check ping result if (result.statusCode === StatusCodes.OK) { // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleRegisterOicpEndpoint', message: `Oicp Endpoint '${oicpEndpoint.name}' can be reached successfully`, @@ -399,7 +399,7 @@ export default class OICPEndpointService { res.json(Object.assign(result, Constants.REST_RESPONSE_SUCCESS)); } else { // Log - await Logging.logError({ + Logging.beError()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleRegisterOicpEndpoint', message: `Oicp Endpoint '${oicpEndpoint.name}' cannot be reached`, diff --git a/src/server/rest/v1/service/PricingService.ts b/src/server/rest/v1/service/PricingService.ts index b7f04fcd49..b5a09997b1 100644 --- a/src/server/rest/v1/service/PricingService.ts +++ b/src/server/rest/v1/service/PricingService.ts @@ -130,7 +130,7 @@ export default class PricingService { // Save newPricingDefinition.id = await PricingStorage.savePricingDefinition(req.tenant, newPricingDefinition); // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleCreatePricingDefinition', message: `Pricing model '${newPricingDefinition.id}' has been created successfully`, @@ -172,7 +172,7 @@ export default class PricingService { // Update Pricing await PricingStorage.savePricingDefinition(req.tenant, pricingDefinition); // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleUpdatePricingDefinition', message: `Pricing model '${pricingDefinition.id}' has been updated successfully`, @@ -201,7 +201,7 @@ export default class PricingService { // Delete await PricingStorage.deletePricingDefinition(req.tenant, pricingDefinition.id); // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleDeletePricingDefinition', message: `Pricing model '${pricingDefinitionID}' has been deleted successfully`, @@ -249,7 +249,7 @@ export default class PricingService { } catch (error) { canCreate = false; if (!(error instanceof AppAuthError)) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'alterCanCreate', message: 'Unexpected error while checking site access permissions', diff --git a/src/server/rest/v1/service/RegistrationTokenService.ts b/src/server/rest/v1/service/RegistrationTokenService.ts index 6a28ef380b..94c4de4ce8 100644 --- a/src/server/rest/v1/service/RegistrationTokenService.ts +++ b/src/server/rest/v1/service/RegistrationTokenService.ts @@ -41,7 +41,7 @@ export default class RegistrationTokenService { }; // Save registrationToken.id = await RegistrationTokenStorage.saveRegistrationToken(req.tenant, registrationToken); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getRegistrationTokenProperties(registrationToken), tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleCreateRegistrationToken', @@ -72,7 +72,7 @@ export default class RegistrationTokenService { registrationToken.revocationDate = null; // Save await RegistrationTokenStorage.saveRegistrationToken(req.tenant, registrationToken); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getRegistrationTokenProperties(registrationToken), tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleUpdateRegistrationToken', @@ -91,7 +91,7 @@ export default class RegistrationTokenService { req.tenant, req.user, registrationTokenID, Action.DELETE, action); // Delete await RegistrationTokenStorage.deleteRegistrationToken(req.tenant, registrationToken.id); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getRegistrationTokenProperties(registrationToken), tenantID: req.tenant.id, user: req.user, @@ -126,7 +126,7 @@ export default class RegistrationTokenService { registrationToken.lastChangedOn = now; // Save await RegistrationTokenStorage.saveRegistrationToken(req.tenant, registrationToken); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getRegistrationTokenProperties(registrationToken), tenantID: req.tenant.id, user: req.user, diff --git a/src/server/rest/v1/service/SettingService.ts b/src/server/rest/v1/service/SettingService.ts index d585d7fb8a..25f86d9f3c 100644 --- a/src/server/rest/v1/service/SettingService.ts +++ b/src/server/rest/v1/service/SettingService.ts @@ -28,7 +28,7 @@ export default class SettingService { // Delete await SettingStorage.deleteSetting(req.tenant, settingID); // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleDeleteSetting', message: `Setting '${setting.identifier}' has been deleted successfully`, @@ -110,7 +110,7 @@ export default class SettingService { // Save Setting filteredRequest.id = await SettingStorage.saveSettings(req.tenant, filteredRequest); // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleCreateSetting', message: `Setting '${filteredRequest.identifier}' has been created successfully`, @@ -223,7 +223,7 @@ export default class SettingService { } } // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleUpdateSetting', message: `Setting '${filteredRequest.id}' has been updated successfully`, diff --git a/src/server/rest/v1/service/SiteAreaService.ts b/src/server/rest/v1/service/SiteAreaService.ts index 6a23761324..5563833224 100644 --- a/src/server/rest/v1/service/SiteAreaService.ts +++ b/src/server/rest/v1/service/SiteAreaService.ts @@ -51,7 +51,7 @@ export default class SiteAreaService { await SiteAreaStorage.removeAssetsFromSiteArea( req.tenant, filteredRequest.siteAreaID, assets.map((asset) => asset.id)); } - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getSiteAreaProperties(siteArea), tenantID: req.tenant.id, user: req.user, @@ -105,7 +105,7 @@ export default class SiteAreaService { req.tenant, filteredRequest.siteAreaID, chargingStations.map((chargingStation) => chargingStation.id)); } // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getSiteAreaProperties(siteArea), tenantID: req.tenant.id, user: req.user, @@ -131,7 +131,7 @@ export default class SiteAreaService { // Update children await SiteAreaStorage.attachSiteAreaChildrenToNewParent(req.tenant, siteArea.id, siteArea.parentSiteAreaID); // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getSiteAreaProperties(siteArea), tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleDeleteSiteArea', @@ -332,7 +332,7 @@ export default class SiteAreaService { req.tenant, rootSiteArea, siteArea, parentSiteArea, subSiteAreasActions); // Save siteArea.id = await SiteAreaStorage.saveSiteArea(req.tenant, siteArea, Utils.objectHasProperty(filteredRequest, 'image')); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getSiteAreaProperties(siteArea), tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleCreateSiteArea', @@ -414,7 +414,7 @@ export default class SiteAreaService { } // Retrigger Smart Charging void SiteAreaService.triggerSmartCharging(req.tenant, action, siteArea); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getSiteAreaProperties(siteArea), tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleUpdateSiteArea', @@ -492,7 +492,7 @@ export default class SiteAreaService { await smartCharging.computeAndApplyChargingProfiles(siteArea); } } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getSiteAreaProperties(siteArea), tenantID: tenant.id, action, module: MODULE_NAME, method: 'triggerSmartCharging', diff --git a/src/server/rest/v1/service/SiteService.ts b/src/server/rest/v1/service/SiteService.ts index 8268b91e57..3c75f35dd0 100644 --- a/src/server/rest/v1/service/SiteService.ts +++ b/src/server/rest/v1/service/SiteService.ts @@ -44,7 +44,7 @@ export default class SiteService { const user = await UtilsService.checkAndGetUserAuthorization(req.tenant, req.user, filteredRequest.userID, Action.READ, action); // Update await SiteStorage.updateSiteUserAdmin(req.tenant, filteredRequest.siteID, filteredRequest.userID, filteredRequest.siteAdmin); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getSiteProperties(site), tenantID: req.tenant.id, user: req.user, actionOnUser: user, @@ -70,7 +70,7 @@ export default class SiteService { req.tenant, req.user, filteredRequest.userID, Action.READ, action); // Update await SiteStorage.updateSiteOwner(req.tenant, filteredRequest.siteID, filteredRequest.userID, filteredRequest.siteOwner); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getSiteProperties(site), tenantID: req.tenant.id, user: req.user, actionOnUser: user, @@ -111,7 +111,7 @@ export default class SiteService { } else { await SiteStorage.removeUsersFromSite(req.tenant, site.id, users.map((user) => user.id)); } - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getSiteProperties(site), tenantID: req.tenant.id, user: req.user, @@ -169,7 +169,7 @@ export default class SiteService { req.tenant, req.user, siteID, Action.DELETE, action); // Delete await SiteStorage.deleteSite(req.tenant, site.id); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getSiteProperties(site), tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleDeleteSite', @@ -314,7 +314,7 @@ export default class SiteService { } // Save site.id = await SiteStorage.saveSite(req.tenant, site, Utils.objectHasProperty(filteredRequest, 'image')); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getSiteProperties(site), tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleCreateSite', @@ -393,7 +393,7 @@ export default class SiteService { await SiteStorage.saveSite(req.tenant, site, Utils.objectHasProperty(filteredRequest, 'image')); // Update all refs void SiteStorage.updateEntitiesWithOrganizationIDs(req.tenant, site.companyID, filteredRequest.id); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getSiteProperties(site), tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleUpdateSite', diff --git a/src/server/rest/v1/service/TagService.ts b/src/server/rest/v1/service/TagService.ts index 88cbca338d..1b81da2de9 100644 --- a/src/server/rest/v1/service/TagService.ts +++ b/src/server/rest/v1/service/TagService.ts @@ -188,7 +188,7 @@ export default class TagService { await TagStorage.saveTag(req.tenant, newTag); // OCPI void TagService.updateTagRoaming(action, req.tenant, req.user, newTag); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getTagProperties(newTag), tenantID: req.tenant.id, action: action, @@ -264,7 +264,7 @@ export default class TagService { await TagStorage.saveTag(req.tenant, tag); // OCPI void TagService.updateTagRoaming(action, req.tenant, req.user, tag); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getTagProperties(tag), tenantID: req.tenant.id, action: action, @@ -306,7 +306,7 @@ export default class TagService { // Save await TagStorage.saveTag(req.tenant, tag); void TagService.updateTagRoaming(action, req.tenant, req.user, tag); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getTagProperties(tag), tenantID: req.tenant.id, action: action, @@ -382,7 +382,7 @@ export default class TagService { } // OCPI void TagService.updateTagRoaming(action, req.tenant, req.user, tag); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getTagProperties(tag), tenantID: req.tenant.id, action: action, @@ -490,7 +490,7 @@ export default class TagService { }, async (error: CSVError) => { // Release the lock await LockingManager.release(importTagsLock); - await Logging.logError({ + Logging.beError()?.log({ tenantID: req.tenant.id, module: MODULE_NAME, method: 'handleImportTags', action: action, @@ -562,7 +562,7 @@ export default class TagService { parser.on('error', async (error) => { // Release the lock await LockingManager.release(importTagsLock); - await Logging.logError({ + Logging.beError()?.log({ tenantID: req.tenant.id, module: MODULE_NAME, method: 'handleImportTags', action: action, @@ -580,7 +580,7 @@ export default class TagService { } else { // Release the lock await LockingManager.release(importTagsLock); - await Logging.logError({ + Logging.beError()?.log({ tenantID: req.tenant.id, module: MODULE_NAME, method: 'handleImportTags', action: action, @@ -629,7 +629,7 @@ export default class TagService { // Handle dup keys result.inSuccess += error.result.nInserted; result.inError += error.writeErrors.length; - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'insertTags', action: action, @@ -663,7 +663,7 @@ export default class TagService { } } catch (error) { result.inError++; - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'deleteTags', action: ServerAction.TAG_DELETE, @@ -708,7 +708,7 @@ export default class TagService { } } catch (error) { result.inError++; - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'unassignTags', action: ServerAction.TAG_DELETE, @@ -833,7 +833,7 @@ export default class TagService { UserValidatorRest.getInstance().validateUserImportCreateReq(newImportedUser); tagToImport = { ...tagToImport, ...newImportedUser as ImportedTag }; } catch (error) { - await Logging.logWarning({ + Logging.beWarning()?.log({ tenantID: req.tenant.id, module: MODULE_NAME, method: 'processTag', action: action, @@ -846,7 +846,7 @@ export default class TagService { tagsToBeImported.push(tagToImport); return true; } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: req.tenant.id, module: MODULE_NAME, method: 'importTag', action: action, @@ -875,7 +875,7 @@ export default class TagService { }); } } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'checkAndDeleteTagOCPI', action: ServerAction.TAG_DELETE, @@ -898,7 +898,7 @@ export default class TagService { ); } } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action: action, module: MODULE_NAME, method: 'updateTagOCPI', diff --git a/src/server/rest/v1/service/TenantService.ts b/src/server/rest/v1/service/TenantService.ts index 4c58e5ad07..586640a9ce 100644 --- a/src/server/rest/v1/service/TenantService.ts +++ b/src/server/rest/v1/service/TenantService.ts @@ -65,7 +65,7 @@ export default class TenantService { // Remove collection await TenantStorage.deleteTenantDB(tenant.id); // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleDeleteTenant', message: `Tenant '${tenant.name}' has been deleted successfully`, @@ -344,7 +344,7 @@ export default class TenantService { Logging.logPromiseError(error, req?.tenant?.id); }); // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleCreateTenant', message: `Tenant '${filteredRequest.name}' has been created successfully`, @@ -418,7 +418,7 @@ export default class TenantService { // Update with components await TenantService.updateSettingsWithComponents(filteredRequest, req); // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleUpdateTenant', message: `Tenant '${filteredRequest.name}' has been updated successfully`, @@ -457,7 +457,7 @@ export default class TenantService { // Update Tenant await TenantStorage.saveTenant(tenant, Utils.objectHasProperty(filteredRequest, 'logo') ? true : false); // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, method: 'handleUpdateTenantData', message: `Tenant '${filteredRequest.name}' data has been updated successfully`, diff --git a/src/server/rest/v1/service/TransactionService.ts b/src/server/rest/v1/service/TransactionService.ts index d3bcc65dca..a51a98ee79 100644 --- a/src/server/rest/v1/service/TransactionService.ts +++ b/src/server/rest/v1/service/TransactionService.ts @@ -70,7 +70,7 @@ export default class TransactionService { res.json(response); next(); } catch (error) { - await Logging.logActionExceptionMessageAndSendResponse(action, error, req, res, next); + Logging.logActionExceptionMessageAndSendResponse(action, error, req, res, next); } } @@ -196,7 +196,7 @@ export default class TransactionService { } // Save await TransactionStorage.saveTransactionOcpiData(req.tenant, transaction.id, transaction.ocpiData); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: req.tenant.id, action, module: MODULE_NAME, method: 'handlePushTransactionCdr', @@ -231,7 +231,7 @@ export default class TransactionService { } // Save await TransactionStorage.saveTransactionOicpData(req.tenant, transaction.id, transaction.oicpData); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: req.tenant.id, user: req.user, actionOnUser: (transaction.user ?? null), @@ -421,7 +421,7 @@ export default class TransactionService { }; res.json(advenirPayload); } catch (error) { - await Logging.logActionExceptionMessageAndSendResponse(action, error, req, res, next); + Logging.logActionExceptionMessageAndSendResponse(action, error, req, res, next); } } @@ -685,7 +685,7 @@ export default class TransactionService { // Transaction refunded if (refundConnector && !refundConnector.canBeDeleted(transaction)) { result.inError++; - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: loggedUser.tenantID, user: loggedUser, @@ -698,7 +698,7 @@ export default class TransactionService { // Transaction billed if (billingImpl && transaction.billingData?.stop?.status === BillingStatus.BILLED) { result.inError++; - await Logging.logError({ + Logging.beError()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: loggedUser.tenantID, user: loggedUser, @@ -811,7 +811,7 @@ export default class TransactionService { OCPPUtils.clearChargingStationConnectorRuntimeData(chargingStation, transaction.connectorId); await ChargingStationStorage.saveChargingStationConnectors(req.tenant, chargingStation.id, chargingStation.connectors); } - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: req.tenant.id, user: req.user, actionOnUser: transaction.userID, @@ -833,7 +833,7 @@ export default class TransactionService { try { await new OCPPService(Configuration.getChargingStationConfig()).softStopTransaction( req.tenant, transaction, chargingStation, chargingStation.siteArea); - await Logging.logInfo({ + Logging.beInfo()?.log({ ...LoggingHelper.getTransactionProperties(transaction), tenantID: req.tenant.id, user: req.user, actionOnUser: transaction.userID, diff --git a/src/server/rest/v1/service/UserService.ts b/src/server/rest/v1/service/UserService.ts index b7c7ef7b7c..d8c2ede83d 100644 --- a/src/server/rest/v1/service/UserService.ts +++ b/src/server/rest/v1/service/UserService.ts @@ -221,7 +221,7 @@ export default class UserService { } else { await UserStorage.removeSitesFromUser(req.tenant, filteredRequest.userID, sites.map((site) => site.id)); } - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, module: MODULE_NAME, @@ -241,7 +241,7 @@ export default class UserService { if (!user.issuer) { // Delete User await UserStorage.deleteUser(req.tenant, user.id); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, actionOnUser: user, module: MODULE_NAME, method: 'handleDeleteUser', @@ -261,7 +261,7 @@ export default class UserService { // Delete User await UserStorage.deleteUser(req.tenant, user.id); // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, actionOnUser: user, module: MODULE_NAME, method: 'handleDeleteUser', @@ -326,7 +326,7 @@ export default class UserService { // Update Billing await UserService.syncUserAndUpdateBillingData(ServerAction.USER_UPDATE, req.tenant, req.user, user); // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, actionOnUser: user, module: MODULE_NAME, method: 'handleUpdateUser', @@ -366,7 +366,7 @@ export default class UserService { mobileVersion: filteredRequest.mobileVersion, mobileLastChangedOn: new Date() }); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: user, module: MODULE_NAME, method: 'handleUpdateUserMobileData', @@ -586,7 +586,7 @@ export default class UserService { // Release the lock await LockingManager.release(importUsersLock); // Log - await Logging.logError({ + Logging.beError()?.log({ tenantID: req.tenant.id, module: MODULE_NAME, method: 'handleImportUsers', action: action, @@ -661,7 +661,7 @@ export default class UserService { // Release the lock await LockingManager.release(importUsersLock); // Log - await Logging.logError({ + Logging.beError()?.log({ tenantID: req.tenant.id, module: MODULE_NAME, method: 'handleImportUsers', action: action, @@ -680,7 +680,7 @@ export default class UserService { // Release the lock await LockingManager.release(importUsersLock); // Log - await Logging.logError({ + Logging.beError()?.log({ tenantID: req.tenant.id, module: MODULE_NAME, method: 'handleImportUsers', action: action, @@ -748,7 +748,7 @@ export default class UserService { // Update Billing await UserService.syncUserAndUpdateBillingData(ServerAction.USER_CREATE, req.tenant, req.user, newUser); // Log - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: req.tenant.id, user: req.user, actionOnUser: req.user, module: MODULE_NAME, method: 'handleCreateUser', @@ -767,7 +767,7 @@ export default class UserService { // Handle dup keys result.inSuccess += error.result.nInserted; result.inError += error.writeErrors.length; - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'insertUsers', action: action, @@ -884,7 +884,7 @@ export default class UserService { usersToBeImported.push(newImportedUser); return true; } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: req.tenant.id, module: MODULE_NAME, method: 'importUser', action: action, @@ -905,7 +905,7 @@ export default class UserService { ...await billingImpl.precheckStartTransactionPrerequisites(user)); } } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'checkBillingErrorCodes', @@ -972,7 +972,7 @@ export default class UserService { } } } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'checkAndDeleteUserOCPI', @@ -1013,7 +1013,7 @@ export default class UserService { // For performance reasons, the creation of a customer in the billing system should be done in a LAZY mode await billingImpl.synchronizeUser(user); } catch (error) { - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenant.id, action, module: MODULE_NAME, method: 'syncUserAndUpdateBillingData', user: loggedUser, actionOnUser: user, diff --git a/src/server/rest/v1/service/UtilsService.ts b/src/server/rest/v1/service/UtilsService.ts index 5fc97750f7..48da759d13 100644 --- a/src/server/rest/v1/service/UtilsService.ts +++ b/src/server/rest/v1/service/UtilsService.ts @@ -104,7 +104,7 @@ export default class UtilsService { message: `The Captcha score is too low, got ${response.data.score as string} but expected ${centralSystemRestConfig.captchaScore}`, }); } - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant?.id, module: MODULE_NAME, action, method, message: `The Captcha score is ${response.data.score as string} (score limit is ${centralSystemRestConfig.captchaScore})`, @@ -1072,10 +1072,10 @@ export default class UtilsService { public static async handleUnknownAction(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise { // Action provided if (!action) { - await Logging.logActionExceptionMessageAndSendResponse( + Logging.logActionExceptionMessageAndSendResponse( null, new Error('No Action has been provided'), req, res, next); } else { - await Logging.logActionExceptionMessageAndSendResponse( + Logging.logActionExceptionMessageAndSendResponse( action, new Error(`The Action '${action}' does not exist`), req, res, next); } } diff --git a/src/start.ts b/src/start.ts index e628a26ee9..f4d48212ff 100644 --- a/src/start.ts +++ b/src/start.ts @@ -109,7 +109,7 @@ export default class Bootstrap { } else { const message = `Monitoring Server implementation does not exist '${this.monitoringConfig.implementation}'`; Logging.logConsoleError(message); - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.STARTUP, module: MODULE_NAME, method: 'startServers', message @@ -211,7 +211,7 @@ export default class Bootstrap { await this.logDuration(startTimeGlobalMillis, `${serverStarted.join(', ')} server has been started successfully`, ServerAction.BOOTSTRAP_STARTUP); } catch (error) { Logging.logConsoleError(error); - global.database && await Logging.logError({ + global.database && Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.BOOTSTRAP_STARTUP, module: MODULE_NAME, method: 'start', @@ -225,7 +225,7 @@ export default class Bootstrap { const timeStartMillis = Date.now(); Logging.logConsoleDebug(logMessage); if (global.database) { - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.STARTUP, module: MODULE_NAME, method: 'start', @@ -240,7 +240,7 @@ export default class Bootstrap { logMessage = `${logMessage} in ${timeDurationSecs} secs`; Logging.logConsoleDebug(logMessage); if (global.database) { - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action, module: MODULE_NAME, method: 'start', @@ -326,7 +326,7 @@ export default class Bootstrap { } } catch (error) { Logging.logConsoleError(error.stack); - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.STARTUP, module: MODULE_NAME, method: 'startServers', diff --git a/src/storage/mongodb/ChargingStationStorage.ts b/src/storage/mongodb/ChargingStationStorage.ts index 140955f100..df1672ae7b 100644 --- a/src/storage/mongodb/ChargingStationStorage.ts +++ b/src/storage/mongodb/ChargingStationStorage.ts @@ -599,6 +599,19 @@ export default class ChargingStationStorage { await Logging.traceDatabaseRequestEnd(tenant, MODULE_NAME, 'saveChargingStationRuntimeData', startTime, runtimeData); } + public static async saveChargingStationsLastSeen(tenant: Tenant, ids: string[] = [], lastSeen: Date): Promise { + const startTime = Logging.traceDatabaseRequestStart(); + DatabaseUtils.checkTenantObject(tenant); + // Modify all + if (!Utils.isEmptyArray(ids) && lastSeen) { + await global.database.getCollection(tenant.id, 'chargingstations').updateMany( + { '_id': { $in: ids } }, + { $set: { lastSeen } }, + { upsert: false }); + } + await Logging.traceDatabaseRequestEnd(tenant, MODULE_NAME, 'saveChargingStationsLastSeen', startTime, { ids, lastSeen }); + } + public static async saveChargingStationOcpiData(tenant: Tenant, id: string, ocpiData: ChargingStationOcpiData): Promise { const startTime = Logging.traceDatabaseRequestStart(); DatabaseUtils.checkTenantObject(tenant); diff --git a/src/storage/mongodb/MongoDBStorage.ts b/src/storage/mongodb/MongoDBStorage.ts index 287173adea..31bee4753a 100644 --- a/src/storage/mongodb/MongoDBStorage.ts +++ b/src/storage/mongodb/MongoDBStorage.ts @@ -71,7 +71,7 @@ export default class MongoDBStorage { const changeStream = dbCollection.watch([], { fullDocument: 'updateLookup' }); const message = `Database collection '${tenant.id}.${collectionName}' is being watched`; Utils.isDevelopmentEnv() && Logging.logConsoleDebug(message); - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenant.id, action: ServerAction.MONGO_DB, message, module: MODULE_NAME, method: 'watchDatabaseCollection' @@ -96,7 +96,7 @@ export default class MongoDBStorage { action: ServerAction.MONGO_DB }); } - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenantID, action: ServerAction.MONGO_DB, message: 'Check of MongoDB database...', @@ -207,7 +207,7 @@ export default class MongoDBStorage { { fields: { 'connectors.status': 1 } }, { fields: { 'ocpiData.evses.uid': 1 }, options: { partialFilterExpression: { 'ocpiData.evses': { $exists: true } } } } ]); - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenantID, action: ServerAction.MONGO_DB, message: 'Check of MongoDB database done', @@ -331,7 +331,7 @@ export default class MongoDBStorage { this.dbPingFailed++; const message = `${this.dbPingFailed} database ping(s) failed: ${error.message as string}`; Logging.logConsoleError(message); - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.MONGO_DB, module: MODULE_NAME, method: 'ping', @@ -405,7 +405,7 @@ export default class MongoDBStorage { } catch (error) { const message = 'Error while checking Database in tenant \'default\''; Logging.logConsoleError(message); - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.MONGO_DB, module: MODULE_NAME, method: 'handleIndexesInCollection', @@ -435,7 +435,7 @@ export default class MongoDBStorage { } catch (error) { const message = `Error while checking Database in tenant '${tenantId}'`; Logging.logConsoleError(message); - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.MONGO_DB, module: MODULE_NAME, method: 'handleIndexesInCollection', @@ -470,7 +470,7 @@ export default class MongoDBStorage { } catch (error) { const message = `Error in creating collection '${tenantID}.${tenantCollectionName}': ${error.message as string}`; Logging.logConsoleError(message); - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.MONGO_DB, module: MODULE_NAME, method: 'handleIndexesInCollection', @@ -508,7 +508,7 @@ export default class MongoDBStorage { if (Utils.isDevelopmentEnv()) { const message = `Drop index '${databaseIndex.name as string}' in collection ${tenantCollectionName}`; Utils.isDevelopmentEnv() && Logging.logConsoleDebug(message); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.MONGO_DB, module: MODULE_NAME, method: 'handleIndexesInCollection', @@ -520,7 +520,7 @@ export default class MongoDBStorage { } catch (error) { const message = `Error in dropping index '${databaseIndex.name as string}' in '${tenantCollectionName}': ${error.message as string}`; Logging.logConsoleError(message); - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.MONGO_DB, module: MODULE_NAME, method: 'handleIndexesInCollection', @@ -539,7 +539,7 @@ export default class MongoDBStorage { if (Utils.isDevelopmentEnv()) { const message = `Create index ${JSON.stringify(index)} in collection ${tenantCollectionName}`; Utils.isDevelopmentEnv() && Logging.logConsoleDebug(message); - await Logging.logInfo({ + Logging.beInfo()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.MONGO_DB, module: MODULE_NAME, method: 'handleIndexesInCollection', @@ -551,7 +551,7 @@ export default class MongoDBStorage { } catch (error) { const message = `Error in creating index '${JSON.stringify(index.fields)}' with options '${JSON.stringify(index.options)}' in '${tenantCollectionName}': ${error.message as string}`; Logging.logConsoleError(message); - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.MONGO_DB, module: MODULE_NAME, method: 'handleIndexesInCollection', @@ -564,7 +564,7 @@ export default class MongoDBStorage { } catch (error) { const message = `Unexpected error in handling Collection '${tenantID}.${name}': ${error.message as string}`; Logging.logConsoleError(message); - await Logging.logError({ + Logging.beError()?.log({ tenantID: Constants.DEFAULT_TENANT_ID, action: ServerAction.MONGO_DB, module: MODULE_NAME, method: 'handleIndexesInCollection', diff --git a/src/storage/mongodb/PerformanceStorage.ts b/src/storage/mongodb/PerformanceStorage.ts index 7734ce55e0..f44ece77d2 100644 --- a/src/storage/mongodb/PerformanceStorage.ts +++ b/src/storage/mongodb/PerformanceStorage.ts @@ -1,7 +1,9 @@ import PerformanceRecord, { PerformanceRecordGroup } from '../../types/Performance'; import global, { FilterParams } from '../../types/GlobalType'; +import { ServerAction } from '../../types/Server'; import Constants from '../../utils/Constants'; +import Logging from '../../utils/Logging'; import DatabaseUtils from './DatabaseUtils'; import { DeletedResult } from '../../types/DataResult'; import { LabelValues } from 'prom-client'; @@ -34,7 +36,7 @@ export default class PerformanceStorage { return Promise.resolve(new ObjectId().toString()); } - public static async updatePerformanceRecord(performanceRecord: PerformanceRecord, labelValues: LabelValues): Promise { + public static async updatePerformanceRecord(performanceRecord: PerformanceRecord, labelValues: LabelValues = null): Promise { if (PERFS_ENABLED) { // Validate const performanceRecordMDB = PerformanceValidatorStorage.getInstance().validatePerformance(performanceRecord); @@ -73,6 +75,7 @@ export default class PerformanceStorage { private static savePrometheusMetric(performanceRecord: PerformanceRecord, labelValues:LabelValues) { // const grafanaGroup = performanceRecord.group.replace('-', ''); // ACHTUNG - does not work - only replaces the first occurrence! + const grafanaGroup = performanceRecord.group.replace(/-/g, ''); const values = Object.values(labelValues).toString(); const hashCode = Utils.positiveHashCode(values); diff --git a/src/storage/mongodb/SiteAreaStorage.ts b/src/storage/mongodb/SiteAreaStorage.ts index 8dbfbee840..deda4dcf4a 100644 --- a/src/storage/mongodb/SiteAreaStorage.ts +++ b/src/storage/mongodb/SiteAreaStorage.ts @@ -131,7 +131,7 @@ export default class SiteAreaStorage { }, Constants.DB_PARAMS_SINGLE_RECORD, projectFields); // No unique key on OCPI Location (avoid create several Site Area with the same location ID) if (siteAreaMDB.count > 1) { - await Logging.logWarning({ + Logging.beWarning()?.log({ tenantID: tenant.id, action: ServerAction.UNKNOWN_ACTION, module: MODULE_NAME, method: 'getSiteAreaByOcpiLocationUid', diff --git a/src/storage/mongodb/TagStorage.ts b/src/storage/mongodb/TagStorage.ts index 9c456c41f6..33cae324a0 100644 --- a/src/storage/mongodb/TagStorage.ts +++ b/src/storage/mongodb/TagStorage.ts @@ -24,7 +24,7 @@ export default class TagStorage { const id = Utils.generateTagID(); existingTag = await TagStorage.getTag(tenant, id); if (existingTag) { - await Logging.logWarning({ + Logging.beWarning()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'findAvailableID', action: ServerAction.TAG_CREATE, diff --git a/src/storage/mongodb/TransactionStorage.ts b/src/storage/mongodb/TransactionStorage.ts index 78c59978c3..d0f724ef6a 100644 --- a/src/storage/mongodb/TransactionStorage.ts +++ b/src/storage/mongodb/TransactionStorage.ts @@ -1126,42 +1126,6 @@ export default class TransactionStorage { return transactionsMDB.count === 1 ? transactionsMDB.result[0] : null; } - public static async getActiveTransaction(tenant: Tenant, chargeBoxID: string, connectorId: number): Promise { - const startTime = Logging.traceDatabaseRequestStart(); - DatabaseUtils.checkTenantObject(tenant); - const aggregation = []; - // Filters - aggregation.push({ - $match: { - 'chargeBoxID': chargeBoxID, - 'connectorId': Utils.convertToInt(connectorId), - 'stop': { $exists: false } - } - }); - // Add User - DatabaseUtils.pushUserLookupInAggregation({ - tenantID: tenant.id, aggregation, localField: 'userID', foreignField: '_id', asField: 'user', - oneToOneCardinality: true, oneToOneCardinalityNotNull: false - }); - // Rename ID - DatabaseUtils.pushRenameDatabaseIDToNumber(aggregation); - // Convert Object ID to string - DatabaseUtils.pushConvertObjectIDToString(aggregation, 'userID'); - DatabaseUtils.pushConvertObjectIDToString(aggregation, 'siteID'); - DatabaseUtils.pushConvertObjectIDToString(aggregation, 'siteAreaID'); - DatabaseUtils.pushConvertObjectIDToString(aggregation, 'stop.userID'); - DatabaseUtils.pushConvertObjectIDToString(aggregation, 'remotestop.userID'); - // Set to null - DatabaseUtils.clearFieldValueIfSubFieldIsNull(aggregation, 'stop', 'timestamp'); - DatabaseUtils.clearFieldValueIfSubFieldIsNull(aggregation, 'remotestop', 'timestamp'); - // Read DB - const transactionsMDB = await global.database.getCollection(tenant.id, 'transactions') - .aggregate(aggregation, DatabaseUtils.buildAggregateOptions()) - .toArray() as Transaction[]; - await Logging.traceDatabaseRequestEnd(tenant, MODULE_NAME, 'getActiveTransaction', startTime, aggregation, transactionsMDB); - return transactionsMDB.length === 1 ? transactionsMDB[0] : null; - } - public static async getLastTransactionFromChargingStation(tenant: Tenant, chargeBoxID: string, connectorId: number, params: { withChargingStation?: boolean; withUser?: boolean; withTag?: boolean; } = {}): Promise { const startTime = Logging.traceDatabaseRequestStart(); @@ -1234,7 +1198,7 @@ export default class TransactionStorage { const id = Utils.getRandomIntSafe(); existingTransaction = await TransactionStorage.getTransaction(tenant, id); if (existingTransaction) { - await Logging.logWarning({ + Logging.beWarning()?.log({ tenantID: tenant.id, module: MODULE_NAME, method: 'findAvailableID', action: ServerAction.TRANSACTION_STARTED, diff --git a/src/types/Server.ts b/src/types/Server.ts index 8dfd19aff6..8d2b7ba5d4 100644 --- a/src/types/Server.ts +++ b/src/types/Server.ts @@ -273,6 +273,7 @@ export enum ServerAction { WS_SERVER_CONNECTION_CLOSE = 'WsServerConnectionClose', WS_SERVER_CONNECTION_OPEN = 'WsServerConnectionOpen', WS_SERVER_CONNECTION_ERROR = 'WsServerConnectionError', + WS_SERVER_CONNECTION_LAST_SEEN = 'WsServerConnectionLastSeen', WS_CLIENT_ERROR = 'WsClientError', WS_CLIENT_MESSAGE = 'WsClientMessage', @@ -280,6 +281,8 @@ export enum ServerAction { WS_CLIENT_CONNECTION_CLOSE = 'WsClientConnectionClose', WS_CLIENT_CONNECTION_OPEN = 'WsClientConnectionOpen', WS_CLIENT_CONNECTION_ERROR = 'WsClientConnectionError', + WS_CLIENT_CONNECTION_PING = 'WsClientConnectionPing', + WS_CLIENT_CONNECTION_PONG = 'WsClientConnectionPong', NOTIFICATION = 'Notification', CHARGING_STATION_STATUS_ERROR = 'ChargingStationStatusError', diff --git a/src/types/ocpp/OCPPCommon.ts b/src/types/ocpp/OCPPCommon.ts index feb3c3d3cf..a5590c0c12 100644 --- a/src/types/ocpp/OCPPCommon.ts +++ b/src/types/ocpp/OCPPCommon.ts @@ -4,12 +4,11 @@ import OCPPError from '../../exception/OcppError'; export type FctOCPPResponse = (payload?: Record | string) => void; export type FctOCPPReject = (reason?: OCPPError) => void; -export type OCPPRequest = [FctOCPPResponse, FctOCPPReject, Command]; - -export type OCPPIncomingRequest = [OCPPMessageType, string, Command, Record, Record]; -export type OCPPIncomingResponse = [OCPPMessageType, string, Record, Record]; - -export type OCPPOutgoingRequest = [OCPPMessageType, string, Command, Record]; +export type OCPPPayload = Record; +export type OCPPIncomingRequest = [OCPPMessageType, string, Command, OCPPPayload, OCPPPayload]; +export type OCPPIncomingResponse = [OCPPMessageType, string, OCPPPayload]; +export type OCPPIncomingError = [OCPPMessageType, string, OCPPErrorType, string, OCPPPayload]; +export type OCPPOutgoingRequest = [OCPPMessageType, string, Command, OCPPPayload]; export enum OCPPMessageType { CALL_MESSAGE = 2, // Caller to Callee diff --git a/src/types/ocpp/OCPPHeader.ts b/src/types/ocpp/OCPPHeader.ts index ce445f3059..5583668599 100644 --- a/src/types/ocpp/OCPPHeader.ts +++ b/src/types/ocpp/OCPPHeader.ts @@ -8,17 +8,28 @@ export interface OCPPHeader { ocppVersion?: OCPPVersion; ocppProtocol?: OCPPProtocol; chargeBoxIdentity: string; - chargingStation?: ChargingStation; siteID?: string; siteAreaID?: string; companyID?: string; currentIPAddress?: string | string[]; - tenantID: string; - tenant?: Tenant; - token?: RegistrationToken; - tokenID?: string; + // tenantID: string; + // tokenID?: string; chargingStationURL?: string; From?: { Address: string | string[]; }; + rawConnectionData?: OcppRawConnectionData; + connectionContext?: OcppConnectionContext; +} + +export interface OcppRawConnectionData { + tenantID: string, + chargingStationID: string, + tokenID: string +} + +export interface OcppConnectionContext { + tenant: Tenant, + chargingStation: ChargingStation, + token?: RegistrationToken } diff --git a/src/utils/Constants.ts b/src/utils/Constants.ts index 6c3a86c352..311f062102 100644 --- a/src/utils/Constants.ts +++ b/src/utils/Constants.ts @@ -481,8 +481,8 @@ export default class Constants { public static readonly WEB_SOCKET_CURRENT_REQUEST = 'web_socket_current_request'; public static readonly WEB_SOCKET_REST_CONNECTIONS_COUNT = 'web_socket_rest_connections_count'; public static readonly WEB_SOCKET_RUNNING_REQUEST = 'web_socket_running_request'; - public static readonly WEB_SOCKET_RUNNING_REQUEST_RESPONSE = 'web_socket_running_request_response'; - public static readonly WEB_SOCKET_QUEUED_REQUEST = 'web_socket_queued_request'; + // public static readonly WEB_SOCKET_RUNNING_REQUEST_RESPONSE = 'web_socket_running_request_response'; + // public static readonly WEB_SOCKET_QUEUED_REQUEST = 'web_socket_queued_request'; public static readonly MONGODB_CONNECTION_POOL_CREATED = 'mongodb_connectionPoolCreated'; public static readonly MONGODB_CONNECTION_POOL_CLOSED = 'mongodb_connectionPoolClosed'; diff --git a/src/utils/FeatureToggles.ts b/src/utils/FeatureToggles.ts index 1131683de1..80aec0deca 100644 --- a/src/utils/FeatureToggles.ts +++ b/src/utils/FeatureToggles.ts @@ -6,6 +6,11 @@ export enum Feature { BILLING_PREVENT_CUSTOMER_DELETION, BILLING_SHOW_PRICING_DETAIL, BILLING_PLATFORM_USE_EXPRESS_ACCOUNT, + WS_SEND_PING_AUTOMATICALLY, + OCPP_STORE_HEARTBEATS, + OCPP_METER_VALUE_ABORT_GHOST_TRANSACTION, + OCPP_IGNORE_UNCHANGED_STATUS, + HEALTH_CHECK_PING_DATABASE, } export default class FeatureToggles { @@ -15,6 +20,11 @@ export default class FeatureToggles { Feature.BILLING_INVOICES_EXCLUDE_PENDING_ITEMS, Feature.BILLING_PREVENT_CUSTOMER_DELETION, Feature.BILLING_PLATFORM_USE_EXPRESS_ACCOUNT, + Feature.WS_SEND_PING_AUTOMATICALLY, + // Feature.OCPP_STORE_HEARTBEATS, + // Feature.OCPP_METER_VALUE_ABORT_GHOST_TRANSACTION + // Feature.OCPP_IGNORE_UNCHANGED_STATUS + // Feature.HEALTH_CHECK_PING_DATABASE, ]; // Check whether the feature is active or not! diff --git a/src/utils/Logging.ts b/src/utils/Logging.ts index 135303ec0b..7f4d6d3b4e 100644 --- a/src/utils/Logging.ts +++ b/src/utils/Logging.ts @@ -28,10 +28,94 @@ import sizeof from 'object-sizeof'; const MODULE_NAME = 'Logging'; +export abstract class AbstractLightLogger { + public abstract log(log: Log): void ; +} + +export class LightLogger extends AbstractLightLogger { + + private logLevel: LogLevel; + + public constructor(logLevel: LogLevel) { + super(); + this.logLevel = logLevel; + } + + public log(log: Log): void { + log.level = this.logLevel; + log.timestamp = new Date(); + Logging.lightLog(log); + } +} + export default class Logging { private static logConfig: LogConfiguration; private static traceConfig: TraceConfiguration; + public static isLevelEnabled(expectedLogLevel: LogLevel): boolean { + // Check the configuration for the actual log level being enabled + const logConfig = Logging.getConfiguration(); + const logLevelLetter = logConfig.logLevel ? logConfig.logLevel : 'D'; + const logLevel = logLevelLetter as LogLevel; + switch (logLevel) { + case LogLevel.NONE: + return false; + case LogLevel.INFO: + if (expectedLogLevel === LogLevel.DEBUG) { + return false; + } + break; + case LogLevel.WARNING: + if (expectedLogLevel === LogLevel.INFO || expectedLogLevel === LogLevel.DEBUG) { + return false; + } + break; + case LogLevel.ERROR: + if (expectedLogLevel === LogLevel.INFO || expectedLogLevel === LogLevel.WARNING || expectedLogLevel === LogLevel.DEBUG) { + return false; + } + break; + case LogLevel.DEBUG: + default: + break; + } + return true; + } + + public static lightLog(log: Log): void { + Logging.log(log).catch(() => { /* Intentional */ }); + } + + public static beError(): AbstractLightLogger { + return Logging.beThatLevel(LogLevel.ERROR); + } + + public static beWarning(): AbstractLightLogger { + return Logging.beThatLevel(LogLevel.WARNING); + } + + public static beInfo(): AbstractLightLogger { + return Logging.beThatLevel(LogLevel.INFO); + } + + public static beDebug(): AbstractLightLogger { + return Logging.beThatLevel(LogLevel.DEBUG); + } + + public static beThatLevel(expectedLogLevel: LogLevel): AbstractLightLogger { + if (Logging.isLevelEnabled(expectedLogLevel)) { + return new LightLogger(expectedLogLevel); + } + // ------------------------------------------------------------------------------ + // ACHTUNG - returns null when the level is disabled + // ------------------------------------------------------------------------------ + // The purpose here is to avoid evaluating the log parameters and thus + // avoid triggering unnecessary garbage collection of log messages + // Make sure to use optional chaining operator (?.) when calling the log method + // ------------------------------------------------------------------------------ + return null; + } + public static getConfiguration(): LogConfiguration { if (!this.logConfig) { this.logConfig = Configuration.getLogConfig(); @@ -163,19 +247,16 @@ export default class Logging { public static async logDebug(log: Log): Promise { log.level = LogLevel.DEBUG; - // eslint-disable-next-line @typescript-eslint/no-floating-promises return Logging.log(log); } public static async logInfo(log: Log): Promise { log.level = LogLevel.INFO; - // eslint-disable-next-line @typescript-eslint/no-floating-promises return Logging.log(log); } public static async logWarning(log: Log): Promise { log.level = LogLevel.WARNING; - // eslint-disable-next-line @typescript-eslint/no-floating-promises return Logging.log(log); } @@ -389,8 +470,7 @@ export default class Logging { public static traceExpressResponse(req: Request, res: Response, next: NextFunction, action?: ServerAction): void { if (Logging.getTraceConfiguration().traceIngressHttp) { - // eslint-disable-next-line @typescript-eslint/no-misused-promises - res.on('finish', async () => { + res.on('finish',() => { // Get Tenant info const tenantID = req['tenantID'] as string; // Compute duration @@ -407,7 +487,7 @@ export default class Logging { Utils.isDevelopmentEnv() && Logging.logConsoleInfo(message); if (sizeOfResponseDataKB > Constants.PERF_MAX_DATA_VOLUME_KB) { const error = new Error(`Data must be < ${Constants.PERF_MAX_DATA_VOLUME_KB} KB, got ${(sizeOfResponseDataKB > 0) ? sizeOfResponseDataKB : '?'} KB`); - await Logging.logWarning({ + Logging.beWarning()?.log({ tenantID, action: ServerAction.PERFORMANCES, module: MODULE_NAME, method: 'logExpressResponse', @@ -424,7 +504,7 @@ export default class Logging { } if (executionDurationMillis > Constants.PERF_MAX_RESPONSE_TIME_MILLIS) { const error = new Error(`Execution must be < ${Constants.PERF_MAX_RESPONSE_TIME_MILLIS} ms, got ${(executionDurationMillis > 0) ? executionDurationMillis : '?'} ms`); - await Logging.logWarning({ + Logging.beWarning()?.log({ tenantID, action: ServerAction.PERFORMANCES, module: MODULE_NAME, method: 'logExpressResponse', @@ -439,7 +519,7 @@ export default class Logging { Logging.logConsoleWarning('===================================='); } } - await Logging.logDebug({ + Logging.beDebug()?.log({ tenantID: tenantID, user: req.user, action: action ?? ServerAction.HTTP_RESPONSE, @@ -459,7 +539,9 @@ export default class Logging { durationMs: executionDurationMillis, resSizeKb: sizeOfResponseDataKB, } as PerformanceRecord; - await PerformanceStorage.updatePerformanceRecord(performanceRecord, null); + PerformanceStorage.updatePerformanceRecord(performanceRecord).catch((error) => { + Logging.logPromiseError(error, tenantID); + }); } }); } @@ -469,8 +551,8 @@ export default class Logging { } } - public static async traceExpressError(error: Error, req: Request, res: Response, next: NextFunction): Promise { - await Logging.logActionExceptionMessageAndSendResponse( + public static traceExpressError(error: Error, req: Request, res: Response, next: NextFunction): void { + Logging.logActionExceptionMessageAndSendResponse( error['params'] && error['params']['action'] ? error['params']['action'] : ServerAction.HTTP_ERROR, error, req, res, next); if (Logging.getTraceConfiguration().traceIngressHttp) { // Nothing done yet @@ -642,40 +724,40 @@ export default class Logging { } } - public static async logException(exception: Error, action: ServerAction, - module: string, method: string, tenantID: string, user?: UserToken | User | string): Promise { + public static logException(exception: Error, action: ServerAction, + module: string, method: string, tenantID: string, user?: UserToken | User | string): void { if (exception instanceof AppAuthError) { - await Logging.logActionAppAuthException(tenantID, action, exception); + Logging.logActionAppAuthException(tenantID, action, exception); } else if (exception instanceof AppError) { - await Logging.logActionAppException(tenantID, action, exception); + Logging.logActionAppException(tenantID, action, exception); } else if (exception instanceof OCPPError) { - await Logging.logActionOcppException(tenantID, action, exception); + Logging.logActionOcppException(tenantID, action, exception); } else if (exception instanceof BackendError) { - await Logging.logActionBackendException(tenantID, action, exception); + Logging.logActionBackendException(tenantID, action, exception); } else { - await Logging.logError( + Logging.beError()?.log( Logging.buildLogError(action, module, method, tenantID, user, exception)); } } // Used to log exception in catch(...) only - public static async logActionExceptionMessage(tenantID: string, action: ServerAction, exception: Error, detailedMessages = {}): Promise { + public static logActionExceptionMessage(tenantID: string, action: ServerAction, exception: Error, detailedMessages = {}): void { if (exception instanceof AppError) { - await Logging.logActionAppException(tenantID, action, exception, detailedMessages); + Logging.logActionAppException(tenantID, action, exception, detailedMessages); } else if (exception instanceof BackendError) { - await Logging.logActionBackendException(tenantID, action, exception, detailedMessages); + Logging.logActionBackendException(tenantID, action, exception, detailedMessages); } else if (exception instanceof AppAuthError) { - await Logging.logActionAppAuthException(tenantID, action, exception, detailedMessages); + Logging.logActionAppAuthException(tenantID, action, exception, detailedMessages); } else if (exception instanceof OCPPError) { - await Logging.logActionOcppException(tenantID, action, exception); + Logging.logActionOcppException(tenantID, action, exception); } else { - await Logging.logActionException(tenantID, action, exception, detailedMessages); + Logging.logActionException(tenantID, action, exception, detailedMessages); } } // Used to log exception in catch(...) only - public static async logActionExceptionMessageAndSendResponse(action: ServerAction, exception: Error, - req: Request, res: Response, next: NextFunction, tenantID = Constants.DEFAULT_TENANT_ID): Promise { + public static logActionExceptionMessageAndSendResponse(action: ServerAction, exception: Error, + req: Request, res: Response, next: NextFunction, tenantID = Constants.DEFAULT_TENANT_ID): void { // Clear password if (action === ServerAction.LOGIN && req.body.password) { req.body.password = '####'; @@ -687,15 +769,15 @@ export default class Logging { tenantID = req.tenant.id; } if (exception instanceof AppError) { - await Logging.logActionAppException(tenantID, action, exception); + Logging.logActionAppException(tenantID, action, exception); } else if (exception instanceof BackendError) { - await Logging.logActionBackendException(tenantID, action, exception); + Logging.logActionBackendException(tenantID, action, exception); } else if (exception instanceof AppAuthError) { - await Logging.logActionAppAuthException(tenantID, action, exception); + Logging.logActionAppAuthException(tenantID, action, exception); } else if (exception instanceof OCPPError) { - await Logging.logActionOcppException(tenantID, action, exception); + Logging.logActionOcppException(tenantID, action, exception); } else { - await Logging.logActionException(tenantID, action, exception); + Logging.logActionException(tenantID, action, exception); } // Send error if (!res.headersSent) { @@ -809,17 +891,17 @@ export default class Logging { } public static logPromiseError(error, tenantID?: string): void { - Logging.logError({ + Logging.beError()?.log({ tenantID, action: ServerAction.UNKNOWN_ACTION, module: MODULE_NAME, method: 'logPromiseError', message: 'Unexpected error in floating promise', detailedMessages: { error: error.stack } - }).catch(() => { /* Intentional */ }); + }); } - private static async logActionException(tenantID: string, action: ServerAction, exception: any, detailedMessages = {}): Promise { - await Logging.logError({ + private static logActionException(tenantID: string, action: ServerAction, exception: any, detailedMessages = {}): void { + Logging.beError()?.log({ tenantID: tenantID, user: exception.user, module: exception.module, @@ -830,9 +912,9 @@ export default class Logging { }); } - private static async logActionAppException(tenantID: string, action: ServerAction, exception: AppError, detailedMessages = {}): Promise { + private static logActionAppException(tenantID: string, action: ServerAction, exception: AppError, detailedMessages = {}): void { Utils.handleExceptionDetailedMessages(exception); - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenantID, chargingStationID: exception.params.chargingStationID, siteID: exception.params.siteID, @@ -851,9 +933,9 @@ export default class Logging { }); } - private static async logActionBackendException(tenantID: string, action: ServerAction, exception: BackendError, detailedMessages = {}): Promise { + private static logActionBackendException(tenantID: string, action: ServerAction, exception: BackendError, detailedMessages = {}): void { Utils.handleExceptionDetailedMessages(exception); - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenantID, chargingStationID: exception.params.chargingStationID, siteID: exception.params.siteID, @@ -873,9 +955,9 @@ export default class Logging { } // Used to check URL params (not in catch) - private static async logActionAppAuthException(tenantID: string, action: ServerAction, exception: AppAuthError, detailedMessages = {}): Promise { + private static logActionAppAuthException(tenantID: string, action: ServerAction, exception: AppAuthError, detailedMessages = {}): void { Utils.handleExceptionDetailedMessages(exception); - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenantID, user: exception.params.user, chargingStationID: exception.params.chargingStationID, @@ -894,9 +976,9 @@ export default class Logging { }); } - private static async logActionOcppException(tenantID: string, action: ServerAction, exception: OCPPError, detailedMessages = {}): Promise { + private static logActionOcppException(tenantID: string, action: ServerAction, exception: OCPPError, detailedMessages = {}): void { Utils.handleExceptionDetailedMessages(exception); - await Logging.logError({ + Logging.beError()?.log({ tenantID: tenantID, chargingStationID: exception.params.chargingStationID, siteID: exception.params.siteID, @@ -961,7 +1043,7 @@ export default class Logging { break; } // Timestamp - log.timestamp = new Date(); + log.timestamp = log.timestamp || new Date(); // Host log.host = Utils.getHostName(); if (log.detailedMessages) { @@ -1090,3 +1172,4 @@ export default class Logging { }; } } + diff --git a/src/utils/LoggingHelper.ts b/src/utils/LoggingHelper.ts index 0dd83ec6a9..b25ad8104d 100644 --- a/src/utils/LoggingHelper.ts +++ b/src/utils/LoggingHelper.ts @@ -9,6 +9,7 @@ import SiteArea from '../types/SiteArea'; import Tag from '../types/Tag'; import Transaction from '../types/Transaction'; import User from '../types/User'; +import WSConnection from '../server/ocpp/json/web-socket/WSConnection'; import WSWrapper from '../server/ocpp/json/web-socket/WSWrapper'; export default class LoggingHelper { @@ -42,13 +43,21 @@ export default class LoggingHelper { }; } - public static getWSWrapperProperties(wsWrapper: WSWrapper): { tenantID: string; siteID: string; siteAreaID: string; companyID: string; chargingStationID: string; } { + public static getWSWrapperProperties(wsWrapper: WSWrapper): { siteID: string; siteAreaID: string; companyID: string; chargingStationID } { return { - tenantID: wsWrapper?.tenantID, - siteID: wsWrapper?.siteID, - siteAreaID: wsWrapper?.siteAreaID, - companyID: wsWrapper?.companyID, - chargingStationID: wsWrapper?.chargingStationID, + siteID: wsWrapper?.wsConnection?.getSiteID(), + siteAreaID: wsWrapper?.wsConnection?.getSiteAreaID(), + companyID: wsWrapper?.wsConnection?.getCompanyID(), + chargingStationID: wsWrapper?.wsConnection?.getChargingStationID(), + }; + } + + public static getWSConnectionProperties(wsConnection: WSConnection): { siteID: string; siteAreaID: string; companyID: string; chargingStationID } { + return { + siteID: wsConnection?.getSiteID(), + siteAreaID: wsConnection?.getSiteAreaID(), + companyID: wsConnection?.getCompanyID(), + chargingStationID: wsConnection?.getChargingStationID(), }; } diff --git a/src/utils/RouterUtils.ts b/src/utils/RouterUtils.ts index b8587161a2..c9ce27bec8 100644 --- a/src/utils/RouterUtils.ts +++ b/src/utils/RouterUtils.ts @@ -37,7 +37,7 @@ export default class RouterUtils { // Trace } catch (error) { Utils.isDevelopmentEnv() && Logging.logConsoleError(error.stack); - void Logging.logActionExceptionMessage(req.tenant?.id ?? Constants.DEFAULT_TENANT_ID, error.params?.action ?? ServerAction.OCPI_ENDPOINT, error); + Logging.logActionExceptionMessage(req.tenant?.id ?? Constants.DEFAULT_TENANT_ID, error.params?.action ?? ServerAction.OCPI_ENDPOINT, error); res.status(error.params?.errorCode ?? HTTPError.GENERAL_ERROR).json(OCPIUtils.toErrorResponse(error)); next(); } diff --git a/src/utils/Utils.ts b/src/utils/Utils.ts index 7413c5a114..77a13d8def 100644 --- a/src/utils/Utils.ts +++ b/src/utils/Utils.ts @@ -347,26 +347,6 @@ export default class Utils { } } - public static getWebSocketCloseEventStatusString(code: number): string { - if (code >= 0 && code <= 999) { - return '(Unused)'; - } else if (code >= 1016) { - if (code <= 1999) { - return '(For WebSocket standard)'; - } else if (code <= 2999) { - return '(For WebSocket extensions)'; - } else if (code <= 3999) { - return '(For libraries and frameworks)'; - } else if (code <= 4999) { - return '(For applications)'; - } - } - if (!Utils.isUndefined(WebSocketCloseEventStatusString[code])) { - return WebSocketCloseEventStatusString[code]; - } - return '(Unknown)'; - } - public static convertToBoolean(value: any): boolean { let result = false; // Check boolean diff --git a/test/api/SmartChargingTest.ts b/test/api/SmartChargingTest.ts index 232783c834..6f4b3e0b27 100644 --- a/test/api/SmartChargingTest.ts +++ b/test/api/SmartChargingTest.ts @@ -385,7 +385,7 @@ describeif(testData.chargingSettingProvided)('Smart Charging Service', () => { }); it('Test for two cars charging', async () => { - const transactionStartResponse = await testData.chargingStationContext.startTransaction(2, testData.userContext.tags[0].id, 180, new Date); + const transactionStartResponse = await testData.chargingStationContext.startTransaction(2, testData.userContext.tags[0].id, 180, moment().add(1, 'seconds').toDate()); const transactionResponse = await testData.centralUserService.transactionApi.readById(transactionStartResponse.transactionId); transaction1 = transactionResponse.data; await testData.chargingStationContext.setConnectorStatus(chargingStationConnector2Charging); @@ -419,7 +419,7 @@ describeif(testData.chargingSettingProvided)('Smart Charging Service', () => { 'Test for three cars charging with lower site area limit and one car on a single phased station', async () => { // Start transaction on single phased Charging Station - const transactionStartResponse = await testData.chargingStationContext1.startTransaction(1, testData.userContext.tags[0].id, 180, new Date); + const transactionStartResponse = await testData.chargingStationContext1.startTransaction(1, testData.userContext.tags[0].id, 180, moment().add(2, 'seconds').toDate()); const transactionResponse = await testData.centralUserService.transactionApi.readById(transactionStartResponse.transactionId); transaction2 = transactionResponse.data; await testData.chargingStationContext1.setConnectorStatus(chargingStationConnector1Charging); @@ -488,7 +488,7 @@ describeif(testData.chargingSettingProvided)('Smart Charging Service', () => { const chargingProfiles = await smartChargingIntegration.buildChargingProfiles(testData.siteAreaContext.getSiteArea()); // Charging Profiles should have limits according the sent meter values + buffer - let chargingProfile = TestData.validateAndReturnChargingProfile(chargingProfiles, transaction) + let chargingProfile = TestData.validateAndReturnChargingProfile(chargingProfiles, transaction); expect(chargingProfile.profile.chargingSchedule.chargingSchedulePeriod).containSubset([ { 'startPeriod': 0, @@ -504,7 +504,7 @@ describeif(testData.chargingSettingProvided)('Smart Charging Service', () => { } ]); await ChargingStationStorage.saveChargingProfile(testData.tenantContext.getTenant(), chargingProfile); - chargingProfile = TestData.validateAndReturnChargingProfile(chargingProfiles, transaction1) + chargingProfile = TestData.validateAndReturnChargingProfile(chargingProfiles, transaction1); expect(chargingProfile.profile.chargingSchedule.chargingSchedulePeriod).containSubset([ { 'startPeriod': 0, @@ -759,7 +759,7 @@ describeif(testData.chargingSettingProvided)('Smart Charging Service', () => { ); it('Test for two cars charging', async () => { - const transactionStartResponse = await testData.chargingStationContext.startTransaction(2, testData.userContext.tags[0].id, 180, new Date); + const transactionStartResponse = await testData.chargingStationContext.startTransaction(2, testData.userContext.tags[0].id, 180, moment().add(1,'seconds').toDate()); const transactionResponse = await testData.centralUserService.transactionApi.readById(transactionStartResponse.transactionId); transaction1 = transactionResponse.data; await testData.chargingStationContext.setConnectorStatus(chargingStationConnector2Charging); @@ -993,7 +993,7 @@ describeif(testData.chargingSettingProvided)('Smart Charging Service', () => { ); it('Test for two cars charging', async () => { - const transactionStartResponse = await testData.chargingStationContext.startTransaction(2, testData.userContext.tags[0].id, 180, new Date); + const transactionStartResponse = await testData.chargingStationContext.startTransaction(2, testData.userContext.tags[0].id, 180, moment().subtract(1, 'seconds').toDate()); const transactionResponse = await testData.centralUserService.transactionApi.readById(transactionStartResponse.transactionId); transaction1 = transactionResponse.data; await testData.chargingStationContext.setConnectorStatus(chargingStationConnector2Charging); @@ -1050,7 +1050,7 @@ describeif(testData.chargingSettingProvided)('Smart Charging Service', () => { testData.siteAreaContext.getSiteArea().maximumPower = 100000; await testData.userService.siteAreaApi.update(testData.siteAreaContext.getSiteArea()); const chargingProfiles = await smartChargingIntegration.buildChargingProfiles(testData.siteAreaContext.getSiteArea()); - expect(TestData.validateAndReturnChargingProfile(chargingProfiles, transaction).profile.chargingSchedule.chargingSchedulePeriod).containSubset([ + expect(TestData.validateAndReturnChargingProfile(chargingProfiles, transaction1).profile.chargingSchedule.chargingSchedulePeriod).containSubset([ { 'startPeriod': 0, 'limit': 327 @@ -1064,7 +1064,7 @@ describeif(testData.chargingSettingProvided)('Smart Charging Service', () => { 'limit': 327 } ]); - expect(TestData.validateAndReturnChargingProfile(chargingProfiles, transaction1).profile.chargingSchedule.chargingSchedulePeriod).containSubset([ + expect(TestData.validateAndReturnChargingProfile(chargingProfiles, transaction).profile.chargingSchedule.chargingSchedulePeriod).containSubset([ { 'startPeriod': 0, 'limit': 86 @@ -1086,7 +1086,7 @@ describeif(testData.chargingSettingProvided)('Smart Charging Service', () => { await TestData.sendMeterValue(Voltage.VOLTAGE_400, 100, transaction, testData.chargingStationContext); await TestData.sendMeterValue(Voltage.VOLTAGE_400, 75, transaction1, testData.chargingStationContext); const chargingProfiles = await smartChargingIntegration.buildChargingProfiles(testData.siteAreaContext.getSiteArea()); - let chargingProfile = TestData.validateAndReturnChargingProfile(chargingProfiles, transaction) + let chargingProfile = TestData.validateAndReturnChargingProfile(chargingProfiles, transaction); expect(chargingProfile.profile.chargingSchedule.chargingSchedulePeriod).containSubset([ { 'startPeriod': 0, @@ -1102,7 +1102,7 @@ describeif(testData.chargingSettingProvided)('Smart Charging Service', () => { }, ]); await ChargingStationStorage.saveChargingProfile(testData.tenantContext.getTenant(), chargingProfile); - chargingProfile = TestData.validateAndReturnChargingProfile(chargingProfiles, transaction1) + chargingProfile = TestData.validateAndReturnChargingProfile(chargingProfiles, transaction1); expect(chargingProfile.profile.chargingSchedule.chargingSchedulePeriod).containSubset([ { 'startPeriod': 0, @@ -1160,7 +1160,7 @@ describeif(testData.chargingSettingProvided)('Smart Charging Service', () => { 'Test for sticky limit disabled - two cars charging with lower site area limit', async () => { const chargingProfiles = await smartChargingIntegrationWithoutStickyLimit.buildChargingProfiles(testData.siteAreaContext.getSiteArea()); - expect(TestData.validateAndReturnChargingProfile(chargingProfiles, transaction).profile.chargingSchedule.chargingSchedulePeriod).containSubset([ + expect(TestData.validateAndReturnChargingProfile(chargingProfiles, transaction1).profile.chargingSchedule.chargingSchedulePeriod).containSubset([ { 'startPeriod': 0, 'limit': 327 @@ -1174,7 +1174,7 @@ describeif(testData.chargingSettingProvided)('Smart Charging Service', () => { 'limit': 327 } ]); - expect(TestData.validateAndReturnChargingProfile(chargingProfiles, transaction1).profile.chargingSchedule.chargingSchedulePeriod).containSubset([ + expect(TestData.validateAndReturnChargingProfile(chargingProfiles, transaction).profile.chargingSchedule.chargingSchedulePeriod).containSubset([ { 'startPeriod': 0, 'limit': 86 diff --git a/test/api/context/ContextBuilder.ts b/test/api/context/ContextBuilder.ts index 4abc5c498c..84b549b057 100644 --- a/test/api/context/ContextBuilder.ts +++ b/test/api/context/ContextBuilder.ts @@ -67,23 +67,27 @@ export default class ContextBuilder { } public async prepareContexts(): Promise { - // Connect to the DB - await global.database.start(); - // Populate the DB with some initial templates (that the tests require when creating fake charging stations ) - await ContextBuilder.populateTemplates(); - // Destroy all tenants - await this.destroyTestTenants(); - let tenantDefinitions = ContextDefinition.TENANT_CONTEXT_LIST; - if (process.env.TENANT_FILTER) { - // Just an optimization allowing to only initialize a single tenant - // e.g.: npm run mochatest:create:utbilling - tenantDefinitions = ContextDefinition.TENANT_CONTEXT_LIST.filter((def) => RegExp(process.env.TENANT_FILTER).exec(def.subdomain)); - } - for (const tenantContextDef of tenantDefinitions) { - await this.buildTenantContext(tenantContextDef); + try { + // Connect to the DB + await global.database.start(); + // Populate the DB with some initial templates (that the tests require when creating fake charging stations ) + await ContextBuilder.populateTemplates(); + // Destroy all tenants + await this.destroyTestTenants(); + let tenantDefinitions = ContextDefinition.TENANT_CONTEXT_LIST; + if (process.env.TENANT_FILTER) { + // Just an optimization allowing to only initialize a single tenant + // e.g.: npm run mochatest:create:utbilling + tenantDefinitions = ContextDefinition.TENANT_CONTEXT_LIST.filter((def) => RegExp(process.env.TENANT_FILTER).exec(def.subdomain)); + } + for (const tenantContextDef of tenantDefinitions) { + await this.buildTenantContext(tenantContextDef); + } + // Close DB connection + await global.database.stop(); + } catch (error) { + console.error(`>>>> Failed to prepare test context : ${error.message as string}`); } - // Close DB connection - await global.database.stop(); } private async destroyTestTenants(): Promise { diff --git a/test/api/context/TenantContext.ts b/test/api/context/TenantContext.ts index e647bd55d7..fa93e78161 100644 --- a/test/api/context/TenantContext.ts +++ b/test/api/context/TenantContext.ts @@ -272,7 +272,12 @@ export default class TenantContext { id: faker.random.alphaNumeric(12) }), connectorsDef = null, siteArea: SiteArea = null) { const ocppService = await this.getOCPPServiceForContextCreation(ocppVersion, siteArea?.id); - const response = await ocppService.executeBootNotification(chargingStation.id, chargingStation); + let response; + try { + response = await ocppService.executeBootNotification(chargingStation.id, chargingStation); + } catch (error) { + console.error(`>>>> Failed to execute bootstrap (${ocppVersion}): ${error.message as string}`); + } expect(response).to.not.be.null; expect(response.status).to.eql('Accepted'); expect(response).to.have.property('currentTime'); @@ -357,7 +362,12 @@ export default class TenantContext { id: faker.random.alphaNumeric(12) }), connectorsDef = null, siteArea: SiteArea = null) { const ocppService = await this.getOCPPServiceForContextCreation(ocppVersion, siteArea?.id); - const response = await ocppService.executeBootNotification(chargingStation.id, chargingStation); + let response; + try { + response = await ocppService.executeBootNotification(chargingStation.id, chargingStation); + } catch (error) { + console.error(`>>>> Failed to execute bootstrap (${ocppVersion}): ${error.message as string}`); + } expect(response).to.not.be.null; expect(response.status).to.eql('Accepted'); expect(response).to.have.property('currentTime'); @@ -378,7 +388,11 @@ export default class TenantContext { }; } for (const connector of createdChargingStation.connectors) { - await ocppService.executeStatusNotification(createdChargingStation.id, connector); + try { + await ocppService.executeStatusNotification(createdChargingStation.id, connector); + } catch (error) { + console.error(`>>>> Failed to execute status notification : ${error.message as string}`); + } } createdChargingStation = await this.getAdminCentralServerService().getEntityById( this.getAdminCentralServerService().chargingStationApi, chargingStation); @@ -448,7 +462,12 @@ export default class TenantContext { id: faker.random.alphaNumeric(12) }), connectorsDef = null, siteArea = null) { const ocppService = await this.getOCPPServiceForContextCreation(ocppVersion, siteArea?.id); - const response = await ocppService.executeBootNotification(chargingStation.id, chargingStation); + let response; + try { + response = await ocppService.executeBootNotification(chargingStation.id, chargingStation); + } catch (error) { + console.error(`>>>> Failed to execute bootstrap (${ocppVersion}): ${error.message as string}`); + } expect(response).to.not.be.null; expect(response.status).to.eql('Accepted'); expect(response).to.have.property('currentTime'); diff --git a/test/api/ocpp/json/OCPPJsonService16.ts b/test/api/ocpp/json/OCPPJsonService16.ts index 12e1588bf8..4bb9f74734 100644 --- a/test/api/ocpp/json/OCPPJsonService16.ts +++ b/test/api/ocpp/json/OCPPJsonService16.ts @@ -1,7 +1,7 @@ import { OCPP15MeterValuesRequest, OCPPAuthorizeRequest, OCPPAuthorizeResponse, OCPPBootNotificationRequest, OCPPBootNotificationResponse, OCPPDataTransferRequest, OCPPDataTransferResponse, OCPPDiagnosticsStatusNotificationRequest, OCPPDiagnosticsStatusNotificationResponse, OCPPFirmwareStatusNotificationRequest, OCPPFirmwareStatusNotificationResponse, OCPPHeartbeatRequest, OCPPHeartbeatResponse, OCPPMeterValuesRequest, OCPPMeterValuesResponse, OCPPStartTransactionRequest, OCPPStartTransactionResponse, OCPPStatusNotificationRequest, OCPPStatusNotificationResponse, OCPPStopTransactionRequest, OCPPStopTransactionResponse, OCPPVersion } from '../../../../src/types/ocpp/OCPPServer'; import { OCPPIncomingRequest, OCPPMessageType } from '../../../../src/types/ocpp/OCPPCommon'; -import { Command } from '../../../types/ChargingStation'; +import { Command } from '../../../../src/types/ChargingStation'; import OCPPService from '../OCPPService'; import Utils from '../../../../src/utils/Utils'; import WSClient from '../../../../src/client/websocket/WSClient'; @@ -52,7 +52,7 @@ export default class OCPPJsonService16 extends OCPPService { reject(error); }; // Handle Server Message - wsConnection.onmessage = async (message) => { + wsConnection.onmessage = (message) => { const t1 = performance.now(); try { // Parse the message @@ -67,7 +67,9 @@ export default class OCPPJsonService16 extends OCPPService { // Respond to the request sentRequests[messageId].resolve(response); } else if (messageType === OCPPMessageType.CALL_MESSAGE) { - await this.handleRequest(chargeBoxIdentity, messageId, command, commandPayload); + this.handleRequest(chargeBoxIdentity, messageId, command, commandPayload).catch((responseError) => { + reject(responseError); + }); } } catch (error) { reject(error); diff --git a/test/api/ocpp/soap/OCPPSoapService15.ts b/test/api/ocpp/soap/OCPPSoapService15.ts index f3d150ff86..be54c5450e 100644 --- a/test/api/ocpp/soap/OCPPSoapService15.ts +++ b/test/api/ocpp/soap/OCPPSoapService15.ts @@ -67,8 +67,13 @@ export default class OCPPSoapService15 extends OCPPService { const payload = {}; payload[this.getRequestNameFromAction(request.name)] = request.data; // Execute it - const { result } = await this.service[request.name](payload); - return result || {}; + let wtf; + try { + wtf = await this.service[request.name](payload); + } catch (error) { + console.error(`>>>> Failed to invoke ${request.name} - error: ${error.message as string}`); + } + return wtf?.result || {}; } private buildSOAPRequest(chargeBoxIdentity: string, action: string, payload: any): any {