From ad73ea9306bfb6f96eb7d330630865aa92ac4bd9 Mon Sep 17 00:00:00 2001
From: Martin Weise <martin.weise@tuwien.ac.at>
Date: Sun, 23 Feb 2025 12:10:09 +0100
Subject: [PATCH] Update migration script

Signed-off-by: Martin Weise <martin.weise@tuwien.ac.at>
---
 .gitlab-ci.yml                                |   2 +-
 .../target/create-event-listener.jar          | Bin 10145 -> 10141 bytes
 .../migration/16/gen_data_sql.py              | 152 ++++++++++++++++++
 .../migration/16/requirements.txt             |   1 +
 .../tuwien/endpoints/IdentifierEndpoint.java  |   2 +-
 helm/dbrepo/files/create-event-listener.jar   | Bin 10145 -> 10141 bytes
 lib/python/dbrepo/RestClient.py               |  33 +++-
 lib/python/dbrepo/api/dto.py                  |  19 ++-
 lib/python/pyproject.toml                     |   2 +-
 lib/python/setup.py                           |   2 +-
 lib/python/tests/test_unit_image.py           |  31 ++++
 lib/python/tests/test_unit_messages.py        |  31 ++++
 12 files changed, 263 insertions(+), 12 deletions(-)
 create mode 100644 dbrepo-metadata-db/migration/16/gen_data_sql.py
 create mode 100644 dbrepo-metadata-db/migration/16/requirements.txt
 create mode 100644 lib/python/tests/test_unit_image.py
 create mode 100644 lib/python/tests/test_unit_messages.py

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 5a47aa19e5..0cfcd600cd 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -403,7 +403,7 @@ test-lib:
   script:
     - "pip install pipenv"
     - "pipenv install gunicorn && pipenv install --dev --system --deploy"
-    - cd ./lib/python/ && coverage run -m pytest tests/test_unit_analyse.py tests/test_unit_container.py tests/test_unit_database.py tests/test_unit_identifier.py tests/test_unit_license.py tests/test_unit_query.py tests/test_unit_rest_client.py tests/test_unit_table.py tests/test_unit_user.py tests/test_unit_view.py --junitxml=report.xml && coverage html --omit="test/*" && coverage report --omit="test/*" > ./coverage.txt
+    - cd ./lib/python/ && coverage run -m pytest tests/test_unit_analyse.py tests/test_unit_container.py tests/test_unit_database.py tests/test_unit_identifier.py tests/test_unit_image.py tests/test_unit_messages.py tests/test_unit_license.py tests/test_unit_query.py tests/test_unit_rest_client.py tests/test_unit_table.py tests/test_unit_user.py tests/test_unit_view.py --junitxml=report.xml && coverage html --omit="test/*" && coverage report --omit="test/*" > ./coverage.txt
     - "cat ./coverage.txt | grep -o 'TOTAL[^%]*%'"
   artifacts:
     when: always
diff --git a/dbrepo-auth-service/listeners/target/create-event-listener.jar b/dbrepo-auth-service/listeners/target/create-event-listener.jar
index f370c8825750a431296ef68c3d482a2e4eee9389..a33db1e9045a92823996c61a9223aafb0d25404e 100644
GIT binary patch
delta 4486
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
FAOO@xI!pin

