diff --git a/.docker/docker-compose.yml b/.docker/docker-compose.yml index 16195084bd3c02649bd803cb6340b753d7cc3366..b90ccd74098883a0f8f71c5cbc8f83bcf381f0f9 100644 --- a/.docker/docker-compose.yml +++ b/.docker/docker-compose.yml @@ -86,6 +86,9 @@ services: ports: - "8080:8080" environment: + LDAP_ROOT: "${IDENTITY_SERVICE_ROOT:-dc=dbrepo,dc=at}" + LDAP_ADMIN_DN: "${IDENTITY_SERVICE_ADMIN_DN:-cn=admin,dc=dbrepo,dc=at}" + LDAP_ADMIN_PASSWORD: "${IDENTITY_SERVICE_ADMIN_PASSWORD:-admin}" KEYCLOAK_ENABLE_HEALTH_ENDPOINTS: "true" KEYCLOAK_ENABLE_HTTPS: "false" KEYCLOAK_ENABLE_STATISTICS: "true" @@ -93,7 +96,7 @@ services: KEYCLOAK_DATABASE_NAME: "${AUTH_DB_NAME:-keycloak}" KEYCLOAK_DATABASE_USER: "${AUTH_DB_USERNAME:-keycloak}" KEYCLOAK_DATABASE_PASSWORD: "${AUTH_DB_PASSWORD:-dbrepo}" - METADATA_SERVICE_ENDPOINT: "${METADATA_SERVICE_ENDPOINT:-http://metadata-service:8080}/api/user" + METADATA_SERVICE_ENDPOINT: "${METADATA_SERVICE_ENDPOINT:-http://metadata-service:8080}" SYSTEM_USERNAME: "${SYSTEM_USERNAME:-admin}" SYSTEM_PASSWORD: "${SYSTEM_PASSWORD:-admin}" healthcheck: @@ -113,7 +116,7 @@ services: init: true restart: "no" container_name: dbrepo-auth-service-init - image: registry.datalab.tuwien.ac.at/dbrepo/metadata-service:1.7.1 + image: registry.datalab.tuwien.ac.at/dbrepo/metadata-service:1.7.2 environment: AUTH_SERVICE_ADMIN: ${AUTH_SERVICE_ADMIN:-admin} AUTH_SERVICE_ADMIN_PASSWORD: ${AUTH_SERVICE_ADMIN_PASSWORD:-admin} @@ -134,7 +137,7 @@ services: restart: "no" container_name: dbrepo-metadata-service hostname: metadata-service - image: registry.datalab.tuwien.ac.at/dbrepo/metadata-service:1.7.1 + image: registry.datalab.tuwien.ac.at/dbrepo/metadata-service:1.7.2 volumes: - "${SHARED_VOLUME:-/tmp}:/tmp" environment: @@ -197,7 +200,7 @@ services: restart: "no" container_name: dbrepo-analyse-service hostname: analyse-service - image: registry.datalab.tuwien.ac.at/dbrepo/analyse-service:1.7.1 + image: registry.datalab.tuwien.ac.at/dbrepo/analyse-service:1.7.2 environment: AUTH_SERVICE_CLIENT: ${AUTH_SERVICE_CLIENT:-dbrepo-client} AUTH_SERVICE_CLIENT_SECRET: ${AUTH_SERVICE_CLIENT:-MUwRc7yfXSJwX8AdRMWaQC3Nep1VjwgG} @@ -252,7 +255,7 @@ services: restart: "no" container_name: dbrepo-search-db hostname: search-db - image: registry.datalab.tuwien.ac.at/dbrepo/search-db:1.7.1 + image: registry.datalab.tuwien.ac.at/dbrepo/search-db:1.7.2 healthcheck: test: curl -sSL localhost:9200/_plugins/_security/health | jq .status | grep UP interval: 10s @@ -276,7 +279,7 @@ services: restart: "no" container_name: dbrepo-search-service hostname: search-service - image: registry.datalab.tuwien.ac.at/dbrepo/search-service:1.7.1 + image: registry.datalab.tuwien.ac.at/dbrepo/search-service:1.7.2 environment: AUTH_SERVICE_CLIENT: ${AUTH_SERVICE_CLIENT:-dbrepo-client} AUTH_SERVICE_CLIENT_SECRET: ${AUTH_SERVICE_CLIENT_SECRET:-MUwRc7yfXSJwX8AdRMWaQC3Nep1VjwgG} @@ -300,12 +303,11 @@ services: restart: "no" container_name: dbrepo-ui hostname: ui - image: registry.datalab.tuwien.ac.at/dbrepo/ui:1.7.1 + image: registry.datalab.tuwien.ac.at/dbrepo/ui:1.7.2 environment: NUXT_PUBLIC_API_CLIENT: "${BASE_URL:-http://localhost}" NUXT_PUBLIC_API_SERVER: "${BASE_URL:-http://gateway-service}" NUXT_OIDC_PROVIDERS_KEYCLOAK_AUTHORIZATION_URL: "${BASE_URL:-http://localhost}/realms/dbrepo/protocol/openid-connect/auth" - NUXT_OIDC_PROVIDERS_KEYCLOAK_BASE_URL: "${BASE_URL:-http://localhost}/realms/dbrepo" NUXT_OIDC_PROVIDERS_KEYCLOAK_CLIENT_ID: "${AUTH_SERVICE_CLIENT:-dbrepo-client}" NUXT_OIDC_PROVIDERS_KEYCLOAK_CLIENT_SECRET: "${AUTH_SERVICE_CLIENT:-MUwRc7yfXSJwX8AdRMWaQC3Nep1VjwgG}" NUXT_OIDC_PROVIDERS_KEYCLOAK_LOGOUT_REDIRECT_URI: "${BASE_URL:-http://localhost}" @@ -377,7 +379,7 @@ services: init: true container_name: dbrepo-search-service-init hostname: search-service-init - image: registry.datalab.tuwien.ac.at/dbrepo/search-service-init:1.7.1 + image: registry.datalab.tuwien.ac.at/dbrepo/search-service-init:1.7.2 environment: LOG_LEVEL: ${LOG_LEVEL:-info} METADATA_SERVICE_ENDPOINT: ${METADATA_SERVICE_ENDPOINT:-http://metadata-service:8080} @@ -434,7 +436,7 @@ services: restart: "no" container_name: dbrepo-dashboard-service hostname: dashboard-service - image: registry.datalab.tuwien.ac.at/dbrepo/dashboard-service:1.7.1 + image: registry.datalab.tuwien.ac.at/dbrepo/dashboard-service:1.7.2 ports: - "3000:3000" volumes: @@ -446,7 +448,7 @@ services: LDAP_ADMIN_PASSWORD: "${IDENTITY_SERVICE_ADMIN_PASSWORD:-admin}" LDAP_ROOT: "${IDENTITY_SERVICE_ROOT:-dc=dbrepo,dc=at}" healthcheck: - test: test -f /opt/bitnami/grafana/tmp/grafana.pid + test: curl -fsSL --head http://127.0.0.1:3000 interval: 10s timeout: 5s retries: 12 @@ -461,7 +463,7 @@ services: init: true container_name: dbrepo-storage-service-init hostname: storage-service-init - image: registry.datalab.tuwien.ac.at/dbrepo/storage-service-init:1.7.1 + image: registry.datalab.tuwien.ac.at/dbrepo/storage-service-init:1.7.2 environment: S3_ACCESS_KEY_ID: ${S3_ACCESS_KEY_ID:-seaweedfsadmin} S3_BUCKET: "${S3_BUCKET:-dbrepo}" @@ -477,7 +479,7 @@ services: restart: "no" container_name: dbrepo-data-service hostname: data-service - image: registry.datalab.tuwien.ac.at/dbrepo/data-service:1.7.1 + image: registry.datalab.tuwien.ac.at/dbrepo/data-service:1.7.2 volumes: - "${SHARED_VOLUME:-/tmp}:/tmp" environment: @@ -486,6 +488,7 @@ services: AUTH_SERVICE_CLIENT: "${AUTH_SERVICE_CLIENT:-dbrepo-client}" AUTH_SERVICE_CLIENT_SECRET: "${AUTH_SERVICE_CLIENT:-MUwRc7yfXSJwX8AdRMWaQC3Nep1VjwgG}" AUTH_SERVICE_ENDPOINT: "${AUTH_SERVICE_ENDPOINT:-http://auth-service:8080}" + BASE_URL: "${BASE_URL:-http://localhost}" BROKER_EXCHANGE_NAME: "${BROKER_EXCHANGE_NAME:-dbrepo}" BROKER_QUEUE_NAME: "${BROKER_QUEUE_NAME:-dbrepo}" BROKER_HOST: "${BROKER_ENDPOINT:-broker-service}" diff --git a/.docs/.openapi/api-data.yaml b/.docs/.openapi/api-data.yaml index 6b1855a99e5e183c98270ce961899322beaa569e..8f4b4f0718e4b8371ba342e6a88c2a390261247c 100644 --- a/.docs/.openapi/api-data.yaml +++ b/.docs/.openapi/api-data.yaml @@ -8,10 +8,10 @@ info: license: name: Apache 2.0 url: https://www.apache.org/licenses/LICENSE-2.0 - version: 1.7.1 + version: 1.7.2 externalDocs: description: Sourcecode Documentation - url: https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7.1/system-services-metadata/ + url: https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7.2/system-services-metadata/ servers: - url: http://localhost description: Development instance diff --git a/.docs/.openapi/api-metadata.yaml b/.docs/.openapi/api-metadata.yaml index e3769be04d2a9726dc40999bad56daa1c537d613..e48f8277b775de6e5fe687d660198af65ca12052 100644 --- a/.docs/.openapi/api-metadata.yaml +++ b/.docs/.openapi/api-metadata.yaml @@ -8,10 +8,10 @@ info: license: name: Apache 2.0 url: https://www.apache.org/licenses/LICENSE-2.0 - version: 1.7.1 + version: 1.7.2 externalDocs: description: Sourcecode Documentation - url: https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7.1/system-services-metadata/ + url: https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7.2/system-services-metadata/ servers: - url: http://localhost description: Development instance diff --git a/.docs/.openapi/api.base.yaml b/.docs/.openapi/api.base.yaml index 6cf9e007278f12039b4779d01f44eadded03dcd7..b78ff419b7f6863751a9b2727c742ac9c8f62f16 100644 --- a/.docs/.openapi/api.base.yaml +++ b/.docs/.openapi/api.base.yaml @@ -24,7 +24,7 @@ info: name: Apache 2.0 url: https://www.apache.org/licenses/LICENSE-2.0 title: DBRepo REST API - version: 1.7.1 + version: 1.7.2 openapi: 3.1.0 servers: - description: Test Instance diff --git a/.docs/.openapi/api.yaml b/.docs/.openapi/api.yaml index 0fcd84503c6bd92530804d6e3e02242fe205d689..37a174c34136d93438f6c58e39c5eaa62087c332 100644 --- a/.docs/.openapi/api.yaml +++ b/.docs/.openapi/api.yaml @@ -16,7 +16,7 @@ info: name: Apache 2.0 url: 'https://www.apache.org/licenses/LICENSE-2.0' title: DBRepo REST API - version: 1.7.1 + version: 1.7.2 servers: - description: Test Instance url: 'https://test.dbrepo.tuwien.ac.at' diff --git a/.docs/changelog.md b/.docs/changelog.md index 941b3ccc59758e4bf709514ac296b738e13158cc..0f4c837edf765b48ca628b9f8c66769a7e383027 100644 --- a/.docs/changelog.md +++ b/.docs/changelog.md @@ -2,8 +2,20 @@ author: Martin Weise --- +## v1.7.2 (2025-03-13) + +[:simple-gitlab: GitLab Release](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/tags/v1.7.2) + +#### Fixes + +* Fixed a wrong configuration of `caffeine` in the Data Service that did not find views/subsets after table creation + within the cache period of 60 seconds + in [#506](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/issues/506). + ## v1.7.1 (2025-03-06) +[:simple-gitlab: GitLab Release](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/tags/v1.7.1) + #### Features * Added support to download `pandas` DataFrame by PID @@ -18,7 +30,7 @@ author: Martin Weise ## v1.7.0 (2025-03-03) -[:simple-gitlab: GitLab Release](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/tags/v1.7.1) +[:simple-gitlab: GitLab Release](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/tags/v1.7.0) !!! warning "Contains Breaking Changes" diff --git a/.docs/index.md b/.docs/index.md index 6beb128e843e1bd5befb0808e99171b927b2c182..12f027bd103d4b8f595a2e10d261fd4b332c6673 100644 --- a/.docs/index.md +++ b/.docs/index.md @@ -14,7 +14,7 @@ author: Martin Weise   -Documentation for version: [v1.7.1](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/releases). +Documentation for version: [v1.7.2](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/releases). DBRepo is a repository for data in databases that are used from the beginning until the end of a research project supporting data evolution, -citation and -versioning. It implements the query store of the diff --git a/.docs/kubernetes.md b/.docs/kubernetes.md index 16f21bd991e6850175f10da5539a7423609d6d3d..0d8f66b5dafccc33980d6157f7bacf4997ae984f 100644 --- a/.docs/kubernetes.md +++ b/.docs/kubernetes.md @@ -14,7 +14,7 @@ helm upgrade --install dbrepo \ -n dbrepo \ "oci://registry.datalab.tuwien.ac.at/dbrepo/helm/dbrepo" \ --values ./values.yaml \ - --version "1.7.1" \ + --version "1.7.2" \ --create-namespace \ --cleanup-on-fail ``` diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index af716078e781edd4f36839e6fcfe25a2cf17b1c9..bef70c68da14f6a604039b8c7e96fa1a457b39b3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -11,9 +11,9 @@ variables: SONARQUBE_VERSION: "10.0" BUN_VERSION: "1.1.40" DOC_VERSION: "1.7" - APP_VERSION: "1.7.1" - CHART_VERSION: "1.7.1" - SUPPORTED_VERSIONS: "[\"1.7.0\",\"1.7.1\"]" + APP_VERSION: "1.7.2" + CHART_VERSION: "1.7.2" + SUPPORTED_VERSIONS: "[\"1.7.0\",\"1.7.1\",\"1.7.2\"]" CACHE_FALLBACK_KEY: "${CI_DEFAULT_BRANCH}" # This will supress any download for dependencies and plugins or upload messages which would clutter the console log. # `showDateTime` will show the passed time in milliseconds. You need to specify `--batch-mode` to make this work. @@ -250,6 +250,7 @@ build-helm: stage: build only: - merge_requests + - tags - /^release-.*/ before_script: - apk add --no-cache helm make @@ -468,8 +469,8 @@ clean-images: image: docker:${DOCKER_VERSION}-dind only: refs: + - tags - dev - - /^release-.*/ before_script: - "docker logout ${CI_REGISTRY_URL}" - "echo ${CI_REGISTRY_PASSWORD} | docker login --username ${CI_REGISTRY_USER} --password-stdin ${CI_REGISTRY_URL}" @@ -531,8 +532,7 @@ release-helm: stage: release image: docker:${DOCKER_VERSION}-dind only: - - /^release-.*/ - when: manual + - tags needs: - build-helm dependencies: @@ -592,10 +592,8 @@ release-docs: release-libs: stage: release image: docker.io/python:${PYTHON_VERSION}-alpine${ALPINE_VERSION} - when: manual only: - refs: - - /^release-.*/ + - tags variables: PIPENV_PIPFILE: "./dbrepo-analyse-service/Pipfile" before_script: diff --git a/Makefile b/Makefile index c7ef9b35f9a668634ea7f587fd54ed247934a1a0..94cc643573fe23be90df9586270f54c0dcd0db7a 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: all -APP_VERSION ?= 1.7.1 -CHART_VERSION ?= 1.7.1 +APP_VERSION ?= 1.7.2 +CHART_VERSION ?= 1.7.2 REPOSITORY_URL ?= registry.datalab.tuwien.ac.at/dbrepo .PHONY: all diff --git a/dbrepo-analyse-service/Pipfile b/dbrepo-analyse-service/Pipfile index cb2c838e85fe758941d8a0fe504d99ed4d908db7..d6498c9b35063d816af2f568073824d9218a43a7 100644 --- a/dbrepo-analyse-service/Pipfile +++ b/dbrepo-analyse-service/Pipfile @@ -21,7 +21,7 @@ numpy = "*" pandas = "*" minio = "*" pydantic = "*" -dbrepo = {path = "./lib/dbrepo-1.7.1.tar.gz"} +dbrepo = {path = "./lib/dbrepo-1.7.2.tar.gz"} opensearch-py = "*" [dev-packages] diff --git a/dbrepo-analyse-service/Pipfile.lock b/dbrepo-analyse-service/Pipfile.lock index 995400fd16e50f79ff7fe5b0b4114ef6c407041e..dcf464b05307f7d02595f19af63455f36c6be699 100644 --- a/dbrepo-analyse-service/Pipfile.lock +++ b/dbrepo-analyse-service/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "15b4fb696eabcc9059097bb4250de1545aa9c00211e2d50386e7ceead50aee4f" + "sha256": "91a5f1d0235af5d5d1888395045bf7550fd647d7dfa55abfe50cb745f91305f6" }, "pipfile-spec": 6, "requires": { @@ -18,11 +18,11 @@ "default": { "aiohappyeyeballs": { "hashes": [ - "sha256:19728772cb12263077982d2f55453babd8bec6a052a926cd5c0c42796da8bf62", - "sha256:6cac4f5dd6e34a9644e69cf9021ef679e4394f54e58a183056d12009e42ea9e3" + "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", + "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8" ], "markers": "python_version >= '3.9'", - "version": "==2.4.8" + "version": "==2.6.1" }, "aiohttp": { "hashes": [ @@ -164,11 +164,11 @@ }, "attrs": { "hashes": [ - "sha256:1c97078a80c814273a76b2a298a932eb681c87415c11dee0a6921de7f1b02c3e", - "sha256:c75a69e28a550a7e93789579c22aa26b0f5b83b75dc4e08fe092980051e1090a" + "sha256:18a06db706db43ac232cce80443fcd9f2500702059ecf53489e3c5a3f417acaf", + "sha256:611344ff0a5fed735d86d7784610c84f8126b95e549bcad9ff61b4242f2d386b" ], "markers": "python_version >= '3.8'", - "version": "==25.1.0" + "version": "==25.2.0" }, "blinker": { "hashes": [ @@ -180,20 +180,20 @@ }, "boto3": { "hashes": [ - "sha256:4c661389e68437a3fbc1f63decea24b88f7175e022c68622848d47fdf6e0144f", - "sha256:e2f4a1edb7e6dbd541c2962117e1c6fea8d5a42788c441a958700a43a3ca7c47" + "sha256:8eec08363ef5db05c2fbf58e89f0c0de6276cda2fdce01e76b3b5f423cd5c0f4", + "sha256:da6c22fc8a7e9bca5d7fc465a877ac3d45b6b086d776bd1a6c55bdde60523741" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==1.37.6" + "version": "==1.37.11" }, "botocore": { "hashes": [ - "sha256:2cb121a403cbec047d76e2401a402a6b2efd3309169037fbac588e8f7125aec4", - "sha256:cd282fe9c8adbb55a08c7290982a98ac6cc4507fa1c493f48bc43fd6c8376a57" + "sha256:02505309b1235f9f15a6da79103ca224b3f3dc5f6a62f8630fbb2c6ed05e2da8", + "sha256:72eb3a9a58b064be26ba154e5e56373633b58f951941c340ace0d379590d98b5" ], "markers": "python_version >= '3.8'", - "version": "==1.37.6" + "version": "==1.37.11" }, "certifi": { "hashes": [ @@ -425,9 +425,9 @@ }, "dbrepo": { "hashes": [ - "sha256:e70ea4f7030191eb80116e5d0a4b17b041c94c80359d5d8e707d62218edd9a54" + "sha256:e7c1d1a6c0c251e68ce8b865b3e5e95545cc5d861f0d0014a6ad1d8842eb21ed" ], - "path": "./lib/dbrepo-1.7.1.tar.gz" + "path": "./lib/dbrepo-1.7.2.tar.gz" }, "events": { "hashes": [ @@ -736,11 +736,11 @@ }, "jinja2": { "hashes": [ - "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb", - "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb" + "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", + "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67" ], "markers": "python_version >= '3.7'", - "version": "==3.1.5" + "version": "==3.1.6" }, "jmespath": { "hashes": [ @@ -1102,11 +1102,11 @@ }, "prometheus-flask-exporter": { "hashes": [ - "sha256:587c770a1061e93d72c5cbcdefbd7b633fb764e39dffd7dd16932c9124559244", - "sha256:ab49b2c40b57cd35cd51e91e59b3c306b3754477095c4f3cf679034c5122398c" + "sha256:41fc9bbd7d48cc958ed8384aacf60c3621d9e903768be61c4e7f0c63872eaf1a", + "sha256:94922a636d4c1d8b68e1ee605c30a23e9bbb0b21756df8222aa919634871784c" ], "index": "pypi", - "version": "==0.23.1" + "version": "==0.23.2" }, "propcache": { "hashes": [ @@ -1591,11 +1591,11 @@ }, "setuptools": { "hashes": [ - "sha256:4880473a969e5f23f2a2be3646b2dfd84af9028716d398e46192f84bc36900d2", - "sha256:558e47c15f1811c1fa7adbd0096669bf76c1d3f433f58324df69f3f5ecac4e8f" + "sha256:199466a166ff664970d0ee145839f5582cb9bca7a0a3a2e795b6a9cb2308e9c6", + "sha256:43b4ee60e10b0d0ee98ad11918e114c70701bc6051662a9a675a0496c1a158f4" ], "markers": "python_version >= '3.9'", - "version": "==75.8.2" + "version": "==76.0.0" }, "six": { "hashes": [ diff --git a/dbrepo-analyse-service/lib/dbrepo-1.7.1.tar.gz b/dbrepo-analyse-service/lib/dbrepo-1.7.1.tar.gz deleted file mode 100644 index 6708e1d892771d6cdf9293a6e9f5197f4dd9e304..0000000000000000000000000000000000000000 Binary files a/dbrepo-analyse-service/lib/dbrepo-1.7.1.tar.gz and /dev/null differ diff --git a/dbrepo-analyse-service/lib/dbrepo-1.7.1-py3-none-any.whl b/dbrepo-analyse-service/lib/dbrepo-1.7.2-py3-none-any.whl similarity index 59% rename from dbrepo-analyse-service/lib/dbrepo-1.7.1-py3-none-any.whl rename to dbrepo-analyse-service/lib/dbrepo-1.7.2-py3-none-any.whl index 61f52896c18ecbec8090177b38b8dbaeb0e1a95e..c66b0e29e8b7cd48aa8393e391690bf1bdf09311 100644 Binary files a/dbrepo-analyse-service/lib/dbrepo-1.7.1-py3-none-any.whl and b/dbrepo-analyse-service/lib/dbrepo-1.7.2-py3-none-any.whl differ diff --git a/dbrepo-analyse-service/lib/dbrepo-1.7.2.tar.gz b/dbrepo-analyse-service/lib/dbrepo-1.7.2.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..12cef6f73928370726f75f4f3909aa6510049543 Binary files /dev/null and b/dbrepo-analyse-service/lib/dbrepo-1.7.2.tar.gz differ diff --git a/dbrepo-auth-service/listeners/target/create-event-listener.jar b/dbrepo-auth-service/listeners/target/create-event-listener.jar index 72d17863f14cc38c1fd026dd7e40e56a25fc4318..57f3daf0eb71bd8de1e9a6374da6e6c6403ac104 100644 Binary files a/dbrepo-auth-service/listeners/target/create-event-listener.jar and b/dbrepo-auth-service/listeners/target/create-event-listener.jar differ diff --git a/dbrepo-dashboard-service/access.py b/dbrepo-dashboard-service/access.py new file mode 100644 index 0000000000000000000000000000000000000000..b72b2dcfbf3afb35d00d882afaecafe4189ee4f1 --- /dev/null +++ b/dbrepo-dashboard-service/access.py @@ -0,0 +1,30 @@ +import logging + +from grafana_client.client import GrafanaException + +from api.dto import Permission +from dbrepo.api.dto import Database +from clients import grafana_client + +statistics_row_title = '${table_id}' + + +def update_anonymous_read_access(uid: str, is_public: bool, is_schema_public: bool) -> None: + grafana = grafana_client.connect() + permissions = grafana.dashboard.get_permissions_by_uid(uid) + viewer_role = [permission for permission in permissions if + 'permissionName' in permission and permission['permissionName'] != 'View'] + permission = '' + if is_public or is_schema_public: + permission = 'View' + if len(viewer_role) == 0: + logging.warning(f'Failed to find permissionName=View') + return None + try: + response = grafana_client.generic_post(f'/api/access-control/dashboards/{uid}/builtInRoles/Viewer', + Permission(permission=permission).model_dump()) + if response.status_code != 200: + raise OSError(f'Failed to update anonymous read access: {response.content}') + except GrafanaException as e: + raise OSError(f'Failed to update anonymous read access: {e.message}') + logging.info(f"Updated anonymous read access for dashboard with uid: {uid}") diff --git a/dbrepo-dashboard-service/api/dto.py b/dbrepo-dashboard-service/api/dto.py new file mode 100644 index 0000000000000000000000000000000000000000..e2dab237d52e9aa7a29b93081f20d76c97fabd19 --- /dev/null +++ b/dbrepo-dashboard-service/api/dto.py @@ -0,0 +1,50 @@ +from __future__ import annotations + +from typing import Optional + +from pydantic import BaseModel + + +class Datasource(BaseModel): + uid: str + type: str + id: Optional[int] = None + orgId: Optional[int] = None + name: Optional[str] = None + typeLogoUrl: Optional[str] = None + access: Optional[str] = None + url: Optional[str] = None + user: Optional[str] = None + basicAuth: Optional[bool] = None + withCredentials: Optional[bool] = None + isDefault: Optional[bool] = None + version: Optional[int] = None + readOnly: Optional[bool] = None + jsonData: Optional[dict] = None + secureJsonFields: Optional[dict] = None + basicAuthUser: Optional[str] = None + basicAuthPassword: Optional[str] = None + password: Optional[str] = None + + +class CreateDatasource(BaseModel): + name: str + type: str + access: str + url: str + basicAuth: bool + version: int + readOnly: bool + jsonData: Optional[dict] = None + secureJsonData: Optional[dict] = None + basicAuthUser: Optional[str] = None + + +class Permission(BaseModel): + permission: str + + +class CreateDatasourceRequest(BaseModel): + database_internal_name: str + readonly: bool + type: str diff --git a/dbrepo-dashboard-service/clients/grafana_client.py b/dbrepo-dashboard-service/clients/grafana_client.py new file mode 100644 index 0000000000000000000000000000000000000000..8f7d5aab0f3b28b702cf83cfd51e98bf1bc3c98e --- /dev/null +++ b/dbrepo-dashboard-service/clients/grafana_client.py @@ -0,0 +1,27 @@ +import logging +import os + +import requests +from requests import Response + +from grafana_client import GrafanaApi + +url = os.getenv('DASHBOARD_UI_ENDPOINT', 'http://localhost:3000') +username = os.getenv('SYSTEM_USERNAME', 'admin') +password = os.getenv('SYSTEM_PASSWORD', 'admin') + + +def connect() -> GrafanaApi: + return GrafanaApi.from_url(url=f'{url}', credential=(username, password)) + + +def generic_get(api_url: str) -> Response: + request_url = url + api_url + logging.debug(f'generic get url={request_url}, auth=({username}, <reacted>)') + return requests.get(request_url, auth=(username, password)) + + +def generic_post(api_url: str, payload: dict) -> Response: + request_url = url + api_url + logging.debug(f'generic post url={request_url}, payload={payload}, auth=({username}, <reacted>)') + return requests.post(request_url, json=payload, auth=(username, password)) diff --git a/dbrepo-dashboard-service/clients/keycloak_client.py b/dbrepo-dashboard-service/clients/keycloak_client.py new file mode 100644 index 0000000000000000000000000000000000000000..7abb0a28a5122178e55e7902c9b634e9b61a558f --- /dev/null +++ b/dbrepo-dashboard-service/clients/keycloak_client.py @@ -0,0 +1,35 @@ +from dataclasses import dataclass +from typing import List + +import requests +from flask import current_app +from jwt import jwk_from_pem, JWT + + +@dataclass(init=True, eq=True) +class User: + username: str + roles: List[str] + + +class KeycloakClient: + + def obtain_user_token(self, username: str, password: str) -> str: + response = requests.post( + f"{current_app.config['AUTH_SERVICE_ENDPOINT']}/realms/dbrepo/protocol/openid-connect/token", + data={ + "username": username, + "password": password, + "grant_type": "password", + "client_id": current_app.config["AUTH_SERVICE_CLIENT"], + "client_secret": current_app.config["AUTH_SERVICE_CLIENT_SECRET"] + }) + body = response.json() + if "access_token" not in body: + raise AssertionError(f"Failed to obtain user token(s): {response.status_code}") + return response.json()["access_token"] + + def verify_jwt(self, access_token: str) -> User: + public_key = jwk_from_pem(str(current_app.config["JWT_PUBKEY"]).encode('utf-8')) + payload = JWT().decode(message=access_token, key=public_key, do_time_check=True) + return User(username=payload.get('client_id'), roles=payload.get('realm_access')["roles"]) diff --git a/dbrepo-dashboard-service/dashboard.py b/dbrepo-dashboard-service/dashboard.py new file mode 100644 index 0000000000000000000000000000000000000000..f8d4212be404b05d5d6daa78117868498d6885f9 --- /dev/null +++ b/dbrepo-dashboard-service/dashboard.py @@ -0,0 +1,344 @@ +import logging +import os + +from dbrepo.api.dto import Database, View + +from clients import grafana_client + +statistics_row_title = '${view_id}' + +base_url = os.getenv('BASE_URL', 'http://localhost') +datasource_uid = os.getenv('JSON_DATASOURCE_NAME', 'dbrepojson0') + + +def map_link(title: str, url: str) -> dict: + return dict(targetBlank=True, + asDropdown=False, + includeVars=False, + keepTime=False, + tags=[], + type='link', + icon='info', + title=title, + url=url) + + +def map_statistics_row(dashboard: dict) -> dict | None: + filtered_panels = [panel for panel in dashboard['panels'] if + panel['type'] == 'row' and panel['title'] == statistics_row_title] + if len(filtered_panels) == 0: + logging.warning(f"Failed to find statistics row title {statistics_row_title} in: {filtered_panels}") + return None + return filtered_panels[0] + + +def map_links(database: Database) -> [dict]: + links = [] + if len(database.identifiers) > 0: + links.append(map_link('Database', f"{base_url}/pid/{database.identifiers[0].id}")) + else: + links.append(map_link('Database', f"{base_url}/database/{database.id}")) + return links + + +def map_templating(database: Database) -> dict: + options = [dict(selected=False, + text=view.name, + value=str(view.id)) for view in database.views] + selected = dict(selected=True, + text=[view.name for view in database.views], + value=[str(view.id) for view in database.views]) + datasource = dict(uid=datasource_uid, + type='yesoreyeram-infinity-datasource') + return dict(list=[dict(description='', + name='view_id', + hide=0, + includeAll=True, + multi=True, + datasource=datasource, + refresh=1, + regex='', + sort=0, + definition='dbrepo-json- (infinity) json', + query=dict(queryType='infinity', + query='', + infinityQuery=dict(format='table', + filters=[], + parser='backend', + refId='variable', + root_selector='', + source='url', + type='json', + url=f"/api/database/{database.id}/view", + columns=[dict(selector='id', + text='value', + type='string'), + dict( + selector='internal_name', + text='name', + type='string')], + url_options=dict(data='', + method='GET'))), + label='Datasource', + skipUrlSync=False, + type='query', + current=selected, + options=options)]) + + +def map_timeseries_panel(database: Database, view: View) -> dict: + datasource = dict(uid=datasource_uid, + type='yesoreyeram-infinity-datasource') + return dict( + title=view['name'], + type='timeseries', + datasource=datasource, + targets=[dict(datasource=datasource, + format='table', + global_query_id='', + hide=False, + refId='A', + root_selector='', + source='url', + type='json', + url=f"/api/database/{database['id']}/view/{view['id']}", + url_options=dict(data='', + method='GET'))], + gridPos=dict(h=8, + w=12, + x=0, + y=0), + options=dict(legend=dict(displayMode='list', + placement='bottom', + showLegend=True), + tooltip=dict(mode='single', + sort='none')), + fieldConfig=dict( + defaults=dict(color=dict(mode='palette-classic'), + custom=dict( + axisBorderShow=False, + axisCenteredZero=False, + axisColorMode='text', + axisLabel='', + axisPlacement='auto', + barAlignment=0, + drawStyle='line', + fillOpacity=0, + gradientMode='none', + hideFrom=dict(legend=False, + tooltip=False, + viz=False), + insertNulls=False, + lineInterpolation='linear', + lineWidth=1, + pointSize=5, + scaleDistribution=dict(type='linear'), + showPoints='auto', + spanNulls=False, + stacking=dict(group='A', + mode='none'), + thresholdsStyle=dict(mode='absolute'))))) + + +def map_statistics_panel(database_id: str, view: View) -> dict: + datasource = dict(uid=datasource_uid, + type='yesoreyeram-infinity-datasource') + return dict( + title=view.name, + type='table', + datasource=datasource, + targets=[dict(datasource=datasource, + columns=[], + filters=[], + format='table', + global_query_id='', + hide=False, + refId='A', + root_selector='', + source='url', + type='json', + url=f"/api/database/{database_id}/view/{view.id}/data", + url_options=dict(data='', + method='GET'))], + options=dict(cellHeight="sm", + showHeader=True, + footer=dict(countRows=False, + fields="", + reducer=["sum"], + show=False)), + gridPos=dict(h=8, + w=12, + x=12, + y=0), + transformations=dict(id="organize", + options=dict(excludeByName=dict(), + includeByName=dict(), + indexByName=dict( + HEADER_AVG=3, + HEADER_COL=0, + HEADER_STDDEV=4, + HEADER_MAX=2, + HEADER_MIN=1))), + fieldConfig=dict(defaults=dict(custom=dict(align="auto", + filterable="true", + cellOptions=dict(type="auto"), + inspect=False), + mappings=[], + thresholds=dict(mode="absolute", + steps=[dict(color="green", + value=None), + dict(color="red", + value=80) + ])), + overrides=[dict(matcher=dict(id="byName", + options="HEADER_COL"), + properties=[dict(id="custom.align", + value="center")]), + dict(matcher=dict(id="byName", + options="HEADER_MIN"), + properties=[dict(id="custom.width", + value=115)]), + dict(matcher=dict(id="byName", + options="HEADER_MAX"), + properties=[dict(id="custom.width", + value=115)]), + dict(matcher=dict(id="byName", + options="HEADER_AVG"), + properties=[dict(id="custom.width", + value=115)]), + dict(matcher=dict(id="byName", + options="HEADER_STDDEV"), + properties=[dict(id="custom.width", + value=115)]) + ])) + + +def map_overview_panel(database_id: str) -> dict: + datasource = dict(uid=datasource_uid, + type='yesoreyeram-infinity-datasource') + return dict(title='Preview', + type='table', + fieldConfig=dict( + defaults=dict( + color=dict(mode='palette-classic'), + custom=dict(axisBorderShow=False, + axisCenteredZero=False, + axisColorMode='text', + axisLabel='', + axisPlacement='auto', + barAlignment=0, + drawStyle='line', + fillOpacity=0, + gradientMode='none', + hideFrom=dict( + legend=False, + tooltip=False, + viz=False), + insertNulls=False, + lineInterpolation='linear', + lineWidth=1, + pointSize=5, + scaleDistribution=dict( + type='linear'), + showPoints='auto', + spanNulls=False, + stacking=dict(group='A', + mode='none'), + thresholdsStyle=dict( + mode='off'))), + overrides=[]), + options=dict(legend=dict(displayMode='list', + placement='bottom', + showLegend=True, + calcs=[]), + tooltip=dict(mode='single', + sort='none')), + targets=[dict(format='json', + columns=[], + datasource=datasource, + filters=[], + global_query_id='', + refId='A', + root_selector='', + source='url', + type='json', + url='/api/database/' + database_id + '/view/${view_id}/data', + url_options=dict(data='', + method='GET'))], + datasource=datasource, + gridPos=dict(h=4, + w=12, + x=0, + y=0)) + + +def map_row() -> dict: + datasource = dict(uid=datasource_uid, + type='yesoreyeram-infinity-datasource') + return dict(collapsed=False, + repeat='view_id', + repeatDirection='h', + title=statistics_row_title, + type='row', + panels=[], + targets=[dict(refId='A', + datasource=datasource)], + gridPos=dict(h=1, + w=24, + x=0, + y=0)) + + +def map_panels(dashboard: dict, database: Database) -> [dict]: + if map_statistics_row(dashboard) is None: + dashboard['panels'].append(map_row()) + dashboard['panels'].append(map_overview_panel(database.id)) + for view in database.views: + dashboard['panels'].append(map_statistics_panel(database.id, view)) + return dashboard['panels'] + + +def find(uid: str): + grafana = grafana_client.connect() + return grafana.dashboard.get_dashboard(uid) + + +def create(database_name: str, uid: str = '') -> dict: + grafana = grafana_client.connect() + dashboard = dict(uid=uid, + title=f'{database_name} Overview', + tags=['dbrepo'], + timezone='browser', + fiscalYearStartMonth=1, + panels=[]) + dashboard['panels'] = [] + payload = dict(folderUid='', + overwrite=False, + dashboard=dashboard) + dashboard = grafana.dashboard.update_dashboard(payload) + logging.info(f"Created dashboard with uid: {dashboard['uid']}") + return dashboard + + +def delete(uid: str) -> None: + grafana = grafana_client.connect() + grafana.dashboard.delete_dashboard(uid) + + +def update(database: Database) -> None: + grafana = grafana_client.connect() + dashboard = find(database.dashboard_uid)['dashboard'] + # update metadata + if len(database.identifiers) > 0 and len(database.identifiers[0].titles) > 0: + dashboard['title'] = database.identifiers[0].titles[0].title + if len(database.identifiers) > 0 and len(database.identifiers[0].descriptions) > 0: + dashboard['description'] = database.identifiers[0].descriptions[0].description + dashboard['links'] = map_links(database) + dashboard['templating'] = map_templating(database) + # update panels + dashboard['panels'] = map_panels(dashboard, database) + payload = dict(folderUid='', + overwrite=True, + dashboard=dashboard) + response = grafana.dashboard.update_dashboard(payload) + logging.info(f"Updated dashboard with uid: {response['uid']}") diff --git a/dbrepo-dashboard-service/panel.py b/dbrepo-dashboard-service/panel.py new file mode 100644 index 0000000000000000000000000000000000000000..acb3d548bb6c3a736ed56055ef368431e4a1d8de --- /dev/null +++ b/dbrepo-dashboard-service/panel.py @@ -0,0 +1,252 @@ +import os + +datasource_uid = os.getenv('JSON_DATASOURCE_NAME', 'dbrepojson0') + +statistics_row_title = '${view_id}' + + +def _get_start_index(dashboard: dict) -> int: + return [panel['title'] for panel in dashboard['panels']].index(statistics_row_title) + + +def get_panels(dashboard: dict) -> [dict]: + return [] + + +def map_timeseries_panel(database_id: str) -> dict: + datasource = dict(uid=datasource_uid, + type='yesoreyeram-infinity-datasource') + return dict(title='${view_id}', + type='timeseries', + datasource=datasource, + targets=[dict(datasource=datasource, + format='table', + global_query_id='', + hide=False, + refId='A', + root_selector='', + source='url', + type='json', + url='/api/database/' + database_id + '/view/${view_id}/data', + url_options=dict(data='', + method='GET'))], + gridPos=dict(h=8, + w=12, + x=12, + y=8), + options=dict(legend=dict(displayMode='list', + placement='bottom', + showLegend=True), + tooltip=dict(mode='single', + sort='none')), + fieldConfig=dict( + defaults=dict(color=dict(mode='palette-classic'), + custom=dict( + axisBorderShow=False, + axisCenteredZero=False, + axisColorMode='text', + axisLabel='', + axisPlacement='auto', + barAlignment=0, + drawStyle='line', + fillOpacity=0, + gradientMode='none', + hideFrom=dict(legend=False, + tooltip=False, + viz=False), + insertNulls=False, + lineInterpolation='linear', + lineWidth=1, + pointSize=5, + scaleDistribution=dict(type='linear'), + showPoints='auto', + spanNulls=False, + stacking=dict(group='A', + mode='none'), + thresholdsStyle=dict(mode='absolute'))))) + + +def map_number_panel(database_id: str, title: str, root_selector: str, y: int = 0) -> dict: + datasource = dict(uid=datasource_uid, + type='yesoreyeram-infinity-datasource') + return dict(title=title, + type='stat', + datasource=datasource, + targets=[dict(datasource=datasource, + columns=[], + filters=[], + format='table', + global_query_id='', + hide=False, + refId='A', + root_selector=root_selector, + source='url', + type='json', + url='/api/database/' + database_id + '/view/${view_id}/statistic', + url_options=dict(data='', + method='GET'))], + fieldConfig=dict(defaults=dict(mappings=[], + thresholds=dict(mode='absolute', + steps=[dict(color='blue', + value=None)]), + unit=''), + overrides=[]), + gridPos=dict(h=4, + w=6, + x=18, + y=y), + options=dict(colorMode='background', + graphMode='area', + justifyMode='auto', + orientation='auto', + reduceOptions=dict(calcs=[], + fields='/.*/', + values=True), + showPercentChange=False, + textMode='auto', + wideLayout=True)) + + +def map_statistics_panel(database_id: str) -> dict: + datasource = dict(uid=datasource_uid, + type='yesoreyeram-infinity-datasource') + return dict(title='Statistics', + type='table', + gridPos=dict(h=8, + w=12, + x=0, + y=8), + datasource=datasource, + targets=[dict(datasource=datasource, + columns=[], + filters=[], + format='table', + global_query_id='', + hide=False, + refId='A', + root_selector='columns', + source='url', + type='json', + url='/api/database/' + database_id + '/view/${view_id}/statistic', + url_options=dict(data='', + method='GET'))], + options=dict(cellHeight="sm", + showHeader=True, + footer=dict(countRows=False, + fields="", + reducer=["sum"], + show=False)), + transformations=[dict(id="organize", + options=dict(excludeByName=dict(), + includeByName=dict(), + indexByName=dict(name=0, + val_min=1, + val_max=2, + mean=3, + median=4, + std_dev=5), + renameByName=dict(name="Name", + mean="Mean", + median="Median", + std_dev="std.dev", + val_min="Minimum", + val_max="Maximum")))], + fieldConfig=dict(defaults=dict(custom=dict(align="auto", + filterable="true", + cellOptions=dict(type="auto"), + inspect=False), + mappings=[], + thresholds=dict(mode="absolute", + steps=[dict(color="green", + value=None), + dict(color="red", + value=80) + ])), + overrides=[])) + + +def map_overview_panel(database_id: str) -> dict: + datasource = dict(uid=datasource_uid, + type='yesoreyeram-infinity-datasource') + return dict(title='Datasource Preview', + type='table', + gridPos=dict(h=8, + w=18, + x=0, + y=4), + fieldConfig=dict( + defaults=dict( + color=dict(mode='palette-classic'), + custom=dict(axisBorderShow=False, + axisCenteredZero=False, + axisColorMode='text', + axisLabel='', + axisPlacement='auto', + barAlignment=0, + drawStyle='line', + fillOpacity=0, + gradientMode='none', + hideFrom=dict( + legend=False, + tooltip=False, + viz=False), + insertNulls=False, + lineInterpolation='linear', + lineWidth=1, + pointSize=5, + scaleDistribution=dict( + type='linear'), + showPoints='auto', + spanNulls=False, + stacking=dict(group='A', + mode='none'), + thresholdsStyle=dict( + mode='off'))), + overrides=[]), + options=dict(legend=dict(displayMode='list', + placement='bottom', + showLegend=True, + calcs=[]), + tooltip=dict(mode='single', + sort='none')), + targets=[dict(format='json', + columns=[], + datasource=datasource, + filters=[], + global_query_id='', + refId='A', + root_selector='', + source='url', + type='json', + url='/api/database/' + database_id + '/view/${view_id}/data', + url_options=dict(data='', + method='GET'))], + datasource=datasource) + + +def map_row() -> dict: + datasource = dict(uid=datasource_uid, + type='yesoreyeram-infinity-datasource') + return dict(collapsed=False, + repeat='view_id', + repeatDirection='h', + title=statistics_row_title, + type='row', + panels=[], + targets=[dict(refId='A', + datasource=datasource)], + gridPos=dict(h=1, + w=24, + x=0, + y=0)) + + +def map_panels(dashboard: dict, database: Database) -> [dict]: + if get_statistics_row(dashboard) is None: + dashboard['panels'].append(map_row()) # repeating + dashboard['panels'].append(map_overview_panel(database.id)) # left top + dashboard['panels'].append(map_number_panel(database.id, 'Total Entries', 'rows', 0)) # right top + dashboard['panels'].append(map_number_panel(database.id, 'Variables', '$count(columns)', 4)) # right top + dashboard['panels'].append(map_statistics_panel(database.id)) # left + dashboard['panels'].append(map_timeseries_panel(database.id)) # middle + return dashboard['panels'] diff --git a/dbrepo-data-service/pom.xml b/dbrepo-data-service/pom.xml index 519f3a613b550f33e166fa4414df86b4b0af6ad1..e4ca259081947502c2d9164c56fc82e1070cda23 100644 --- a/dbrepo-data-service/pom.xml +++ b/dbrepo-data-service/pom.xml @@ -16,7 +16,7 @@ <groupId>at.tuwien</groupId> <artifactId>dbrepo-data-service</artifactId> <name>dbrepo-data-service</name> - <version>1.7.1</version> + <version>1.7.2</version> <description>Service that manages the data</description> @@ -298,6 +298,12 @@ <version>${project.version}</version> <scope>test</scope> </dependency> + <dependency> + <groupId>at.tuwien</groupId> + <artifactId>dbrepo-metadata-service-entities</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> diff --git a/dbrepo-data-service/querystore/pom.xml b/dbrepo-data-service/querystore/pom.xml index 12c1688ff501c9302c9aa6713c81b59c01d11622..a60fc702b3ac98563f52fcf466364c0768c49be7 100644 --- a/dbrepo-data-service/querystore/pom.xml +++ b/dbrepo-data-service/querystore/pom.xml @@ -6,12 +6,12 @@ <parent> <groupId>at.tuwien</groupId> <artifactId>dbrepo-data-service</artifactId> - <version>1.7.1</version> + <version>1.7.2</version> </parent> <artifactId>dbrepo-data-service-querystore</artifactId> <name>dbrepo-data-service-querystore</name> - <version>1.7.1</version> + <version>1.7.2</version> <dependencies/> diff --git a/dbrepo-data-service/report/pom.xml b/dbrepo-data-service/report/pom.xml index 5944f7cb39ee14d9f46182c541eb11c80f90aa76..d2ca544cd2e63183f5828d62d3c38b10453658aa 100644 --- a/dbrepo-data-service/report/pom.xml +++ b/dbrepo-data-service/report/pom.xml @@ -6,12 +6,12 @@ <parent> <groupId>at.tuwien</groupId> <artifactId>dbrepo-data-service</artifactId> - <version>1.7.1</version> + <version>1.7.2</version> </parent> <artifactId>report</artifactId> <name>dbrepo-data-service-report</name> - <version>1.7.1</version> + <version>1.7.2</version> <description> This module is only intended for the pipeline coverage report. See the detailed report in the respective modules diff --git a/dbrepo-data-service/rest-service/pom.xml b/dbrepo-data-service/rest-service/pom.xml index 4bc6e196144862161c4d7375d45840cfd6352103..71973f222dd43428d76450bb0583c6570ca2ce26 100644 --- a/dbrepo-data-service/rest-service/pom.xml +++ b/dbrepo-data-service/rest-service/pom.xml @@ -6,18 +6,18 @@ <parent> <groupId>at.tuwien</groupId> <artifactId>dbrepo-data-service</artifactId> - <version>1.7.1</version> + <version>1.7.2</version> </parent> <artifactId>rest-service</artifactId> <name>dbrepo-data-service-rest-service</name> - <version>1.7.1</version> + <version>1.7.2</version> <dependencies> <dependency> <groupId>at.tuwien</groupId> <artifactId>services</artifactId> - <version>1.7.1</version> + <version>1.7.2</version> </dependency> </dependencies> diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java index 801c6b638f3e1548711aa9d82989a83c62adde46..752aa83196c44f4d08dd7d6a326609f884188ed3 100644 --- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java +++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java @@ -5,12 +5,12 @@ import at.tuwien.api.database.AccessTypeDto; import at.tuwien.api.database.DatabaseDto; import at.tuwien.api.database.internal.CreateDatabaseDto; import at.tuwien.api.error.ApiErrorDto; -import at.tuwien.api.user.UserDto; import at.tuwien.api.user.internal.UpdateUserPasswordDto; import at.tuwien.exception.*; +import at.tuwien.mapper.MetadataMapper; import at.tuwien.service.AccessService; -import at.tuwien.service.ContainerService; import at.tuwien.service.CacheService; +import at.tuwien.service.ContainerService; import at.tuwien.service.DatabaseService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; @@ -38,14 +38,16 @@ public class DatabaseEndpoint extends RestEndpoint { private final CacheService cacheService; private final AccessService accessService; + private final MetadataMapper metadataMapper; private final DatabaseService databaseService; private final ContainerService containerService; @Autowired public DatabaseEndpoint(CacheService cacheService, AccessService accessService, DatabaseService databaseService, - ContainerService containerService) { + ContainerService containerService, MetadataMapper metadataMapper) { this.cacheService = cacheService; this.accessService = accessService; + this.metadataMapper = metadataMapper; this.databaseService = databaseService; this.containerService = containerService; } @@ -91,12 +93,7 @@ public class DatabaseEndpoint extends RestEndpoint { try { final DatabaseDto database = containerService.createDatabase(container, data); containerService.createQueryStore(container, data.getInternalName()); - final UserDto user = UserDto.builder() - .id(data.getUserId()) - .username(data.getUsername()) - .password(data.getPassword()) - .build(); - accessService.create(database, user, AccessTypeDto.WRITE_ALL); + accessService.create(database, metadataMapper.createDatabaseDtoToPrivilegedUserDto(data), AccessTypeDto.WRITE_ALL); return ResponseEntity.status(HttpStatus.CREATED) .body(database); } catch (SQLException e) { diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java index 7bf598db0b878b619db6c04537da6084d7cb79eb..fb076ce3a237646d19258b6fff1ee2562fb264dd 100644 --- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java +++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java @@ -279,7 +279,7 @@ public class SubsetEndpoint extends RestEndpoint { log.debug("timestamp not set: default to {}", timestamp); } /* create */ - final DatabaseDto database = cacheService.getDatabase(databaseId); + final DatabaseDto database = cacheService.getDatabase(databaseId, true); if (!database.getIsSchemaPublic()) { if (principal == null) { log.error("Failed to create subset: no authentication found"); diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java index b4c7fa715f667d7edf2727e7248af696266bf5e5..add04964d031225cd7bef3d02cb2d471f9626666 100644 --- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java +++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java @@ -24,6 +24,7 @@ import jakarta.validation.constraints.NotNull; import lombok.extern.log4j.Log4j2; import org.apache.spark.sql.Dataset; import org.apache.spark.sql.Row; +import org.jooq.DSLContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -44,6 +45,7 @@ import java.util.UUID; @RequestMapping(path = "/api/database/{databaseId}/view") public class ViewEndpoint extends RestEndpoint { + private final DSLContext context; private final ViewService viewService; private final CacheService cacheService; private final MariaDbMapper mariaDbMapper; @@ -53,9 +55,11 @@ public class ViewEndpoint extends RestEndpoint { private final EndpointValidator endpointValidator; @Autowired - public ViewEndpoint(ViewService viewService, CacheService cacheService, MariaDbMapper mariaDbMapper, - SubsetService subsetService, StorageService storageService, DatabaseService databaseService, + public ViewEndpoint(DSLContext context, ViewService viewService, CacheService cacheService, + MariaDbMapper mariaDbMapper, SubsetService subsetService, + StorageService storageService, DatabaseService databaseService, EndpointValidator endpointValidator) { + this.context = context; this.viewService = viewService; this.cacheService = cacheService; this.mariaDbMapper = mariaDbMapper; @@ -155,11 +159,11 @@ public class ViewEndpoint extends RestEndpoint { /* check */ endpointValidator.validateSubsetParams(data.getQuery()); /* create */ - final DatabaseDto database = cacheService.getDatabase(databaseId); + final DatabaseDto database = cacheService.getDatabase(databaseId, true); try { return ResponseEntity.status(HttpStatus.CREATED) .body(databaseService.createView(database, mariaDbMapper.nameToInternalName(data.getName()), - mariaDbMapper.subsetDtoToRawQuery(database, data.getQuery()))); + mariaDbMapper.subsetDtoToRawQuery(context, database, data.getQuery()))); } catch (SQLException e) { log.error("Failed to establish connection to database: {}", e.getMessage()); throw new DatabaseUnavailableException("Failed to establish connection to database: " + e.getMessage(), e); @@ -201,7 +205,7 @@ public class ViewEndpoint extends RestEndpoint { ViewMalformedException, MetadataServiceException, DatabaseNotFoundException { log.debug("endpoint delete view, databaseId={}, viewId={}", databaseId, viewId); final ViewDto view = cacheService.getView(databaseId, viewId); - final DatabaseDto database = cacheService.getDatabase(databaseId); + final DatabaseDto database = cacheService.getDatabase(databaseId, true); try { viewService.delete(database, view); return ResponseEntity.status(HttpStatus.ACCEPTED) diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java index ebb39f7c1879e354233a163c4ef677376ee2e44b..655741cc23d89ed41dc9b30f67c38b16b38d69a7 100644 --- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java +++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java @@ -6,7 +6,6 @@ import at.tuwien.api.database.DatabaseDto; import at.tuwien.api.database.query.FilterDto; import at.tuwien.api.database.query.FilterTypeDto; import at.tuwien.api.database.query.SubsetDto; -import at.tuwien.config.QueryConfig; import at.tuwien.endpoints.RestEndpoint; import at.tuwien.exception.*; import at.tuwien.service.CacheService; @@ -15,23 +14,17 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.security.Principal; -import java.util.Arrays; -import java.util.LinkedList; import java.util.List; import java.util.UUID; -import java.util.regex.Matcher; -import java.util.regex.Pattern; @Log4j2 @Component public class EndpointValidator extends RestEndpoint { - private final QueryConfig queryConfig; private final CacheService credentialService; @Autowired - public EndpointValidator(QueryConfig queryConfig, CacheService credentialService) { - this.queryConfig = queryConfig; + public EndpointValidator(CacheService credentialService) { this.credentialService = credentialService; } @@ -51,21 +44,6 @@ public class EndpointValidator extends RestEndpoint { } } - public void validateOnlyPrivateSchemaAccess(DatabaseDto database, Principal principal) - throws NotAllowedException, RemoteUnavailableException, MetadataServiceException { - validateOnlyPrivateSchemaAccess(database, principal, false); - } - - public void validateOnlyPrivateSchemaAccess(DatabaseDto database, Principal principal, - boolean writeAccessOnly) throws NotAllowedException, - RemoteUnavailableException, MetadataServiceException { - if (database.getIsSchemaPublic()) { - log.trace("database schema with id {} is public: no access needed", database.getId()); - return; - } - validateOnlyAccess(database, principal, writeAccessOnly); - } - public void validateSubsetParams(SubsetDto subset) throws QueryMalformedException { if (subset.getFilter() != null) { final List<FilterDto> filters = subset.getFilter(); @@ -82,25 +60,6 @@ public class EndpointValidator extends RestEndpoint { } } - public void validateOnlyPrivateSchemaHasRole(DatabaseDto database, Principal principal, String role) - throws NotAllowedException { - if (database.getIsSchemaPublic()) { - log.trace("database with id {} has public schema: no access needed", database.getId()); - return; - } - log.trace("database with id {} has private schema", database.getId()); - if (principal == null) { - log.error("Access not allowed: no authorization provided"); - throw new NotAllowedException("Access not allowed: no authorization provided"); - } - log.trace("principal: {}", principal.getName()); - if (!hasRole(principal, role)) { - log.error("Access not allowed: role {} missing", role); - throw new NotAllowedException("Access not allowed: role " + role + " missing"); - } - log.trace("principal has role '{}': access granted", role); - } - public void validateOnlyAccess(DatabaseDto database, Principal principal, boolean writeAccessOnly) throws NotAllowedException, RemoteUnavailableException, MetadataServiceException { if (principal == null) { @@ -117,25 +76,6 @@ public class EndpointValidator extends RestEndpoint { } } - public void validateForbiddenStatements(String query) throws QueryNotSupportedException { - final List<String> words = new LinkedList<>(); - Arrays.stream(queryConfig.getForbiddenKeywords()) - .forEach(keyword -> { - final Pattern pattern = Pattern.compile("(" + keyword + ")"); - final Matcher matcher = pattern.matcher(query); - final boolean found = matcher.find(); - if (found) { - words.add(keyword); - log.debug("query contains keyword '{}' matching '{}'", keyword, matcher.group(1)); - } - }); - if (words.isEmpty()) { - return; - } - log.error("Query contains forbidden keyword(s): {}", words); - throw new QueryNotSupportedException("Query contains forbidden keyword(s): " + Arrays.toString(words.toArray())); - } - public void validateOnlyWriteOwnOrWriteAllAccess(AccessTypeDto access, UUID owner, UUID user) throws NotAllowedException { if (access.equals(AccessTypeDto.READ)) { log.error("Failed to create table data: no write access"); diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/SubsetEndpointUnitTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/SubsetEndpointUnitTest.java index 33248abbdaddf6cdba3b0eacbccb0f67cdd07323..92bead36748a83f0781917cd2129edb36f787097 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/SubsetEndpointUnitTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/SubsetEndpointUnitTest.java @@ -63,7 +63,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { private DatabaseService databaseService; @MockBean - private CacheService credentialService; + private CacheService cacheService; @MockBean private MetadataServiceGateway metadataServiceGateway; @@ -94,7 +94,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { MetadataServiceException { /* mock */ - when(credentialService.getAccess(DATABASE_3_ID, USER_3_ID)) + when(cacheService.getAccess(DATABASE_3_ID, USER_3_ID)) .thenReturn(DATABASE_3_USER_1_READ_ACCESS_DTO); when(subsetService.findAll(DATABASE_3_PRIVILEGED_DTO, null)) .thenReturn(List.of(QUERY_1_DTO, QUERY_2_DTO, QUERY_3_DTO, QUERY_4_DTO, QUERY_5_DTO, QUERY_6_DTO)); @@ -120,7 +120,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { DatabaseNotFoundException, RemoteUnavailableException, MetadataServiceException { /* mock */ - when(credentialService.getDatabase(DATABASE_3_ID)) + when(cacheService.getDatabase(DATABASE_3_ID)) .thenReturn(DATABASE_3_PRIVILEGED_DTO); doThrow(SQLException.class) .when(subsetService) @@ -138,7 +138,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { RemoteUnavailableException, MetadataServiceException { /* mock */ - when(credentialService.getDatabase(DATABASE_1_ID)) + when(cacheService.getDatabase(DATABASE_1_ID)) .thenReturn(DATABASE_1_PRIVILEGED_DTO); /* test */ @@ -154,7 +154,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { QueryNotFoundException, MetadataServiceException { /* mock */ - when(credentialService.getDatabase(DATABASE_1_ID)) + when(cacheService.getDatabase(DATABASE_1_ID)) .thenReturn(DATABASE_1_PRIVILEGED_DTO); when(subsetService.findById(DATABASE_1_PRIVILEGED_DTO, QUERY_1_ID)) .thenReturn(QUERY_1_DTO); @@ -170,7 +170,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { QueryNotFoundException, MetadataServiceException { /* mock */ - when(credentialService.getDatabase(DATABASE_1_ID)) + when(cacheService.getDatabase(DATABASE_1_ID)) .thenReturn(DATABASE_1_PRIVILEGED_DTO); when(subsetService.findById(DATABASE_1_PRIVILEGED_DTO, QUERY_1_ID)) .thenReturn(QUERY_1_DTO); @@ -186,7 +186,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { QueryNotFoundException, MetadataServiceException { /* mock */ - when(credentialService.getDatabase(DATABASE_3_ID)) + when(cacheService.getDatabase(DATABASE_3_ID)) .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(subsetService.findById(DATABASE_3_PRIVILEGED_DTO, QUERY_5_ID)) .thenReturn(QUERY_5_DTO); @@ -202,7 +202,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { QueryNotFoundException, SQLException, MetadataServiceException, NotAllowedException { /* mock */ - when(credentialService.getDatabase(DATABASE_1_ID)) + when(cacheService.getDatabase(DATABASE_1_ID)) .thenReturn(DATABASE_1_PRIVILEGED_DTO); when(subsetService.findById(DATABASE_1_PRIVILEGED_DTO, QUERY_1_ID)) .thenReturn(QUERY_5_DTO); @@ -218,7 +218,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { NotAllowedException, QueryNotFoundException, SQLException { /* mock */ - when(credentialService.getDatabase(DATABASE_3_ID)) + when(cacheService.getDatabase(DATABASE_3_ID)) .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(subsetService.findById(DATABASE_3_PRIVILEGED_DTO, QUERY_5_ID)) .thenReturn(QUERY_5_DTO); @@ -236,7 +236,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { final Dataset<Row> mock = sparkSession.emptyDataFrame(); /* mock */ - when(credentialService.getDatabase(DATABASE_3_ID)) + when(cacheService.getDatabase(DATABASE_3_ID)) .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(subsetService.findById(DATABASE_3_PRIVILEGED_DTO, QUERY_5_ID)) .thenReturn(QUERY_5_DTO); @@ -256,7 +256,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { /* mock */ doThrow(DatabaseNotFoundException.class) - .when(credentialService) + .when(cacheService) .getDatabase(DATABASE_3_ID); /* test */ @@ -271,7 +271,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { MetadataServiceException, SQLException, UserNotFoundException, QueryNotFoundException { /* mock */ - when(credentialService.getDatabase(DATABASE_3_ID)) + when(cacheService.getDatabase(DATABASE_3_ID)) .thenReturn(DATABASE_3_PRIVILEGED_DTO); doThrow(SQLException.class) .when(subsetService) @@ -294,7 +294,9 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { final Dataset<Row> mock = sparkSession.emptyDataFrame(); /* mock */ - when(credentialService.getDatabase(DATABASE_3_ID)) + when(cacheService.getDatabase(DATABASE_3_ID, true)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); + when(cacheService.getDatabase(DATABASE_3_ID)) .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(subsetService.getData(any(DatabaseDto.class), anyString())) .thenReturn(mock); @@ -324,7 +326,9 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { final Dataset<Row> mock = sparkSession.emptyDataFrame(); /* mock */ - when(credentialService.getDatabase(DATABASE_3_ID)) + when(cacheService.getDatabase(DATABASE_3_ID, true)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); + when(cacheService.getDatabase(DATABASE_3_ID)) .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(subsetService.create(any(DatabaseDto.class), any(SubsetDto.class), any(Instant.class), eq(USER_1_ID))) .thenReturn(QUERY_5_ID); @@ -352,8 +356,8 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { /* mock */ doThrow(DatabaseNotFoundException.class) - .when(credentialService) - .getDatabase(DATABASE_3_ID); + .when(cacheService) + .getDatabase(DATABASE_3_ID, true); when(httpServletRequest.getMethod()) .thenReturn("POST"); @@ -374,7 +378,9 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { final Dataset<Row> mock = sparkSession.emptyDataFrame(); /* mock */ - when(credentialService.getDatabase(DATABASE_4_ID)) + when(cacheService.getDatabase(DATABASE_4_ID, true)) + .thenReturn(DATABASE_4_PRIVILEGED_DTO); + when(cacheService.getDatabase(DATABASE_4_ID)) .thenReturn(DATABASE_4_PRIVILEGED_DTO); when(subsetService.findById(eq(DATABASE_4_PRIVILEGED_DTO), any(UUID.class))) .thenReturn(QUERY_9_DTO); @@ -402,7 +408,9 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { final Dataset<Row> mock = sparkSession.emptyDataFrame(); /* mock */ - when(credentialService.getDatabase(DATABASE_1_ID)) + when(cacheService.getDatabase(DATABASE_1_ID, true)) + .thenReturn(DATABASE_1_PRIVILEGED_DTO); + when(cacheService.getDatabase(DATABASE_1_ID)) .thenReturn(DATABASE_1_PRIVILEGED_DTO); when(subsetService.findById(any(DatabaseDto.class), any(UUID.class))) .thenReturn(QUERY_1_DTO); @@ -429,7 +437,9 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { final Dataset<Row> mock = sparkSession.emptyDataFrame(); /* mock */ - when(credentialService.getDatabase(DATABASE_2_ID)) + when(cacheService.getDatabase(DATABASE_2_ID, true)) + .thenReturn(DATABASE_2_PRIVILEGED_DTO); + when(cacheService.getDatabase(DATABASE_2_ID)) .thenReturn(DATABASE_2_PRIVILEGED_DTO); when(subsetService.findById(eq(DATABASE_2_PRIVILEGED_DTO), any(UUID.class))) .thenReturn(QUERY_8_DTO); @@ -454,7 +464,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { final Dataset<Row> mock = sparkSession.emptyDataFrame(); /* mock */ - when(credentialService.getDatabase(DATABASE_3_ID)) + when(cacheService.getDatabase(DATABASE_3_ID)) .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(subsetService.findById(DATABASE_3_PRIVILEGED_DTO, QUERY_5_ID)) .thenReturn(QUERY_5_DTO); @@ -483,7 +493,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { ViewNotFoundException, ViewMalformedException, StorageUnavailableException, FormatNotAvailableException { /* mock */ - when(credentialService.getDatabase(DATABASE_3_ID)) + when(cacheService.getDatabase(DATABASE_3_ID)) .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(subsetService.findById(DATABASE_3_PRIVILEGED_DTO, QUERY_5_ID)) .thenReturn(QUERY_5_DTO); @@ -511,7 +521,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { final Dataset<Row> mock = sparkSession.emptyDataFrame(); /* mock */ - when(credentialService.getDatabase(DATABASE_1_ID)) + when(cacheService.getDatabase(DATABASE_1_ID)) .thenReturn(DATABASE_1_PRIVILEGED_DTO); when(subsetService.findById(DATABASE_1_PRIVILEGED_DTO, QUERY_1_ID)) .thenReturn(QUERY_1_DTO); @@ -539,7 +549,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { MetadataServiceException { /* mock */ - when(credentialService.getDatabase(DATABASE_1_ID)) + when(cacheService.getDatabase(DATABASE_1_ID)) .thenReturn(DATABASE_1_PRIVILEGED_DTO); /* test */ @@ -554,10 +564,10 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { NotAllowedException, MetadataServiceException { /* mock */ - when(credentialService.getDatabase(DATABASE_1_ID)) + when(cacheService.getDatabase(DATABASE_1_ID)) .thenReturn(DATABASE_1_PRIVILEGED_DTO); doThrow(NotAllowedException.class) - .when(credentialService) + .when(cacheService) .getAccess(DATABASE_1_ID, USER_1_ID); /* test */ @@ -575,7 +585,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { FormatNotAvailableException { /* mock */ - when(credentialService.getDatabase(DATABASE_1_ID)) + when(cacheService.getDatabase(DATABASE_1_ID)) .thenReturn(DATABASE_1_PRIVILEGED_DTO); when(subsetService.findById(DATABASE_1_PRIVILEGED_DTO, QUERY_1_ID)) .thenReturn(QUERY_1_DTO); @@ -603,9 +613,9 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { .build(); /* mock */ - when(credentialService.getAccess(DATABASE_3_ID, USER_3_ID)) + when(cacheService.getAccess(DATABASE_3_ID, USER_3_ID)) .thenReturn(DATABASE_3_USER_3_READ_ACCESS_DTO); - when(credentialService.getDatabase(DATABASE_3_ID)) + when(cacheService.getDatabase(DATABASE_3_ID)) .thenReturn(DATABASE_3_PRIVILEGED_DTO); doNothing() .when(subsetService) @@ -639,7 +649,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { /* mock */ doThrow(NotAllowedException.class) - .when(credentialService) + .when(cacheService) .getAccess(DATABASE_3_ID, USER_3_ID); /* test */ @@ -657,10 +667,10 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { .build(); /* mock */ - when(credentialService.getAccess(DATABASE_3_ID, USER_3_ID)) + when(cacheService.getAccess(DATABASE_3_ID, USER_3_ID)) .thenReturn(DATABASE_3_USER_3_READ_ACCESS_DTO); doThrow(DatabaseNotFoundException.class) - .when(credentialService) + .when(cacheService) .getDatabase(DATABASE_3_ID); /* test */ @@ -678,9 +688,9 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { .build(); /* mock */ - when(credentialService.getDatabase(DATABASE_3_ID)) + when(cacheService.getDatabase(DATABASE_3_ID)) .thenReturn(DATABASE_3_PRIVILEGED_DTO); - when(credentialService.getAccess(DATABASE_3_ID, USER_3_ID)) + when(cacheService.getAccess(DATABASE_3_ID, USER_3_ID)) .thenReturn(DATABASE_3_USER_3_READ_ACCESS_DTO); doThrow(SQLException.class) .when(subsetService) @@ -698,11 +708,11 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { /* mock */ if (database != null) { - when(credentialService.getDatabase(databaseId)) + when(cacheService.getDatabase(databaseId)) .thenReturn(database); } else { doThrow(DatabaseNotFoundException.class) - .when(credentialService) + .when(cacheService) .getDatabase(databaseId); } diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/ViewEndpointUnitTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/ViewEndpointUnitTest.java index 23ad1b73e3db99c355d08aa8011ab658fb48e728..5ce2990700a30a18f454d65ccb904fe9f2cd8347 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/ViewEndpointUnitTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/ViewEndpointUnitTest.java @@ -72,7 +72,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { ImageNotFoundException, QueryMalformedException { /* mock */ - when(credentialService.getDatabase(DATABASE_1_ID)) + when(credentialService.getDatabase(DATABASE_1_ID, true)) .thenReturn(DATABASE_1_DTO); when(databaseService.createView(any(DatabaseDto.class), anyString(), anyString())) .thenReturn(VIEW_1_DTO); @@ -88,7 +88,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { ViewMalformedException, MetadataServiceException { /* mock */ - when(credentialService.getDatabase(DATABASE_1_ID)) + when(credentialService.getDatabase(DATABASE_1_ID, true)) .thenReturn(DATABASE_1_DTO); doThrow(SQLException.class) .when(databaseService) @@ -125,7 +125,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { /* mock */ doThrow(DatabaseNotFoundException.class) .when(credentialService) - .getDatabase(DATABASE_1_ID); + .getDatabase(DATABASE_1_ID, true); /* test */ assertThrows(DatabaseNotFoundException.class, () -> { @@ -228,10 +228,10 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { MetadataServiceException, ViewNotFoundException, DatabaseNotFoundException { /* mock */ + when(credentialService.getDatabase(DATABASE_1_ID, true)) + .thenReturn(DATABASE_1_PRIVILEGED_DTO); when(credentialService.getView(DATABASE_1_ID, VIEW_1_ID)) .thenReturn(VIEW_1_DTO); - when(credentialService.getDatabase(DATABASE_1_ID)) - .thenReturn(DATABASE_1_PRIVILEGED_DTO); doThrow(SQLException.class) .when(viewService) .delete(DATABASE_1_PRIVILEGED_DTO, VIEW_1_DTO); diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/validation/EndpointValidatorUnitTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/validation/EndpointValidatorUnitTest.java index e237c32d2862c70e4f0f1ea4ccfae8f44e468ffb..d833d3fc1a04c1b5f4671859801aa6f070ed6d52 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/validation/EndpointValidatorUnitTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/validation/EndpointValidatorUnitTest.java @@ -1,7 +1,6 @@ package at.tuwien.validation; import at.tuwien.exception.PaginationException; -import at.tuwien.exception.QueryNotSupportedException; import at.tuwien.test.AbstractUnitTest; import lombok.extern.log4j.Log4j2; import org.junit.jupiter.api.Test; @@ -67,29 +66,4 @@ public class EndpointValidatorUnitTest extends AbstractUnitTest { }); } - @Test - public void validateForbiddenStatements_succeeds() throws QueryNotSupportedException { - - /* test */ - endpointValidator.validateForbiddenStatements("SELECT country FROM some_table"); - } - - @Test - public void validateForbiddenStatements_fails() { - - /* test */ - assertThrows(QueryNotSupportedException.class, () -> { - endpointValidator.validateForbiddenStatements("SELECT COUNT(id) FROM some_table"); - }); - } - - @Test - public void validateForbiddenStatements_lowercase_fails() { - - /* test */ - assertThrows(QueryNotSupportedException.class, () -> { - endpointValidator.validateForbiddenStatements("SELECT COUNT(id) FROM some_table"); - }); - } - } diff --git a/dbrepo-data-service/services/pom.xml b/dbrepo-data-service/services/pom.xml index 57d2b2a7f6c9abcc47e436215b3027c540adc985..73ce0428d502ddf61fe6c9ba2ea1b803a0a7a6d9 100644 --- a/dbrepo-data-service/services/pom.xml +++ b/dbrepo-data-service/services/pom.xml @@ -6,18 +6,18 @@ <parent> <groupId>at.tuwien</groupId> <artifactId>dbrepo-data-service</artifactId> - <version>1.7.1</version> + <version>1.7.2</version> </parent> <artifactId>services</artifactId> <name>dbrepo-data-service-services</name> - <version>1.7.1</version> + <version>1.7.2</version> <dependencies> <dependency> <groupId>at.tuwien</groupId> <artifactId>dbrepo-data-service-querystore</artifactId> - <version>1.7.1</version> + <version>1.7.2</version> </dependency> </dependencies> diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/config/QueryConfig.java b/dbrepo-data-service/services/src/main/java/at/tuwien/config/QueryConfig.java index b6363911705d4778111879d8cce3dc30a0475992..cea199f3ac751c3369e86751818f42e342a0c746 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/config/QueryConfig.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/config/QueryConfig.java @@ -2,15 +2,29 @@ package at.tuwien.config; import lombok.Getter; import lombok.extern.log4j.Log4j2; -import org.springframework.beans.factory.annotation.Value; +import org.jooq.DSLContext; +import org.jooq.SQLDialect; +import org.jooq.conf.Settings; +import org.jooq.conf.StatementType; +import org.jooq.impl.DefaultConfiguration; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import static org.jooq.impl.DSL.using; + @Log4j2 @Getter @Configuration public class QueryConfig { - @Value("${dbrepo.sql.forbidden}") - private String[] forbiddenKeywords; + @Bean + public DSLContext context() { + final DefaultConfiguration configuration = new DefaultConfiguration(); + final Settings settings = new Settings(); + settings.setStatementType(StatementType.STATIC_STATEMENT); + configuration.setSettings(settings); + configuration.set(SQLDialect.MARIADB); + return using(configuration); + } } diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MariaDbMapper.java b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MariaDbMapper.java index 66d8219c2a7205d0e320b7b22c07b8a90d284e2f..a080dfb1636e40a9af41254f3a1bec8b02d708dc 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MariaDbMapper.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MariaDbMapper.java @@ -39,7 +39,7 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import static org.jooq.impl.DSL.field; -import static org.jooq.impl.DSL.select; +import static org.jooq.impl.DSL.name; @Mapper(componentModel = "spring", uses = {MetadataMapper.class, DataMapper.class}) public interface MariaDbMapper { @@ -79,7 +79,6 @@ public interface MariaDbMapper { .append("`@`%` IDENTIFIED BY PASSWORD '") .append(password) .append("';"); - log.trace("mapped create user statement: {}", statement); return statement.toString(); } @@ -107,7 +106,7 @@ public interface MariaDbMapper { .append("` TO `") .append(username) .append("`@`%`;"); - log.trace("mapped revoke privileges statement: {}", statement); + log.trace("mapped grant privileges statement: {}", statement); return statement.toString(); } @@ -181,7 +180,7 @@ public interface MariaDbMapper { } default String databaseTableSelectRawQuery() { - final String statement = "SELECT t.`TABLE_NAME`, t.`TABLE_TYPE`, t.`TABLE_ROWS`, t.`AVG_ROW_LENGTH`, t.`DATA_LENGTH`, t.`MAX_DATA_LENGTH`, COALESCE(t.`CREATE_TIME`, NOW()) as `CREATE_TIME`, t.`UPDATE_TIME`, v.`VIEW_DEFINITION`, t.`TABLE_COMMENT` FROM information_schema.TABLES t LEFT JOIN information_schema.VIEWS v ON t.`TABLE_NAME` = v.`TABLE_NAME` WHERE t.`TABLE_SCHEMA` = ? AND t.`TABLE_TYPE` = 'SYSTEM VERSIONED' AND t.`TABLE_NAME` != 'qs_queries' AND t.`TABLE_NAME` = ?"; + final String statement = "SELECT t.`TABLE_NAME`, t.`TABLE_TYPE`, t.`TABLE_ROWS`, t.`AVG_ROW_LENGTH`, t.`DATA_LENGTH`, t.`MAX_DATA_LENGTH`, COALESCE(t.`CREATE_TIME`, NOW()) as `CREATE_TIME`, t.`UPDATE_TIME`, v.`VIEW_DEFINITION`, t.`TABLE_COMMENT` FROM information_schema.TABLES t LEFT JOIN information_schema.VIEWS v ON t.`TABLE_NAME` = v.`TABLE_NAME` WHERE t.`TABLE_SCHEMA` = ? AND t.`TABLE_TYPE` IN ('SYSTEM VERSIONED', 'VIEW') AND t.`TABLE_NAME` != 'qs_queries' AND t.`TABLE_NAME` = ?"; log.trace("mapped select table statement: {}", statement); return statement; } @@ -846,33 +845,33 @@ public interface MariaDbMapper { switch (operator) { case "=": case "<=>": - return field(column.getInternalName()).eq(data.getValue()); + return field(name(column.getInternalName())).eq(data.getValue()); case "<": - return field(column.getInternalName()).lt(data.getValue()); + return field(name(column.getInternalName())).lt(data.getValue()); case "<=": - return field(column.getInternalName()).le(data.getValue()); + return field(name(column.getInternalName())).le(data.getValue()); case ">": - return field(column.getInternalName()).gt(data.getValue()); + return field(name(column.getInternalName())).gt(data.getValue()); case ">=": - return field(column.getInternalName()).ge(data.getValue()); + return field(name(column.getInternalName())).ge(data.getValue()); case "!=": - return field(column.getInternalName()).ne(data.getValue()); + return field(name(column.getInternalName())).ne(data.getValue()); case "LIKE": - return field(column.getInternalName()).like(data.getValue()); + return field(name(column.getInternalName())).like(data.getValue()); case "NOT LIKE": - return field(column.getInternalName()).notLike(data.getValue()); + return field(name(column.getInternalName())).notLike(data.getValue()); case "IN": - return field(column.getInternalName()).in(data.getValue()); + return field(name(column.getInternalName())).in(data.getValue()); case "NOT IN": - return field(column.getInternalName()).notIn(data.getValue()); + return field(name(column.getInternalName())).notIn(data.getValue()); case "IS NOT NULL": - return field(column.getInternalName()).isNotNull(); + return field(name(column.getInternalName())).isNotNull(); case "IS NULL": - return field(column.getInternalName()).isNull(); + return field(name(column.getInternalName())).isNull(); case "REGEXP": - return field(column.getInternalName()).likeRegex(data.getValue()); + return field(name(column.getInternalName())).likeRegex(data.getValue()); case "NOT REGEXP": - return field(column.getInternalName()).notLikeRegex(data.getValue()); + return field(name(column.getInternalName())).notLikeRegex(data.getValue()); } log.error("Failed to map operator: {}", operator); throw new IllegalArgumentException("Failed to map operator: " + operator); @@ -884,26 +883,27 @@ public interface MariaDbMapper { for (OrderDto order : data.getOrder()) { final ColumnDto column = columnIdToColumnDto(database, order.getColumnId()); if (order.getDirection() == null) { - sort.add(field(column.getInternalName())); + sort.add(field(name(column.getInternalName()))); continue; } switch (order.getDirection()) { - case ASC -> sort.add(field(column.getInternalName()).asc()); - case DESC -> sort.add(field(column.getInternalName()).desc()); + case ASC -> sort.add(field(name(column.getInternalName())).asc()); + case DESC -> sort.add(field(name(column.getInternalName())).desc()); } } return step.orderBy(sort); } - default String subsetDtoToRawQuery(DatabaseDto database, SubsetDto data) throws TableNotFoundException, ImageNotFoundException { + default String subsetDtoToRawQuery(DSLContext context, DatabaseDto database, SubsetDto data) + throws TableNotFoundException, ImageNotFoundException { final TableDto table = tableIdToTableDto(database, data.getTableId()); final List<Field<Object>> columns = table.getColumns() .stream() .filter(c -> data.getColumns().contains(c.getId())) - .map(c -> field(c.getInternalName())) + .map(c -> field(name(c.getInternalName()))) .toList(); - final SelectJoinStep<Record> query = select(columns) - .from(table.getInternalName()); + final SelectJoinStep<Record> query = context.select(columns) + .from(name(table.getInternalName())); final SelectConditionStep<Record> where = subsetDtoToSelectConditions(query, database, data); final String sql; if (data.getOrder() == null) { @@ -966,7 +966,8 @@ public interface MariaDbMapper { .findFirst(); if (optional.isEmpty()) { log.error("Failed to find table with id: {}", tableId); - throw new TableNotFoundException("Failed to find table"); + log.trace("known table ids: {}", database.getTables().stream().map(TableDto::getId).collect(Collectors.toList())); + throw new TableNotFoundException("Failed to find table id: " + tableId); } return optional.get(); } diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MetadataMapper.java b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MetadataMapper.java index 0bd399d454d4427440684a57d3f2611079279bca..8539b00432f4cc24acde9b27596543f7329b34c5 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MetadataMapper.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MetadataMapper.java @@ -6,6 +6,8 @@ import at.tuwien.api.database.DatabaseBriefDto; import at.tuwien.api.database.DatabaseDto; import at.tuwien.api.database.ViewColumnDto; import at.tuwien.api.database.ViewDto; +import at.tuwien.api.database.internal.CreateDatabaseDto; +import at.tuwien.api.database.query.QueryDto; import at.tuwien.api.database.table.TableBriefDto; import at.tuwien.api.database.table.TableDto; import at.tuwien.api.database.table.columns.ColumnDto; @@ -28,6 +30,13 @@ public interface MetadataMapper { ContainerDto containerDtoToContainerDto(ContainerDto data); + @Mappings({ + @Mapping(target = "id", source = "userId"), + @Mapping(target = "username", source = "privilegedUsername"), + @Mapping(target = "password", source = "privilegedPassword"), + }) + UserDto createDatabaseDtoToPrivilegedUserDto(CreateDatabaseDto data); + DatabaseBriefDto databaseDtoToDatabaseBriefDto(DatabaseDto data); ColumnDto viewColumnDtoToColumnDto(ViewColumnDto data); diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/CacheService.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/CacheService.java index c61b1e1c917056194a67817573b40f01cf6491ba..208d6e755e67b0de50ed4c72db77d325f05b043d 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/CacheService.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/CacheService.java @@ -13,6 +13,9 @@ import java.util.UUID; public interface CacheService { + DatabaseDto getDatabase(UUID id, Boolean forceReload) throws DatabaseNotFoundException, RemoteUnavailableException, + MetadataServiceException; + /** * Gets credentials for a database with given id either from the cache (if not expired) or retrieves them from the * Metadata Service. diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/CacheServiceImpl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/CacheServiceImpl.java index 4abfc453e52e6f086572d32c193b35af36225506..2346fe1071f458ced7f399b7ef3b85c782cd4541 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/CacheServiceImpl.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/CacheServiceImpl.java @@ -5,7 +5,6 @@ import at.tuwien.api.database.DatabaseAccessDto; import at.tuwien.api.database.DatabaseDto; import at.tuwien.api.database.ViewDto; import at.tuwien.api.database.table.TableDto; -import at.tuwien.api.keycloak.TokenDto; import at.tuwien.api.user.UserDto; import at.tuwien.exception.*; import at.tuwien.gateway.MetadataServiceGateway; @@ -44,19 +43,27 @@ public class CacheServiceImpl implements CacheService { } @Override - public DatabaseDto getDatabase(UUID id) throws DatabaseNotFoundException, RemoteUnavailableException, + public DatabaseDto getDatabase(UUID id, Boolean forceReload) throws DatabaseNotFoundException, RemoteUnavailableException, MetadataServiceException { - final DatabaseDto cacheDatabase = databaseCache.getIfPresent(id); - if (cacheDatabase != null) { - log.trace("found database with id {} in cache", id); - return cacheDatabase; + if (!forceReload) { + final DatabaseDto cacheDatabase = databaseCache.getIfPresent(id); + if (cacheDatabase != null) { + log.trace("found database with id {} in cache", id); + return cacheDatabase; + } + log.debug("database with id {} not it cache (anymore): reload from metadata service", id); } - log.debug("database with id {} not it cache (anymore): reload from metadata service", id); final DatabaseDto database = gateway.getDatabaseById(id); databaseCache.put(id, database); return database; } + @Override + public DatabaseDto getDatabase(UUID id) throws DatabaseNotFoundException, RemoteUnavailableException, + MetadataServiceException { + return getDatabase(id, false); + } + @Override public TableDto getTable(UUID databaseId, UUID tableId) throws RemoteUnavailableException, MetadataServiceException, TableNotFoundException { diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/StorageServiceS3Impl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/StorageServiceS3Impl.java index d7f3c0da30e3ef937149adf9264b8580f9bf8cef..2d421ed0f309a01a3390ab08bd2c5eaebf8c4cdd 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/StorageServiceS3Impl.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/StorageServiceS3Impl.java @@ -51,7 +51,7 @@ public class StorageServiceS3Impl implements StorageService { final String key = "dbr_" + RandomStringUtils.randomAlphanumeric(96) .toLowerCase(); s3Client.putObject(PutObjectRequest.builder() - .key(key) + .key(key) .bucket(s3Config.getS3Bucket()) .build(), RequestBody.fromBytes(content)); log.debug("put object in S3 bucket {} with key: {}", s3Config.getS3Bucket(), key); @@ -156,7 +156,8 @@ public class StorageServiceS3Impl implements StorageService { log.debug("read dataset from s3 path: {} using header: {}", path, withHeader); Dataset<Row> dataset; try { - log.trace("spark read conf: header={}, delimiter={}", withHeader, delimiter); + final String logDelimiter = delimiter.equals("\t") ? "[tab]" : delimiter; + log.trace("spark read conf: header={}, delimiter={}", withHeader, logDelimiter); dataset = sparkSession.read() .option("delimiter", delimiter) .option("header", withHeader) diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/SubsetServiceMariaDbImpl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/SubsetServiceMariaDbImpl.java index a2b70ece8623d321683aaa73b6bd29dd8e7b524b..274654db63e333f4a99fd3bdf800bfac22754f76 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/SubsetServiceMariaDbImpl.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/SubsetServiceMariaDbImpl.java @@ -16,6 +16,7 @@ import org.apache.spark.sql.Dataset; import org.apache.spark.sql.Row; import org.apache.spark.sql.SparkSession; import org.apache.spark.sql.catalyst.ExtendedAnalysisException; +import org.jooq.DSLContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -29,14 +30,16 @@ import java.util.UUID; @Service public class SubsetServiceMariaDbImpl extends DataConnector implements SubsetService { + private final DSLContext context; private final DataMapper dataMapper; private final SparkSession sparkSession; private final MariaDbMapper mariaDbMapper; private final MetadataServiceGateway metadataServiceGateway; @Autowired - public SubsetServiceMariaDbImpl(DataMapper dataMapper, MariaDbMapper mariaDbMapper, SparkSession sparkSession, - MetadataServiceGateway metadataServiceGateway) { + public SubsetServiceMariaDbImpl(DSLContext context, DataMapper dataMapper, MariaDbMapper mariaDbMapper, + SparkSession sparkSession, MetadataServiceGateway metadataServiceGateway) { + this.context = context; this.dataMapper = dataMapper; this.sparkSession = sparkSession; this.mariaDbMapper = mariaDbMapper; @@ -68,7 +71,7 @@ public class SubsetServiceMariaDbImpl extends DataConnector implements SubsetSer public UUID create(DatabaseDto database, SubsetDto subset, Instant timestamp, UUID userId) throws QueryStoreInsertException, SQLException, QueryMalformedException, TableNotFoundException, ImageNotFoundException, ViewMalformedException { - final String statement = mariaDbMapper.subsetDtoToRawQuery(database, subset); + final String statement = mariaDbMapper.subsetDtoToRawQuery(context, database, subset); return storeQuery(database, statement, timestamp, userId); } diff --git a/dbrepo-metadata-service/api/pom.xml b/dbrepo-metadata-service/api/pom.xml index 37662b64cbb9c65d104871a349ed2d6f127f89b1..94db9a12304dff139a1019c1859ae9ee42ab9671 100644 --- a/dbrepo-metadata-service/api/pom.xml +++ b/dbrepo-metadata-service/api/pom.xml @@ -6,18 +6,18 @@ <parent> <groupId>at.tuwien</groupId> <artifactId>dbrepo-metadata-service</artifactId> - <version>1.7.1</version> + <version>1.7.2</version> </parent> <artifactId>dbrepo-metadata-service-api</artifactId> <name>dbrepo-metadata-service-api</name> - <version>1.7.1</version> + <version>1.7.2</version> <dependencies> <dependency> <groupId>at.tuwien</groupId> <artifactId>dbrepo-metadata-service-entities</artifactId> - <version>1.7.1</version> + <version>1.7.2</version> <scope>compile</scope> </dependency> </dependencies> diff --git a/dbrepo-metadata-service/entities/pom.xml b/dbrepo-metadata-service/entities/pom.xml index 76ef98f9f1f7100d5360326d9413466a35bf0add..fcbed64dfb0cb9aff7eab142afe9382513aa4b09 100644 --- a/dbrepo-metadata-service/entities/pom.xml +++ b/dbrepo-metadata-service/entities/pom.xml @@ -6,12 +6,12 @@ <parent> <groupId>at.tuwien</groupId> <artifactId>dbrepo-metadata-service</artifactId> - <version>1.7.1</version> + <version>1.7.2</version> </parent> <artifactId>dbrepo-metadata-service-entities</artifactId> <name>dbrepo-metadata-service-entity</name> - <version>1.7.1</version> + <version>1.7.2</version> <dependencies/> diff --git a/dbrepo-metadata-service/oai/pom.xml b/dbrepo-metadata-service/oai/pom.xml index 7a5df8b329e3ac371f65d28b2bae4a1532a329f0..b8f8251fad231e8a947af8cb47f1dda43739e463 100644 --- a/dbrepo-metadata-service/oai/pom.xml +++ b/dbrepo-metadata-service/oai/pom.xml @@ -6,12 +6,12 @@ <parent> <groupId>at.tuwien</groupId> <artifactId>dbrepo-metadata-service</artifactId> - <version>1.7.1</version> + <version>1.7.2</version> </parent> <artifactId>dbrepo-metadata-service-oai</artifactId> <name>dbrepo-metadata-service-oai</name> - <version>1.7.1</version> + <version>1.7.2</version> <dependencies/> diff --git a/dbrepo-metadata-service/pom.xml b/dbrepo-metadata-service/pom.xml index 53198bb0dead1ab4c2975b6cbf02d18584dd5688..783c6af6627c73d027fbedaaa398eef8833d532b 100644 --- a/dbrepo-metadata-service/pom.xml +++ b/dbrepo-metadata-service/pom.xml @@ -16,7 +16,7 @@ <groupId>at.tuwien</groupId> <artifactId>dbrepo-metadata-service</artifactId> <name>dbrepo-metadata-service</name> - <version>1.7.1</version> + <version>1.7.2</version> <description>Service that manages the metadata</description> diff --git a/dbrepo-metadata-service/report/pom.xml b/dbrepo-metadata-service/report/pom.xml index dc6186ed9c30a034c9a18360c365a50c5771e51d..07bcadccb154bfba857c8fa58dd4c88185d8664d 100644 --- a/dbrepo-metadata-service/report/pom.xml +++ b/dbrepo-metadata-service/report/pom.xml @@ -6,12 +6,12 @@ <parent> <artifactId>dbrepo-metadata-service</artifactId> <groupId>at.tuwien</groupId> - <version>1.7.1</version> + <version>1.7.2</version> </parent> <artifactId>dbrepo-metadata-service-report</artifactId> <name>dbrepo-metadata-service-report</name> - <version>1.7.1</version> + <version>1.7.2</version> <dependencies> <dependency> diff --git a/dbrepo-metadata-service/repositories/pom.xml b/dbrepo-metadata-service/repositories/pom.xml index 273740f1d07c4c0575dd9b59754d27eb4335eaa8..5ef70b7ca5e9f71b37ce7ab6e732476f508e84b9 100644 --- a/dbrepo-metadata-service/repositories/pom.xml +++ b/dbrepo-metadata-service/repositories/pom.xml @@ -6,12 +6,12 @@ <parent> <artifactId>dbrepo-metadata-service</artifactId> <groupId>at.tuwien</groupId> - <version>1.7.1</version> + <version>1.7.2</version> </parent> <artifactId>dbrepo-metadata-service-repositories</artifactId> <name>dbrepo-metadata-service-repositories</name> - <version>1.7.1</version> + <version>1.7.2</version> <dependencies> <dependency> diff --git a/dbrepo-metadata-service/rest-service/pom.xml b/dbrepo-metadata-service/rest-service/pom.xml index 6427153b504248bda78827974eedae242e6e6c08..96ca585be428bdc157c8f51bd10a1ef1ac1872e5 100644 --- a/dbrepo-metadata-service/rest-service/pom.xml +++ b/dbrepo-metadata-service/rest-service/pom.xml @@ -6,12 +6,12 @@ <parent> <artifactId>dbrepo-metadata-service</artifactId> <groupId>at.tuwien</groupId> - <version>1.7.1</version> + <version>1.7.2</version> </parent> <artifactId>dbrepo-metadata-service-rest-service</artifactId> <name>dbrepo-metadata-service-rest</name> - <version>1.7.1</version> + <version>1.7.2</version> <dependencies> <dependency> diff --git a/dbrepo-metadata-service/services/pom.xml b/dbrepo-metadata-service/services/pom.xml index f06002c2bad12d8ed2307167dff0478c8ac98222..19a2f78f8e54cc5a0f7cebedf9fbf18e848e0e11 100644 --- a/dbrepo-metadata-service/services/pom.xml +++ b/dbrepo-metadata-service/services/pom.xml @@ -6,12 +6,12 @@ <parent> <artifactId>dbrepo-metadata-service</artifactId> <groupId>at.tuwien</groupId> - <version>1.7.1</version> + <version>1.7.2</version> </parent> <artifactId>dbrepo-metadata-service-services</artifactId> <name>dbrepo-metadata-service-services</name> - <version>1.7.1</version> + <version>1.7.2</version> <dependencies> <dependency> diff --git a/dbrepo-metadata-service/test/pom.xml b/dbrepo-metadata-service/test/pom.xml index 3f68c6efdeebcebaea5f897aac65d6c22a43e2d6..1a75b2ea9ba7464099f5306baa50010e1379a601 100644 --- a/dbrepo-metadata-service/test/pom.xml +++ b/dbrepo-metadata-service/test/pom.xml @@ -6,12 +6,12 @@ <parent> <groupId>at.tuwien</groupId> <artifactId>dbrepo-metadata-service</artifactId> - <version>1.7.1</version> + <version>1.7.2</version> </parent> <artifactId>dbrepo-metadata-service-test</artifactId> <name>dbrepo-metadata-service-test</name> - <version>1.7.1</version> + <version>1.7.2</version> <dependencies> <dependency> diff --git a/dbrepo-search-service/Pipfile b/dbrepo-search-service/Pipfile index 605020f3ef6702ee9706a3cd87d34c3ad90cd424..b2db00687f00885f4900cf6be1112e73613045ba 100644 --- a/dbrepo-search-service/Pipfile +++ b/dbrepo-search-service/Pipfile @@ -18,7 +18,7 @@ jwt = "~=1.3" testcontainers-opensearch = "*" pytest = "*" rdflib = "*" -dbrepo = {path = "./lib/dbrepo-1.7.1.tar.gz"} +dbrepo = {path = "./lib/dbrepo-1.7.2.tar.gz"} gunicorn = "*" [dev-packages] diff --git a/dbrepo-search-service/Pipfile.lock b/dbrepo-search-service/Pipfile.lock index e520c5d0f8890461117ca6d7ab6645de932c2261..6e88d1f2e4479e1f4c16c21543075a8061c9c9f8 100644 --- a/dbrepo-search-service/Pipfile.lock +++ b/dbrepo-search-service/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "26523c9bb9e0fc013fddc72cf725c325312b536cb9ea8440b3870b9ebd263b7b" + "sha256": "516a2ba81d7f60434ccc0b9a1f08b35e5a9cb07a69343c22689161426586c38f" }, "pipfile-spec": 6, "requires": { @@ -18,11 +18,11 @@ "default": { "aiohappyeyeballs": { "hashes": [ - "sha256:19728772cb12263077982d2f55453babd8bec6a052a926cd5c0c42796da8bf62", - "sha256:6cac4f5dd6e34a9644e69cf9021ef679e4394f54e58a183056d12009e42ea9e3" + "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", + "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8" ], "markers": "python_version >= '3.9'", - "version": "==2.4.8" + "version": "==2.6.1" }, "aiohttp": { "hashes": [ @@ -129,11 +129,11 @@ }, "attrs": { "hashes": [ - "sha256:1c97078a80c814273a76b2a298a932eb681c87415c11dee0a6921de7f1b02c3e", - "sha256:c75a69e28a550a7e93789579c22aa26b0f5b83b75dc4e08fe092980051e1090a" + "sha256:18a06db706db43ac232cce80443fcd9f2500702059ecf53489e3c5a3f417acaf", + "sha256:611344ff0a5fed735d86d7784610c84f8126b95e549bcad9ff61b4242f2d386b" ], "markers": "python_version >= '3.8'", - "version": "==25.1.0" + "version": "==25.2.0" }, "blinker": { "hashes": [ @@ -373,9 +373,9 @@ }, "dbrepo": { "hashes": [ - "sha256:e70ea4f7030191eb80116e5d0a4b17b041c94c80359d5d8e707d62218edd9a54" + "sha256:e7c1d1a6c0c251e68ce8b865b3e5e95545cc5d861f0d0014a6ad1d8842eb21ed" ], - "path": "./lib/dbrepo-1.7.1.tar.gz" + "path": "./lib/dbrepo-1.7.2.tar.gz" }, "docker": { "hashes": [ @@ -653,11 +653,11 @@ }, "jinja2": { "hashes": [ - "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb", - "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb" + "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", + "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67" ], "markers": "python_version >= '3.7'", - "version": "==3.1.5" + "version": "==3.1.6" }, "jsonschema": { "hashes": [ @@ -1008,11 +1008,11 @@ }, "prometheus-flask-exporter": { "hashes": [ - "sha256:587c770a1061e93d72c5cbcdefbd7b633fb764e39dffd7dd16932c9124559244", - "sha256:ab49b2c40b57cd35cd51e91e59b3c306b3754477095c4f3cf679034c5122398c" + "sha256:41fc9bbd7d48cc958ed8384aacf60c3621d9e903768be61c4e7f0c63872eaf1a", + "sha256:94922a636d4c1d8b68e1ee605c30a23e9bbb0b21756df8222aa919634871784c" ], "index": "pypi", - "version": "==0.23.1" + "version": "==0.23.2" }, "propcache": { "hashes": [ @@ -1492,66 +1492,66 @@ }, "sqlalchemy": { "hashes": [ - "sha256:0398361acebb42975deb747a824b5188817d32b5c8f8aba767d51ad0cc7bb08d", - "sha256:0561832b04c6071bac3aad45b0d3bb6d2c4f46a8409f0a7a9c9fa6673b41bc03", - "sha256:07258341402a718f166618470cde0c34e4cec85a39767dce4e24f61ba5e667ea", - "sha256:0a826f21848632add58bef4f755a33d45105d25656a0c849f2dc2df1c71f6f50", - "sha256:1052723e6cd95312f6a6eff9a279fd41bbae67633415373fdac3c430eca3425d", - "sha256:12d5b06a1f3aeccf295a5843c86835033797fea292c60e72b07bcb5d820e6dd3", - "sha256:12f5c9ed53334c3ce719155424dc5407aaa4f6cadeb09c5b627e06abb93933a1", - "sha256:2a0ef3f98175d77180ffdc623d38e9f1736e8d86b6ba70bff182a7e68bed7727", - "sha256:2f2951dc4b4f990a4b394d6b382accb33141d4d3bd3ef4e2b27287135d6bdd68", - "sha256:3868acb639c136d98107c9096303d2d8e5da2880f7706f9f8c06a7f961961149", - "sha256:386b7d136919bb66ced64d2228b92d66140de5fefb3c7df6bd79069a269a7b06", - "sha256:3d3043375dd5bbcb2282894cbb12e6c559654c67b5fffb462fda815a55bf93f7", - "sha256:3e35d5565b35b66905b79ca4ae85840a8d40d31e0b3e2990f2e7692071b179ca", - "sha256:402c2316d95ed90d3d3c25ad0390afa52f4d2c56b348f212aa9c8d072a40eee5", - "sha256:40310db77a55512a18827488e592965d3dec6a3f1e3d8af3f8243134029daca3", - "sha256:40e9cdbd18c1f84631312b64993f7d755d85a3930252f6276a77432a2b25a2f3", - "sha256:49aa2cdd1e88adb1617c672a09bf4ebf2f05c9448c6dbeba096a3aeeb9d4d443", - "sha256:57dd41ba32430cbcc812041d4de8d2ca4651aeefad2626921ae2a23deb8cd6ff", - "sha256:5dba1cdb8f319084f5b00d41207b2079822aa8d6a4667c0f369fce85e34b0c86", - "sha256:5e1d9e429028ce04f187a9f522818386c8b076723cdbe9345708384f49ebcec6", - "sha256:63178c675d4c80def39f1febd625a6333f44c0ba269edd8a468b156394b27753", - "sha256:6493bc0eacdbb2c0f0d260d8988e943fee06089cd239bd7f3d0c45d1657a70e2", - "sha256:64aa8934200e222f72fcfd82ee71c0130a9c07d5725af6fe6e919017d095b297", - "sha256:665255e7aae5f38237b3a6eae49d2358d83a59f39ac21036413fab5d1e810578", - "sha256:6db316d6e340f862ec059dc12e395d71f39746a20503b124edc255973977b728", - "sha256:70065dfabf023b155a9c2a18f573e47e6ca709b9e8619b2e04c54d5bcf193178", - "sha256:8455aa60da49cb112df62b4721bd8ad3654a3a02b9452c783e651637a1f21fa2", - "sha256:8b0ac78898c50e2574e9f938d2e5caa8fe187d7a5b69b65faa1ea4648925b096", - "sha256:8bf312ed8ac096d674c6aa9131b249093c1b37c35db6a967daa4c84746bc1bc9", - "sha256:92f99f2623ff16bd4aaf786ccde759c1f676d39c7bf2855eb0b540e1ac4530c8", - "sha256:9c8bcad7fc12f0cc5896d8e10fdf703c45bd487294a986903fe032c72201596b", - "sha256:9cd136184dd5f58892f24001cdce986f5d7e96059d004118d5410671579834a4", - "sha256:9eb4fa13c8c7a2404b6a8e3772c17a55b1ba18bc711e25e4d6c0c9f5f541b02a", - "sha256:a2bc4e49e8329f3283d99840c136ff2cd1a29e49b5624a46a290f04dff48e079", - "sha256:a5645cd45f56895cfe3ca3459aed9ff2d3f9aaa29ff7edf557fa7a23515a3725", - "sha256:a9afbc3909d0274d6ac8ec891e30210563b2c8bdd52ebbda14146354e7a69373", - "sha256:aa498d1392216fae47eaf10c593e06c34476ced9549657fca713d0d1ba5f7248", - "sha256:afd776cf1ebfc7f9aa42a09cf19feadb40a26366802d86c1fba080d8e5e74bdd", - "sha256:b335a7c958bc945e10c522c069cd6e5804f4ff20f9a744dd38e748eb602cbbda", - "sha256:b3c4817dff8cef5697f5afe5fec6bc1783994d55a68391be24cb7d80d2dbc3a6", - "sha256:b79ee64d01d05a5476d5cceb3c27b5535e6bb84ee0f872ba60d9a8cd4d0e6579", - "sha256:b87a90f14c68c925817423b0424381f0e16d80fc9a1a1046ef202ab25b19a444", - "sha256:bf89e0e4a30714b357f5d46b6f20e0099d38b30d45fa68ea48589faf5f12f62d", - "sha256:c058b84c3b24812c859300f3b5abf300daa34df20d4d4f42e9652a4d1c48c8a4", - "sha256:c09a6ea87658695e527104cf857c70f79f14e9484605e205217aae0ec27b45fc", - "sha256:c57b8e0841f3fce7b703530ed70c7c36269c6d180ea2e02e36b34cb7288c50c7", - "sha256:c9cea5b756173bb86e2235f2f871b406a9b9d722417ae31e5391ccaef5348f2c", - "sha256:cb39ed598aaf102251483f3e4675c5dd6b289c8142210ef76ba24aae0a8f8aba", - "sha256:e036549ad14f2b414c725349cce0772ea34a7ab008e9cd67f9084e4f371d1f32", - "sha256:e185ea07a99ce8b8edfc788c586c538c4b1351007e614ceb708fd01b095ef33e", - "sha256:e5a4d82bdb4bf1ac1285a68eab02d253ab73355d9f0fe725a97e1e0fa689decb", - "sha256:eae27ad7580529a427cfdd52c87abb2dfb15ce2b7a3e0fc29fbb63e2ed6f8120", - "sha256:ecef029b69843b82048c5b347d8e6049356aa24ed644006c9a9d7098c3bd3bfd", - "sha256:ee3bee874cb1fadee2ff2b79fc9fc808aa638670f28b2145074538d4a6a5028e", - "sha256:f0d3de936b192980209d7b5149e3c98977c3810d401482d05fb6d668d53c1c63", - "sha256:f53c0d6a859b2db58332e0e6a921582a02c1677cc93d4cbb36fdf49709b327b2", - "sha256:f9d57f1b3061b3e21476b0ad5f0397b112b94ace21d1f439f2db472e568178ae" + "sha256:018ee97c558b499b58935c5a152aeabf6d36b3d55d91656abeb6d93d663c0c4c", + "sha256:01da15490c9df352fbc29859d3c7ba9cd1377791faeeb47c100832004c99472c", + "sha256:04545042969833cb92e13b0a3019549d284fd2423f318b6ba10e7aa687690a3c", + "sha256:06205eb98cb3dd52133ca6818bf5542397f1dd1b69f7ea28aa84413897380b06", + "sha256:08cf721bbd4391a0e765fe0fe8816e81d9f43cece54fdb5ac465c56efafecb3d", + "sha256:0d7e3866eb52d914aea50c9be74184a0feb86f9af8aaaa4daefe52b69378db0b", + "sha256:125a7763b263218a80759ad9ae2f3610aaf2c2fbbd78fff088d584edf81f3782", + "sha256:23c5aa33c01bd898f879db158537d7e7568b503b15aad60ea0c8da8109adf3e7", + "sha256:2600a50d590c22d99c424c394236899ba72f849a02b10e65b4c70149606408b5", + "sha256:2d7332868ce891eda48896131991f7f2be572d65b41a4050957242f8e935d5d7", + "sha256:2ed107331d188a286611cea9022de0afc437dd2d3c168e368169f27aa0f61338", + "sha256:3395e7ed89c6d264d38bea3bfb22ffe868f906a7985d03546ec7dc30221ea980", + "sha256:344cd1ec2b3c6bdd5dfde7ba7e3b879e0f8dd44181f16b895940be9b842fd2b6", + "sha256:34d5c49f18778a3665d707e6286545a30339ad545950773d43977e504815fa70", + "sha256:35e72518615aa5384ef4fae828e3af1b43102458b74a8c481f69af8abf7e802a", + "sha256:3eb14ba1a9d07c88669b7faf8f589be67871d6409305e73e036321d89f1d904e", + "sha256:412c6c126369ddae171c13987b38df5122cb92015cba6f9ee1193b867f3f1530", + "sha256:4600c7a659d381146e1160235918826c50c80994e07c5b26946a3e7ec6c99249", + "sha256:463ecfb907b256e94bfe7bcb31a6d8c7bc96eca7cbe39803e448a58bb9fcad02", + "sha256:4a06e6c8e31c98ddc770734c63903e39f1947c9e3e5e4bef515c5491b7737dde", + "sha256:4b2de1523d46e7016afc7e42db239bd41f2163316935de7c84d0e19af7e69538", + "sha256:4dabd775fd66cf17f31f8625fc0e4cfc5765f7982f94dc09b9e5868182cb71c0", + "sha256:4eff9c270afd23e2746e921e80182872058a7a592017b2713f33f96cc5f82e32", + "sha256:52607d0ebea43cf214e2ee84a6a76bc774176f97c5a774ce33277514875a718e", + "sha256:533e0f66c32093a987a30df3ad6ed21170db9d581d0b38e71396c49718fbb1ca", + "sha256:5493a8120d6fc185f60e7254fc056a6742f1db68c0f849cfc9ab46163c21df47", + "sha256:5d2d1fe548def3267b4c70a8568f108d1fed7cbbeccb9cc166e05af2abc25c22", + "sha256:5dfbc543578058c340360f851ddcecd7a1e26b0d9b5b69259b526da9edfa8875", + "sha256:66a40003bc244e4ad86b72abb9965d304726d05a939e8c09ce844d27af9e6d37", + "sha256:67de057fbcb04a066171bd9ee6bcb58738d89378ee3cabff0bffbf343ae1c787", + "sha256:6827f8c1b2f13f1420545bd6d5b3f9e0b85fe750388425be53d23c760dcf176b", + "sha256:6b35e07f1d57b79b86a7de8ecdcefb78485dab9851b9638c2c793c50203b2ae8", + "sha256:7399d45b62d755e9ebba94eb89437f80512c08edde8c63716552a3aade61eb42", + "sha256:788b6ff6728072b313802be13e88113c33696a9a1f2f6d634a97c20f7ef5ccce", + "sha256:78f1b79132a69fe8bd6b5d91ef433c8eb40688ba782b26f8c9f3d2d9ca23626f", + "sha256:79f4f502125a41b1b3b34449e747a6abfd52a709d539ea7769101696bdca6716", + "sha256:7a8517b6d4005facdbd7eb4e8cf54797dbca100a7df459fdaff4c5123265c1cd", + "sha256:7bd5c5ee1448b6408734eaa29c0d820d061ae18cb17232ce37848376dcfa3e92", + "sha256:7f5243357e6da9a90c56282f64b50d29cba2ee1f745381174caacc50d501b109", + "sha256:805cb481474e111ee3687c9047c5f3286e62496f09c0e82e8853338aaaa348f8", + "sha256:871f55e478b5a648c08dd24af44345406d0e636ffe021d64c9b57a4a11518304", + "sha256:87a1ce1f5e5dc4b6f4e0aac34e7bb535cb23bd4f5d9c799ed1633b65c2bcad8c", + "sha256:8a10ca7f8a1ea0fd5630f02feb055b0f5cdfcd07bb3715fc1b6f8cb72bf114e4", + "sha256:995c2bacdddcb640c2ca558e6760383dcdd68830160af92b5c6e6928ffd259b4", + "sha256:9f03143f8f851dd8de6b0c10784363712058f38209e926723c80654c1b40327a", + "sha256:a1c6b0a5e3e326a466d809b651c63f278b1256146a377a528b6938a279da334f", + "sha256:a28f9c238f1e143ff42ab3ba27990dfb964e5d413c0eb001b88794c5c4a528a9", + "sha256:b2cf5b5ddb69142511d5559c427ff00ec8c0919a1e6c09486e9c32636ea2b9dd", + "sha256:b761a6847f96fdc2d002e29e9e9ac2439c13b919adfd64e8ef49e75f6355c548", + "sha256:bf555f3e25ac3a70c67807b2949bfe15f377a40df84b71ab2c58d8593a1e036e", + "sha256:c08a972cbac2a14810463aec3a47ff218bb00c1a607e6689b531a7c589c50723", + "sha256:c457a38351fb6234781d054260c60e531047e4d07beca1889b558ff73dc2014b", + "sha256:c4c433f78c2908ae352848f56589c02b982d0e741b7905228fad628999799de4", + "sha256:d9f119e7736967c0ea03aff91ac7d04555ee038caf89bb855d93bbd04ae85b41", + "sha256:e6b0a1c7ed54a5361aaebb910c1fa864bae34273662bb4ff788a527eafd6e14d", + "sha256:f2bcb085faffcacf9319b1b1445a7e1cfdc6fb46c03f2dce7bc2d9a4b3c1cdc5", + "sha256:fe193d3ae297c423e0e567e240b4324d6b6c280a048e64c77a3ea6886cc2aa87" ], "markers": "python_version >= '3.7'", - "version": "==2.0.38" + "version": "==2.0.39" }, "sqlalchemy-utils": { "hashes": [ diff --git a/dbrepo-search-service/init/Pipfile b/dbrepo-search-service/init/Pipfile index 9a5559cf98006683941ab9dbf7bfe2309c43adcb..4500b61ee90a2f667485eef68cf329c6fd290daa 100644 --- a/dbrepo-search-service/init/Pipfile +++ b/dbrepo-search-service/init/Pipfile @@ -9,7 +9,7 @@ opensearch-py = "~=2.2" python-dotenv = "~=1.0" testcontainers-opensearch = "*" pytest = "*" -dbrepo = {path = "./lib/dbrepo-1.7.1.tar.gz"} +dbrepo = {path = "./lib/dbrepo-1.7.2.tar.gz"} rdflib = "*" [dev-packages] diff --git a/dbrepo-search-service/init/Pipfile.lock b/dbrepo-search-service/init/Pipfile.lock index 7e637809c29b2223d18dc64896ae84432efbf7c5..611938f07ed74c4300fbd055599ca75ff11e0289 100644 --- a/dbrepo-search-service/init/Pipfile.lock +++ b/dbrepo-search-service/init/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "ed0f513080ab2ba2ac3f24121f21348ea1265e6722066cb6d9a0240fae2e76ae" + "sha256": "034876149745bd1c09898250cf1ca9d2ed75fd0193147ef3b66b675559ec4b21" }, "pipfile-spec": 6, "requires": { @@ -18,11 +18,11 @@ "default": { "aiohappyeyeballs": { "hashes": [ - "sha256:19728772cb12263077982d2f55453babd8bec6a052a926cd5c0c42796da8bf62", - "sha256:6cac4f5dd6e34a9644e69cf9021ef679e4394f54e58a183056d12009e42ea9e3" + "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", + "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8" ], "markers": "python_version >= '3.9'", - "version": "==2.4.8" + "version": "==2.6.1" }, "aiohttp": { "hashes": [ @@ -129,11 +129,11 @@ }, "attrs": { "hashes": [ - "sha256:1c97078a80c814273a76b2a298a932eb681c87415c11dee0a6921de7f1b02c3e", - "sha256:c75a69e28a550a7e93789579c22aa26b0f5b83b75dc4e08fe092980051e1090a" + "sha256:18a06db706db43ac232cce80443fcd9f2500702059ecf53489e3c5a3f417acaf", + "sha256:611344ff0a5fed735d86d7784610c84f8126b95e549bcad9ff61b4242f2d386b" ], "markers": "python_version >= '3.8'", - "version": "==25.1.0" + "version": "==25.2.0" }, "blinker": { "hashes": [ @@ -259,9 +259,9 @@ }, "dbrepo": { "hashes": [ - "sha256:e70ea4f7030191eb80116e5d0a4b17b041c94c80359d5d8e707d62218edd9a54" + "sha256:e7c1d1a6c0c251e68ce8b865b3e5e95545cc5d861f0d0014a6ad1d8842eb21ed" ], - "path": "./lib/dbrepo-1.7.1.tar.gz" + "path": "./lib/dbrepo-1.7.2.tar.gz" }, "docker": { "hashes": [ @@ -410,11 +410,11 @@ }, "jinja2": { "hashes": [ - "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb", - "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb" + "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", + "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67" ], "markers": "python_version >= '3.7'", - "version": "==3.1.5" + "version": "==3.1.6" }, "markupsafe": { "hashes": [ diff --git a/dbrepo-search-service/init/lib/dbrepo-1.7.1.tar.gz b/dbrepo-search-service/init/lib/dbrepo-1.7.1.tar.gz deleted file mode 100644 index 6708e1d892771d6cdf9293a6e9f5197f4dd9e304..0000000000000000000000000000000000000000 Binary files a/dbrepo-search-service/init/lib/dbrepo-1.7.1.tar.gz and /dev/null differ diff --git a/dbrepo-search-service/lib/dbrepo-1.7.1-py3-none-any.whl b/dbrepo-search-service/init/lib/dbrepo-1.7.2-py3-none-any.whl similarity index 59% rename from dbrepo-search-service/lib/dbrepo-1.7.1-py3-none-any.whl rename to dbrepo-search-service/init/lib/dbrepo-1.7.2-py3-none-any.whl index 61f52896c18ecbec8090177b38b8dbaeb0e1a95e..c66b0e29e8b7cd48aa8393e391690bf1bdf09311 100644 Binary files a/dbrepo-search-service/lib/dbrepo-1.7.1-py3-none-any.whl and b/dbrepo-search-service/init/lib/dbrepo-1.7.2-py3-none-any.whl differ diff --git a/dbrepo-search-service/init/lib/dbrepo-1.7.2.tar.gz b/dbrepo-search-service/init/lib/dbrepo-1.7.2.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..12cef6f73928370726f75f4f3909aa6510049543 Binary files /dev/null and b/dbrepo-search-service/init/lib/dbrepo-1.7.2.tar.gz differ diff --git a/dbrepo-search-service/lib/dbrepo-1.7.1.tar.gz b/dbrepo-search-service/lib/dbrepo-1.7.1.tar.gz deleted file mode 100644 index 6708e1d892771d6cdf9293a6e9f5197f4dd9e304..0000000000000000000000000000000000000000 Binary files a/dbrepo-search-service/lib/dbrepo-1.7.1.tar.gz and /dev/null differ diff --git a/dbrepo-search-service/init/lib/dbrepo-1.7.1-py3-none-any.whl b/dbrepo-search-service/lib/dbrepo-1.7.2-py3-none-any.whl similarity index 59% rename from dbrepo-search-service/init/lib/dbrepo-1.7.1-py3-none-any.whl rename to dbrepo-search-service/lib/dbrepo-1.7.2-py3-none-any.whl index 61f52896c18ecbec8090177b38b8dbaeb0e1a95e..c66b0e29e8b7cd48aa8393e391690bf1bdf09311 100644 Binary files a/dbrepo-search-service/init/lib/dbrepo-1.7.1-py3-none-any.whl and b/dbrepo-search-service/lib/dbrepo-1.7.2-py3-none-any.whl differ diff --git a/dbrepo-search-service/lib/dbrepo-1.7.2.tar.gz b/dbrepo-search-service/lib/dbrepo-1.7.2.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..12cef6f73928370726f75f4f3909aa6510049543 Binary files /dev/null and b/dbrepo-search-service/lib/dbrepo-1.7.2.tar.gz differ diff --git a/docker-compose.yml b/docker-compose.yml index 84905a7d057f6ea27dae62f7402eaa53f0d92cb7..877da8d622e43efe68cf4ee3fd47cbf1d095729d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -21,7 +21,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}" @@ -484,7 +483,6 @@ services: volumes: - dashboard-service-data:/opt/bitnami/grafana/data environment: - BITNAMI_DEBUG: true GF_SERVER_DOMAIN: "dashboard-service" GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION: "true" LDAP_ADMIN_USERNAME: "${IDENTITY_SERVICE_ADMIN_USERNAME:-admin}" diff --git a/helm/dbrepo/Chart.yaml b/helm/dbrepo/Chart.yaml index ddcbbcc3431d01f7d52cc435a2261b0800677d2a..f54d690487f9b13d8e8582fa2345116780dae602 100644 --- a/helm/dbrepo/Chart.yaml +++ b/helm/dbrepo/Chart.yaml @@ -7,8 +7,8 @@ description: Helm Chart for installing DBRepo sources: - https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services type: application -version: "1.7.1" -appVersion: "1.7.1" +version: "1.7.2" +appVersion: "1.7.2" keywords: - dbrepo maintainers: diff --git a/helm/dbrepo/README.md b/helm/dbrepo/README.md index a1ba96733100f8b70c22c2764ae5d48486466a74..56a34d5a70f93113f2f676c6529b4666fa611745 100644 --- a/helm/dbrepo/README.md +++ b/helm/dbrepo/README.md @@ -11,7 +11,7 @@ sample [ for your deployment and update the variables, especially `hostname`. ```bash -helm install my-release "oci://registry.datalab.tuwien.ac.at/dbrepo/helm/dbrepo" --values ./values.yaml --version "1.7.1" +helm install my-release "oci://registry.datalab.tuwien.ac.at/dbrepo/helm/dbrepo" --values ./values.yaml --version "1.7.2" ``` ## Prerequisites @@ -34,7 +34,7 @@ variable when you increase the available Pod memory for performance. To install the chart with the release name `my-release`: ```bash -helm install my-release "oci://oci://registry.datalab.tuwien.ac.at/dbrepo/helm" --values ./values.yaml --version "1.7.1" +helm install my-release "oci://oci://registry.datalab.tuwien.ac.at/dbrepo/helm" --values ./values.yaml --version "1.7.2" ``` The command deploys DBRepo on the Kubernetes cluster in the default configuration. The Parameters section lists the diff --git a/helm/dbrepo/files/create-event-listener.jar b/helm/dbrepo/files/create-event-listener.jar index 72d17863f14cc38c1fd026dd7e40e56a25fc4318..57f3daf0eb71bd8de1e9a6374da6e6c6403ac104 100644 Binary files a/helm/dbrepo/files/create-event-listener.jar and b/helm/dbrepo/files/create-event-listener.jar differ diff --git a/helm/dbrepo/values.yaml b/helm/dbrepo/values.yaml index 418009deec6a494536f359b8ecae102a5d8df58b..ca399d3e5cd0dadf24809982b47cdb6b4ad4d915 100644 --- a/helm/dbrepo/values.yaml +++ b/helm/dbrepo/values.yaml @@ -122,7 +122,7 @@ authservice: setupJob: image: ## @skip authservice.setupJob.image.name - name: registry.datalab.tuwien.ac.at/dbrepo/auth-service-init:1.7.1 + name: registry.datalab.tuwien.ac.at/dbrepo/auth-service-init:1.7.2 ## @param authservice.setupJob.resourcesPreset The container resource preset resourcesPreset: "nano" ## @param authservice.setupJob.resources Set container requests and limits for different resources like CPU or memory (essential for production workloads) @@ -415,7 +415,7 @@ analyseservice: enabled: true image: ## @skip analyseservice.image.name - name: registry.datalab.tuwien.ac.at/dbrepo/analyse-service:1.7.1 + name: registry.datalab.tuwien.ac.at/dbrepo/analyse-service:1.7.2 ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod podSecurityContext: ## @param analyseservice.podSecurityContext.enabled Enable pods' Security Context @@ -476,7 +476,7 @@ metadataservice: enabled: true image: ## @skip metadataservice.image.name - name: registry.datalab.tuwien.ac.at/dbrepo/metadata-service:1.7.1 + name: registry.datalab.tuwien.ac.at/dbrepo/metadata-service:1.7.2 ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod podSecurityContext: ## @param metadataservice.podSecurityContext.enabled Enable pods' Security Context @@ -573,7 +573,7 @@ dataservice: endpoint: http://data-service image: ## @skip dataservice.image.name - name: registry.datalab.tuwien.ac.at/dbrepo/data-service:1.7.1 + name: registry.datalab.tuwien.ac.at/dbrepo/data-service:1.7.2 ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod podSecurityContext: ## @param dataservice.podSecurityContext.enabled Enable pods' Security Context @@ -659,7 +659,7 @@ searchservice: endpoint: http://search-service image: ## @skip searchservice.image.name - name: registry.datalab.tuwien.ac.at/dbrepo/search-service:1.7.1 + name: registry.datalab.tuwien.ac.at/dbrepo/search-service:1.7.2 ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod podSecurityContext: ## @param searchservice.podSecurityContext.enabled Enable pods' Security Context @@ -706,7 +706,7 @@ searchservice: init: image: ## @skip searchservice.init.image.name - name: registry.datalab.tuwien.ac.at/dbrepo/search-service-init:1.7.1 + name: registry.datalab.tuwien.ac.at/dbrepo/search-service-init:1.7.2 ## @param searchservice.init.resourcesPreset The container resource preset resourcesPreset: "nano" ## @param searchservice.init.resources Set container requests and limits for different resources like CPU or memory (essential for production workloads) @@ -767,7 +767,7 @@ storageservice: init: image: ## @skip storageservice.init.image.name - name: registry.datalab.tuwien.ac.at/dbrepo/storage-service-init:1.7.1 + name: registry.datalab.tuwien.ac.at/dbrepo/storage-service-init:1.7.2 s3: ## @param storageservice.init.s3.endpoint The S3-capable endpoint the microservice connects to. endpoint: http://storage-service-s3:8333 @@ -876,7 +876,7 @@ ui: enabled: true image: ## @skip ui.image.name - name: registry.datalab.tuwien.ac.at/dbrepo/ui:1.7.1 + name: registry.datalab.tuwien.ac.at/dbrepo/ui:1.7.2 ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod podSecurityContext: ## @param ui.podSecurityContext.enabled Enable pods' Security Context diff --git a/install.sh b/install.sh index 84b139ddf95128d994a912a3de3d1ba6db1cef1d..5677d91b1535f5d4754bd7ec597ace618d99ea29 100644 --- a/install.sh +++ b/install.sh @@ -1,7 +1,7 @@ #!/bin/bash # preset -VERSION="1.7.1" +VERSION="1.7.2" MIN_CPU=8 MIN_RAM=4 MIN_MAP_COUNT=262144 diff --git a/lib/python/docs/index.rst b/lib/python/docs/index.rst index 2ebdc80b2d703c3d3e799950079f3a4c7a9d83df..ede20730f5d54c90fba7da03de453cb7a7a9f7f3 100644 --- a/lib/python/docs/index.rst +++ b/lib/python/docs/index.rst @@ -6,7 +6,7 @@ Pandas `DataFrame <https://pandas.pydata.org/docs/reference/api/pandas.DataFrame provides an object-oriented API as well as low-level access to DBRepo services. .. note:: - The SDK has been implemented and documented for DBRepo version 1.7.1, earlier versions may be supported but are not tested for compatibility. + The SDK has been implemented and documented for DBRepo version 1.7.2, earlier versions may be supported but are not tested for compatibility. Quickstart ---------- diff --git a/lib/python/pyproject.toml b/lib/python/pyproject.toml index 61b31fcce1795064df1451c82193f2ed73e836db..4814bf4db02e4dcac6c8385947530e27741cf3a9 100644 --- a/lib/python/pyproject.toml +++ b/lib/python/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "dbrepo" -version = "1.7.1" +version = "1.7.2" description = "DBRepo Python Library" keywords = [ "DBRepo", diff --git a/lib/python/setup.py b/lib/python/setup.py index 73d4ced6de7822ff0d430c4488f226a553894e7c..afc15e4a2f5b6ff8a7c8a0079b5bdd916c1b1af3 100644 --- a/lib/python/setup.py +++ b/lib/python/setup.py @@ -2,7 +2,7 @@ from distutils.core import setup setup(name="dbrepo", - version="1.7.1", + version="1.7.2", description="A library for communicating with DBRepo", url="https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7/", author="Martin Weise", diff --git a/sonar-project.properties b/sonar-project.properties index 24cf0e14a408513b25631817b2b3c8fcaf6f05ee..eb3050bc96e75c9446c340a1d34f6e606335be85 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -2,7 +2,7 @@ sonar.projectKey=fair-data-austria-db-repository_fda-services_a57fa043-ab99-4cdd-a721-162d9a916d77 sonar.host.url=https://s39.datalab.tuwien.ac.at # project -sonar.projectVersion=1.7.1 +sonar.projectVersion=1.7.2 # general sonar.qualitygate.wait=true sonar.projectCreation.mainBranchName=master