diff --git a/package-lock.json b/package-lock.json index ec9d2bdd..251222d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,17 +35,17 @@ "sockjs-client": "1.6.1", "tslib": "2.6.2", "webstomp-client": "1.2.6", - "zone.js": "0.14.2" + "zone.js": "0.14.3" }, "devDependencies": { "@angular-builders/jest": "17.0.0", - "@angular-devkit/build-angular": "17.0.9", + "@angular-devkit/build-angular": "17.0.10", "@angular-eslint/eslint-plugin": "17.1.1", - "@angular/cli": "17.0.9", + "@angular/cli": "17.0.10", "@angular/compiler-cli": "17.0.4", "@angular/service-worker": "17.0.4", "@types/jest": "29.5.10", - "@types/node": "20.10.6", + "@types/node": "20.11.1", "@types/sockjs-client": "1.5.4", "@typescript-eslint/eslint-plugin": "6.18.0", "@typescript-eslint/parser": "6.12.0", @@ -62,7 +62,7 @@ "jest-preset-angular": "13.1.4", "jest-sonar": "0.2.16", "lint-staged": "15.2.0", - "prettier": "3.1.1", + "prettier": "3.2.2", "prettier-plugin-java": "2.5.0", "prettier-plugin-packagejson": "2.4.9", "rimraf": "5.0.5", @@ -135,15 +135,15 @@ } }, "node_modules/@angular-devkit/build-angular": { - "version": "17.0.9", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-17.0.9.tgz", - "integrity": "sha512-yH6AfR2/CXrp05dIFQCroyl6Eaq8mS6tt4P7yS48+KXvAbQq2KzYW+TrDD4flFXe3qLVQGFpds3jE2auiwhHsA==", + "version": "17.0.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-17.0.10.tgz", + "integrity": "sha512-RWVu5Pdg6VdO3v1i0oI+HGr/NE4rhbNelM43w+9TqrzDtwmvckWsadSp0H88cPhQ4YGY5ldGKyQufO1UItR26w==", "dev": true, "dependencies": { "@ampproject/remapping": "2.2.1", - "@angular-devkit/architect": "0.1700.9", - "@angular-devkit/build-webpack": "0.1700.9", - "@angular-devkit/core": "17.0.9", + "@angular-devkit/architect": "0.1700.10", + "@angular-devkit/build-webpack": "0.1700.10", + "@angular-devkit/core": "17.0.10", "@babel/core": "7.23.2", "@babel/generator": "7.23.0", "@babel/helper-annotate-as-pure": "7.22.5", @@ -154,7 +154,7 @@ "@babel/preset-env": "7.23.2", "@babel/runtime": "7.23.2", "@discoveryjs/json-ext": "0.5.7", - "@ngtools/webpack": "17.0.9", + "@ngtools/webpack": "17.0.10", "@vitejs/plugin-basic-ssl": "1.0.1", "ansi-colors": "4.1.3", "autoprefixer": "10.4.16", @@ -257,6 +257,48 @@ } } }, + "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/architect": { + "version": "0.1700.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1700.10.tgz", + "integrity": "sha512-JD/3jkdN1jrFMIDEk9grKdbjutIoxUDMRazq1LZooWjTkzlYk09i/s6HwvIPao7zvxJfelD6asTPspgkjOMP5A==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "17.0.10", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.13.0 || >=20.9.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/core": { + "version": "17.0.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.0.10.tgz", + "integrity": "sha512-93N6oHnmtRt0hL3AXxvnk47sN1rHndfj+pqI5haEY41AGWzIWv9cSBsqlM0PWltNpo6VivcExZESvbLJ71wqbQ==", + "dev": true, + "dependencies": { + "ajv": "8.12.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.2.0", + "picomatch": "3.0.1", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.13.0 || >=20.9.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^3.5.2" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, "node_modules/@angular-devkit/build-angular/node_modules/@babel/core": { "version": "7.23.2", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.2.tgz", @@ -931,12 +973,12 @@ } }, "node_modules/@angular-devkit/build-webpack": { - "version": "0.1700.9", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1700.9.tgz", - "integrity": "sha512-NBpTb5kdnTePtNirsJQFXfOIFKTPdDqJe0b0sI3FI860po7uvUFu1m5pL5QSkJLmdqrjfPkNq7svGf7NlHQ8JA==", + "version": "0.1700.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1700.10.tgz", + "integrity": "sha512-jjcH5zGWre+adnVqjBdAr04Yto8oG6j7fFWuoiBVWEtK8AmesukGJQY8+QKX5UcrsyjP7COsfbz5WeJk3g1KOg==", "dev": true, "dependencies": { - "@angular-devkit/architect": "0.1700.9", + "@angular-devkit/architect": "0.1700.10", "rxjs": "7.8.1" }, "engines": { @@ -949,6 +991,60 @@ "webpack-dev-server": "^4.0.0" } }, + "node_modules/@angular-devkit/build-webpack/node_modules/@angular-devkit/architect": { + "version": "0.1700.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1700.10.tgz", + "integrity": "sha512-JD/3jkdN1jrFMIDEk9grKdbjutIoxUDMRazq1LZooWjTkzlYk09i/s6HwvIPao7zvxJfelD6asTPspgkjOMP5A==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "17.0.10", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.13.0 || >=20.9.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/build-webpack/node_modules/@angular-devkit/core": { + "version": "17.0.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.0.10.tgz", + "integrity": "sha512-93N6oHnmtRt0hL3AXxvnk47sN1rHndfj+pqI5haEY41AGWzIWv9cSBsqlM0PWltNpo6VivcExZESvbLJ71wqbQ==", + "dev": true, + "dependencies": { + "ajv": "8.12.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.2.0", + "picomatch": "3.0.1", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.13.0 || >=20.9.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^3.5.2" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-webpack/node_modules/picomatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-3.0.1.tgz", + "integrity": "sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/@angular-devkit/core": { "version": "17.0.9", "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.0.9.tgz", @@ -989,12 +1085,12 @@ } }, "node_modules/@angular-devkit/schematics": { - "version": "17.0.9", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-17.0.9.tgz", - "integrity": "sha512-5ti7g45F2KjDJS0DbgnOGI1GyKxGpn4XsKTYJFJrSAWj6VpuvPy/DINRrXNuRVo09VPEkqA+IW7QwaG9icptQg==", + "version": "17.0.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-17.0.10.tgz", + "integrity": "sha512-hjf4gaMx2uB6ZhBstBSH0Q2hzfp6kxI4IiJ5i1QrxPNE1MdGnb2h+LgPTRCdO72a7PGeWcSxFRE7cxrXeQy19g==", "dev": true, "dependencies": { - "@angular-devkit/core": "17.0.9", + "@angular-devkit/core": "17.0.10", "jsonc-parser": "3.2.0", "magic-string": "0.30.5", "ora": "5.4.1", @@ -1006,6 +1102,45 @@ "yarn": ">= 1.13.0" } }, + "node_modules/@angular-devkit/schematics/node_modules/@angular-devkit/core": { + "version": "17.0.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.0.10.tgz", + "integrity": "sha512-93N6oHnmtRt0hL3AXxvnk47sN1rHndfj+pqI5haEY41AGWzIWv9cSBsqlM0PWltNpo6VivcExZESvbLJ71wqbQ==", + "dev": true, + "dependencies": { + "ajv": "8.12.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.2.0", + "picomatch": "3.0.1", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.13.0 || >=20.9.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^3.5.2" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/schematics/node_modules/picomatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-3.0.1.tgz", + "integrity": "sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/@angular-eslint/bundled-angular-compiler": { "version": "17.1.1", "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-17.1.1.tgz", @@ -1073,15 +1208,15 @@ } }, "node_modules/@angular/cli": { - "version": "17.0.9", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-17.0.9.tgz", - "integrity": "sha512-a1rLAu3TNU5d56ozBnx9UZchJDKC8qMvZL4ThJhcaTUJb0Cj//gqLJdNdMcB0p1Ve9lmmAQ3J17+2Xij1u3sNg==", + "version": "17.0.10", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-17.0.10.tgz", + "integrity": "sha512-52rd8KmOMe3NJDp/wA+Mwj21qd4HR8fuLtfrErgVnZaJZKX2Bzi/z7FHQD3gdgMAdzUiG0OJWGM0h75Ls9X6Gw==", "dev": true, "dependencies": { - "@angular-devkit/architect": "0.1700.9", - "@angular-devkit/core": "17.0.9", - "@angular-devkit/schematics": "17.0.9", - "@schematics/angular": "17.0.9", + "@angular-devkit/architect": "0.1700.10", + "@angular-devkit/core": "17.0.10", + "@angular-devkit/schematics": "17.0.10", + "@schematics/angular": "17.0.10", "@yarnpkg/lockfile": "1.1.0", "ansi-colors": "4.1.3", "ini": "4.1.1", @@ -1106,6 +1241,60 @@ "yarn": ">= 1.13.0" } }, + "node_modules/@angular/cli/node_modules/@angular-devkit/architect": { + "version": "0.1700.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1700.10.tgz", + "integrity": "sha512-JD/3jkdN1jrFMIDEk9grKdbjutIoxUDMRazq1LZooWjTkzlYk09i/s6HwvIPao7zvxJfelD6asTPspgkjOMP5A==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "17.0.10", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.13.0 || >=20.9.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular/cli/node_modules/@angular-devkit/core": { + "version": "17.0.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.0.10.tgz", + "integrity": "sha512-93N6oHnmtRt0hL3AXxvnk47sN1rHndfj+pqI5haEY41AGWzIWv9cSBsqlM0PWltNpo6VivcExZESvbLJ71wqbQ==", + "dev": true, + "dependencies": { + "ajv": "8.12.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.2.0", + "picomatch": "3.0.1", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.13.0 || >=20.9.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^3.5.2" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular/cli/node_modules/picomatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-3.0.1.tgz", + "integrity": "sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/@angular/common": { "version": "17.0.4", "resolved": "https://registry.npmjs.org/@angular/common/-/common-17.0.4.tgz", @@ -4735,9 +4924,9 @@ } }, "node_modules/@ngtools/webpack": { - "version": "17.0.9", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-17.0.9.tgz", - "integrity": "sha512-ilbzwW30NaccrhYbdY3jy/ZpbC0l7W6+L2Cd3dzHFQ1gZGckibDdMzjibW/vyq/vRf0xr25+oBVIqUn8kZ606g==", + "version": "17.0.10", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-17.0.10.tgz", + "integrity": "sha512-UCiLrV2aLrtR7Wr/jJi0nH2Xzb7ETenrPWU/EcW9V3lnlDun5g1J0y01jRzvcipxNTOmFfI4lqv288nKSmSOAA==", "dev": true, "engines": { "node": "^18.13.0 || >=20.9.0", @@ -5029,13 +5218,13 @@ } }, "node_modules/@schematics/angular": { - "version": "17.0.9", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-17.0.9.tgz", - "integrity": "sha512-XPaHAhobxdQMswH8wSrfToKN7wmGJFh/K5jq/3J+78KeSBZStYxZkVIQbvJkSU8Y1MsdVaeMYKDE8rjFN83OYA==", + "version": "17.0.10", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-17.0.10.tgz", + "integrity": "sha512-rRBlDMXfVPkW3CqVQxazFqkuJXd0BFnD1zjI9WtDiNt3o2pTHbLzuWJnXKuIt5rzv0x/bFwNqIt4CPW2DYGNMg==", "dev": true, "dependencies": { - "@angular-devkit/core": "17.0.9", - "@angular-devkit/schematics": "17.0.9", + "@angular-devkit/core": "17.0.10", + "@angular-devkit/schematics": "17.0.10", "jsonc-parser": "3.2.0" }, "engines": { @@ -5044,6 +5233,45 @@ "yarn": ">= 1.13.0" } }, + "node_modules/@schematics/angular/node_modules/@angular-devkit/core": { + "version": "17.0.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.0.10.tgz", + "integrity": "sha512-93N6oHnmtRt0hL3AXxvnk47sN1rHndfj+pqI5haEY41AGWzIWv9cSBsqlM0PWltNpo6VivcExZESvbLJ71wqbQ==", + "dev": true, + "dependencies": { + "ajv": "8.12.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.2.0", + "picomatch": "3.0.1", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.13.0 || >=20.9.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^3.5.2" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@schematics/angular/node_modules/picomatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-3.0.1.tgz", + "integrity": "sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/@sideway/address": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", @@ -5526,9 +5754,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.10.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.6.tgz", - "integrity": "sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw==", + "version": "20.11.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.1.tgz", + "integrity": "sha512-DsXojJUES2M+FE8CpptJTKpg+r54moV9ZEncPstni1WHFmTcCzeFLnMFfyhCVS8XNOy/OQG+8lVxRLRrVHmV5A==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -7075,9 +7303,9 @@ } }, "node_modules/bonjour-service": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.0.tgz", - "integrity": "sha512-xdzMA6JGckxyJzZByjEWRcfKmDxXaGXZWVftah3FkCqdlePNS9DjHSUN5zkP4oEfz/t0EXXlro88EIhzwMB4zA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", + "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.3", @@ -16658,9 +16886,9 @@ } }, "node_modules/prettier": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.1.tgz", - "integrity": "sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.2.tgz", + "integrity": "sha512-HTByuKZzw7utPiDO523Tt2pLtEyK7OibUD9suEJQrPUCYQqrHr74GGX6VidMrovbf/I50mPqr8j/II6oBAuc5A==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -20060,9 +20288,9 @@ } }, "node_modules/zone.js": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.14.2.tgz", - "integrity": "sha512-X4U7J1isDhoOmHmFWiLhloWc2lzMkdnumtfQ1LXzf/IOZp5NQYuMUTaviVzG/q1ugMBIXzin2AqeVJUoSEkNyQ==", + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.14.3.tgz", + "integrity": "sha512-jYoNqF046Q+JfcZSItRSt+oXFcpXL88yq7XAZjb/NKTS7w2hHpKjRJ3VlFD1k75wMaRRXNUt5vrZVlygiMyHbA==", "dependencies": { "tslib": "^2.3.0" } diff --git a/package.json b/package.json index a44048a3..acfe156f 100644 --- a/package.json +++ b/package.json @@ -96,17 +96,17 @@ "sockjs-client": "1.6.1", "tslib": "2.6.2", "webstomp-client": "1.2.6", - "zone.js": "0.14.2" + "zone.js": "0.14.3" }, "devDependencies": { "@angular-builders/jest": "17.0.0", - "@angular-devkit/build-angular": "17.0.9", + "@angular-devkit/build-angular": "17.0.10", "@angular-eslint/eslint-plugin": "17.1.1", - "@angular/cli": "17.0.9", + "@angular/cli": "17.0.10", "@angular/compiler-cli": "17.0.4", "@angular/service-worker": "17.0.4", "@types/jest": "29.5.10", - "@types/node": "20.10.6", + "@types/node": "20.11.1", "@types/sockjs-client": "1.5.4", "@typescript-eslint/eslint-plugin": "6.18.0", "@typescript-eslint/parser": "6.12.0", @@ -123,7 +123,7 @@ "jest-preset-angular": "13.1.4", "jest-sonar": "0.2.16", "lint-staged": "15.2.0", - "prettier": "3.1.1", + "prettier": "3.2.2", "prettier-plugin-java": "2.5.0", "prettier-plugin-packagejson": "2.4.9", "rimraf": "5.0.5", diff --git a/src/main/docker/config/mysql/my.cnf b/src/main/docker/config/mysql/my.cnf index 582bdd19..ea086c41 100644 --- a/src/main/docker/config/mysql/my.cnf +++ b/src/main/docker/config/mysql/my.cnf @@ -63,7 +63,7 @@ innodb_ft_total_cache_size=32000000 #### http://www.tocker.ca/2014/03/10/configuring-mysql-to-use-minimal-memory.html # per thread or per operation settings -thread_stack=131072 +thread_stack=192000 sort_buffer_size=32K read_buffer_size=8200 read_rnd_buffer_size=8200 diff --git a/src/main/java/de/tum/cit/ase/domain/SimulationStats.java b/src/main/java/de/tum/cit/ase/domain/SimulationStats.java index c5786586..5ea63560 100644 --- a/src/main/java/de/tum/cit/ase/domain/SimulationStats.java +++ b/src/main/java/de/tum/cit/ase/domain/SimulationStats.java @@ -22,6 +22,10 @@ public class SimulationStats { @JoinColumn(name = "simulation_stats_id") private Set statsByMinute; + @OneToMany(cascade = CascadeType.REMOVE, fetch = FetchType.EAGER) + @JoinColumn(name = "simulation_stats_id") + private Set statsBySecond; + @Enumerated(EnumType.STRING) @Column(name = "request_type", nullable = false) private RequestType requestType; @@ -79,6 +83,14 @@ public void setSimulationRun(SimulationRun simulationRun) { this.simulationRun = simulationRun; } + public Set getStatsBySecond() { + return statsBySecond; + } + + public void setStatsBySecond(Set statsBySecond) { + this.statsBySecond = statsBySecond; + } + @Override public String toString() { return ( diff --git a/src/main/java/de/tum/cit/ase/domain/StatsBySecond.java b/src/main/java/de/tum/cit/ase/domain/StatsBySecond.java new file mode 100644 index 00000000..d4195b98 --- /dev/null +++ b/src/main/java/de/tum/cit/ase/domain/StatsBySecond.java @@ -0,0 +1,67 @@ +package de.tum.cit.ase.domain; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import jakarta.persistence.*; +import java.time.ZonedDateTime; + +@Entity +public class StatsBySecond { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "date_time", nullable = false) + private ZonedDateTime dateTime; + + @Column(name = "number_of_requests", nullable = false) + private long numberOfRequests; + + @Column(name = "avg_response_time", nullable = false) + private long avgResponseTime; + + @ManyToOne + @JoinColumn(name = "simulation_stats_id", nullable = false) + @JsonIgnore + private SimulationStats simulationStats; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public ZonedDateTime getDateTime() { + return dateTime; + } + + public void setDateTime(ZonedDateTime dateTime) { + this.dateTime = dateTime; + } + + public long getNumberOfRequests() { + return numberOfRequests; + } + + public void setNumberOfRequests(long numberOfRequests) { + this.numberOfRequests = numberOfRequests; + } + + public long getAvgResponseTime() { + return avgResponseTime; + } + + public void setAvgResponseTime(long avgResponseTime) { + this.avgResponseTime = avgResponseTime; + } + + public SimulationStats getSimulationStats() { + return simulationStats; + } + + public void setSimulationStats(SimulationStats simulationStats) { + this.simulationStats = simulationStats; + } +} diff --git a/src/main/java/de/tum/cit/ase/repository/StatsBySecondRepository.java b/src/main/java/de/tum/cit/ase/repository/StatsBySecondRepository.java new file mode 100644 index 00000000..568274fe --- /dev/null +++ b/src/main/java/de/tum/cit/ase/repository/StatsBySecondRepository.java @@ -0,0 +1,6 @@ +package de.tum.cit.ase.repository; + +import de.tum.cit.ase.domain.StatsBySecond; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface StatsBySecondRepository extends JpaRepository {} diff --git a/src/main/java/de/tum/cit/ase/service/simulation/SimulationResultService.java b/src/main/java/de/tum/cit/ase/service/simulation/SimulationResultService.java index 5387326a..11ac8ef1 100644 --- a/src/main/java/de/tum/cit/ase/service/simulation/SimulationResultService.java +++ b/src/main/java/de/tum/cit/ase/service/simulation/SimulationResultService.java @@ -4,6 +4,7 @@ import de.tum.cit.ase.domain.RequestType; import de.tum.cit.ase.repository.SimulationStatsRepository; import de.tum.cit.ase.repository.StatsByMinuteRepository; +import de.tum.cit.ase.repository.StatsBySecondRepository; import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; import java.util.Collection; @@ -18,10 +19,16 @@ public class SimulationResultService { private final SimulationStatsRepository simulationStatsRepository; private final StatsByMinuteRepository statsByMinuteRepository; + private final StatsBySecondRepository statsBySecondRepository; - public SimulationResultService(SimulationStatsRepository simulationStatsRepository, StatsByMinuteRepository statsByMinuteRepository) { + public SimulationResultService( + SimulationStatsRepository simulationStatsRepository, + StatsByMinuteRepository statsByMinuteRepository, + StatsBySecondRepository statsBySecondRepository + ) { this.simulationStatsRepository = simulationStatsRepository; this.statsByMinuteRepository = statsByMinuteRepository; + this.statsBySecondRepository = statsBySecondRepository; } /** @@ -37,12 +44,18 @@ public SimulationRun calculateAndSaveResult(SimulationRun simulationRun, List totalStatsByMinute = calculateStatsByMinute(requestStats); + Set totalStatsBySecond = calculateStatsBySecond(requestStats); simulationStatsRepository.save(totalStats); totalStats.setStatsByMinute(totalStatsByMinute); totalStatsByMinute.forEach(statsByMinute -> { statsByMinute.setSimulationStats(totalStats); statsByMinuteRepository.save(statsByMinute); }); + totalStats.setStatsBySecond(totalStatsBySecond); + totalStatsBySecond.forEach(statsByTenSec -> { + statsByTenSec.setSimulationStats(totalStats); + statsBySecondRepository.save(statsByTenSec); + }); SimulationStats authStats = calculateStatsForRequestType(requestStats, RequestType.AUTHENTICATION, simulationRun); @@ -90,6 +103,12 @@ private SimulationStats calculateStatsForRequestType(List requestSt statsByMinute.setSimulationStats(simulationStats); statsByMinuteRepository.save(statsByMinute); }); + Set statsBySecond = calculateStatsBySecond(filteredRequestStats); + simulationStats.setStatsBySecond(statsBySecond); + statsBySecond.forEach(statsByTenSec -> { + statsByTenSec.setSimulationStats(simulationStats); + statsBySecondRepository.save(statsByTenSec); + }); return simulationStats; } @@ -117,6 +136,23 @@ private static Set calculateStatsByMinute(Collection .collect(Collectors.toSet()); } + private static Set calculateStatsBySecond(Collection requestStats) { + Map requestsBySecond = calculateRequestsBySecond(requestStats); + Map avgResponseTimeBySecond = calculateAvgResponseTimeBySecond(requestStats); + + return requestsBySecond + .keySet() + .stream() + .map(dateTime -> { + StatsBySecond statsBySecond = new StatsBySecond(); + statsBySecond.setDateTime(dateTime); + statsBySecond.setNumberOfRequests(requestsBySecond.get(dateTime)); + statsBySecond.setAvgResponseTime(avgResponseTimeBySecond.get(dateTime).longValue()); + return statsBySecond; + }) + .collect(Collectors.toSet()); + } + private static Map calculateRequestsByMinute(Collection requestStats) { return requestStats .stream() @@ -133,4 +169,21 @@ private static Map calculateAvgResponseTimeByMinute(Colle ) ); } + + private static Map calculateRequestsBySecond(Collection requestStats) { + return requestStats + .stream() + .collect(Collectors.groupingBy(stat -> stat.dateTime().truncatedTo(ChronoUnit.SECONDS), Collectors.counting())); + } + + private static Map calculateAvgResponseTimeBySecond(Collection requestStats) { + return requestStats + .stream() + .collect( + Collectors.groupingBy( + stat -> stat.dateTime().truncatedTo(ChronoUnit.SECONDS), + Collectors.averagingLong(RequestStat::duration) + ) + ); + } } diff --git a/src/main/resources/config/application.yml b/src/main/resources/config/application.yml index d9c50436..537869fe 100644 --- a/src/main/resources/config/application.yml +++ b/src/main/resources/config/application.yml @@ -132,6 +132,16 @@ spring: implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy messages: basename: i18n/messages + mail: + host: postout.lrz.de + port: 587 + protocol: smtp + tls: true + username: + password: + properties.mail.smtp: + auth: true + starttls.enable: true main: allow-bean-definition-overriding: true mvc: diff --git a/src/main/resources/config/liquibase/changelog/00000000000016_add_stats_by_second.xml b/src/main/resources/config/liquibase/changelog/00000000000016_add_stats_by_second.xml new file mode 100644 index 00000000..0b5508e4 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/00000000000016_add_stats_by_second.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/master.xml b/src/main/resources/config/liquibase/master.xml index 453fb47e..1258bdbd 100644 --- a/src/main/resources/config/liquibase/master.xml +++ b/src/main/resources/config/liquibase/master.xml @@ -24,6 +24,7 @@ + diff --git a/src/main/webapp/app/app.module.ts b/src/main/webapp/app/app.module.ts index b89528ad..e0c48e05 100644 --- a/src/main/webapp/app/app.module.ts +++ b/src/main/webapp/app/app.module.ts @@ -29,6 +29,8 @@ import { ServerBadgeComponent } from './layouts/server-badge/server-badge.compon import { ModeExplanationComponent } from './layouts/mode-explanation/mode-explanation.component'; import { PrometheusBoxComponent } from './layouts/prometheus-box/prometheus-box.component'; import { LocalCiStatusCardComponent } from './layouts/local-ci-status-card/local-ci-status-card.component'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { NgxChartsModule } from '@swimlane/ngx-charts'; // jhipster-needle-angular-add-module-import JHipster will add new module here @NgModule({ @@ -46,6 +48,8 @@ import { LocalCiStatusCardComponent } from './layouts/local-ci-status-card/local NgbAccordionModule, PrometheusBoxComponent, LocalCiStatusCardComponent, + NgxChartsModule, + BrowserAnimationsModule, ], providers: [ Title, diff --git a/src/main/webapp/app/entities/simulation/simulationStats.ts b/src/main/webapp/app/entities/simulation/simulationStats.ts index af8ee5ba..15086ec8 100644 --- a/src/main/webapp/app/entities/simulation/simulationStats.ts +++ b/src/main/webapp/app/entities/simulation/simulationStats.ts @@ -1,6 +1,6 @@ import { SimulationRun } from './simulationRun'; import { RequestType } from './requestType'; -import { StatsByMinute } from './statsByMinute'; +import { StatsByTime } from './statsByTime'; export class SimulationStats { constructor( @@ -9,7 +9,8 @@ export class SimulationStats { public avgResponseTime: number, public simulationRun: SimulationRun, public requestType: RequestType, - public statsByMinute: StatsByMinute[], + public statsByMinute: StatsByTime[], + public statsBySecond: StatsByTime[], ) {} } diff --git a/src/main/webapp/app/entities/simulation/statsByMinute.ts b/src/main/webapp/app/entities/simulation/statsByTime.ts similarity index 89% rename from src/main/webapp/app/entities/simulation/statsByMinute.ts rename to src/main/webapp/app/entities/simulation/statsByTime.ts index fecdd4ed..fbb339a0 100644 --- a/src/main/webapp/app/entities/simulation/statsByMinute.ts +++ b/src/main/webapp/app/entities/simulation/statsByTime.ts @@ -1,6 +1,6 @@ import { SimulationStats } from './simulationStats'; -export class StatsByMinute { +export class StatsByTime { constructor( public id: number, public dateTime: Date, diff --git a/src/main/webapp/app/layouts/result-box/result-box.component.html b/src/main/webapp/app/layouts/result-box/result-box.component.html index 2b0a658b..ece20682 100644 --- a/src/main/webapp/app/layouts/result-box/result-box.component.html +++ b/src/main/webapp/app/layouts/result-box/result-box.component.html @@ -1,29 +1,81 @@
{{ formatRequestType(simulationStats!.requestType) }} + @if (statsBySecond.length >= 3) { +
+ +
+ }

Number of requests: {{ simulationStats!.numberOfRequests }}

Average response time: {{ formatDuration(simulationStats!.avgResponseTime) }}

-
-
- Requests per minute: -
- @for (statsMinute of simulationStats!.statsByMinute; track statsMinute) { -

{{ statsMinute.dateTime | date: 'HH:mm' }}: {{ statsMinute.numberOfRequests }}

- } + @if (!showChart) { +
+
+ Requests per minute: +
+ @for (statsMinute of simulationStats!.statsByMinute; track statsMinute) { +

{{ statsMinute.dateTime | date: 'HH:mm' }}: {{ statsMinute.numberOfRequests }}

+ } +
-
-
- Avg. response time by minute: -
- @for (statsMinute of simulationStats!.statsByMinute; track statsMinute) { -

{{ statsMinute.dateTime | date: 'HH:mm' }}: {{ formatDuration(statsMinute.avgResponseTime) }}

- } +
+ Avg. response time by minute: +
+ @for (statsMinute of simulationStats!.statsByMinute; track statsMinute) { +

{{ statsMinute.dateTime | date: 'HH:mm' }}: {{ formatDuration(statsMinute.avgResponseTime) }}

+ } +
-
+ } @else { + @if (statsBySecond.length < 3) { +

No data

+ } @else { +
+ + +
+
+ + +
+ } + }
diff --git a/src/main/webapp/app/layouts/result-box/result-box.component.scss b/src/main/webapp/app/layouts/result-box/result-box.component.scss index e69de29b..e840f9d3 100644 --- a/src/main/webapp/app/layouts/result-box/result-box.component.scss +++ b/src/main/webapp/app/layouts/result-box/result-box.component.scss @@ -0,0 +1,9 @@ +/* Customize horizontal grid lines */ +:host ::ng-deep .line-chart .y { + stroke-opacity: 0.3; /* Set the desired opacity (0 to 1) */ +} + +/* Hide vertical grid lines */ +:host ::ng-deep .line-chart .x { + stroke-opacity: 0; +} diff --git a/src/main/webapp/app/layouts/result-box/result-box.component.ts b/src/main/webapp/app/layouts/result-box/result-box.component.ts index 020654a6..84931f60 100644 --- a/src/main/webapp/app/layouts/result-box/result-box.component.ts +++ b/src/main/webapp/app/layouts/result-box/result-box.component.ts @@ -1,17 +1,49 @@ import { Component, Input, OnInit } from '@angular/core'; import { SimulationStats } from '../../entities/simulation/simulationStats'; import { RequestType } from '../../entities/simulation/requestType'; +import { DatePipe } from '@angular/common'; +import { StatsByTime } from 'app/entities/simulation/statsByTime'; +import { faChartLine, faTable } from '@fortawesome/free-solid-svg-icons'; +import { ScaleType } from '@swimlane/ngx-charts'; @Component({ selector: 'jhi-result-box', templateUrl: './result-box.component.html', + providers: [DatePipe], styleUrls: ['./result-box.component.scss'], }) export class ResultBoxComponent implements OnInit { + faChartLine = faChartLine; + faTable = faTable; + @Input() simulationStats?: SimulationStats; + dataResponseTime: any[] = []; + dataNumberOfRequests: any[] = []; + statsBySecond: StatsByTime[] = []; + showChart = false; + referenceLine: any[] = []; + + colorSchemeResponseTime = { + name: 'colorTime', + selectable: true, + group: ScaleType.Linear, + domain: ['#EB0505'], + }; + + colorSchemeNumberOfRequests = { + name: 'colorNumber', + selectable: true, + group: ScaleType.Linear, + domain: ['#33ADFF'], + }; + + constructor(private datePipe: DatePipe) {} ngOnInit(): void { this.simulationStats?.statsByMinute.sort((a, b) => new Date(a.dateTime).getTime() - new Date(b.dateTime).getTime()); + this.statsBySecond = + this.simulationStats?.statsBySecond.sort((a, b) => new Date(a.dateTime).getTime() - new Date(b.dateTime).getTime()) ?? []; + this.initChart(); } formatDuration(durationInNanoSeconds: number): string { const durationInMicroSeconds = durationInNanoSeconds / 1000; @@ -29,4 +61,35 @@ export class ResultBoxComponent implements OnInit { formatRequestType(requestType: RequestType): string { return requestType.replace(/_/g, ' '); } + + initChart(): void { + if (this.simulationStats) { + this.referenceLine = [ + { + name: 'Avg. response time', + value: this.simulationStats.avgResponseTime / 1_000_000, + }, + ]; + this.dataResponseTime = [ + { + name: this.formatRequestType(this.simulationStats.requestType), + series: this.statsBySecond.map(stats => ({ + name: stats.dateTime, + value: stats.avgResponseTime / 1_000_000, + })), + }, + ]; + this.dataNumberOfRequests = [ + { + name: this.formatRequestType(this.simulationStats.requestType), + series: this.statsBySecond.map(stats => ({ + name: stats.dateTime, + value: stats.numberOfRequests, + })), + }, + ]; + } + } + + axisFormat = (val: any): string => this.datePipe.transform(val, 'HH:mm:ss') ?? ''; } diff --git a/src/test/java/de/tum/cit/ase/service/SimulationResultServiceIT.java b/src/test/java/de/tum/cit/ase/service/SimulationResultServiceIT.java index 8951a796..98f820ce 100644 --- a/src/test/java/de/tum/cit/ase/service/SimulationResultServiceIT.java +++ b/src/test/java/de/tum/cit/ase/service/SimulationResultServiceIT.java @@ -9,6 +9,7 @@ import de.tum.cit.ase.domain.SimulationRun; import de.tum.cit.ase.repository.SimulationStatsRepository; import de.tum.cit.ase.repository.StatsByMinuteRepository; +import de.tum.cit.ase.repository.StatsBySecondRepository; import de.tum.cit.ase.service.simulation.SimulationResultService; import jakarta.transaction.Transactional; import java.time.ZonedDateTime; @@ -32,6 +33,9 @@ public class SimulationResultServiceIT { @MockBean private StatsByMinuteRepository statsByMinuteRepository; + @MockBean + private StatsBySecondRepository statsBySecondRepository; + private List requestStats; private SimulationRun simulationRun;