diff --git a/.docker/docker-compose.yml b/.docker/docker-compose.yml index 87dab50c910aa24671b50db413f4838e48d10369..bf483e93bab0a478ecee93de8cd37d1fd3154f22 100644 --- a/.docker/docker-compose.yml +++ b/.docker/docker-compose.yml @@ -15,7 +15,7 @@ services: restart: "no" container_name: dbrepo-metadata-db hostname: metadata-db - image: docker.io/bitnami/mariadb:11.1.3-debian-11-r6 + image: docker.io/bitnami/mariadb-galera:11.1.3-debian-11-r8 volumes: - metadata-db-data:/bitnami/mariadb - ./config/1_setup-schema.sql:/docker-entrypoint-initdb.d/1_setup-schema.sql @@ -25,6 +25,7 @@ services: environment: MARIADB_DATABASE: "${METADATA_DB:-dbrepo}" MARIADB_ROOT_PASSWORD: "${METADATA_DB_PASSWORD:-dbrepo}" + MARIADB_GALERA_MARIABACKUP_PASSWORD: "${METADATA_DB_BACKUP_PASSWORD:-dbrepobackup}" healthcheck: test: mysqladmin ping --user=root --password="${METADATA_DB_PASSWORD:-dbrepo}" --silent interval: 10s @@ -37,7 +38,7 @@ services: restart: "no" container_name: dbrepo-data-db hostname: data-db - image: docker.io/bitnami/mariadb:11.1.3-debian-11-r6 + image: docker.io/bitnami/mariadb-galera:11.1.3-debian-11-r8 volumes: - data-db-data:/bitnami/mariadb - "${SHARED_VOLUME:-/tmp}:/tmp" @@ -45,6 +46,7 @@ services: - "3307:3306" environment: MARIADB_ROOT_PASSWORD: "${DATA_DB_PASSWORD:-dbrepo}" + MARIADB_GALERA_MARIABACKUP_PASSWORD: "${DATA_DB_BACKUP_PASSWORD:-dbrepobackup}" healthcheck: test: mysqladmin ping --user=root --password="${DATA_DB_PASSWORD:-dbrepo}" --silent interval: 10s @@ -65,6 +67,7 @@ services: environment: MARIADB_DATABASE: "${AUTH_DB_NAME:-keycloak}" MARIADB_ROOT_PASSWORD: "${AUTH_DB_PASSWORD:-dbrepo}" + MARIADB_GALERA_MARIABACKUP_PASSWORD: "${AUTH_DB_BACKUP_PASSWORD:-dbrepobackup}" healthcheck: test: mysqladmin ping --user=root --password="${AUTH_DB_PASSWORD:-dbrepo}" --silent interval: 15s @@ -190,7 +193,7 @@ services: restart: "no" container_name: dbrepo-broker-service hostname: broker-service - image: docker.io/bitnami/rabbitmq:3.12-debian-12 + image: docker.io/bitnami/rabbitmq:3.13.7-debian-12-r4 ports: - 5672:5672 - 1883:1883 @@ -200,6 +203,8 @@ services: - ./config/enabled_plugins:/etc/rabbitmq/enabled_plugins - ./config/definitions.json:/app/definitions.json - broker-service-data:/bitnami/rabbitmq/mnesia + environment: + RABBITMQ_FEATURE_FLAGS: mqtt_v5 depends_on: dbrepo-identity-service: condition: service_healthy @@ -251,6 +256,11 @@ services: OPENSEARCH_USERNAME: ${SEARCH_DB_USERNAME:-admin} OPENSEARCH_PASSWORD: ${SEARCH_DB_PASSWORD:-admin} LOG_LEVEL: ${LOG_LEVEL:-info} + healthcheck: + test: curl -sSL localhost:8080/health | grep 'UP' || exit 1 + interval: 10s + timeout: 5s + retries: 12 dbrepo-data-db-sidecar: restart: "no" @@ -281,9 +291,14 @@ services: environment: NUXT_PUBLIC_API_CLIENT: "${BASE_URL:-http://localhost}" NUXT_PUBLIC_API_SERVER: "${BASE_URL:-http://localhost}" - NUXT_PUBLIC_UPLOAD_CLIENT: "${BASE_URL:-http://localhost}/api/upload/files/" + NUXT_PUBLIC_UPLOAD_CLIENT: "${BASE_URL:-http://localhost}/api/upload/files" + depends_on: + dbrepo-search-service: + condition: service_healthy + dbrepo-upload-service: + condition: service_healthy healthcheck: - test: wget -qO- localhost:3000 | grep "Database Repository" || exit 1 + test: curl -fsSL http://127.0.0.1:3000 && curl -fsSL http://127.0.0.1:3000/health interval: 10s timeout: 5s retries: 12 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f943d18b85c705bd5e5b8aa92adb86473ea5522b..cb06af28364f2560a9aeca24163e21a120afbb1f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -97,7 +97,7 @@ build-data-service: expire_in: 1 days build-ui: - image: oven/bun:1.0.26-alpine + image: oven/bun:1.1.20-alpine stage: build script: - "cd ./dbrepo-ui && bun install && bun run build" @@ -299,6 +299,21 @@ test-lib: junit: ./lib/python/report.xml coverage: '/TOTAL.*?([0-9]{1,3})%/' +test-ui: + stage: test + image: docker.io/docker:24-dind + needs: + - build-ui + dependencies: + - build-ui + before_script: + - "apk add bash apache2-utils" + - "docker compose build dbrepo-ui" + - "docker run --name dbrepo-ui -e NODE_OPTIONS='--max_old_space_size=256' -p 3000:3000 -d dbrepo-ui:latest" + script: + - "sleep 30" + - "ENDPOINT=http://localhost:3000 bash ./dbrepo-ui/test/test_heap.sh" + scan-sonarqube: image: sonarsource/sonar-scanner-cli:10.0 stage: scan diff --git a/dbrepo-dashboard-service/dashboards/system.json b/dbrepo-dashboard-service/dashboards/system.json index 4eb40a1a2ea5311ed634f406f0603e82d4c1ee91..e37d7be19f66f2b9b39928d85fe1741e45db760f 100644 --- a/dbrepo-dashboard-service/dashboards/system.json +++ b/dbrepo-dashboard-service/dashboards/system.json @@ -92,7 +92,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.2.2", + "pluginVersion": "10.4.9", "targets": [ { "datasource": { @@ -160,7 +160,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.2.2", + "pluginVersion": "10.4.9", "targets": [ { "datasource": { @@ -276,7 +276,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.2.2", + "pluginVersion": "10.4.9", "targets": [ { "datasource": { @@ -306,18 +306,17 @@ "x": 0, "y": 4 }, - "id": 2, + "id": 22, "panels": [], - "title": "Services", + "title": "UI", "type": "row" }, { "datasource": { - "default": true, "type": "prometheus", "uid": "P18F45E9DC7E75912" }, - "description": "Quality of Service", + "description": "", "fieldConfig": { "defaults": { "mappings": [], @@ -327,38 +326,34 @@ "mode": "absolute", "steps": [ { - "color": "purple", + "color": "green", "value": null }, { - "color": "red", - "value": 0 + "color": "#EAB839", + "value": 300 }, { "color": "orange", - "value": 60 - }, - { - "color": "#EAB839", - "value": 80 + "value": 600 }, { - "color": "green", - "value": 100 + "color": "red", + "value": 900 } ] }, - "unit": "percent" + "unit": "ms" }, "overrides": [] }, "gridPos": { - "h": 4, + "h": 3, "w": 4, "x": 0, "y": 5 }, - "id": 9, + "id": 17, "options": { "colorMode": "background", "graphMode": "none", @@ -376,7 +371,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.2.2", + "pluginVersion": "10.4.9", "targets": [ { "datasource": { @@ -385,17 +380,17 @@ }, "disableTextWrap": false, "editorMode": "code", - "expr": "sum(up)*100/count(up)", + "expr": "avg(page_render_time)", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, - "legendFormat": "Services Running", + "legendFormat": "__auto", "range": true, "refId": "A", "useBackend": false } ], - "title": "QoS", + "title": "UI Response Time (avg)", "type": "stat" }, { @@ -403,72 +398,132 @@ "type": "prometheus", "uid": "P18F45E9DC7E75912" }, + "description": "", "fieldConfig": { "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": { - "fillOpacity": 70, - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineWidth": 1 - }, - "mappings": [ - { - "options": { - "0": { - "index": 0, - "text": "DOWN" - }, - "1": { - "index": 1, - "text": "UP" - } - }, - "type": "value" - } - ], + "mappings": [], + "max": 100, + "min": 0, "thresholds": { "mode": "absolute", "steps": [ { - "color": "red", + "color": "green", "value": null }, { - "color": "green", - "value": 1 + "color": "#EAB839", + "value": 0.02 + }, + { + "color": "orange", + "value": 0.05 + }, + { + "color": "red", + "value": 0.1 } ] - } + }, + "unit": "s" }, "overrides": [] }, "gridPos": { - "h": 8, - "w": 20, + "h": 3, + "w": 4, "x": 4, "y": 5 }, - "id": 16, + "id": 24, "options": { - "colWidth": 0.9, - "legend": { - "displayMode": "list", - "placement": "bottom", - "showLegend": false + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false }, - "rowHeight": 0.9, - "showValue": "auto", - "tooltip": { - "mode": "single", - "sort": "none" + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.4.9", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P18F45E9DC7E75912" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "nodejs_eventloop_lag_mean_seconds", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false } + ], + "title": "UI Event Lag (avg)", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P18F45E9DC7E75912" + }, + "description": "", + "fieldConfig": { + "defaults": { + "mappings": [], + "max": 100, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "blue", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 8, + "y": 5 + }, + "id": 25, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true }, + "pluginVersion": "10.4.9", "targets": [ { "datasource": { @@ -476,26 +531,26 @@ "uid": "P18F45E9DC7E75912" }, "disableTextWrap": false, - "editorMode": "builder", - "expr": "up", + "editorMode": "code", + "expr": "nodejs_active_handles{type=\"Server\"}", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, - "legendFormat": "{{instance}}", + "legendFormat": "__auto", "range": true, "refId": "A", "useBackend": false } ], - "title": "Service QoS", - "type": "status-history" + "title": "UI Servers", + "type": "stat" }, { "datasource": { "type": "prometheus", "uid": "P18F45E9DC7E75912" }, - "description": "Total used disk space in Storage Service", + "description": "", "fieldConfig": { "defaults": { "mappings": [], @@ -510,17 +565,17 @@ } ] }, - "unit": "decbytes" + "unit": "none" }, "overrides": [] }, "gridPos": { - "h": 4, + "h": 3, "w": 4, - "x": 0, - "y": 9 + "x": 12, + "y": 5 }, - "id": 17, + "id": 26, "options": { "colorMode": "background", "graphMode": "none", @@ -534,11 +589,527 @@ "fields": "", "values": false }, - "showPercentChange": false, - "textMode": "auto", - "wideLayout": true + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.4.9", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P18F45E9DC7E75912" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "nodejs_active_handles{type=\"Socket\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "UI Sockets", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P18F45E9DC7E75912" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "blue", + "mode": "fixed" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "blue", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 16, + "y": 5 + }, + "id": 27, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.4.9", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P18F45E9DC7E75912" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "nodejs_active_requests_total", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Active Requests", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P18F45E9DC7E75912" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 300 + }, + { + "color": "orange", + "value": 600 + }, + { + "color": "red", + "value": 900 + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 20, + "options": { + "displayMode": "basic", + "maxVizHeight": 300, + "minVizHeight": 16, + "minVizWidth": 8, + "namePlacement": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showUnfilled": true, + "sizing": "auto", + "valueMode": "color" + }, + "pluginVersion": "10.4.9", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P18F45E9DC7E75912" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "page_render_time", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{path}}", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "UI Response Time per Path (avg)", + "type": "bargauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P18F45E9DC7E75912" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "dashed" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 256000000 + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 8 + }, + "id": 21, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P18F45E9DC7E75912" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "nodejs_heap_space_size_total_bytes", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{space}}", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "NodeJS Heap Bytes", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 15 + }, + "id": 2, + "panels": [], + "title": "Services", + "type": "row" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "P18F45E9DC7E75912" + }, + "description": "Quality of Service", + "fieldConfig": { + "defaults": { + "mappings": [], + "max": 100, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "purple", + "value": null + }, + { + "color": "red", + "value": 0 + }, + { + "color": "orange", + "value": 60 + }, + { + "color": "#EAB839", + "value": 80 + }, + { + "color": "green", + "value": 100 + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 0, + "y": 16 + }, + "id": 9, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.4.9", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P18F45E9DC7E75912" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "sum(up)*100/count(up)", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Services Running", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "QoS", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P18F45E9DC7E75912" + }, + "description": "", + "fieldConfig": { + "defaults": { + "mappings": [], + "max": 100, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "blue", + "value": null + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 4, + "y": 16 + }, + "id": 28, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.4.9", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P18F45E9DC7E75912" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "min(process_uptime_seconds)", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Uptime", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P18F45E9DC7E75912" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "fillOpacity": 70, + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineWidth": 1 + }, + "mappings": [ + { + "options": { + "0": { + "index": 0, + "text": "DOWN" + }, + "1": { + "index": 1, + "text": "UP" + } + }, + "type": "value" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "green", + "value": 1 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 16 + }, + "id": 16, + "options": { + "colWidth": 0.9, + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": false + }, + "rowHeight": 0.9, + "showValue": "auto", + "tooltip": { + "mode": "single", + "sort": "none" + } }, - "pluginVersion": "11.2.2", "targets": [ { "datasource": { @@ -546,25 +1117,26 @@ "uid": "P18F45E9DC7E75912" }, "disableTextWrap": false, - "editorMode": "code", - "expr": "SeaweedFS_volumeServer_total_disk_size", + "editorMode": "builder", + "expr": "up", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, - "legendFormat": "__auto", + "legendFormat": "{{instance}}", "range": true, "refId": "A", "useBackend": false } ], - "title": "S3 Volume", - "type": "stat" + "title": "Service QoS", + "type": "status-history" }, { "datasource": { "type": "prometheus", "uid": "P18F45E9DC7E75912" }, + "description": "", "fieldConfig": { "defaults": { "color": { @@ -577,9 +1149,8 @@ "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, - "barWidthFactor": 0.6, "drawStyle": "line", - "fillOpacity": 25, + "fillOpacity": 0, "gradientMode": "none", "hideFrom": { "legend": false, @@ -597,7 +1168,7 @@ "spanNulls": false, "stacking": { "group": "A", - "mode": "normal" + "mode": "none" }, "thresholdsStyle": { "mode": "off" @@ -616,79 +1187,17 @@ "value": 80 } ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "auth-service:8080" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "yellow", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "data-service:8080" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "blue", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "metadata-service:8080" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "purple", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "metadata-service:80" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "blue", - "mode": "fixed" - } - } - ] } - ] + }, + "overrides": [] }, "gridPos": { "h": 7, "w": 12, "x": 0, - "y": 13 + "y": 19 }, - "id": 6, + "id": 23, "options": { "legend": { "calcs": [], @@ -701,7 +1210,7 @@ "sort": "none" } }, - "pluginVersion": "11.2.0", + "pluginVersion": "10.4.9", "targets": [ { "datasource": { @@ -709,19 +1218,18 @@ "uid": "P18F45E9DC7E75912" }, "disableTextWrap": false, - "editorMode": "builder", - "expr": "process_cpu_usage", + "editorMode": "code", + "expr": "process_open_fds\n", "fullMetaSearch": false, - "hide": false, "includeNullMetadata": true, "instant": false, "legendFormat": "{{instance}}", "range": true, - "refId": "process_cpu_usage", + "refId": "process_open_fds", "useBackend": false } ], - "title": "CPU Usage", + "title": "File Descriptors", "type": "timeseries" }, { @@ -743,7 +1251,6 @@ "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, - "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 25, "gradientMode": "none", @@ -848,7 +1355,7 @@ "h": 7, "w": 12, "x": 12, - "y": 13 + "y": 23 }, "id": 7, "options": { @@ -903,7 +1410,6 @@ "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, - "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 25, "gradientMode": "none", @@ -923,7 +1429,7 @@ "spanNulls": false, "stacking": { "group": "A", - "mode": "none" + "mode": "normal" }, "thresholdsStyle": { "mode": "off" @@ -936,22 +1442,26 @@ { "color": "green", "value": null + }, + { + "color": "red", + "value": 80 } ] }, - "unit": "reqps" + "unit": "none" }, "overrides": [ { "matcher": { - "id": "byRegexp", - "options": "/.*search-service.*/" + "id": "byName", + "options": "auth-service:8080" }, "properties": [ { "id": "color", "value": { - "fixedColor": "orange", + "fixedColor": "yellow", "mode": "fixed" } } @@ -959,14 +1469,44 @@ }, { "matcher": { - "id": "byRegexp", - "options": "/.*analyse-service.*/" + "id": "byName", + "options": "data-service:8080" }, "properties": [ { "id": "color", "value": { - "fixedColor": "super-light-orange", + "fixedColor": "blue", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "metadata-service:8080" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "purple", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "metadata-service:80" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "blue", "mode": "fixed" } } @@ -978,9 +1518,9 @@ "h": 7, "w": 12, "x": 0, - "y": 20 + "y": 26 }, - "id": 18, + "id": 6, "options": { "legend": { "calcs": [], @@ -993,21 +1533,27 @@ "sort": "none" } }, + "pluginVersion": "11.2.0", "targets": [ { "datasource": { "type": "prometheus", "uid": "P18F45E9DC7E75912" }, - "editorMode": "code", - "expr": "rate(flask_http_request_duration_seconds_count{status=~\"200|201|202\",path!=\"/health\"}[$__rate_interval])", + "disableTextWrap": false, + "editorMode": "builder", + "expr": "process_cpu_usage", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, "instant": false, - "legendFormat": "{{method}} {{instance}} {{path}} ({{status}})", + "legendFormat": "{{instance}}", "range": true, - "refId": "A" + "refId": "process_cpu_usage", + "useBackend": false } ], - "title": "Successful API Requests", + "title": "CPU Usage", "type": "timeseries" }, { @@ -1027,7 +1573,6 @@ "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, - "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 25, "gradientMode": "none", @@ -1102,7 +1647,7 @@ "h": 7, "w": 12, "x": 12, - "y": 20 + "y": 30 }, "id": 19, "options": { @@ -1136,7 +1681,6 @@ }, { "datasource": { - "default": true, "type": "prometheus", "uid": "P18F45E9DC7E75912" }, @@ -1152,9 +1696,8 @@ "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, - "barWidthFactor": 0.6, "drawStyle": "line", - "fillOpacity": 0, + "fillOpacity": 25, "gradientMode": "none", "hideFrom": { "legend": false, @@ -1162,8 +1705,8 @@ "viz": false }, "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, + "lineInterpolation": "smooth", + "lineWidth": 2, "pointSize": 5, "scaleDistribution": { "type": "linear" @@ -1187,58 +1730,14 @@ "value": null } ] - } + }, + "unit": "reqps" }, "overrides": [ { "matcher": { - "id": "byName", - "options": "DELETE" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "red", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "GET" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "blue", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "HEAD" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "purple", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "PATCH" + "id": "byRegexp", + "options": "/.*search-service.*/" }, "properties": [ { @@ -1252,28 +1751,14 @@ }, { "matcher": { - "id": "byName", - "options": "OPTIONS" - }, - "properties": [ - { - "id": "color", - "value": { - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "POST" + "id": "byRegexp", + "options": "/.*analyse-service.*/" }, "properties": [ { "id": "color", "value": { - "fixedColor": "green", + "fixedColor": "super-light-orange", "mode": "fixed" } } @@ -1285,9 +1770,9 @@ "h": 7, "w": 12, "x": 0, - "y": 27 + "y": 33 }, - "id": 20, + "id": 18, "options": { "legend": { "calcs": [], @@ -1296,7 +1781,7 @@ "showLegend": true }, "tooltip": { - "mode": "single", + "mode": "multi", "sort": "none" } }, @@ -1306,23 +1791,19 @@ "type": "prometheus", "uid": "P18F45E9DC7E75912" }, - "disableTextWrap": false, - "editorMode": "builder", - "expr": "tusd_requests_total", - "fullMetaSearch": false, - "includeNullMetadata": true, + "editorMode": "code", + "expr": "rate(flask_http_request_duration_seconds_count{status=~\"200|201|202\",path!=\"/health\"}[$__rate_interval])", "instant": false, - "legendFormat": "{{method}}", + "legendFormat": "{{method}} {{instance}} {{path}} ({{status}})", "range": true, - "refId": "A", - "useBackend": false + "refId": "A" } ], - "title": "Storage Service Requests", + "title": "Successful API Requests", "type": "timeseries" } ], - "refresh": "10s", + "refresh": "5s", "schemaVersion": 39, "tags": [ "provisioned", @@ -1332,13 +1813,13 @@ "list": [] }, "time": { - "from": "now-1h", + "from": "now-30m", "to": "now" }, "timepicker": {}, "timezone": "browser", - "title": "DBRepo - Overview", - "uid": "bdz20owu8zn5se", + "title": "NEW", + "uid": "bdz20owu8zn5se1", "version": 1, "weekStart": "" } \ No newline at end of file diff --git a/dbrepo-metric-db/prometheus.yml b/dbrepo-metric-db/prometheus.yml index 82986b249082b38e12247ba865cab6a7cd3d440f..e56ba4e7fdf5b0da04e514cccf8023c6bb8c4df7 100644 --- a/dbrepo-metric-db/prometheus.yml +++ b/dbrepo-metric-db/prometheus.yml @@ -12,8 +12,8 @@ scrape_configs: - job_name: 'actuator scrape' metrics_path: '/actuator/prometheus' static_configs: - - targets: ['data-service:8080', 'metadata-service:8080', 'ui:3000'] + - targets: ['data-service:8080', 'metadata-service:8080'] - job_name: 'metrics scrape' metrics_path: '/metrics' static_configs: - - targets: ['auth-service:8080', 'analyse-service:8080', 'search-service:8080', 'data-db-sidecar:8080', 'broker-service:15692', 'storage-service:9090', 'upload-service:8080', 'dashboard-service:3000'] + - targets: ['ui:3000', 'auth-service:8080', 'analyse-service:8080', 'search-service:8080', 'data-db-sidecar:8080', 'broker-service:15692', 'storage-service:9090', 'upload-service:8080', 'dashboard-service:3000'] diff --git a/dbrepo-ui/Dockerfile b/dbrepo-ui/Dockerfile index 07f7f5d903e09c477753bdd0e52042cd61bcf6fb..a73e31674fd8b7b755779bc5aa479855c3e6ffd8 100644 --- a/dbrepo-ui/Dockerfile +++ b/dbrepo-ui/Dockerfile @@ -2,6 +2,7 @@ FROM oven/bun:1.1.20-alpine AS build WORKDIR /app +COPY ./bun.lockb ./bun.lockb COPY ./package.json ./package.json RUN bun install @@ -24,11 +25,13 @@ COPY ./nuxt.config.ts ./nuxt.config.ts RUN bun run build -FROM oven/bun:1.1.20-alpine AS runtime +FROM node:22.9.0-alpine3.20 AS runtime ARG APP_VERSION="latest" ARG COMMIT="" +RUN apk add --no-cache curl bash + USER 1000 WORKDIR /app @@ -39,8 +42,7 @@ RUN chmod -R 755 /app/.output ENV NUXT_PUBLIC_VERSION="${APP_VERSION:-}" ENV NUXT_PUBLIC_COMMIT="${COMMIT:-}" -ENV NODE_OPTIONS="--max_old_space_size=4096" EXPOSE 3000 -ENTRYPOINT [ "bun", "run", ".output/server/index.mjs" ] +ENTRYPOINT [ "node", ".output/server/index.mjs" ] diff --git a/dbrepo-ui/assets/globals.css b/dbrepo-ui/assets/globals.css index 8f791a9edd2b82244332b41587708c3197f1d1b3..52da2e48c8c2e7589ddcbce27fe67520acd74763 100644 --- a/dbrepo-ui/assets/globals.css +++ b/dbrepo-ui/assets/globals.css @@ -1,4 +1,13 @@ a { color: var(--v-theme-primary); } +label.native, +select.native { + display: block; } + +select.native { + -webkit-appearance: listbox; + border-style: solid; + width: 100%; } + /*# sourceMappingURL=globals.css.map */ diff --git a/dbrepo-ui/assets/globals.css.map b/dbrepo-ui/assets/globals.css.map index b9c0623a76d6530341406b9f715d4dea45c77046..6f271c8f99f4295e8438524dea16b6a48b253635 100644 --- a/dbrepo-ui/assets/globals.css.map +++ b/dbrepo-ui/assets/globals.css.map @@ -1,6 +1,6 @@ { "version": 3, -"mappings": "AAAA,CAAE;EACA,KAAK,EAAE,sBAAsB", +"mappings": "AAAA,CAAE;EACA,KAAK,EAAE,sBAAsB;;AAG/B;aACc;EACZ,OAAO,EAAE,KAAK;;AAGhB,aAAc;EACZ,kBAAkB,EAAE,OAAO;EAC3B,YAAY,EAAE,KAAK;EACnB,KAAK,EAAE,IAAI", "sources": ["globals.scss"], "names": [], "file": "globals.css" diff --git a/dbrepo-ui/assets/globals.scss b/dbrepo-ui/assets/globals.scss index 6b6b26ac202cdfae8c6783d7a8f5c31116e98697..5d4d4e06a7cdcde8e801cccd14c0eb2f07c0824d 100644 --- a/dbrepo-ui/assets/globals.scss +++ b/dbrepo-ui/assets/globals.scss @@ -1,3 +1,14 @@ a { color: var(--v-theme-primary); } + +label.native, +select.native { + display: block; +} + +select.native { + -webkit-appearance: listbox; + border-style: solid; + width: 100%; +} diff --git a/dbrepo-ui/bun.lockb b/dbrepo-ui/bun.lockb index d4a0ef58602cbb7a069d13bc894340f4b0d72465..32e73e364f9bd9e573f92d3f4a72d9596cb21363 100755 Binary files a/dbrepo-ui/bun.lockb and b/dbrepo-ui/bun.lockb differ diff --git a/dbrepo-ui/components/OntologiesList.vue b/dbrepo-ui/components/OntologiesList.vue index c3ffd3994541bf29dfa7c3f091d6089760624f86..44f0eddc3f4c8b3542cd1b7f237cac05603c6375 100644 --- a/dbrepo-ui/components/OntologiesList.vue +++ b/dbrepo-ui/components/OntologiesList.vue @@ -8,10 +8,12 @@ rounded="0"> <v-divider class="mx-4" /> - <v-card-title - v-text="ontology.prefix" /> - <v-card-subtitle - v-text="ontology.uri" /> + <v-card-title> + {{ ontology.prefix }} + </v-card-title> + <v-card-subtitle> + {{ ontology.uri }} + </v-card-subtitle> <v-card-text> <div class="db-tags"> diff --git a/dbrepo-ui/components/container/ContainerCard.vue b/dbrepo-ui/components/container/ContainerCard.vue index b2937cf6b4fb7f1a243056ea52ccd4649e205772..ed1479f64d3ad8043968e03edbfcd940190e3fb6 100644 --- a/dbrepo-ui/components/container/ContainerCard.vue +++ b/dbrepo-ui/components/container/ContainerCard.vue @@ -4,9 +4,12 @@ variant="flat" rounded="0"> <v-divider class="mx-4" /> - <v-card-title - v-text="container.name" /> - <v-card-subtitle v-text="$t('pages.container.subtitle.text')" /> + <v-card-title> + {{ container.name }} + </v-card-title> + <v-card-subtitle> + {{ $t('pages.container.subtitle.text') }} + </v-card-subtitle> <v-card-text> <v-progress-linear v-model="utilization" diff --git a/dbrepo-ui/components/database/DatabaseCard.vue b/dbrepo-ui/components/database/DatabaseCard.vue index 48aefa7493ce5beb52d8ec62cf794d64368b8489..fba3853a31cf25649f915d4c0a3e422f5ec879bf 100644 --- a/dbrepo-ui/components/database/DatabaseCard.vue +++ b/dbrepo-ui/components/database/DatabaseCard.vue @@ -9,8 +9,9 @@ <v-divider class="mx-4" /> <v-card-title> <span - class="text-primary text-decoration-underline" - v-text="formatTitle(database)" /> + class="text-primary text-decoration-underline"> + {{ formatTitle(database) }} + </span> <v-progress-circular v-if="loading" color="primary" @@ -18,56 +19,66 @@ class="ml-1" indeterminate /> </v-card-title> - <v-card-subtitle - v-text="formatCreators(database)" /> + <v-card-subtitle> + {{ formatCreators(database) }} + </v-card-subtitle> <v-card-text> - <div v-text="identifierDescription(database)" /> + <div> + {{ identifierDescription(database) }} + </div> <div class="mt-2 db-tags"> <v-chip v-if="database.is_public" size="small" color="success" - :text="$t('toolbars.database.public')" - variant="outlined" /> + variant="outlined"> + {{ $t('toolbars.database.public') }} + </v-chip> <v-chip v-if="!database.is_public" size="small" :color="colorVariant" variant="outlined" - :text="$t('toolbars.database.private')" - flat /> + flat> + {{ $t('toolbars.database.private') }} + </v-chip> <v-chip v-if="identifierYear(database)" size="small" :color="colorVariant" - variant="outlined" - v-text="identifierYear(database)" /> + variant="outlined"> + {{ identifierYear(database) }} + </v-chip> <v-chip v-if="identifier(database)" size="small" :color="colorVariant" - variant="outlined" - v-text="identifierPublisher(database)" /> + variant="outlined"> + {{ identifierPublisher(database) }} + </v-chip> <v-chip v-for="(license, i) in identifierLicenses(database)" :key="`l-${i}`" size="small" color="success" - variant="outlined" - v-text="license.identifier" /> + variant="outlined"> + {{ license.identifier }} + </v-chip> <v-chip v-for="(funder, i) in identifierFunders(database)" :key="`f-${i}`" size="small" :color="colorVariant" - variant="outlined" - v-text="funder.funder_name" /> + variant="outlined"> + {{ funder.funder_name }} + </v-chip> <v-chip v-if="identifierLanguage(database)" size="small" :color="colorVariant" - variant="outlined" - v-text="identifierLanguage(database)" /> + variant="outlined"> + {{ identifierLanguage(database) }} + </v-chip> </div> </v-card-text> </v-card> diff --git a/dbrepo-ui/components/database/DatabaseCreate.vue b/dbrepo-ui/components/database/DatabaseCreate.vue index 8d909b4da350c1cbc10dfad7d595799aa3adee4e..5da87cebbda9731ae842636654a40ce6fdea14a8 100644 --- a/dbrepo-ui/components/database/DatabaseCreate.vue +++ b/dbrepo-ui/components/database/DatabaseCreate.vue @@ -6,9 +6,13 @@ autocomplete="off" @submit.prevent="submit"> <v-card - variant="elevated" - :title="$t('pages.database.subpages.create.title')" - :subtitle="$t('pages.database.subpages.create.subtitle')"> + variant="elevated"> + <v-card-title> + {{ $t('pages.database.subpages.create.title') }} + </v-card-title> + <v-card-subtitle> + {{ $t('pages.database.subpages.create.subtitle') }} + </v-card-subtitle> <v-card-text> <v-row dense> <v-col> @@ -58,16 +62,18 @@ <v-spacer /> <v-btn :variant="buttonVariant" - :text="$t('navigation.cancel')" - @click="cancel" /> + @click="cancel"> + {{ $t('navigation.cancel') }} + </v-btn> <v-btn :disabled="!valid || loading" color="primary" type="submit" variant="flat" - :text="$t('pages.database.subpages.create.submit.text')" :loading="loading" - @click="create" /> + @click="create"> + {{ $t('pages.database.subpages.create.submit.text') }} + </v-btn> </v-card-actions> </v-card> </v-form> diff --git a/dbrepo-ui/components/database/DatabaseToolbar.vue b/dbrepo-ui/components/database/DatabaseToolbar.vue index 741252475c31ef841260266d3d4fcb459b35cd64..5f3c8c83989bd20fa67f6f327fdc9676767acbb4 100644 --- a/dbrepo-ui/components/database/DatabaseToolbar.vue +++ b/dbrepo-ui/components/database/DatabaseToolbar.vue @@ -8,8 +8,9 @@ type="subtitle" width="200" /> <span - v-if="database && $vuetify.display.lgAndUp" - v-text="database.name" /> + v-if="database && $vuetify.display.lgAndUp"> + {{ database.name }} + </span> <v-chip v-if="database && database.is_public" size="small" diff --git a/dbrepo-ui/components/dialogs/DropTable.vue b/dbrepo-ui/components/dialogs/DropTable.vue index 1f62735de5e6ce549386894f525074f53d5cdd5a..d465c882d0529a817be21f836ea82739fc30155b 100644 --- a/dbrepo-ui/components/dialogs/DropTable.vue +++ b/dbrepo-ui/components/dialogs/DropTable.vue @@ -7,9 +7,13 @@ <v-card-text> <v-row dense> <v-col> - <span v-text="$t('pages.table.subpages.drop.warning.prefix')" /> + <span> + {{ $t('pages.table.subpages.drop.warning.prefix') }} + </span> <code class="code-key">{{ table.internal_name }}</code> - <span v-text="$t('pages.table.subpages.drop.warning.suffix')" /> + <span> + {{ $t('pages.table.subpages.drop.warning.suffix') }} + </span> </v-col> </v-row> <v-row> diff --git a/dbrepo-ui/components/dialogs/Semantics.vue b/dbrepo-ui/components/dialogs/Semantics.vue index a4a7104788ce1e12460ad693ac543058b60cdf6c..8d3c573f7b205368fd354372a9e166f2ee81a14f 100644 --- a/dbrepo-ui/components/dialogs/Semantics.vue +++ b/dbrepo-ui/components/dialogs/Semantics.vue @@ -12,14 +12,21 @@ <v-alert border="start" color="info"> - <p - v-text="$t('pages.table.subpages.semantics.info')" /> + <p> + {{ $t('pages.table.subpages.semantics.info') }} + </p> <p class="mt-1" v-for="(ontology, idx) in ontologies" :key="`o-${idx}`"> - <v-badge inline :content="badge(ontology).text" :color="badge(ontology).color"> - <a :href="ontology.uri" v-text="ontology.uri_pattern" /> + <v-badge + inline + :content="badge(ontology).text" + :color="badge(ontology).color"> + <a + :href="ontology.uri"> + {{ ontology.uri_pattern }} + </a> </v-badge> </p> </v-alert> @@ -34,11 +41,13 @@ color="info"> <p> <a - :href="entity.uri" - v-text="entity.name ? entity.name : entity.uri" /> + :href="entity.uri"> + {{ entity.name ? entity.name : entity.uri }} + </a> + </p> + <p> + {{ entity.description }} </p> - <p - v-text="entity.description" /> </v-alert> </v-col> </v-row> @@ -65,8 +74,9 @@ lines="one" v-model="recommendation" select-strategy="single-independent"> - <v-list-subheader - v-text="$t('pages.table.subpages.semantics.recommended')" /> + <v-list-subheader> + {{ $t('pages.table.subpages.semantics.recommended') }} + </v-list-subheader> <v-list-item v-for="(item, idx) in recommendations" :key="`r-${idx}`" @@ -77,8 +87,12 @@ <v-checkbox-btn :model-value="isActive"></v-checkbox-btn> </v-list-item-action> </template> - <v-list-item-title v-text="item.label" /> - <v-list-item-subtitle v-text="subtitle(item)" /> + <v-list-item-title> + {{ item.label }} + </v-list-item-title> + <v-list-item-subtitle> + {{ subtitle(item) }} + </v-list-item-subtitle> </v-list-item> </v-list> </v-col> diff --git a/dbrepo-ui/components/dialogs/ViewSemanticEntity.vue b/dbrepo-ui/components/dialogs/ViewSemanticEntity.vue index ede7fe25bcd421c0304f41d224be7615598a9251..41b69f89892e3068a781e5cac0ffafee767c473a 100644 --- a/dbrepo-ui/components/dialogs/ViewSemanticEntity.vue +++ b/dbrepo-ui/components/dialogs/ViewSemanticEntity.vue @@ -1,17 +1,32 @@ <template> <div> <v-card> - <v-card-title v-text="entity.name" /> + <v-card-title> + {{ entity.name }} + </v-card-title> <v-card-subtitle> - <a :href="entity.uri" target="_blank" v-text="entity.uri" /> + <a + :href="entity.uri" + target="_blank"> + {{ entity.uri }} + </a> </v-card-subtitle> <v-card-text> - <p v-text="description" /> + <p> + {{ description }} + </p> </v-card-text> - <div v-for="(item,idx) in entity.columns" :key="idx"> + <div + v-for="(item,idx) in entity.columns" + :key="idx"> <v-list-item two-line :to="link(item)"> - <v-list-item-title v-text="item.name" /> - <v-list-item-subtitle class="mt-2" v-text="link(item)" /> + <v-list-item-title> + {{ item.name }} + </v-list-item-title> + <v-list-item-subtitle + class="mt-2"> + {{ link(item) }} + </v-list-item-subtitle> </v-list-item> </div> <v-card-actions> diff --git a/dbrepo-ui/components/identifier/Citation.vue b/dbrepo-ui/components/identifier/Citation.vue index 6f35ac915e255610965015ccd16adcf1dad03597..7cd99194b099987f3853fde4afd7bf92f463dd38 100644 --- a/dbrepo-ui/components/identifier/Citation.vue +++ b/dbrepo-ui/components/identifier/Citation.vue @@ -1,7 +1,10 @@ <template> - <v-row no-gutters> - <v-col v-if="!loading" md="10"> - <pre v-text="citation" /> + <v-row + no-gutters> + <v-col + v-if="!loading" + md="10"> + <pre>{{ citation }}</pre> </v-col> <v-col v-if="!$vuetify.display.mdAndDown" diff --git a/dbrepo-ui/components/identifier/Creators.vue b/dbrepo-ui/components/identifier/Creators.vue index 706736b21b155f5dc0265b0993f23b435bd5c345..8aa5fac7aa7f06ca809179a3903a5e23830504e4 100644 --- a/dbrepo-ui/components/identifier/Creators.vue +++ b/dbrepo-ui/components/identifier/Creators.vue @@ -16,12 +16,14 @@ v-if="hasRor(personOrOrg)" class="mr-1" :ror="personOrOrg.name_identifier" /> - <span - v-text="personOrOrg.creator_name" /> + <span> + {{ personOrOrg.creator_name }} + </span> <sup v-if="hasAffiliation(personOrOrg)" - v-text="personOrOrg.affiliation_index" - class="ml-1" /> + class="ml-1"> + {{ personOrOrg.affiliation_index }} + </sup> <span v-if="!isLast(creators, i)">; </span> </span> @@ -30,7 +32,9 @@ <span v-for="(affiliation, i) in affiliations" :key="`c-${i}`"> - <sup v-text="i+1" /> + <sup> + {{ i+1 }} + </sup> {{ affiliation.name }} <RorIcon v-if="hasRor(affiliation)" diff --git a/dbrepo-ui/components/identifier/Persist.vue b/dbrepo-ui/components/identifier/Persist.vue index 0de61931265d5359c07637d935aa9101a1ebca6a..1795d058660ff08288b9054435e44362d84cf0e7 100644 --- a/dbrepo-ui/components/identifier/Persist.vue +++ b/dbrepo-ui/components/identifier/Persist.vue @@ -589,14 +589,20 @@ v-if="identifier.licenses.length > 0" color="tertiary"> <p> - <a :href="identifier.licenses[0].uri" target="_blank"> - <strong v-text="identifier.licenses[0].identifier" /> <sup><v-icon x-small>mdi-open-in-new</v-icon></sup> + <a + :href="identifier.licenses[0].uri" + target="_blank"> + <strong> + {{ identifier.licenses[0].identifier }} + </strong> + <sup><v-icon x-small>mdi-open-in-new</v-icon></sup> </a> </p> <p v-if="identifier.licenses[0].description" - class="mt-2" - v-text="identifier.licenses[0].description" /> + class="mt-2"> + {{ identifier.licenses[0].description }} + </p> </v-alert> </v-card-text> <v-card-text> @@ -755,7 +761,7 @@ <v-list-item> <v-list-item-title> {{ $t('pages.identifier.subpages.create.summary.record') }} {{ resourceHumanDescription.prefix }} - "<strong v-text="resourceHumanDescription.info" />" + "<strong>{{ resourceHumanDescription.info }}</strong>" </v-list-item-title> <template v-slot:prepend> <v-icon @@ -775,7 +781,7 @@ <v-list-item-title v-if="identifier.licenses.length > 0"> {{ $t('pages.identifier.subpages.create.summary.license') }} - "<strong v-text="identifier.licenses[0].identifier" />" + "<strong>{{ identifier.licenses[0].identifier }}</strong>" </v-list-item-title> <v-list-item-title v-else> @@ -791,7 +797,7 @@ v-if="identifier.publisher"> <v-list-item-title> {{ $t('pages.identifier.subpages.create.summary.publisher') }} - "<strong v-text="identifier.publisher" />" + "<strong>{{ identifier.publisher }}</strong>" </v-list-item-title> <template v-slot:prepend> <v-icon diff --git a/dbrepo-ui/components/identifier/Summary.vue b/dbrepo-ui/components/identifier/Summary.vue index f4a5f7c880fc9618093ca82726159e598c16d998..267693276c18cde26769f387ddc2f3f34ec97689 100644 --- a/dbrepo-ui/components/identifier/Summary.vue +++ b/dbrepo-ui/components/identifier/Summary.vue @@ -18,7 +18,9 @@ <p v-for="(title, i) in identifier.titles" :key="`t-${i}`"> - <span v-text="title.title" /> + <span> + {{ title.title }} + </span> </p> </v-list-item> <v-list-item @@ -28,32 +30,42 @@ v-for="(description, i) in identifier.descriptions" :key="`d-${i}`"> <div - v-text="description?.type" - class="text-subtitle-2" /> - <span v-text="description.description" /> + class="text-subtitle-2"> + {{ description?.type }} + </div> + <span> + {{ description.description }} + </span> </p> </v-list-item> <v-list-item :title="$t('pages.identifier.publisher.title')" density="compact"> - <div v-text="identifier.publisher" /> + <div> + {{ identifier.publisher }} + </div> </v-list-item> <v-list-item :title="$t('pages.identifier.creators.title')" density="compact"> - <Creators :person-or-orgs="identifier.creators" /> + <Creators + :person-or-orgs="identifier.creators" /> </v-list-item> <v-list-item v-if="identifierLang" :title="$t('pages.identifier.language.title')" density="compact"> - <div v-text="identifierLang" /> + <div> + {{ identifierLang }} + </div> </v-list-item> <v-list-item v-if="publication" :title="$t('pages.identifier.publication-date.title')" density="compact"> - <div v-text="publication" /> + <div> + {{ publication }} + </div> </v-list-item> <v-list-item v-if="identifier.related_identifiers && identifier.related_identifiers.length > 0" @@ -75,16 +87,19 @@ :key="`f-${i}`"> <a v-if="funder.funder_identifier" - v-text="funder.funder_name" - :href="funder.funder_identifier" /> + :href="funder.funder_identifier"> + {{ funder.funder_name }} + </a> <span v-if="funder.award_title" - class="ml-1" - v-text="funder.award_title" /> + class="ml-1"> + {{ funder.award_title }} + </span> <span v-if="funder.award_number" - class="ml-1" - v-text="`(${funder.award_number})`" /> + class="ml-1"> + ({{ funder.award_number }}) + </span> </p> </v-list-item> <v-list-item @@ -95,11 +110,14 @@ v-for="(license, i) in identifier.licenses" :key="`l-${i}`"> <span> - <span v-text="i > 0 ? ', ' : ''" /> + <span> + {{ i > 0 ? ', ' : '' }} + </span> <a v-if="license" - v-text="license.identifier" - :href="license.uri" /> + :href="license.uri"> + {{ license.identifier }} + </a> </span> </p> </v-list-item> diff --git a/dbrepo-ui/components/search/AdvancedSearch.vue b/dbrepo-ui/components/search/AdvancedSearch.vue index 17a2839c64ce4b7584591c64e1be8f00715d7f28..13de402e019f2a791f0233c4fc611164e46e20d8 100644 --- a/dbrepo-ui/components/search/AdvancedSearch.vue +++ b/dbrepo-ui/components/search/AdvancedSearch.vue @@ -110,7 +110,9 @@ v-if="isEligibleYearRangeSearch" dense> <v-col> - <p v-text="$t('pages.search.publication-range.hint')" /> + <p> + {{ $t('pages.search.publication-range.hint') }} + </p> </v-col> </v-row> <v-row @@ -125,7 +127,9 @@ :hint="$t('pages.search.start-year.hint')" :variant="inputVariant" required - :rules="[v => !!v || $t('validation.required')]" + :rules="[ + v => !!v || $t('validation.required') + ]" clearable /> </v-col> <v-col cols="3"> @@ -144,12 +148,17 @@ <v-col> <p v-if="isEligibleUnitIndependentSearch" - v-text="$t('pages.search.concept-unit.hint')" - class="mt-4" /> + class="mt-4"> + {{ $t('pages.search.concept-unit.hint') }} + </p> </v-col> </v-row> - <v-row v-if="isEligibleConceptOrUnitSearch || isEligibleUnitIndependentSearch" dense> - <v-col v-if="isEligibleConceptOrUnitSearch || isEligibleUnitIndependentSearch" cols="3"> + <v-row + v-if="isEligibleConceptOrUnitSearch || isEligibleUnitIndependentSearch" + dense> + <v-col + v-if="isEligibleConceptOrUnitSearch || isEligibleUnitIndependentSearch" + cols="3"> <v-select v-model="advancedSearchData['tables.columns.concept.uri']" clearable @@ -162,7 +171,9 @@ :label="$t('pages.search.concept.label')" :hint="$t('pages.search.concept.hint')" /> </v-col> - <v-col v-if="isEligibleConceptOrUnitSearch || isEligibleUnitIndependentSearch" cols="3"> + <v-col + v-if="isEligibleConceptOrUnitSearch || isEligibleUnitIndependentSearch" + cols="3"> <v-select v-model="advancedSearchData['tables.columns.unit.uri']" clearable @@ -175,7 +186,9 @@ :label="$t('pages.search.unit.label')" :hint="$t('pages.search.unit.hint')" /> </v-col> - <v-col v-if="isEligibleUnitIndependentSearch" cols="3"> + <v-col + v-if="isEligibleUnitIndependentSearch" + cols="3"> <v-text-field v-model="advancedSearchData['t1']" clearable @@ -185,7 +198,9 @@ :label="$t('pages.search.start.label')" :hint="$t('pages.search.start.hint')" /> </v-col> - <v-col v-if="isEligibleUnitIndependentSearch" cols="3"> + <v-col + v-if="isEligibleUnitIndependentSearch" + cols="3"> <v-text-field v-model="advancedSearchData['t2']" clearable @@ -196,7 +211,8 @@ :hint="$t('pages.search.end.hint')" /> </v-col> </v-row> - <v-row dense> + <v-row + dense> <v-col> <v-btn type="submit" @@ -205,8 +221,9 @@ :loading="loading" :disabled="!valid || loading || loadingFields" size="small" - :text="$t('navigation.search')" - @click="advancedSearch" /> + @click="advancedSearch"> + {{ $t('navigation.search') }} + </v-btn> </v-col> </v-row> </v-form> diff --git a/dbrepo-ui/components/subset/Builder.vue b/dbrepo-ui/components/subset/Builder.vue index 9ae991620375976dd3c53eee4b5756c35734ad4e..d19ec1598fb39cf0e9a02d4b6aafcf6d722b99c7 100644 --- a/dbrepo-ui/components/subset/Builder.vue +++ b/dbrepo-ui/components/subset/Builder.vue @@ -194,7 +194,7 @@ <v-col md="8" class="text-center"> - <pre v-text="clause.type.toUpperCase()" /> + <pre>{{ clause.type.toUpperCase() }}</pre> </v-col> </v-row> <div @@ -233,13 +233,17 @@ <v-alert border="start" color="warning"> - <span v-text="$t('pages.subset.subpages.create.expert.warn')" /> - <pre style="white-space:inherit;" v-text="unsupported.join(', ')" /> + <span> + {{ $t('pages.subset.subpages.create.expert.warn') }} + </span> + <pre style="white-space:inherit;">{{ unsupported.join(', ') }}</pre> </v-alert> </v-col> </v-row> <v-row dense> - <v-col v-text="$t('pages.subset.subpages.create.subtitle')" /> + <v-col> + {{ $t('pages.subset.subpages.create.subtitle') }} + </v-col> </v-row> <v-row dense> <v-col> diff --git a/dbrepo-ui/components/table/BlobDownload.vue b/dbrepo-ui/components/table/BlobDownload.vue index 6ae215e95bf782447f0b0261b470af531a378083..7a96b5e27ba1c738da29770c0b667c3f558d3d9d 100644 --- a/dbrepo-ui/components/table/BlobDownload.vue +++ b/dbrepo-ui/components/table/BlobDownload.vue @@ -1,6 +1,6 @@ <template> <div> - <pre v-text="description" /> + <pre>{{ description }}</pre> </div> </template> diff --git a/dbrepo-ui/components/table/TableImport.vue b/dbrepo-ui/components/table/TableImport.vue index a4c55404dc32d3bcdd6f3d249a3c3b2fc5db5a8f..84c1011c9b24842c7bb1ed563919af61f6211833 100644 --- a/dbrepo-ui/components/table/TableImport.vue +++ b/dbrepo-ui/components/table/TableImport.vue @@ -99,8 +99,9 @@ v-if="$route.query.location" dense> <v-col> - <p - v-text="$t('pages.table.subpages.import.storage.text')" /> + <p> + {{ $t('pages.table.subpages.import.storage.text') }} + </p> <v-chip prepend-icon="mdi-cloud-upload" label> @@ -122,9 +123,13 @@ border="start" color="warning"> {{ $t('pages.table.subpages.import.separator.warn.prefix') }} - <strong v-text="tableImport.separator"/> + <strong> + {{ tableImport.separator }} + </strong> {{ $t('pages.table.subpages.import.separator.warn.middle') }} - <strong v-text="suggestedAnalyseSeparator"/> + <strong> + {{ suggestedAnalyseSeparator }} + </strong> {{ $t('pages.table.subpages.import.separator.warn.suffix') }} </v-alert> </v-col> @@ -236,7 +241,9 @@ <v-alert border="start" color="success"> - <span v-text="$t(`pages.table.subpages.import.summary.text`)"/> + <span> + {{ $t(`pages.table.subpages.import.summary.text`)}} + </span> </v-alert> </v-col> </v-row> diff --git a/dbrepo-ui/components/table/TableToolbar.vue b/dbrepo-ui/components/table/TableToolbar.vue index ef95ad1bd2eee6406925a956a3dda14950070a7d..4c1c86fba656fb0d87f87fac7690c98289a26c9e 100644 --- a/dbrepo-ui/components/table/TableToolbar.vue +++ b/dbrepo-ui/components/table/TableToolbar.vue @@ -12,8 +12,9 @@ type="subtitle" width="200" /> <span - v-if="table && $vuetify.display.lgAndUp" - v-text="table.name" /> + v-if="table && $vuetify.display.lgAndUp"> + {{ table.name}} + </span> </v-toolbar-title> <v-spacer /> <v-btn diff --git a/dbrepo-ui/components/user/UserBadge.vue b/dbrepo-ui/components/user/UserBadge.vue index 65945725e4954a99cda99696626d0a6d947edfd7..71da03d9290ba16928411adda02f3f9eb99aec16 100644 --- a/dbrepo-ui/components/user/UserBadge.vue +++ b/dbrepo-ui/components/user/UserBadge.vue @@ -8,9 +8,14 @@ <v-badge inline content="you" - color="code">{{ creatorName }}</v-badge> + color="code"> + {{ creatorName }} + </v-badge> + </span> + <span + v-else> + {{ creatorName }} </span> - <span v-else v-text="creatorName" /> </p> </template> diff --git a/dbrepo-ui/layouts/default.vue b/dbrepo-ui/layouts/default.vue index fef6700c4f95024619ae0563533a9a42fd3425a7..51b936816299f1565b2517fb0b8daeb01fa5af2f 100644 --- a/dbrepo-ui/layouts/default.vue +++ b/dbrepo-ui/layouts/default.vue @@ -17,8 +17,9 @@ <v-list-item class="mt-2"> <v-list-item-title - class="text-h6" - v-text="title" /> + class="text-h6"> + {{ title }} + </v-list-item-title> </v-list-item> <v-list nav> <v-list-item @@ -49,7 +50,7 @@ border="start" tile :type="message.type"> - {{ message.message }}<span v-if="message.link"> — <a :href="message.link" v-text="message.link_text ? message.link_text : message.link" /></span> + {{ message.message }}<span v-if="message.link"> — <a :href="message.link">{{ message.link_text ? message.link_text : message.link }}</a></span> </v-alert> <div class="d-flex pa-2"> <v-spacer /> diff --git a/dbrepo-ui/nuxt.config.ts b/dbrepo-ui/nuxt.config.ts index f07d9aa0dd42dbfa330c65f36ae361c859a2d3c4..a0fa7f34eaf74276d3211dd6ddcf12ddf98f457b 100644 --- a/dbrepo-ui/nuxt.config.ts +++ b/dbrepo-ui/nuxt.config.ts @@ -1,6 +1,6 @@ -import { transformAssetUrls } from 'vite-plugin-vuetify' +import {transformAssetUrls} from 'vite-plugin-vuetify' -const proxy : any = {} +const proxy: any = {} /* proxies the backend calls, >>NOT<< the frontend calls (clicking) */ if (process.env.NODE_ENV === 'development') { @@ -19,154 +19,156 @@ if (process.env.NODE_ENV === 'development') { /** * https://nuxt.com/docs/guide/concepts/rendering#hybrid-rendering */ -const routeRules = { -} +const routeRules = {} export default defineNuxtConfig({ - app: { - head: { - charset: 'utf-8', - viewport: 'width=device-width, initial-scale=1', - meta: [ - { 'http-equiv': 'Content-Security-Policy', content: 'upgrade-insecure-requests' } - ], - htmlAttrs: { - lang: 'en-US' - } - } - }, - - build: { - transpile: ['vuetify'], - }, - - css: [ - 'vuetify/lib/styles/main.sass', - '@mdi/font/css/materialdesignicons.min.css', - '@/assets/globals.css', - '@/assets/overrides.css', - ], - - runtimeConfig: { - public: { - commit: '', - title: 'Database Repository', - logo: '/logo.svg', - icon: '/favicon.ico', - touch: '/apple-touch-icon.png', - version: 'bun-dev', - broker: { - host: 'localhost', - port: { - '5672': false - }, - extra: '' - }, - variant: { - input: { - normal: 'underlined', - contrast: 'outlined', - }, - button: { - normal: 'flat', - contrast: 'outlined', - }, - list: { - normal: '', - contrast: 'flat', - } - }, - api: { - client: 'http://localhost', - server: 'http://gateway-service', - }, - upload: { - client: 'http://localhost/api/upload/files', - prefix: '/' - }, - database: { - unsupported: '*,AVG,BIT_AND,BIT_OR,BIT_XOR,COUNT,COUNTDISTINCT,GROUP_CONCAT,JSON_ARRAYAGG,JSON_OBJECTAGG,MAX,MIN,STD,STDDEV,STDDEV_POP,STDDEV_SAMP,SUM,VARIANCE,VAR_POP,VAR_SAMP,--', - image: { - width: 200, - height: 200 - }, - extra: '' - }, - pid: { - default: { - publisher: 'Example University' - } - }, - doi: { - enabled: false, - endpoint: 'https://doi.org' - }, - links: { - keycloak: { - text: 'Auth Service', - href: '/api/auth/' - }, - grafana: { - text: 'Dashboard Service', - href: '/dashboard/' - } - } - } - }, - - routeRules, - - devServer: { - port: 3001 - }, - - modules: [ - '@pinia/nuxt', - '@pinia-plugin-persistedstate/nuxt', - '@nuxtjs/i18n' - ], - - pinia: { - storesDirs: ['./stores/**'], - }, - - piniaPersistedstate: { - storage: 'localStorage' - }, - - i18n: { - lazy: false, - langDir: 'locales', - strategy: 'no_prefix', - defaultLocale: 'de', - locales: [ - { - 'code': 'en', - 'file': 'en-US.json', - 'name': 'English (US)', - 'iso': 'en-US' - }, - { - 'code': 'de', - 'file': 'de-AT.json', - 'name': 'German (AT)', - 'iso': 'de-AT' - } - ] - - }, - - vite: { - server: { - proxy - }, - vue: { - template: { - transformAssetUrls, - }, - }, - }, - - devtools: { enabled: true }, - compatibilityDate: '2024-07-24' + app: { + head: { + charset: 'utf-8', + viewport: 'width=device-width, initial-scale=1', + meta: [ + {'http-equiv': 'Content-Security-Policy', content: 'upgrade-insecure-requests'} + ], + htmlAttrs: { + lang: 'en-US' + } + } + }, + + build: { + transpile: ['vuetify'], + }, + + builder: 'vite', + + css: [ + 'vuetify/lib/styles/main.sass', + '@mdi/font/css/materialdesignicons.min.css', + '@/assets/globals.css', + '@/assets/overrides.css', + ], + + runtimeConfig: { + public: { + commit: '', + title: 'Database Repository', + logo: '/logo.svg', + icon: '/favicon.ico', + touch: '/apple-touch-icon.png', + version: 'bun-dev', + broker: { + host: 'localhost', + port: { + '5672': false + }, + extra: '' + }, + variant: { + input: { + normal: 'underlined', + contrast: 'outlined', + }, + button: { + normal: 'flat', + contrast: 'outlined', + }, + list: { + normal: '', + contrast: 'flat', + } + }, + api: { + client: 'http://localhost', + server: 'http://gateway-service', + }, + upload: { + client: 'http://localhost/api/upload/files', + prefix: '/' + }, + database: { + unsupported: '*,AVG,BIT_AND,BIT_OR,BIT_XOR,COUNT,COUNTDISTINCT,GROUP_CONCAT,JSON_ARRAYAGG,JSON_OBJECTAGG,MAX,MIN,STD,STDDEV,STDDEV_POP,STDDEV_SAMP,SUM,VARIANCE,VAR_POP,VAR_SAMP,--', + image: { + width: 200, + height: 200 + }, + extra: '' + }, + pid: { + default: { + publisher: 'Example University' + } + }, + doi: { + enabled: false, + endpoint: 'https://doi.org' + }, + links: { + keycloak: { + text: 'Auth Service', + href: '/api/auth/' + }, + grafana: { + text: 'Dashboard Service', + href: '/dashboard/' + } + } + } + }, + + routeRules, + + devServer: { + port: 3001 + }, + + modules: [ + '@artmizu/nuxt-prometheus', + '@nuxtjs/i18n', + '@pinia/nuxt', + '@pinia-plugin-persistedstate/nuxt' + ], + + pinia: { + storesDirs: ['./stores/**'], + }, + + piniaPersistedstate: { + storage: 'localStorage' + }, + + i18n: { + lazy: false, + langDir: 'locales', + strategy: 'no_prefix', + defaultLocale: 'de', + locales: [ + { + 'code': 'en', + 'file': 'en-US.json', + 'name': 'English (US)', + 'iso': 'en-US' + }, + { + 'code': 'de', + 'file': 'de-AT.json', + 'name': 'German (AT)', + 'iso': 'de-AT' + } + ] + + }, + + vite: { + server: { + proxy + }, + vue: { + template: { + transformAssetUrls, + }, + }, + }, + + devtools: {enabled: true}, + compatibilityDate: '2024-07-24' }) diff --git a/dbrepo-ui/package.json b/dbrepo-ui/package.json index 2bbe6696bc2e59845e4d1d30194a860923f2760d..d521b4e61f91766ca0355ec39dd8ea6496be7cf4 100644 --- a/dbrepo-ui/package.json +++ b/dbrepo-ui/package.json @@ -11,6 +11,7 @@ "prod": "bun run .output/server/index.mjs" }, "dependencies": { + "@artmizu/nuxt-prometheus": "^2.4.0", "@fontsource/open-sans": "^5.0.24", "@mdi/font": "^7.4.47", "@nuxtjs/robots": "^3.0.0", @@ -36,7 +37,7 @@ "vue-meta": "^2.4.0", "vue-toast-notification": "^3.1.2", "vue3-ace-editor": "^2.2.4", - "vuetify": "^3.5.7" + "vuetify": "^3.7.2" }, "devDependencies": { "@nuxtjs/i18n": "^8.1.1", diff --git a/dbrepo-ui/pages/database/[database_id]/info.vue b/dbrepo-ui/pages/database/[database_id]/info.vue index e2b139fe8fd2a2616c7dae56b8383e502bdb95e3..432b14e21a60968048440da6f0084eb535aa06a7 100644 --- a/dbrepo-ui/pages/database/[database_id]/info.vue +++ b/dbrepo-ui/pages/database/[database_id]/info.vue @@ -45,22 +45,30 @@ <v-list-item :title="$t('pages.database.name.title')" density="compact"> - <div v-text="database.name" /> + <div> + {{ database.name }} + </div> </v-list-item> <v-list-item :title="$t('pages.database.internal-name.title')" density="compact"> - <div v-text="database.internal_name" /> + <div> + {{ database.internal_name }} + </div> </v-list-item> <v-list-item :title="$t('pages.database.visibility.title')" density="compact"> - <div v-text="`${database.is_public ? 'Public' : 'Private'}`" /> + <div> + {{ database.is_public ? 'Public' : 'Private' }} + </div> </v-list-item> <v-list-item :title="$t('pages.database.size.title')" density="compact"> - <div v-text="databaseSize" /> + <div> + {{ databaseSize }} + </div> </v-list-item> <v-list-item :title="$t('pages.database.owner.title')" @@ -74,7 +82,9 @@ <v-list-item :title="$t('pages.database.created.title')" density="compact"> - <div v-text="createdUTC" /> + <div> + {{ createdUTC }} + </div> </v-list-item> <v-list-item v-if="access && access.type" @@ -87,9 +97,14 @@ inline :content="databaseExtraInfo" color="secondary"> - <span v-text="accessDescription.text" /> + <span> + {{ accessDescription.text }} + </span> </v-badge> - <span v-else v-text="accessDescription.text" /> + <span + v-else> + {{ accessDescription.text }} + </span> </span> </div> </v-list-item> @@ -97,9 +112,8 @@ v-if="access" :title="$t('pages.database.connection.title')" density="compact"> - <div> - <pre class="pb-1" v-text="jdbcString" /> - </div> + <pre + class="pb-1">{{ jdbcString }}</pre> </v-list-item> <v-list-item v-if="database.contact" @@ -131,29 +145,39 @@ <v-list-item :title="$t('pages.container.name.title')" density="compact"> - <div v-text="container_name" /> + <div> + {{ container_name }} + </div> </v-list-item> <v-list-item :title="$t('pages.container.internal-name.title')" density="compact"> - <div v-text="container_internal_name" /> + <div> + {{ container_internal_name }} + </div> </v-list-item> <v-list-item :title="$t('pages.container.image-name.title')" density="compact"> - <div v-text="image_name" /> + <div> + {{ image_name }} + </div> </v-list-item> <v-list-item :title="$t('pages.container.image-tag.title')" density="compact"> - <div v-text="image_version" /> + <div> + {{ image_version }} + </div> </v-list-item> </v-list> </v-card-text> </v-card> </v-window-item> </v-window> - <v-breadcrumbs :items="items" class="pa-0 mt-2" /> + <v-breadcrumbs + :items="items" + class="pa-0 mt-2" /> </div> </template> diff --git a/dbrepo-ui/pages/database/[database_id]/settings.vue b/dbrepo-ui/pages/database/[database_id]/settings.vue index 1d2d9dca0c873f300ec0a1b3c41795595fd085ee..c205e8c431dc6851d9b9b21c0dc8adc916d9d7f5 100644 --- a/dbrepo-ui/pages/database/[database_id]/settings.vue +++ b/dbrepo-ui/pages/database/[database_id]/settings.vue @@ -89,7 +89,10 @@ :items="database.accesses" :items-per-page="10"> <template v-slot:item.qualified_name="{ item }"> - <span v-if="item && item.user" v-text="item.user.qualified_name" /> + <span + v-if="item && item.user"> + {{ item.user.qualified_name }} + </span> </template> <template v-slot:item.action="{ item }"> <v-btn diff --git a/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/data.vue b/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/data.vue index 4902e2c54f243c7a2e4f3df90f3aa16cf7c26753..b063317e074d69d97c99812a74cdd22a5d3feceb 100644 --- a/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/data.vue +++ b/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/data.vue @@ -11,8 +11,9 @@ color="secondary" width="500" /> <span - v-else - v-text="executionUTC" /> + v-else> + {{ executionUTC }} + </span> </v-toolbar-title> <v-spacer /> <v-btn diff --git a/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/info.vue b/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/info.vue index 1d9101fbf240d8d577026e53361f2cedb8f6486e..01620ea35eebf78969c6353b9ccaa0e7e9fdfb05 100644 --- a/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/info.vue +++ b/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/info.vue @@ -52,7 +52,7 @@ <v-list-item :title="$t('pages.subset.query-hash.title')" density="compact"> - <pre v-text="`${$t('pages.subset.query-hash.prefix')}${subset.query_hash}`" /> + <pre>{{ $t('pages.subset.query-hash.prefix') }}{{ subset.query_hash }}</pre> </v-list-item> <v-list-item v-if="executionUTC" @@ -63,7 +63,7 @@ <v-list-item :title="$t('pages.subset.result-hash.title')" density="compact"> - <pre v-text="result_hash" /> + <pre>{{ result_hash }}</pre> </v-list-item> <v-list-item :title="$t('pages.subset.result-rows.title')" @@ -90,8 +90,9 @@ :title="$t('pages.database.name.title')"> <NuxtLink class="text-primary" - :to="`/database/${database.id}`" - v-text="database.internal_name" /> + :to="`/database/${database.id}`"> + {{ database.internal_name }} + </NuxtLink> </v-list-item> </v-list> </v-card-text> diff --git a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/data.vue b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/data.vue index 72e7501d16625e32d3c05e32072a3a3cb3a719e3..85570c5c363ff0cafda08d389c6f8f055a932ce0 100644 --- a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/data.vue +++ b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/data.vue @@ -60,8 +60,9 @@ <v-card v-if="error" variant="flat"> - <v-card-text - v-text="$t('error.table.connection')" /> + <v-card-text> + {{ $t('error.table.connection') }} + </v-card-text> </v-card> <v-data-table-server v-if="!error" diff --git a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/info.vue b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/info.vue index 08b42c0d936c7e034b67e09edbd07203edde12d7..0221c64df232721f3a81b6bf2641ad37ce6fbf32 100644 --- a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/info.vue +++ b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/info.vue @@ -67,9 +67,14 @@ inline color="secondary" :content="brokerExtraInfo"> - <span v-text="accessDescription" /> + <span> + {{ accessDescription }} + </span> </v-badge> - <span v-else v-text="accessDescription" /> + <span + v-else> + {{ accessDescription}} + </span> </span> </v-list-item> </v-list> @@ -87,7 +92,9 @@ dense> <v-list-item :title="$t('pages.table.protocol.title')"> - <span v-text="$t('pages.table.protocol.name')" /> + <span> + {{ $t('pages.table.protocol.name') }} + </span> </v-list-item> <v-list-item :title="$t('pages.table.exchange.title')"> @@ -100,7 +107,7 @@ <v-list-item :title="$t('pages.table.routing-key.title')"> <div v-if="table.routing_key"> - <pre v-text="table.routing_key" /> + <pre>{{ table.routing_key }}</pre> </div> </v-list-item> <v-list-item @@ -113,8 +120,7 @@ :content="port.secure ? $t('pages.table.connection.secure') : $t('pages.table.connection.insecure')" :color="port.secure ? 'success' : ''"> <pre - class="pb-1" - v-text="amqpString(port)" /> + class="pb-1">{{ amqpString(port) }}</pre> </v-badge> </p> </v-list-item> @@ -137,8 +143,9 @@ :title="$t('pages.database.name.title')"> <NuxtLink class="text-primary" - :to="`/database/${database.id}`" - v-text="database.internal_name" /> + :to="`/database/${database.id}`"> + {{ database.internal_name }} + </NuxtLink> </v-list-item> </v-list> </v-card-text> diff --git a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/schema.vue b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/schema.vue index 7e8aed6717ee9fd22190b56ef6b943f441348974..c9f9882c6cff6bc4b2d91d2857eb3d3b15e37c84 100644 --- a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/schema.vue +++ b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/schema.vue @@ -20,8 +20,10 @@ :items="table.columns"> <template v-slot:item.is_null_allowed="{ item }"> <span - v-if="item.is_null_allowed" - v-text="$t('pages.table.subpages.schema.bullet')" /> {{ item.is_null_allowed }} + v-if="item.is_null_allowed"> + {{ $t('pages.table.subpages.schema.bullet') }} + </span> + {{ item.is_null_allowed }} </template> <template v-slot:item.extra="{ item }"> <pre>{{ extra(item) }}</pre> @@ -47,8 +49,9 @@ @click="pick(item, 'concept')" /> <a v-if="!canAssignSemanticInformation && hasConcept(item)" - :href="item.concept.uri" - v-text="item.concept.name ? item.concept.name : item.concept.uri" /> + :href="item.concept.uri"> + {{ item.concept.name ? item.concept.name : item.concept.uri }} + </a> </template> <template v-slot:item.column_unit="{ item }"> <v-btn @@ -68,8 +71,9 @@ @click="pick(item, 'unit')" /> <a v-if="!canAssignSemanticInformation && hasUnit(item)" - :href="item.unit.uri" - v-text="item.unit.name ? item.unit.name : item.unit.uri" /> + :href="item.unit.uri"> + {{ item.unit.name ? item.unit.name : item.unit.uri }} + </a> </template> </v-data-table> </v-card> @@ -84,18 +88,18 @@ <ul> <li v-if="table.constraints.primary_key.length > 0"> <strong>PRIMARY KEY</strong> - (<i v-text="primaryKeysColumns" />) + (<i>{{ primaryKeysColumns }}</i>) </li> <li v-for="(foreignKey, i) in table.constraints.foreign_keys" :key="`fk-${i}`"> - <strong>FOREIGN KEY</strong> <span v-text="foreignKey.name" /> (<i v-text="foreignKeyColumns(foreignKey)" />) <strong>REFERENCES</strong> <a :href="`/database/${database.id}/table/${foreignKey.referenced_table.id}/schema`" v-text="foreignKeyReferencedTable(foreignKey)" /> (<i v-text="foreignKeyReferencedColumns(foreignKey)" />) + <strong>FOREIGN KEY</strong> <span>{{ foreignKey.name }}</span> (<i>{{ foreignKeyColumns(foreignKey) }}</i>) <strong>REFERENCES</strong> <a :href="`/database/${database.id}/table/${foreignKey.referenced_table.id}/schema`">{{ foreignKeyReferencedTable(foreignKey) }}</a> (<i>{{ foreignKeyReferencedColumns(foreignKey) }}</i>) </li> <li v-for="(uniqueConstraint, i) in table.constraints.uniques" :key="`uk-${i}`"> <strong>UNIQUE INDEX</strong> - (<i v-text="uniqueColumns(uniqueConstraint)" />) + (<i>{{ uniqueColumns(uniqueConstraint) }}</i>) </li> <li v-for="(checkConstraint, i) in table.constraints.checks" :key="`uk-${i}`"> <strong>CHECK CONSTRAINT</strong> - (<i v-text="checkConstraint" />) + (<i>{{ checkConstraint }}</i>) </li> </ul> </v-container> diff --git a/dbrepo-ui/pages/database/[database_id]/table/create/dataset.vue b/dbrepo-ui/pages/database/[database_id]/table/create/dataset.vue index e1d71643ea84be7a727ba031715f72ce817b4209..c54314abcba4d714426e4990527d1a53b3a287d6 100644 --- a/dbrepo-ui/pages/database/[database_id]/table/create/dataset.vue +++ b/dbrepo-ui/pages/database/[database_id]/table/create/dataset.vue @@ -22,8 +22,9 @@ color="info"> {{ $t('pages.table.subpages.import.dataset.text') }} <NuxtLink - :href="`/database/${$route.params.database_id}/table/create/schema`" - v-text="$t('pages.table.subpages.import.schema.text')" /> + :href="`/database/${$route.params.database_id}/table/create/schema`"> + {{ $t('pages.table.subpages.import.schema.text') }} + </NuxtLink> </v-alert> </v-col> </v-row> @@ -140,7 +141,9 @@ border="start" color="success"> {{ $t('pages.table.subpages.create.summary.text') }} - <strong v-text="table.internal_name"/> + <strong> + {{ table.internal_name }} + </strong> </v-alert> </v-col> </v-row> diff --git a/dbrepo-ui/pages/database/[database_id]/table/create/schema.vue b/dbrepo-ui/pages/database/[database_id]/table/create/schema.vue index 79493ec39f3a13054df2e4b605f7da3fdb442805..57f943f22b36ee21f858f15120d5ca812b8b8bfc 100644 --- a/dbrepo-ui/pages/database/[database_id]/table/create/schema.vue +++ b/dbrepo-ui/pages/database/[database_id]/table/create/schema.vue @@ -116,8 +116,9 @@ <v-col md="8"> <v-alert border="start" - color="success" - v-text="$t('pages.table.subpages.schema.summary.text') + ' ' + table.internal_name" /> + color="success"> + {{ $t('pages.table.subpages.schema.summary.text') + ' ' + table.internal_name }} + </v-alert> </v-col> </v-row> <v-row> diff --git a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/info.vue b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/info.vue index 3ec97f2bdaec1109edc16f1bedf0ee22b07a1f52..064fa5f3f20f0c9e1be84fc010e215745834d278 100644 --- a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/info.vue +++ b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/info.vue @@ -65,8 +65,9 @@ :title="$t('pages.database.name.title')"> <NuxtLink class="text-primary" - :to="`/database/${database.id}`" - v-text="database.internal_name" /> + :to="`/database/${database.id}`"> + {{ database.internal_name }} + </NuxtLink> </v-list-item> </v-list> </v-card-text> diff --git a/dbrepo-ui/pages/search.vue b/dbrepo-ui/pages/search.vue index fe427b25efa416f242eac5405cecdfb9cb7379a1..b2d0f0219515530ac47b84342c66561ba117a288 100644 --- a/dbrepo-ui/pages/search.vue +++ b/dbrepo-ui/pages/search.vue @@ -2,17 +2,19 @@ <div> <v-toolbar variant="flat"> - <v-toolbar-title - v-text="header" /> + <v-toolbar-title> + {{ header }} + </v-toolbar-title> <v-spacer /> <v-btn v-if="canCreateDatabase" class="mr-4" prepend-icon="mdi-plus" - :text="$t('toolbars.database.create.text')" color="primary" variant="flat" - @click.stop="createDbDialog = true" /> + @click.stop="createDbDialog = true"> + {{ $t('toolbars.database.create.text') }} + </v-btn> </v-toolbar> <v-card rounded="0" @@ -25,7 +27,7 @@ v-if="isDatabaseSearch" :loading="loading" :databases="results" /> - <div v-else> + <div> <v-card v-for="(result, idx) in results" :key="idx" @@ -36,10 +38,16 @@ <v-divider class="mx-4" /> <v-card-title class="text-primary text-decoration-underline"> - <a v-if="link(result)" :href="link(result)">{{ title(result) }}</a> - <span v-else>{{ title(result) }}</span> + <a v-if="link(result)" :href="link(result)"> + {{ title(result) }} + </a> + <span v-else> + {{ title(result) }} + </span> </v-card-title> - <v-card-subtitle v-text="description(result)" /> + <v-card-subtitle> + {{ description(result) }} + </v-card-subtitle> <v-card-text> <div v-if="tags(result).length > 0" @@ -49,8 +57,9 @@ :key="i" size="small" :color="tag.color" - variant="outlined" - v-text="tag.text" /> + variant="outlined"> + {{ tag.text }} + </v-chip> </div> </v-card-text> </v-card> diff --git a/dbrepo-ui/pages/semantic/index.vue b/dbrepo-ui/pages/semantic/index.vue index c5f12d48f48efe9c60825af6f1078f8ae439feb8..480483aaf83bf68911090c1f7dcdbe051542676d 100644 --- a/dbrepo-ui/pages/semantic/index.vue +++ b/dbrepo-ui/pages/semantic/index.vue @@ -1,7 +1,9 @@ <template> <div v-if="canListOntologies"> <v-toolbar flat> - <v-toolbar-title v-text="$t('pages.semantics.title')" /> + <v-toolbar-title> + {{ $t('pages.semantics.title') }} + </v-toolbar-title> <v-spacer /> <v-btn v-if="canListOntologies" @@ -13,10 +15,12 @@ <v-tabs v-model="tab" color="primary"> - <v-tab - v-text="$t('toolbars.semantic.ontologies.concepts')" /> - <v-tab - v-text="$t('toolbars.semantic.ontologies.units')" /> + <v-tab> + {{ $t('toolbars.semantic.ontologies.concepts') }} + </v-tab> + <v-tab> + {{ $t('toolbars.semantic.ontologies.units') }} + </v-tab> </v-tabs> </template> </v-toolbar> @@ -30,7 +34,10 @@ :footer-props="footerProps" :items-per-page-options="footerProps.itemsPerPageOptions"> <template v-slot:item.uri="{ item }"> - <a :href="item.uri" target="_blank" v-text="item.uri" /> + <a :href="item.uri" + target="_blank"> + {{ item.uri }} + </a> </template> <template v-slot:item.action="{ item }"> <v-btn diff --git a/dbrepo-ui/pages/semantic/ontology/_ontology_id/index.vue b/dbrepo-ui/pages/semantic/ontology/_ontology_id/index.vue index 41cfa20426c6d51a12f656ef7cd40bc0dff45405..108ef73e4bfdb6d6f79357c341808dc264302123 100644 --- a/dbrepo-ui/pages/semantic/ontology/_ontology_id/index.vue +++ b/dbrepo-ui/pages/semantic/ontology/_ontology_id/index.vue @@ -1,20 +1,38 @@ <template> - <div v-if="canListOntologies"> + <div + v-if="canListOntologies"> <v-toolbar flat> <v-toolbar-title> - <v-btn id="back-btn" plain class="mr-2" to="/semantic/ontology"> + <v-btn + id="back-btn" + plain + class="mr-2" + to="/semantic/ontology"> <v-icon left>mdi-arrow-left</v-icon> </v-btn> </v-toolbar-title> <v-toolbar-title> - <v-skeleton-loader v-if="loading" type="text" class="skeleton-small" /> + <v-skeleton-loader + v-if="loading" + type="text" + class="skeleton-small" /> <span v-if="!loading"> - Ontology <a v-if="ontology" :href="ontology.uri" target="_blank" v-text="ontology.uri" /> + Ontology + <a + v-if="ontology" + :href="ontology.uri" + target="_blank"> + {{ ontology.uri }} + </a> </span> </v-toolbar-title> <v-spacer /> <v-toolbar-title> - <v-btn v-if="canDeleteOntology" :loading="loadingDelete" color="error" @click="deleteOntology"> + <v-btn + v-if="canDeleteOntology" + :loading="loadingDelete" + color="error" + @click="deleteOntology"> Delete Ontology </v-btn> </v-toolbar-title> diff --git a/dbrepo-ui/pages/semantic/ontology/index.vue b/dbrepo-ui/pages/semantic/ontology/index.vue index c4c5291aefcce046d401c4986fee05a530d897fa..a19b5216c14650cac687b502b2e47706b37ace0a 100644 --- a/dbrepo-ui/pages/semantic/ontology/index.vue +++ b/dbrepo-ui/pages/semantic/ontology/index.vue @@ -6,8 +6,9 @@ size="small" icon="mdi-arrow-left" to="/semantic" /> - <v-toolbar-title - v-text="ontologies.length + ' ' + $t('toolbars.semantic.ontologies.title')" /> + <v-toolbar-title> + {{ ontologies.length + ' ' + $t('toolbars.semantic.ontologies.title') }} + </v-toolbar-title> <v-spacer /> <v-btn v-if="canCreateOntology" diff --git a/dbrepo-ui/server/routes/actuator/prometheus.ts b/dbrepo-ui/server/routes/actuator/prometheus.ts deleted file mode 100644 index 3647103148b19761fe534d9a70ad004bd8e70199..0000000000000000000000000000000000000000 --- a/dbrepo-ui/server/routes/actuator/prometheus.ts +++ /dev/null @@ -1,4 +0,0 @@ -export default defineEventHandler((event) => { - event.node.res.setHeader('Content-Type', 'text/plain'); - return 'service_started 1' -}) diff --git a/dbrepo-ui/test/test_heap.sh b/dbrepo-ui/test/test_heap.sh new file mode 100755 index 0000000000000000000000000000000000000000..d3ed8722cdc1dacdf4678459a847a1488595fd2b --- /dev/null +++ b/dbrepo-ui/test/test_heap.sh @@ -0,0 +1,10 @@ +#!/bin/bash +CALLS=${CALLS:-1000} +CONCURRENCY=${CONCURRENCY:-10} +ENDPOINT=${ENDPOINT:-http://localhost} + +echo "[DEBUG] Testing endpoint: ${ENDPOINT} x${CALLS} (concurrency ${CONCURRENCY})" +ab -n "${CALLS}" -c "${CONCURRENCY}" "${ENDPOINT}/" +ab -n "${CALLS}" -c "${CONCURRENCY}" "${ENDPOINT}/search" +ab -n "${CALLS}" -c "${CONCURRENCY}" "${ENDPOINT}/login" +ab -n "${CALLS}" -c "${CONCURRENCY}" "${ENDPOINT}/signup" \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 9a13b7ca63e2b49ecc32e7004bce2e6ecdc704eb..d74f0c574d3c55c478174485f6b88d09e215e7e9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -23,7 +23,6 @@ services: ports: - "3306:3306" environment: - BITNAMI_DEBUG: "true" MARIADB_DATABASE: "${METADATA_DB:-dbrepo}" MARIADB_ROOT_PASSWORD: "${METADATA_DB_PASSWORD:-dbrepo}" MARIADB_GALERA_MARIABACKUP_PASSWORD: "${METADATA_DB_BACKUP_PASSWORD:-dbrepobackup}" @@ -281,6 +280,11 @@ services: OPENSEARCH_USERNAME: ${SEARCH_DB_USERNAME:-admin} OPENSEARCH_PASSWORD: ${SEARCH_DB_PASSWORD:-admin} LOG_LEVEL: ${LOG_LEVEL:-info} + healthcheck: + test: curl -sSL localhost:8080/health | grep 'UP' || exit 1 + interval: 10s + timeout: 5s + retries: 12 dbrepo-data-db-sidecar: restart: "no" @@ -325,11 +329,11 @@ services: NUXT_PUBLIC_UPLOAD_CLIENT: "${BASE_URL:-http://localhost}/api/upload/files" depends_on: dbrepo-search-service: - condition: service_started - dbrepo-storage-service: + condition: service_healthy + dbrepo-upload-service: condition: service_healthy healthcheck: - test: wget -qO- localhost:3000 | grep "Database Repository" || exit 1 + test: curl -fsSL http://127.0.0.1:3000 && curl -fsSL http://127.0.0.1:3000/health interval: 10s timeout: 5s retries: 12 diff --git a/helm/dbrepo/files/system.json b/helm/dbrepo/files/system.json index 4eb40a1a2ea5311ed634f406f0603e82d4c1ee91..e37d7be19f66f2b9b39928d85fe1741e45db760f 100644 --- a/helm/dbrepo/files/system.json +++ b/helm/dbrepo/files/system.json @@ -92,7 +92,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.2.2", + "pluginVersion": "10.4.9", "targets": [ { "datasource": { @@ -160,7 +160,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.2.2", + "pluginVersion": "10.4.9", "targets": [ { "datasource": { @@ -276,7 +276,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.2.2", + "pluginVersion": "10.4.9", "targets": [ { "datasource": { @@ -306,18 +306,17 @@ "x": 0, "y": 4 }, - "id": 2, + "id": 22, "panels": [], - "title": "Services", + "title": "UI", "type": "row" }, { "datasource": { - "default": true, "type": "prometheus", "uid": "P18F45E9DC7E75912" }, - "description": "Quality of Service", + "description": "", "fieldConfig": { "defaults": { "mappings": [], @@ -327,38 +326,34 @@ "mode": "absolute", "steps": [ { - "color": "purple", + "color": "green", "value": null }, { - "color": "red", - "value": 0 + "color": "#EAB839", + "value": 300 }, { "color": "orange", - "value": 60 - }, - { - "color": "#EAB839", - "value": 80 + "value": 600 }, { - "color": "green", - "value": 100 + "color": "red", + "value": 900 } ] }, - "unit": "percent" + "unit": "ms" }, "overrides": [] }, "gridPos": { - "h": 4, + "h": 3, "w": 4, "x": 0, "y": 5 }, - "id": 9, + "id": 17, "options": { "colorMode": "background", "graphMode": "none", @@ -376,7 +371,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.2.2", + "pluginVersion": "10.4.9", "targets": [ { "datasource": { @@ -385,17 +380,17 @@ }, "disableTextWrap": false, "editorMode": "code", - "expr": "sum(up)*100/count(up)", + "expr": "avg(page_render_time)", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, - "legendFormat": "Services Running", + "legendFormat": "__auto", "range": true, "refId": "A", "useBackend": false } ], - "title": "QoS", + "title": "UI Response Time (avg)", "type": "stat" }, { @@ -403,72 +398,132 @@ "type": "prometheus", "uid": "P18F45E9DC7E75912" }, + "description": "", "fieldConfig": { "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": { - "fillOpacity": 70, - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineWidth": 1 - }, - "mappings": [ - { - "options": { - "0": { - "index": 0, - "text": "DOWN" - }, - "1": { - "index": 1, - "text": "UP" - } - }, - "type": "value" - } - ], + "mappings": [], + "max": 100, + "min": 0, "thresholds": { "mode": "absolute", "steps": [ { - "color": "red", + "color": "green", "value": null }, { - "color": "green", - "value": 1 + "color": "#EAB839", + "value": 0.02 + }, + { + "color": "orange", + "value": 0.05 + }, + { + "color": "red", + "value": 0.1 } ] - } + }, + "unit": "s" }, "overrides": [] }, "gridPos": { - "h": 8, - "w": 20, + "h": 3, + "w": 4, "x": 4, "y": 5 }, - "id": 16, + "id": 24, "options": { - "colWidth": 0.9, - "legend": { - "displayMode": "list", - "placement": "bottom", - "showLegend": false + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false }, - "rowHeight": 0.9, - "showValue": "auto", - "tooltip": { - "mode": "single", - "sort": "none" + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.4.9", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P18F45E9DC7E75912" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "nodejs_eventloop_lag_mean_seconds", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false } + ], + "title": "UI Event Lag (avg)", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P18F45E9DC7E75912" + }, + "description": "", + "fieldConfig": { + "defaults": { + "mappings": [], + "max": 100, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "blue", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 8, + "y": 5 + }, + "id": 25, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true }, + "pluginVersion": "10.4.9", "targets": [ { "datasource": { @@ -476,26 +531,26 @@ "uid": "P18F45E9DC7E75912" }, "disableTextWrap": false, - "editorMode": "builder", - "expr": "up", + "editorMode": "code", + "expr": "nodejs_active_handles{type=\"Server\"}", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, - "legendFormat": "{{instance}}", + "legendFormat": "__auto", "range": true, "refId": "A", "useBackend": false } ], - "title": "Service QoS", - "type": "status-history" + "title": "UI Servers", + "type": "stat" }, { "datasource": { "type": "prometheus", "uid": "P18F45E9DC7E75912" }, - "description": "Total used disk space in Storage Service", + "description": "", "fieldConfig": { "defaults": { "mappings": [], @@ -510,17 +565,17 @@ } ] }, - "unit": "decbytes" + "unit": "none" }, "overrides": [] }, "gridPos": { - "h": 4, + "h": 3, "w": 4, - "x": 0, - "y": 9 + "x": 12, + "y": 5 }, - "id": 17, + "id": 26, "options": { "colorMode": "background", "graphMode": "none", @@ -534,11 +589,527 @@ "fields": "", "values": false }, - "showPercentChange": false, - "textMode": "auto", - "wideLayout": true + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.4.9", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P18F45E9DC7E75912" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "nodejs_active_handles{type=\"Socket\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "UI Sockets", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P18F45E9DC7E75912" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "blue", + "mode": "fixed" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "blue", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 16, + "y": 5 + }, + "id": 27, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.4.9", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P18F45E9DC7E75912" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "nodejs_active_requests_total", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Active Requests", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P18F45E9DC7E75912" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 300 + }, + { + "color": "orange", + "value": 600 + }, + { + "color": "red", + "value": 900 + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 20, + "options": { + "displayMode": "basic", + "maxVizHeight": 300, + "minVizHeight": 16, + "minVizWidth": 8, + "namePlacement": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showUnfilled": true, + "sizing": "auto", + "valueMode": "color" + }, + "pluginVersion": "10.4.9", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P18F45E9DC7E75912" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "page_render_time", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{path}}", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "UI Response Time per Path (avg)", + "type": "bargauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P18F45E9DC7E75912" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "dashed" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 256000000 + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 8 + }, + "id": 21, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P18F45E9DC7E75912" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "nodejs_heap_space_size_total_bytes", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{space}}", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "NodeJS Heap Bytes", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 15 + }, + "id": 2, + "panels": [], + "title": "Services", + "type": "row" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "P18F45E9DC7E75912" + }, + "description": "Quality of Service", + "fieldConfig": { + "defaults": { + "mappings": [], + "max": 100, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "purple", + "value": null + }, + { + "color": "red", + "value": 0 + }, + { + "color": "orange", + "value": 60 + }, + { + "color": "#EAB839", + "value": 80 + }, + { + "color": "green", + "value": 100 + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 0, + "y": 16 + }, + "id": 9, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.4.9", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P18F45E9DC7E75912" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "sum(up)*100/count(up)", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Services Running", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "QoS", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P18F45E9DC7E75912" + }, + "description": "", + "fieldConfig": { + "defaults": { + "mappings": [], + "max": 100, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "blue", + "value": null + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 4, + "y": 16 + }, + "id": 28, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.4.9", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P18F45E9DC7E75912" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "min(process_uptime_seconds)", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Uptime", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P18F45E9DC7E75912" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "fillOpacity": 70, + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineWidth": 1 + }, + "mappings": [ + { + "options": { + "0": { + "index": 0, + "text": "DOWN" + }, + "1": { + "index": 1, + "text": "UP" + } + }, + "type": "value" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "green", + "value": 1 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 16 + }, + "id": 16, + "options": { + "colWidth": 0.9, + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": false + }, + "rowHeight": 0.9, + "showValue": "auto", + "tooltip": { + "mode": "single", + "sort": "none" + } }, - "pluginVersion": "11.2.2", "targets": [ { "datasource": { @@ -546,25 +1117,26 @@ "uid": "P18F45E9DC7E75912" }, "disableTextWrap": false, - "editorMode": "code", - "expr": "SeaweedFS_volumeServer_total_disk_size", + "editorMode": "builder", + "expr": "up", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, - "legendFormat": "__auto", + "legendFormat": "{{instance}}", "range": true, "refId": "A", "useBackend": false } ], - "title": "S3 Volume", - "type": "stat" + "title": "Service QoS", + "type": "status-history" }, { "datasource": { "type": "prometheus", "uid": "P18F45E9DC7E75912" }, + "description": "", "fieldConfig": { "defaults": { "color": { @@ -577,9 +1149,8 @@ "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, - "barWidthFactor": 0.6, "drawStyle": "line", - "fillOpacity": 25, + "fillOpacity": 0, "gradientMode": "none", "hideFrom": { "legend": false, @@ -597,7 +1168,7 @@ "spanNulls": false, "stacking": { "group": "A", - "mode": "normal" + "mode": "none" }, "thresholdsStyle": { "mode": "off" @@ -616,79 +1187,17 @@ "value": 80 } ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "auth-service:8080" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "yellow", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "data-service:8080" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "blue", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "metadata-service:8080" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "purple", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "metadata-service:80" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "blue", - "mode": "fixed" - } - } - ] } - ] + }, + "overrides": [] }, "gridPos": { "h": 7, "w": 12, "x": 0, - "y": 13 + "y": 19 }, - "id": 6, + "id": 23, "options": { "legend": { "calcs": [], @@ -701,7 +1210,7 @@ "sort": "none" } }, - "pluginVersion": "11.2.0", + "pluginVersion": "10.4.9", "targets": [ { "datasource": { @@ -709,19 +1218,18 @@ "uid": "P18F45E9DC7E75912" }, "disableTextWrap": false, - "editorMode": "builder", - "expr": "process_cpu_usage", + "editorMode": "code", + "expr": "process_open_fds\n", "fullMetaSearch": false, - "hide": false, "includeNullMetadata": true, "instant": false, "legendFormat": "{{instance}}", "range": true, - "refId": "process_cpu_usage", + "refId": "process_open_fds", "useBackend": false } ], - "title": "CPU Usage", + "title": "File Descriptors", "type": "timeseries" }, { @@ -743,7 +1251,6 @@ "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, - "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 25, "gradientMode": "none", @@ -848,7 +1355,7 @@ "h": 7, "w": 12, "x": 12, - "y": 13 + "y": 23 }, "id": 7, "options": { @@ -903,7 +1410,6 @@ "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, - "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 25, "gradientMode": "none", @@ -923,7 +1429,7 @@ "spanNulls": false, "stacking": { "group": "A", - "mode": "none" + "mode": "normal" }, "thresholdsStyle": { "mode": "off" @@ -936,22 +1442,26 @@ { "color": "green", "value": null + }, + { + "color": "red", + "value": 80 } ] }, - "unit": "reqps" + "unit": "none" }, "overrides": [ { "matcher": { - "id": "byRegexp", - "options": "/.*search-service.*/" + "id": "byName", + "options": "auth-service:8080" }, "properties": [ { "id": "color", "value": { - "fixedColor": "orange", + "fixedColor": "yellow", "mode": "fixed" } } @@ -959,14 +1469,44 @@ }, { "matcher": { - "id": "byRegexp", - "options": "/.*analyse-service.*/" + "id": "byName", + "options": "data-service:8080" }, "properties": [ { "id": "color", "value": { - "fixedColor": "super-light-orange", + "fixedColor": "blue", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "metadata-service:8080" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "purple", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "metadata-service:80" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "blue", "mode": "fixed" } } @@ -978,9 +1518,9 @@ "h": 7, "w": 12, "x": 0, - "y": 20 + "y": 26 }, - "id": 18, + "id": 6, "options": { "legend": { "calcs": [], @@ -993,21 +1533,27 @@ "sort": "none" } }, + "pluginVersion": "11.2.0", "targets": [ { "datasource": { "type": "prometheus", "uid": "P18F45E9DC7E75912" }, - "editorMode": "code", - "expr": "rate(flask_http_request_duration_seconds_count{status=~\"200|201|202\",path!=\"/health\"}[$__rate_interval])", + "disableTextWrap": false, + "editorMode": "builder", + "expr": "process_cpu_usage", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, "instant": false, - "legendFormat": "{{method}} {{instance}} {{path}} ({{status}})", + "legendFormat": "{{instance}}", "range": true, - "refId": "A" + "refId": "process_cpu_usage", + "useBackend": false } ], - "title": "Successful API Requests", + "title": "CPU Usage", "type": "timeseries" }, { @@ -1027,7 +1573,6 @@ "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, - "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 25, "gradientMode": "none", @@ -1102,7 +1647,7 @@ "h": 7, "w": 12, "x": 12, - "y": 20 + "y": 30 }, "id": 19, "options": { @@ -1136,7 +1681,6 @@ }, { "datasource": { - "default": true, "type": "prometheus", "uid": "P18F45E9DC7E75912" }, @@ -1152,9 +1696,8 @@ "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, - "barWidthFactor": 0.6, "drawStyle": "line", - "fillOpacity": 0, + "fillOpacity": 25, "gradientMode": "none", "hideFrom": { "legend": false, @@ -1162,8 +1705,8 @@ "viz": false }, "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, + "lineInterpolation": "smooth", + "lineWidth": 2, "pointSize": 5, "scaleDistribution": { "type": "linear" @@ -1187,58 +1730,14 @@ "value": null } ] - } + }, + "unit": "reqps" }, "overrides": [ { "matcher": { - "id": "byName", - "options": "DELETE" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "red", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "GET" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "blue", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "HEAD" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "purple", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "PATCH" + "id": "byRegexp", + "options": "/.*search-service.*/" }, "properties": [ { @@ -1252,28 +1751,14 @@ }, { "matcher": { - "id": "byName", - "options": "OPTIONS" - }, - "properties": [ - { - "id": "color", - "value": { - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "POST" + "id": "byRegexp", + "options": "/.*analyse-service.*/" }, "properties": [ { "id": "color", "value": { - "fixedColor": "green", + "fixedColor": "super-light-orange", "mode": "fixed" } } @@ -1285,9 +1770,9 @@ "h": 7, "w": 12, "x": 0, - "y": 27 + "y": 33 }, - "id": 20, + "id": 18, "options": { "legend": { "calcs": [], @@ -1296,7 +1781,7 @@ "showLegend": true }, "tooltip": { - "mode": "single", + "mode": "multi", "sort": "none" } }, @@ -1306,23 +1791,19 @@ "type": "prometheus", "uid": "P18F45E9DC7E75912" }, - "disableTextWrap": false, - "editorMode": "builder", - "expr": "tusd_requests_total", - "fullMetaSearch": false, - "includeNullMetadata": true, + "editorMode": "code", + "expr": "rate(flask_http_request_duration_seconds_count{status=~\"200|201|202\",path!=\"/health\"}[$__rate_interval])", "instant": false, - "legendFormat": "{{method}}", + "legendFormat": "{{method}} {{instance}} {{path}} ({{status}})", "range": true, - "refId": "A", - "useBackend": false + "refId": "A" } ], - "title": "Storage Service Requests", + "title": "Successful API Requests", "type": "timeseries" } ], - "refresh": "10s", + "refresh": "5s", "schemaVersion": 39, "tags": [ "provisioned", @@ -1332,13 +1813,13 @@ "list": [] }, "time": { - "from": "now-1h", + "from": "now-30m", "to": "now" }, "timepicker": {}, "timezone": "browser", - "title": "DBRepo - Overview", - "uid": "bdz20owu8zn5se", + "title": "NEW", + "uid": "bdz20owu8zn5se1", "version": 1, "weekStart": "" } \ No newline at end of file diff --git a/make/test.mk b/make/test.mk index c3d2cd8804831f25d7450d0f34914c69c6f53477..b3ad94f9ba405a39a921b02cb1cd227535d350b5 100644 --- a/make/test.mk +++ b/make/test.mk @@ -15,3 +15,7 @@ test-analyse-service: ## Test the Analyse Service. .PHONY: test-lib test-lib: ## Test the Python Library. bash ./lib/python/test.sh + +.PHONY: test-ui +test-ui: ## Test the UI. + bash ./dbrepo-ui/test/test_heap.sh