delta 4518
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
Vk%56h7{xrr$%X1_Y+IE;f&jt<B98z7

diff --git a/dbrepo-metadata-db/migration/16/gen_data_sql.py b/dbrepo-metadata-db/migration/16/gen_data_sql.py
new file mode 100644
index 0000000000..eeade6f3ab
--- /dev/null
+++ b/dbrepo-metadata-db/migration/16/gen_data_sql.py
@@ -0,0 +1,152 @@
+#!/usr/bin/env python3
+import os
+import uuid
+
+from dbrepo.RestClient import RestClient
+
+endpoint = os.getenv('METADATA_SERVICE_ENDPOINT', 'http://localhost')
+username = os.getenv('SYSTEM_USERNAME', 'admin')
+password = os.getenv('SYSTEM_PASSWORD', 'admin')
+client = RestClient(endpoint=endpoint, username=username, password=password)
+
+plan: [str] = []
+
+
+def update_concepts() -> None:
+    plan.append("-- concepts")
+    plan.append("BEGIN;")
+    for concept in client.get_concepts():
+        old_id: int = concept.id
+        new_id: uuid = uuid.uuid4()
+        plan.append(f"UPDATE mdb_columns_concepts SET id = '{new_id}' WHERE id = {old_id};")
+        plan.append(f"UPDATE mdb_concepts SET id = '{new_id}' WHERE id = {old_id};")
+    plan.append("COMMIT;")
+
+
+def update_ontologies() -> None:
+    plan.append("-- ontologies")
+    plan.append("BEGIN;")
+    plan.append(f"UPDATE mdb_ontology SET id = UUID()")
+    plan.append("COMMIT;")
+
+
+def update_units() -> None:
+    plan.append("-- units")
+    plan.append("BEGIN;")
+    for unit in client.get_units():
+        old_id: int = unit.id
+        new_id: uuid = uuid.uuid4()
+        plan.append(f"UPDATE mdb_columns_units SET id = '{new_id}' WHERE id = {old_id};")
+        plan.append(f"UPDATE mdb_units SET id = '{new_id}' WHERE id = {old_id};")
+    plan.append("COMMIT;")
+
+
+def update_images() -> None:
+    plan.append("-- images")
+    plan.append("BEGIN;")
+    for image in client.get_images():
+        old_id: int = image.id
+        new_id: uuid = uuid.uuid4()
+        plan.append(f"UPDATE mdb_images SET id = '{new_id}' WHERE id = {old_id};")
+        plan.append(f"UPDATE mdb_image_operators SET id = UUID(), image_id = '{new_id}' WHERE image_id = {old_id};")
+        plan.append(f"UPDATE mdb_image_types SET id = UUID(), image_id = '{new_id}' WHERE image_id = {old_id};")
+        plan.append(f"UPDATE mdb_containers SET id = UUID(), image_id = '{new_id}' WHERE image_id = {old_id};")
+    plan.append("COMMIT;")
+
+
+def update_containers() -> None:
+    plan.append("-- containers")
+    plan.append("BEGIN;")
+    for containers in client.get_containers():
+        old_id: int = containers.id
+        new_id: uuid = uuid.uuid4()
+        plan.append(f"UPDATE mdb_containers SET id = '{new_id}' WHERE id = {old_id};")
+        plan.append(f"UPDATE mdb_databases SET cid = '{new_id}' WHERE cid = {old_id};")
+    plan.append("COMMIT;")
+
+
+def update_databases() -> None:
+    plan.append("-- databases")
+    plan.append("BEGIN;")
+    for _database in client.get_databases():
+        database = client.get_database(database_id=_database.id)
+        old_id: int = database.id
+        new_id: uuid = uuid.uuid4()
+        plan.append(f"UPDATE mdb_tables SET tDBID = '{new_id}' WHERE tDBID = {old_id};")
+        plan.append(f"UPDATE mdb_have_access SET database_id = '{new_id}' WHERE database_id = {old_id};")
+        plan.append(f"UPDATE mdb_views SET vdbid = '{new_id}' WHERE vdbid = {old_id};")
+        plan.append(f"UPDATE mdb_identifiers SET dbid = '{new_id}' WHERE dbid = {old_id};")
+        plan.append(f"UPDATE mdb_access SET aDBID = '{new_id}' WHERE aDBID = {old_id};")
+        for view in database.views:
+            v_old_id: int = view.id
+            v_new_id: uuid = uuid.uuid4()
+            plan.append(f"UPDATE mdb_identifiers SET vid = '{v_new_id}' WHERE vid = {v_old_id};")
+            plan.append(f"UPDATE mdb_view_columns SET id = UUID(), view_id = '{v_new_id}' WHERE tid = {v_old_id};")
+        for table in database.tables:
+            tbl_old_id: int = table.id
+            tbl_new_id: uuid = uuid.uuid4()
+            plan.append(f"UPDATE mdb_identifiers SET tid = '{tbl_new_id}' WHERE tid = {tbl_old_id};")
+            plan.append(f"UPDATE mdb_constraints_checks SET id = UUID(), tid = '{tbl_new_id}' WHERE tid = {tbl_old_id};")
+            for fk in table.constraints.foreign_keys:
+                fk_old_id: int = fk.id
+                fk_new_id: uuid = uuid.uuid4()
+                plan.append(f"UPDATE mdb_constraints_foreign_key SET id = '{fk_new_id}', tid = '{tbl_new_id}' WHERE id = {fk_old_id};")
+                for fkref in fk.references:
+                    plan.append(f"UPDATE mdb_constraints_foreign_key_reference SET id = UUID(), fkid = '{fk_new_id}' WHERE fkid = {fkref};")
+            for pk in table.constraints.primary_key:
+                pk_old_id: int = pk.id
+                plan.append(f"UPDATE mdb_constraints_primary_key SET pkid = UUID(), tID = '{tbl_new_id}' WHERE tID = {pk_old_id};")
+            for uk in table.constraints.uniques:
+                uk_old_id: int = uk.id
+                uk_new_id: uuid = uuid.uuid4()
+                plan.append(f"UPDATE mdb_constraints_unique SET uid = '{uk_new_id}', tid = '{tbl_new_id}' WHERE uid = {uk_old_id}")
+                plan.append(f"UPDATE mdb_constraints_unique_columns SET id = UUID(), uid = '{uk_new_id}' WHERE uid = {uk_old_id}")
+            for column in table.columns:
+                col_old_id: int = column.id
+                col_new_id: uuid = uuid.uuid4()
+                plan.append(f"UPDATE mdb_columns SET ID = '{col_new_id}' WHERE ID = {col_old_id};")
+                plan.append(f"UPDATE mdb_constraints_unique_columns SET cid = '{col_new_id}' WHERE cid = {col_old_id};")
+                plan.append(f"UPDATE mdb_constraints_primary_key SET cid = '{col_new_id}' WHERE cid = {col_old_id};")
+                plan.append(f"UPDATE mdb_constraints_foreign_key_reference SET cid = '{col_new_id}' WHERE cid = {col_old_id};")
+                plan.append(f"UPDATE mdb_constraints_foreign_key_reference SET rcid = '{col_new_id}' WHERE rcid = {col_old_id};")
+                plan.append(f"UPDATE mdb_columns_concepts SET cID = '{col_new_id}' WHERE cID = {col_old_id};")
+                plan.append(f"UPDATE mdb_columns_units SET cID = '{col_new_id}' WHERE cID = {col_old_id};")
+                plan.append(f"UPDATE mdb_columns_sets SET column_id = '{col_new_id}' WHERE column_id = {col_old_id};")
+                plan.append(f"UPDATE mdb_columns_enums SET column_id = '{col_new_id}' WHERE column_id = {col_old_id};")
+            plan.append(f"UPDATE mdb_tables SET ID = '{tbl_new_id}' WHERE ID = {tbl_old_id};")
+        plan.append(f"UPDATE mdb_databases SET id = '{new_id}' WHERE id = {old_id};")
+    plan.append("COMMIT;")
+
+def update_messages() -> None:
+    plan.append("-- messages")
+    plan.append("BEGIN;")
+    plan.append(f"UPDATE mdb_banner_messages SET ID = UUID();")
+    plan.append("COMMIT;")
+
+def update_identifiers() -> None:
+    plan.append("-- identifiers")
+    plan.append("BEGIN;")
+    for identified in client.get_identifiers():
+        i_old_id: int = identified.id
+        i_new_id: uuid = uuid.uuid4()
+        plan.append(f"UPDATE mdb_identifiers SET ID = '{i_new_id}' WHERE id = {i_old_id};")
+        plan.append(f"UPDATE mdb_identifier_creators SET id = UUID(), pid = '{i_new_id}' WHERE pid = {i_old_id};")
+        plan.append(f"UPDATE mdb_identifier_descriptions SET id = UUID(), pid = '{i_new_id}' WHERE pid = {i_old_id};")
+        plan.append(f"UPDATE mdb_identifier_titles SET id = UUID(), pid = '{i_new_id}' WHERE pid = {i_old_id};")
+        plan.append(f"UPDATE mdb_identifier_funders SET id = UUID(), pid = '{i_new_id}' WHERE pid = {i_old_id};")
+        plan.append(f"UPDATE mdb_identifier_licenses SET id = UUID(), pid = '{i_new_id}' WHERE pid = {i_old_id};")
+    plan.append("COMMIT;")
+
+
+if __name__ == '__main__':
+    plan.append("SET FOREIGN_KEY_CHECKS=0;")
+    update_concepts()
+    update_units()
+    update_messages()
+    update_ontologies()
+    update_images()
+    update_containers()
+    update_databases()
+    update_identifiers()
+    plan.append("SET FOREIGN_KEY_CHECKS=1;")
+    print("\n".join(plan))
diff --git a/dbrepo-metadata-db/migration/16/requirements.txt b/dbrepo-metadata-db/migration/16/requirements.txt
new file mode 100644
index 0000000000..3f6fcb0a57
--- /dev/null
+++ b/dbrepo-metadata-db/migration/16/requirements.txt
@@ -0,0 +1 @@
+dbrepo==1.6.5rc6
\ No newline at end of file
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/IdentifierEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/IdentifierEndpoint.java
index b3d699086e..13fe028bcf 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/IdentifierEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/IdentifierEndpoint.java
@@ -106,7 +106,7 @@ public class IdentifierEndpoint extends AbstractEndpoint {
                 .filter(i -> !Objects.nonNull(qid) || qid.equals(i.getQueryId()))
                 .filter(i -> !Objects.nonNull(vid) || vid.equals(i.getViewId()))
                 .filter(i -> !Objects.nonNull(tid) || tid.equals(i.getTableId()))
-                .filter(i -> principal != null && i.getStatus().equals(IdentifierStatusType.DRAFT) ? i.getOwnedBy().equals(getId(principal)) : i.getStatus().equals(IdentifierStatusType.PUBLISHED))
+                .filter(i -> principal != null && i.getStatus().equals(IdentifierStatusType.DRAFT) ? (i.getOwnedBy().equals(getId(principal)) || isSystem(principal)) : i.getStatus().equals(IdentifierStatusType.PUBLISHED))
                 .toList();
         if (identifiers.isEmpty()) {
             return ResponseEntity.ok(List.of());
diff --git a/helm/dbrepo/files/create-event-listener.jar b/helm/dbrepo/files/create-event-listener.jar
index f370c8825750a431296ef68c3d482a2e4eee9389..a33db1e9045a92823996c61a9223aafb0d25404e 100644
GIT binary patch
delta 4486
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
FAOO@xI!pin

delta 4518
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
Vk%56h7{xrr$%X1_Y+IE;f&jt<B98z7

diff --git a/lib/python/dbrepo/RestClient.py b/lib/python/dbrepo/RestClient.py
index a0b4bf60c4..f29f606fd6 100644
--- a/lib/python/dbrepo/RestClient.py
+++ b/lib/python/dbrepo/RestClient.py
@@ -1,9 +1,8 @@
 import logging
 import os
+import requests
 import sys
 import time
-
-import requests
 from pandas import DataFrame
 from pydantic import TypeAdapter
 
@@ -1966,7 +1965,7 @@ class RestClient:
         :raises FormatNotAvailable: If the service could not represent the output.
         :raises ResponseCodeError: If something went wrong with the retrieval of the identifiers.
         """
-        url = f'/api/identifiers'
+        url = f'/api/identifier'
         if database_id is not None:
             url += f'?dbid={database_id}'
         if subset_id is not None:
@@ -1993,6 +1992,34 @@ class RestClient:
         raise ResponseCodeError(f'Failed to get identifiers: response code: {response.status_code} is not '
                                 f'200 (OK): {response.text}')
 
+    def get_images(self) -> List[ImageBrief] | str:
+        """
+        Get list of container images.
+
+        :returns: List of images, if successful.
+        """
+        url = f'/api/image'
+        response = self._wrapper(method="get", url=url, headers={'Accept': 'application/json'})
+        if response.status_code == 200:
+            body = response.json()
+            return TypeAdapter(List[ImageBrief]).validate_python(body)
+        raise ResponseCodeError(f'Failed to get images: response code: {response.status_code} is not '
+                                f'200 (OK): {response.text}')
+
+    def get_messages(self) -> List[BannerMessage] | str:
+        """
+        Get list of messages.
+
+        :returns: List of messages, if successful.
+        """
+        url = f'/api/message'
+        response = self._wrapper(method="get", url=url, headers={'Accept': 'application/json'})
+        if response.status_code == 200:
+            body = response.json()
+            return TypeAdapter(List[BannerMessage]).validate_python(body)
+        raise ResponseCodeError(f'Failed to get messages: response code: {response.status_code} is not '
+                                f'200 (OK): {response.text}')
+
     def update_table_column(self, database_id: int, table_id: int, column_id: int, concept_uri: str = None,
                             unit_uri: str = None) -> Column:
         """
diff --git a/lib/python/dbrepo/api/dto.py b/lib/python/dbrepo/api/dto.py
index bd0d13dc18..656c06a9ff 100644
--- a/lib/python/dbrepo/api/dto.py
+++ b/lib/python/dbrepo/api/dto.py
@@ -3,9 +3,8 @@ from __future__ import annotations
 import datetime
 from dataclasses import field
 from enum import Enum
-from typing import List, Optional, Annotated
-
 from pydantic import BaseModel, PlainSerializer
+from typing import List, Optional, Annotated
 
 Timestamp = Annotated[
     datetime.datetime, PlainSerializer(lambda v: v.strftime('%Y-%m-%dT%H:%M:%S.%f')[:-3] + 'Z', return_type=str)
@@ -41,6 +40,16 @@ class ImageBrief(BaseModel):
     name: str
     version: str
     jdbc_method: str
+    default: bool
+
+
+class BannerMessage(BaseModel):
+    id: int
+    type: str
+    link: Optional[str] = None
+    link_text: Optional[str] = None
+    display_start: Optional[Timestamp] = None
+    display_end: Optional[Timestamp] = None
 
 
 class CreateDatabase(BaseModel):
@@ -629,13 +638,13 @@ class Identifier(BaseModel):
     id: int
     database_id: int
     type: IdentifierType
-    owner: UserBrief
     status: IdentifierStatusType
     publication_year: int
     publisher: str
     creators: List[Creator]
     titles: List[IdentifierTitle]
     descriptions: List[IdentifierDescription]
+    owned_by: str
     funders: Optional[List[IdentifierFunder]] = field(default_factory=list)
     doi: Optional[str] = None
     language: Optional[str] = None
@@ -699,7 +708,7 @@ class ViewBrief(BaseModel):
     initial_view: bool
     query: str
     query_hash: str
-    owned_by: str
+    owner: UserBrief
 
 
 class ConceptBrief(BaseModel):
@@ -1024,7 +1033,7 @@ class Database(BaseModel):
     preview_image: Optional[str] = None
     description: Optional[str] = None
     tables: Optional[List[Table]] = field(default_factory=list)
-    views: Optional[List[View]] = field(default_factory=list)
+    views: Optional[List[ViewBrief]] = field(default_factory=list)
     accesses: Optional[List[DatabaseAccess]] = field(default_factory=list)
     exchange_name: Optional[str] = None
 
diff --git a/lib/python/pyproject.toml b/lib/python/pyproject.toml
index b956d6afd0..75113e70b0 100644
--- a/lib/python/pyproject.toml
+++ b/lib/python/pyproject.toml
@@ -1,6 +1,6 @@
 [project]
 name = "dbrepo"
-version = "1.6.4"
+version = "1.6.5rc6"
 description = "DBRepo Python Library"
 keywords = [
     "DBRepo",
diff --git a/lib/python/setup.py b/lib/python/setup.py
index 53f4832404..df4528ab82 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.6.4",
+      version="1.6.5rc6",
       description="A library for communicating with DBRepo",
       url="https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.6/",
       author="Martin Weise",
diff --git a/lib/python/tests/test_unit_image.py b/lib/python/tests/test_unit_image.py
new file mode 100644
index 0000000000..2802efc690
--- /dev/null
+++ b/lib/python/tests/test_unit_image.py
@@ -0,0 +1,31 @@
+import unittest
+
+import requests_mock
+
+from dbrepo.RestClient import RestClient
+
+from dbrepo.api.dto import ImageBrief
+
+
+class ImageUnitTest(unittest.TestCase):
+
+    def test_get_images_empty_succeeds(self):
+        with requests_mock.Mocker() as mock:
+            # mock
+            mock.get('/api/image', json=[])
+            # test
+            response = RestClient().get_images()
+            self.assertEqual([], response)
+
+    def test_get_images_succeeds(self):
+        with requests_mock.Mocker() as mock:
+            exp = [ImageBrief(id=1, name="mariadb", version="11.1.3", jdbc_method="mariadb", default=False)]
+            # mock
+            mock.get('/api/image', json=[exp[0].model_dump()])
+            # test
+            response = RestClient().get_images()
+            self.assertEqual(exp, response)
+
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/lib/python/tests/test_unit_messages.py b/lib/python/tests/test_unit_messages.py
new file mode 100644
index 0000000000..0bc16394a0
--- /dev/null
+++ b/lib/python/tests/test_unit_messages.py
@@ -0,0 +1,31 @@
+import unittest
+
+import requests_mock
+
+from dbrepo.RestClient import RestClient
+
+from dbrepo.api.dto import ImageBrief
+
+
+class ImageUnitTest(unittest.TestCase):
+
+    def test_get_message_empty_succeeds(self):
+        with requests_mock.Mocker() as mock:
+            # mock
+            mock.get('/api/message', json=[])
+            # test
+            response = RestClient().get_images()
+            self.assertEqual([], response)
+
+    def test_get_images_succeeds(self):
+        with requests_mock.Mocker() as mock:
+            exp = [BannerMessage(id=1, type="info")]
+            # mock
+            mock.get('/api/message', json=[exp[0].model_dump()])
+            # test
+            response = RestClient().get_images()
+            self.assertEqual(exp, response)
+
+
+if __name__ == "__main__":
+    unittest.main()
-- 
GitLab