From 1d82036e0b85824f82ed152130b86cd8959c9f94 Mon Sep 17 00:00:00 2001 From: "yvernet@slb.com" Date: Wed, 6 Apr 2022 17:43:11 +0200 Subject: [PATCH 1/3] unified split record_id/version + moved from utils --- app/model/osdu_record_id.py | 39 ++++++++ app/routers/bulk/bulk_routes.py | 10 ++- app/routers/ddms_v3/ddms_v3_utils.py | 70 +-------------- app/routers/ddms_v3/markerset_ddms_v3.py | 16 ++-- app/routers/ddms_v3/well_ddms_v3.py | 22 ++--- app/routers/ddms_v3/wellbore_ddms_v3.py | 24 +++-- .../ddms_v3/wellbore_trajectory_ddms_v3.py | 19 ++-- app/routers/ddms_v3/welllog_ddms_v3.py | 15 ++-- tests/unit/model/osdu_record_id_tests.py | 63 +++++++++++++ .../ddms_v3/ddmsv3_router_utils_test.py | 89 ------------------- 10 files changed, 152 insertions(+), 215 deletions(-) create mode 100644 app/model/osdu_record_id.py create mode 100644 tests/unit/model/osdu_record_id_tests.py delete mode 100644 tests/unit/routers/ddms_v3/ddmsv3_router_utils_test.py diff --git a/app/model/osdu_record_id.py b/app/model/osdu_record_id.py new file mode 100644 index 00000000..42faa1c4 --- /dev/null +++ b/app/model/osdu_record_id.py @@ -0,0 +1,39 @@ +from typing import Tuple, Optional +import re + +from pydantic import constr + + +OSDU_RECORD_ID_WITH_VERSION_REGEX = re.compile(r"^(?P[\w\-\.]+:[^\:]+:[\w\-\.\:\%]+):(?P([0-9])*)$") +""" regex for a record id with version. The format is [record_id]:[version]. The version is always a int """ + +OSDU_RECORD_ID_REGEX = re.compile(r"^[\w\-\.]+:[^\:]+:[\w\-\.\:\%]+$") + + +def split_record_id_version(record_id: str) -> Tuple[Optional[str], Optional[int]]: + """ + split record id and version. If record id without version, then the version returned is None + if input is invalid, then returns (None, None) + e.g. + >>> split_record_id_version('namespace:master-data--custom-type:c7c421a7:123456') + ('namespace:master-data--custom-type:c7c421a7', 123456) + >>> split_record_id_version('namespace:master-data--custom-type:c7c421a7') + ('namespace:master-data--custom-type:c7c421a7', None) + >>> split_record_id_version('invalid-record') + (None, None) + >>> split_record_id_version('invalid-record:123456') + (None, None) + """ + match = OSDU_RECORD_ID_WITH_VERSION_REGEX.match(record_id) + if not match: + return record_id if OSDU_RECORD_ID_REGEX.match(record_id) else None, None + version = match["version"] + return match["record_id"], None if not version else int(version) + + +# specific record_id model regex +OSDU_WELL_REGEX = re.compile(r"^[\w\-\.]+:master-data\-\-Well:[\w\-\.\:\%]+$") +OSDU_WELLBORE_REGEX = re.compile(r"^[\w\-\.]+:master-data\-\-Wellbore:[\w\-\.\:\%]+$") +OSDU_WELLLOG_REGEX = re.compile(r"^[\w\-\.]+:work-product-component\-\-WellLog:[\w\-\.\:\%]+$") +OSDU_WELLBORETRAJECTORY_REGEX = re.compile(r"^[\w\-\.]+:work-product-component\-\-WellboreTrajectory:[\w\-\.\:\%]+$") +OSDU_WELLBOREMARKERSET_REGEX = re.compile(r"^[\w\-\.]+:work-product-component\-\-WellboreMarkerSet:[\w\-\.\:\%]+$") diff --git a/app/routers/bulk/bulk_routes.py b/app/routers/bulk/bulk_routes.py index d11492dd..327b6dea 100644 --- a/app/routers/bulk/bulk_routes.py +++ b/app/routers/bulk/bulk_routes.py @@ -19,6 +19,7 @@ from osdu.core.api.storage.exceptions import ResourceNotFoundException from app.model.filter import BulkReadFilters from app.model.model_chunking import GetDataParams, DataframeBasicDescribe +from app.model.osdu_record_id import split_record_id_version from app.context import Context, get_ctx from app.utils import OpenApiHandler @@ -377,13 +378,14 @@ async def complete_session( i_session = commit_guard.session i_session.session.meta = i_session.session.meta or {} - i_session.session.meta.update({"some_detail_about_merge": "like the shape, number of rows ..."}) + + _, updated_version = split_record_id_version(new_record.record_id_versions[0]) + if updated_version is None: + raise RuntimeError(f"{new_record.record_id_versions[0]} is not valid.") response = CommitSessionResponse( **i_session.session.dict(exclude_unset=True, by_alias=True), - version=DMSV3RouterUtils.get_version_from_record_id_version( - new_record.record_id_versions[0] - ) + version=updated_version ) return response diff --git a/app/routers/ddms_v3/ddms_v3_utils.py b/app/routers/ddms_v3/ddms_v3_utils.py index 36c8cc62..583a8a97 100644 --- a/app/routers/ddms_v3/ddms_v3_utils.py +++ b/app/routers/ddms_v3/ddms_v3_utils.py @@ -1,16 +1,13 @@ import asyncio -import re -from typing import List, Tuple +from typing import List -from fastapi import HTTPException, Request +from fastapi import HTTPException from odes_storage import UnexpectedResponse from odes_storage.models import Record from pydantic import validate_model from starlette import status -from app.bulk_persistence import BulkURI from app.model.entity_utils import get_kind_meta -from app.model.log_bulk import LogBulkHelper from app.model.osdu_model import ( Well, Wellbore, @@ -25,26 +22,6 @@ from app.routers.bulk.bulk_uri_dependencies import BulkIdAccess from app.routers.record_utils import fetch_record from app.context import Context, get_ctx -OSDU_ENTITY_VERSION_REGEX = re.compile(r"^[\w\-\.]+:[^\:]+:[\w\-\.\:\%]+:(?P[0-9]+)$") - -OSDU_WELL_VERSION_REGEX = re.compile(r"^([\w\-\.]+:master-data\-\-Well:[\w\-\.\:\%]+):([0-9]*)$") -OSDU_WELL_REGEX = re.compile(r"^[\w\-\.]+:master-data\-\-Well:[\w\-\.\:\%]+$") - -OSDU_WELLBORE_VERSION_REGEX = re.compile(r"^([\w\-\.]+:master-data\-\-Wellbore:[\w\-\.\:\%]+):([0-9]*)$") -OSDU_WELLBORE_REGEX = re.compile(r"^[\w\-\.]+:master-data\-\-Wellbore:[\w\-\.\:\%]+$") - -OSDU_WELLLOG_VERSION_REGEX = re.compile(r"^([\w\-\.]+:work-product-component\-\-WellLog:[\w\-\.\:\%]+):([0-9]*)$") -OSDU_WELLLOG_REGEX = re.compile(r"^[\w\-\.]+:work-product-component\-\-WellLog:[\w\-\.\:\%]+$") - -OSDU_WELLBORETRAJECTORY_VERSION_REGEX = re.compile( - r"^([\w\-\.]+:work-product-component\-\-WellboreTrajectory:[\w\-\.\:\%]+):([0-9]*)$" -) -OSDU_WELLBORETRAJECTORY_REGEX = re.compile(r"^[\w\-\.]+:work-product-component\-\-WellboreTrajectory:[\w\-\.\:\%]+$") - -OSDU_WELLBOREMARKERSET_VERSION_REGEX = re.compile( - r"^([\w\-\.]+:work-product-component\-\-WellboreMarkerSet:[\w\-\.\:\%]+):([0-9]*)$" -) -OSDU_WELLBOREMARKERSET_REGEX = re.compile(r"^[\w\-\.]+:work-product-component\-\-WellboreMarkerSet:[\w\-\.\:\%]+$") entity_names = { "well": "master-data--Well", @@ -57,49 +34,6 @@ entity_names = { class DMSV3RouterUtils: - @staticmethod - def get_version_from_record_id_version(record_id_version: str) -> int: - match = OSDU_ENTITY_VERSION_REGEX.match(record_id_version) - if not match: - raise RuntimeError(f"{record_id_version} is not a valid, it must match {OSDU_ENTITY_VERSION_REGEX}") - - return int(match["version"]) - - @staticmethod - def is_osdu_wellbore_id(entity_id: str) -> bool: - return OSDU_WELLBORE_REGEX.match(entity_id) is not None - - @staticmethod - def is_osdu_well_id(entity_id: str) -> bool: - return OSDU_WELL_REGEX.match(entity_id) is not None - - @staticmethod - def is_osdu_versioned_entity_id(entity_regexp, entity_id: str) -> Tuple[bool, str, str]: - """ - :param entity_regexp: regexp to test the entity (one regexp per entity) - :param entity_id: id of the entity to test - :return: The first item of the tuple True if the entity is and osdu versioned entity - The second parameter is the osdu entity id without the version or None - The third is the version of osdu entity or None - """ - matches = entity_regexp.match(entity_id) - if matches is None: - return False, None, None - return True, matches.group(1), matches.group(2) - - @staticmethod - def get_id_without_version(entity_regexp, entity_id: str) -> str: - is_versioned, id_without_version, _ = DMSV3RouterUtils.is_osdu_versioned_entity_id(entity_regexp, entity_id) - return id_without_version if is_versioned else entity_id - - @staticmethod - def is_osdu_versioned_wellbore_id(entity_id: str) -> Tuple[bool, str, str]: - return DMSV3RouterUtils.is_osdu_versioned_entity_id(OSDU_WELLBORE_VERSION_REGEX, entity_id) - - @staticmethod - def is_osdu_versioned_well_id(entity_id: str) -> Tuple[bool, str, str]: - return DMSV3RouterUtils.is_osdu_versioned_entity_id(OSDU_WELL_VERSION_REGEX, entity_id) - @staticmethod def raise_if_not_osdu_right_entity_kind(record, state): version = state.version if hasattr(state, 'version') else None diff --git a/app/routers/ddms_v3/markerset_ddms_v3.py b/app/routers/ddms_v3/markerset_ddms_v3.py index b6f039f4..9e5cf08a 100644 --- a/app/routers/ddms_v3/markerset_ddms_v3.py +++ b/app/routers/ddms_v3/markerset_ddms_v3.py @@ -22,9 +22,10 @@ from starlette.requests import Request from app.clients.storage_service_client import get_storage_record_service from app.model.model_utils import to_record, from_record +from app.model.osdu_record_id import split_record_id_version from app.model.osdu_model import WellboreMarkerSet110 as WellboreMarkerSet from app.routers.common_parameters import REQUIRED_ROLES_READ, REQUIRED_ROLES_WRITE -from app.routers.ddms_v3.ddms_v3_utils import DMSV3RouterUtils, OSDU_WELLBOREMARKERSET_VERSION_REGEX +from app.routers.ddms_v3.ddms_v3_utils import DMSV3RouterUtils from app.routers.record_utils import fetch_record from app.context import Context, get_ctx from app.utils import load_schema_example @@ -46,11 +47,11 @@ router = APIRouter(route_class=TracingRoute) async def get_wellbore_markerset_osdu( wellboremarkersetid: str, request: Request, ctx: Context = Depends(get_ctx) ) -> WellboreMarkerSet: + # Note: version is dropped here + record_id, _ = split_record_id_version(wellboremarkersetid) storage_client = await get_storage_record_service(ctx) - wellboremarkersetid = DMSV3RouterUtils.get_id_without_version(OSDU_WELLBOREMARKERSET_VERSION_REGEX, - wellboremarkersetid) wellboreMarkerset_record = await storage_client.get_record( - id=wellboremarkersetid, data_partition_id=ctx.partition_id + id=record_id, data_partition_id=ctx.partition_id ) DMSV3RouterUtils.raise_if_not_osdu_right_entity_kind(wellboreMarkerset_record, request.state) return from_record(WellboreMarkerSet, wellboreMarkerset_record) @@ -73,8 +74,7 @@ async def get_wellbore_markerset_osdu( ) async def del_osdu_wellboreMarkerset(wellboremarkersetid: str, ctx: Context = Depends(get_ctx)): storage_client = await get_storage_record_service(ctx) - wellboremarkersetid = DMSV3RouterUtils.get_id_without_version(OSDU_WELLBOREMARKERSET_VERSION_REGEX, - wellboremarkersetid) + wellboremarkersetid, _ = split_record_id_version(wellboremarkersetid) await storage_client.delete_record( id=wellboremarkersetid, data_partition_id=ctx.partition_id ) @@ -116,8 +116,8 @@ async def get_osdu_wellboreMarkerset_version( wellboremarkersetid: str, version: int, request: Request, ctx: Context = Depends(get_ctx) ) -> WellboreMarkerSet: storage_client = await get_storage_record_service(ctx) - wellboremarkersetid = DMSV3RouterUtils.get_id_without_version(OSDU_WELLBOREMARKERSET_VERSION_REGEX, - wellboremarkersetid) + wellboremarkersetid, _ = split_record_id_version(wellboremarkersetid) + wellboreMarkerset_record = await storage_client.get_record_version( id=wellboremarkersetid, version=version, data_partition_id=ctx.partition_id ) diff --git a/app/routers/ddms_v3/well_ddms_v3.py b/app/routers/ddms_v3/well_ddms_v3.py index 26d80a6c..48da0810 100644 --- a/app/routers/ddms_v3/well_ddms_v3.py +++ b/app/routers/ddms_v3/well_ddms_v3.py @@ -22,6 +22,7 @@ from odes_storage.models import ( RecordVersions, ) from app.model.osdu_model import Well +from app.model.osdu_record_id import split_record_id_version, OSDU_WELL_REGEX from ..common_parameters import REQUIRED_ROLES_READ, REQUIRED_ROLES_WRITE from app.context import Context, get_ctx from app.utils import load_schema_example @@ -33,14 +34,6 @@ from app.helper.traces import TracingRoute router = APIRouter(route_class=TracingRoute) -async def get_osdu_well(wellid: str, ctx: Context) -> Well: - storage_client = await get_storage_record_service(ctx) - well_record = await storage_client.get_record( - id=wellid, data_partition_id=ctx.partition_id - ) - return from_record(Well, well_record) - - @router.get( "/wells/{wellid}", response_model=Well, @@ -55,13 +48,14 @@ async def get_osdu_well(wellid: str, ctx: Context) -> Well: async def get_well_osdu( wellid: str, ctx: Context = Depends(get_ctx) ) -> Well: - is_osdu_versioned, osdu_id, version = DMSV3RouterUtils.is_osdu_versioned_well_id(wellid) - if is_osdu_versioned: - return await get_osdu_well(osdu_id, ctx) - if DMSV3RouterUtils.is_osdu_well_id(wellid): - return await get_osdu_well(wellid, ctx) - raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Id is not OSDU Well") + # Note: version is dropped here + record_id, _ = split_record_id_version(wellid) + if OSDU_WELL_REGEX.match(wellid) is None: + raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Id is not OSDU Well") + storage_client = await get_storage_record_service(ctx) + well_record = await storage_client.get_record(id=record_id, data_partition_id=ctx.partition_id) + return from_record(Well, well_record) @router.delete( diff --git a/app/routers/ddms_v3/wellbore_ddms_v3.py b/app/routers/ddms_v3/wellbore_ddms_v3.py index 7d80e214..94c4b260 100644 --- a/app/routers/ddms_v3/wellbore_ddms_v3.py +++ b/app/routers/ddms_v3/wellbore_ddms_v3.py @@ -16,6 +16,8 @@ from fastapi import APIRouter, Body, Depends, HTTPException, Response, status from odes_storage.models import CreateUpdateRecordsResponse, List, RecordVersions from starlette.requests import Request +from app.model.osdu_record_id import split_record_id_version, OSDU_WELLBORE_REGEX + from app.clients.storage_service_client import get_storage_record_service from app.model.model_utils import from_record, to_record from app.model.osdu_model import Wellbore @@ -30,14 +32,6 @@ from app.helper.traces import TracingRoute router = APIRouter(route_class=TracingRoute) -async def get_osdu_wellbore(wellboreid: str, ctx: Context) -> Wellbore: - storage_client = await get_storage_record_service(ctx) - wellbore_record = await storage_client.get_record( - id=wellboreid, data_partition_id=ctx.partition_id - ) - return from_record(Wellbore, wellbore_record) - - @router.get( "/wellbores/{wellboreid}", response_model=Wellbore, @@ -52,12 +46,14 @@ async def get_osdu_wellbore(wellboreid: str, ctx: Context) -> Wellbore: async def get_wellbore_osdu( wellboreid: str, ctx: Context = Depends(get_ctx) ) -> Wellbore: - is_osdu_versioned, osdu_id, version = DMSV3RouterUtils.is_osdu_versioned_wellbore_id(wellboreid) - if is_osdu_versioned: - return await get_osdu_wellbore(osdu_id, ctx) - if DMSV3RouterUtils.is_osdu_wellbore_id(wellboreid): - return await get_osdu_wellbore(wellboreid, ctx) - raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Id is not OSDU Wellbore") + # Note: version is dropped here + record_id, _ = split_record_id_version(wellboreid) + if OSDU_WELLBORE_REGEX.match(wellboreid) is None: + raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Id is not OSDU Wellbore") + + storage_client = await get_storage_record_service(ctx) + well_record = await storage_client.get_record(id=record_id, data_partition_id=ctx.partition_id) + return from_record(Wellbore, well_record) @router.delete( diff --git a/app/routers/ddms_v3/wellbore_trajectory_ddms_v3.py b/app/routers/ddms_v3/wellbore_trajectory_ddms_v3.py index d6c4a7bc..9bf62b0d 100644 --- a/app/routers/ddms_v3/wellbore_trajectory_ddms_v3.py +++ b/app/routers/ddms_v3/wellbore_trajectory_ddms_v3.py @@ -19,10 +19,11 @@ from starlette.requests import Request from app.clients.storage_service_client import get_storage_record_service from app.consistency import DuplicatedStationProperties, check_trajectory_consistency from app.model.model_utils import from_record, to_record +from app.model.osdu_record_id import split_record_id_version from app.model.osdu_model import WellboreTrajectory110 as WellboreTrajectory from app.routers.bulk.bulk_uri_dependencies import BulkIdAccess, get_bulk_id_access from app.routers.common_parameters import REQUIRED_ROLES_READ, REQUIRED_ROLES_WRITE -from app.routers.ddms_v3.ddms_v3_utils import OSDU_WELLBORETRAJECTORY_VERSION_REGEX, DMSV3RouterUtils +from app.routers.ddms_v3.ddms_v3_utils import DMSV3RouterUtils from app.routers.delete.delete_bulk_data import delete_record from app.routers.record_utils import fetch_record from app.context import Context, get_ctx @@ -49,8 +50,7 @@ async def get_wellbore_trajectory_osdu( wellboretrajectoryid: str, request: Request, ctx: Context = Depends(get_ctx) ) -> WellboreTrajectory: storage_client = await get_storage_record_service(ctx) - wellboretrajectoryid = DMSV3RouterUtils.get_id_without_version(OSDU_WELLBORETRAJECTORY_VERSION_REGEX, - wellboretrajectoryid) + wellboretrajectoryid, _ = split_record_id_version(wellboretrajectoryid) wellboreTrajectory_record = await storage_client.get_record( id=wellboretrajectoryid, data_partition_id=ctx.partition_id @@ -78,9 +78,7 @@ async def del_osdu_wellboreTrajectory( ctx: Context = Depends(get_ctx), bulk_uri_access: BulkIdAccess = Depends(get_bulk_id_access), ): - wellboretrajectoryid = DMSV3RouterUtils.get_id_without_version( - OSDU_WELLBORETRAJECTORY_VERSION_REGEX, wellboretrajectoryid - ) + wellboretrajectoryid, _ = split_record_id_version(wellboretrajectoryid) await delete_record(record_id=wellboretrajectoryid, purge=purge, ctx=ctx, bulk_uri_access=bulk_uri_access) @@ -99,8 +97,8 @@ async def get_osdu_wellboreTrajectory_versions( ) -> RecordVersions: record = await fetch_record(ctx, wellboretrajectoryid) DMSV3RouterUtils.raise_if_not_osdu_right_entity_kind(record, request.state) - wellboretrajectoryid = DMSV3RouterUtils.get_id_without_version(OSDU_WELLBORETRAJECTORY_VERSION_REGEX, - wellboretrajectoryid) + wellboretrajectoryid, _ = split_record_id_version(wellboretrajectoryid) + storage_client = await get_storage_record_service(ctx) return await storage_client.get_all_record_versions( id=wellboretrajectoryid, data_partition_id=ctx.partition_id @@ -122,9 +120,8 @@ async def get_osdu_wellboreTrajectory_version( wellboretrajectoryid: str, version: int, request: Request, ctx: Context = Depends(get_ctx) ) -> WellboreTrajectory: storage_client = await get_storage_record_service(ctx) - wellboretrajectoryid = DMSV3RouterUtils.get_id_without_version( - OSDU_WELLBORETRAJECTORY_VERSION_REGEX, wellboretrajectoryid - ) + wellboretrajectoryid, _ = split_record_id_version(wellboretrajectoryid) + wellboreTrajectory_record = await storage_client.get_record_version( id=wellboretrajectoryid, version=version, data_partition_id=ctx.partition_id ) diff --git a/app/routers/ddms_v3/welllog_ddms_v3.py b/app/routers/ddms_v3/welllog_ddms_v3.py index 5989c327..32827145 100644 --- a/app/routers/ddms_v3/welllog_ddms_v3.py +++ b/app/routers/ddms_v3/welllog_ddms_v3.py @@ -24,9 +24,10 @@ from app.consistency import ( ) from app.model.model_utils import from_record, to_record from app.model.osdu_model import WellLog110 as WellLog +from app.model.osdu_record_id import split_record_id_version from app.routers.bulk.bulk_uri_dependencies import BulkIdAccess, get_bulk_id_access from app.routers.common_parameters import REQUIRED_ROLES_READ, REQUIRED_ROLES_WRITE -from app.routers.ddms_v3.ddms_v3_utils import OSDU_WELLLOG_VERSION_REGEX, DMSV3RouterUtils +from app.routers.ddms_v3.ddms_v3_utils import DMSV3RouterUtils from app.routers.delete.delete_bulk_data import delete_record from app.routers.record_utils import fetch_record from app.context import Context, get_ctx @@ -53,8 +54,8 @@ async def get_welllog_osdu( welllogid: str, request: Request, ctx: Context = Depends(get_ctx) ) -> WellLog: storage_client = await get_storage_record_service(ctx) - welllogid = DMSV3RouterUtils.get_id_without_version(OSDU_WELLLOG_VERSION_REGEX, - welllogid) + welllogid, _ = split_record_id_version(welllogid) + welllog_record = await storage_client.get_record( id=welllogid, data_partition_id=ctx.partition_id ) @@ -83,7 +84,7 @@ async def del_osdu_welllog( ctx: Context = Depends(get_ctx), bulk_uri_access: BulkIdAccess = Depends(get_bulk_id_access), ): - welllogid = DMSV3RouterUtils.get_id_without_version(OSDU_WELLLOG_VERSION_REGEX, welllogid) + welllogid, _ = split_record_id_version(welllogid) await delete_record(record_id=welllogid, purge=purge, ctx=ctx, bulk_uri_access=bulk_uri_access) @@ -103,8 +104,8 @@ async def get_osdu_welllog_versions( record = await fetch_record(ctx, welllogid) DMSV3RouterUtils.raise_if_not_osdu_right_entity_kind(record, request.state) storage_client = await get_storage_record_service(ctx) - welllogid = DMSV3RouterUtils.get_id_without_version(OSDU_WELLLOG_VERSION_REGEX, - welllogid) + welllogid, _ = split_record_id_version(welllogid) + return await storage_client.get_all_record_versions( id=welllogid, data_partition_id=ctx.partition_id ) @@ -125,7 +126,7 @@ async def get_osdu_welllog_version( welllogid: str, version: int, request: Request, ctx: Context = Depends(get_ctx) ) -> WellLog: storage_client = await get_storage_record_service(ctx) - welllogid = DMSV3RouterUtils.get_id_without_version(OSDU_WELLLOG_VERSION_REGEX, welllogid) + welllogid, _ = split_record_id_version(welllogid) welllog_record = await storage_client.get_record_version( id=welllogid, version=version, data_partition_id=ctx.partition_id ) diff --git a/tests/unit/model/osdu_record_id_tests.py b/tests/unit/model/osdu_record_id_tests.py new file mode 100644 index 00000000..e65635bd --- /dev/null +++ b/tests/unit/model/osdu_record_id_tests.py @@ -0,0 +1,63 @@ +import pytest +from app.model.osdu_record_id import split_record_id_version + + +@pytest.mark.parametrize("input_str_id, expected_id, expected_version", [ + + ('namespace:master-data--custom-type:c7c421a7:1', 'namespace:master-data--custom-type:c7c421a7', 1), + ('namespace:master-data--custom-type:c7c421a7', 'namespace:master-data--custom-type:c7c421a7', None), + + # from previous tests cases + ('opendes:work-product-component--WellLog:713b4988cca14719867ae3b1004edf4e:1234', + 'opendes:work-product-component--WellLog:713b4988cca14719867ae3b1004edf4e', 1234), + + ('opendes:work-product-component--WellboreTrajectory:713b4988cca14719867ae3:465', + 'opendes:work-product-component--WellboreTrajectory:713b4988cca14719867ae3', 465), + + ('data-partition:work-product-component--WellLog:713b4988cca14719867ae3b1004:16', + 'data-partition:work-product-component--WellLog:713b4988cca14719867ae3b1004', 16), + + ('9nlnBplxN:master-data--Well:g657DSIO', + '9nlnBplxN:master-data--Well:g657DSIO', None), + ('9nlnBplxN:master-data--Well:g657DSIO:', + '9nlnBplxN:master-data--Well:g657DSIO', None), + ('9nlnBplxN:master-data--Well:g657DSIO:1234', + '9nlnBplxN:master-data--Well:g657DSIO', 1234), + + ('9nlnBplxN:master-data--Wellbore:g657DSIO', + '9nlnBplxN:master-data--Wellbore:g657DSIO', None), + ('9nlnBplxN:master-data--Wellbore:g657DSIO:', + '9nlnBplxN:master-data--Wellbore:g657DSIO', None), + ('9nlnBplxN:master-data--Wellbore:g657DSIO:1234', + '9nlnBplxN:master-data--Wellbore:g657DSIO', 1234), + + ('9nlnBplxN:work-product-component--WellLog:g657DSIO', + '9nlnBplxN:work-product-component--WellLog:g657DSIO', None), + ('9nlnBplxN:work-product-component--WellLog:g657DSIO:', + '9nlnBplxN:work-product-component--WellLog:g657DSIO', None), + ('9nlnBplxN:work-product-component--WellLog:g657DSIO:1234', + '9nlnBplxN:work-product-component--WellLog:g657DSIO', 1234), + + ('9nlnBplxN:work-product-component--WellboreTrajectory:g657DSIO', + '9nlnBplxN:work-product-component--WellboreTrajectory:g657DSIO', None), + ('9nlnBplxN:work-product-component--WellboreTrajectory:g657DSIO:', + '9nlnBplxN:work-product-component--WellboreTrajectory:g657DSIO', None), + ('9nlnBplxN:work-product-component--WellboreTrajectory:g657DSIO:1234', + '9nlnBplxN:work-product-component--WellboreTrajectory:g657DSIO', 1234), + + ('9nlnBplxN:work-product-component--WellboreMarkerSet:g657DSIO', + '9nlnBplxN:work-product-component--WellboreMarkerSet:g657DSIO', None), + ('9nlnBplxN:work-product-component--WellboreMarkerSet:g657DSIO:', + '9nlnBplxN:work-product-component--WellboreMarkerSet:g657DSIO', None), + ('9nlnBplxN:work-product-component--WellboreMarkerSet:g657DSIO:1234', + '9nlnBplxN:work-product-component--WellboreMarkerSet:g657DSIO', 1234), +]) +def test_split_record_id_version(input_str_id, expected_id, expected_version): + assert split_record_id_version(input_str_id) == (expected_id, expected_version) + + +def test_split_record_id_version_straightly_return_invalid(): + assert split_record_id_version('') == (None, None) + assert split_record_id_version(':::1324') == (None, None) + assert split_record_id_version('invalid-record') == (None, None) + assert split_record_id_version('invalid-record:123456') == (None, None) diff --git a/tests/unit/routers/ddms_v3/ddmsv3_router_utils_test.py b/tests/unit/routers/ddms_v3/ddmsv3_router_utils_test.py deleted file mode 100644 index 64b17f3c..00000000 --- a/tests/unit/routers/ddms_v3/ddmsv3_router_utils_test.py +++ /dev/null @@ -1,89 +0,0 @@ -# Copyright 2021 Schlumberger -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import pytest -from app.routers.ddms_v3.ddms_v3_utils import DMSV3RouterUtils, OSDU_WELL_VERSION_REGEX, OSDU_WELLBORE_VERSION_REGEX, \ - OSDU_WELLLOG_VERSION_REGEX, OSDU_WELLBORETRAJECTORY_VERSION_REGEX, OSDU_WELLBOREMARKERSET_VERSION_REGEX - - -GET_WO_VERSION_PARAMS = [ - (OSDU_WELL_VERSION_REGEX, "", ""), - (OSDU_WELL_VERSION_REGEX, "9nlnBplxN:master-data--Well:g657DSIO", "9nlnBplxN:master-data--Well:g657DSIO"), - (OSDU_WELL_VERSION_REGEX, "9nlnBplxN:master-data--Well:g657DSIO:", "9nlnBplxN:master-data--Well:g657DSIO"), - (OSDU_WELL_VERSION_REGEX, "9nlnBplxN:master-data--Well:g657DSIO:123456", "9nlnBplxN:master-data--Well:g657DSIO"), - (OSDU_WELLBORE_VERSION_REGEX, "", ""), - (OSDU_WELLBORE_VERSION_REGEX, "9nlnBplxN:master-data--Wellbore:g657DSIO", "9nlnBplxN:master-data--Wellbore:g657DSIO"), - (OSDU_WELLBORE_VERSION_REGEX, "9nlnBplxN:master-data--Wellbore:g657DSIO:", "9nlnBplxN:master-data--Wellbore:g657DSIO"), - (OSDU_WELLBORE_VERSION_REGEX, "9nlnBplxN:master-data--Wellbore:g657DSIO:123456", "9nlnBplxN:master-data--Wellbore:g657DSIO"), - (OSDU_WELLLOG_VERSION_REGEX, "", ""), - (OSDU_WELLLOG_VERSION_REGEX, "9nlnBplxN:work-product-component--WellLog:g657DSIO", "9nlnBplxN:work-product-component--WellLog:g657DSIO"), - (OSDU_WELLLOG_VERSION_REGEX, "9nlnBplxN:work-product-component--WellLog:g657DSIO:", "9nlnBplxN:work-product-component--WellLog:g657DSIO"), - (OSDU_WELLLOG_VERSION_REGEX, "9nlnBplxN:work-product-component--WellLog:g657DSIO:123456", "9nlnBplxN:work-product-component--WellLog:g657DSIO"), - (OSDU_WELLBORETRAJECTORY_VERSION_REGEX, "", ""), - (OSDU_WELLBORETRAJECTORY_VERSION_REGEX, "9nlnBplxN:work-product-component--WellboreTrajectory:g657DSIO", "9nlnBplxN:work-product-component--WellboreTrajectory:g657DSIO"), - (OSDU_WELLBORETRAJECTORY_VERSION_REGEX, "9nlnBplxN:work-product-component--WellboreTrajectory:g657DSIO:", "9nlnBplxN:work-product-component--WellboreTrajectory:g657DSIO"), - (OSDU_WELLBORETRAJECTORY_VERSION_REGEX, "9nlnBplxN:work-product-component--WellboreTrajectory:g657DSIO:123456", "9nlnBplxN:work-product-component--WellboreTrajectory:g657DSIO"), - (OSDU_WELLBOREMARKERSET_VERSION_REGEX, "", ""), - (OSDU_WELLBOREMARKERSET_VERSION_REGEX, "9nlnBplxN:work-product-component--WellboreMarkerSet:g657DSIO", "9nlnBplxN:work-product-component--WellboreMarkerSet:g657DSIO"), - (OSDU_WELLBOREMARKERSET_VERSION_REGEX, "9nlnBplxN:work-product-component--WellboreMarkerSet:g657DSIO:", "9nlnBplxN:work-product-component--WellboreMarkerSet:g657DSIO"), - (OSDU_WELLBOREMARKERSET_VERSION_REGEX, "9nlnBplxN:work-product-component--WellboreMarkerSet:g657DSIO:123456", "9nlnBplxN:work-product-component--WellboreMarkerSet:g657DSIO"), -] - - -@pytest.mark.parametrize("version_regexp, record_id, expected_id", GET_WO_VERSION_PARAMS) -def test_get_id_without_version(version_regexp, record_id, expected_id): - record_wo_version = DMSV3RouterUtils.get_id_without_version(version_regexp, record_id) - assert record_wo_version == expected_id - - - -@pytest.mark.parametrize( - "record_id_version, expected", - [ - ( - "opendes:work-product-component--WellLog:713b4988cca14719867ae3b1004edf4e:1234", - 1234 - ), - ( - "opendes:work-product-component--WellboreTrajectory:713b4988cca14719867ae3b1004edf4e:465", - 465 - ), - ( - "data-partition:work-product-component--WellLog:713b4988cca14719867ae3b1004edf4e:1646997150219714", - 1646997150219714 - ), - ( - "osdu:log:a01d160506bd4f22a323eb2734cb370c:1991106102849593087389851558600877159", - 1991106102849593087389851558600877159 - ), - - ] -) -def test_get_version_from_record_id_version(record_id_version, expected): - computed = DMSV3RouterUtils.get_version_from_record_id_version(record_id_version) - assert computed == expected - - -@pytest.mark.parametrize( - "record_id_version", - [ - "opendes:work-product-component--WellLog:713b4988cca14719867ae3b1004edf4e:", - "opendes:work-product-component--WellLog:713b4988cca14719867ae3b1004edf4e", - "dummy", - ":::1324" - ] -) -def test_get_version_from_record_id_version_raise(record_id_version): - with pytest.raises(RuntimeError): - DMSV3RouterUtils.get_version_from_record_id_version(record_id_version) -- GitLab From 7420b11a19a9d495309a2a4d14b1dcc5d5f0f5ef Mon Sep 17 00:00:00 2001 From: "yvernet@slb.com" Date: Thu, 7 Apr 2022 16:05:59 +0200 Subject: [PATCH 2/3] check regex post split --- app/routers/ddms_v3/well_ddms_v3.py | 2 +- app/routers/ddms_v3/wellbore_ddms_v3.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/routers/ddms_v3/well_ddms_v3.py b/app/routers/ddms_v3/well_ddms_v3.py index 48da0810..33fcb160 100644 --- a/app/routers/ddms_v3/well_ddms_v3.py +++ b/app/routers/ddms_v3/well_ddms_v3.py @@ -50,7 +50,7 @@ async def get_well_osdu( ) -> Well: # Note: version is dropped here record_id, _ = split_record_id_version(wellid) - if OSDU_WELL_REGEX.match(wellid) is None: + if OSDU_WELL_REGEX.match(record_id) is None: raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Id is not OSDU Well") storage_client = await get_storage_record_service(ctx) diff --git a/app/routers/ddms_v3/wellbore_ddms_v3.py b/app/routers/ddms_v3/wellbore_ddms_v3.py index 94c4b260..8c2f66dc 100644 --- a/app/routers/ddms_v3/wellbore_ddms_v3.py +++ b/app/routers/ddms_v3/wellbore_ddms_v3.py @@ -48,7 +48,7 @@ async def get_wellbore_osdu( ) -> Wellbore: # Note: version is dropped here record_id, _ = split_record_id_version(wellboreid) - if OSDU_WELLBORE_REGEX.match(wellboreid) is None: + if OSDU_WELLBORE_REGEX.match(record_id) is None: raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Id is not OSDU Wellbore") storage_client = await get_storage_record_service(ctx) -- GitLab From 5e85ba5b530d293e734805fe61c3ce44d75511ef Mon Sep 17 00:00:00 2001 From: "yvernet@slb.com" Date: Thu, 7 Apr 2022 16:27:47 +0200 Subject: [PATCH 3/3] id check on top of api router --- app/routers/ddms_v3/well_ddms_v3.py | 4 ++-- app/routers/ddms_v3/wellbore_ddms_v3.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/routers/ddms_v3/well_ddms_v3.py b/app/routers/ddms_v3/well_ddms_v3.py index 33fcb160..535210c9 100644 --- a/app/routers/ddms_v3/well_ddms_v3.py +++ b/app/routers/ddms_v3/well_ddms_v3.py @@ -48,10 +48,10 @@ router = APIRouter(route_class=TracingRoute) async def get_well_osdu( wellid: str, ctx: Context = Depends(get_ctx) ) -> Well: + if OSDU_WELL_REGEX.match(wellid) is None: + raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Id is not OSDU Well") # Note: version is dropped here record_id, _ = split_record_id_version(wellid) - if OSDU_WELL_REGEX.match(record_id) is None: - raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Id is not OSDU Well") storage_client = await get_storage_record_service(ctx) well_record = await storage_client.get_record(id=record_id, data_partition_id=ctx.partition_id) diff --git a/app/routers/ddms_v3/wellbore_ddms_v3.py b/app/routers/ddms_v3/wellbore_ddms_v3.py index 8c2f66dc..5e3c99ea 100644 --- a/app/routers/ddms_v3/wellbore_ddms_v3.py +++ b/app/routers/ddms_v3/wellbore_ddms_v3.py @@ -46,10 +46,10 @@ router = APIRouter(route_class=TracingRoute) async def get_wellbore_osdu( wellboreid: str, ctx: Context = Depends(get_ctx) ) -> Wellbore: + if OSDU_WELLBORE_REGEX.match(wellboreid) is None: + raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Id is not OSDU Wellbore") # Note: version is dropped here record_id, _ = split_record_id_version(wellboreid) - if OSDU_WELLBORE_REGEX.match(record_id) is None: - raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Id is not OSDU Wellbore") storage_client = await get_storage_record_service(ctx) well_record = await storage_client.get_record(id=record_id, data_partition_id=ctx.partition_id) -- GitLab