Skip to content
Snippets Groups Projects
Commit bdfd11aa authored by Christophe Lallement's avatar Christophe Lallement
Browse files

wellLog 1.0.0 check schema against its kind

parent c1b87c22
No related branches found
No related tags found
1 merge request!327Check schema against kind
from .welllog_consistency import welllog_consistency_check, DuplicatedCurveIdException, ReferenceCurveIdNotFoundException
from .welllog_consistency import welllog_consistency_check, \
DuplicatedCurveIdException, ReferenceCurveIdNotFoundException, SchemaException
from app.model.osdu_model import WellLog110 as WellLog
from app.model.osdu_model import WellLog, WellLog110
from pydantic import ValidationError
from app.model.model_utils import from_record, to_record
class DuplicatedCurveIdException(RuntimeError):
"""raised if all curveID values are not unique"""
pass
class ReferenceCurveIdNotFoundException(RuntimeError):
"""raised when there is no curve with a curveID value equal to the ReferenceCurveID value"""
pass
def welllog_consistency_check(wl: WellLog):
class SchemaException(RuntimeError):
"""raised when the object doesn't validate against the schema of its kinds"""
def welllog_consistency_check(wl: WellLog110):
"""Check if wellLog is consistent.
Each curves in data.Curves must have a unique CurveID.
......@@ -25,7 +29,26 @@ def welllog_consistency_check(wl: WellLog):
Raises:
DuplicatedCurveIdException: All CurveIDs are not unique.
ReferenceCurveIdNotFoundException: No curve whose curveID value are equal to ReferenceCurveID value.
SchemaException: Object doesn't validate schema against its kind
"""
# check schema against its kind
namespace, source, type, version = wl.kind.split(":")
if type != "work-product-component--WellLog":
raise SchemaException()
if version == "1.0.0":
try:
# validate against the schema
# fields from wellLog 1.1.0 are set to none by default what makes the validation fail against 1.0.0 schema
# so we convert welllog to dict in ordoer to exclude none and unset values and then we construct a WellLog (1.0.0) from the dict.
_ = WellLog(**wl.dict(exclude_none=True, exclude_unset=True, by_alias=True))
except ValidationError as e:
raise SchemaException()
except Exception as e:
raise SchemaException()
if not wl.data:
return
......
......@@ -26,7 +26,8 @@ from starlette.requests import Request
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 WellLog110 as WellLog
from app.model.osdu_model import WellLog, WellLog110
from app.utils import Context, get_ctx, load_schema_example
from app.routers.ddms_v3.ddms_v3_utils import DMSV3RouterUtils, OSDU_WELLLOG_VERSION_REGEX
......@@ -36,7 +37,11 @@ from app.routers.record_utils import fetch_record
from app.routers.common_parameters import REQUIRED_ROLES_READ, REQUIRED_ROLES_WRITE
from app.routers.delete.delete_bulk_data import delete_record
from app.consistency import welllog_consistency_check, DuplicatedCurveIdException, ReferenceCurveIdNotFoundException
from app.consistency import (
welllog_consistency_check,
DuplicatedCurveIdException,
ReferenceCurveIdNotFoundException,
SchemaException)
router = APIRouter()
......@@ -45,18 +50,18 @@ WELL_LOGS_API_BASE_PATH = '/welllogs'
@router.get(
WELL_LOGS_API_BASE_PATH + "/{welllogid}",
response_model=WellLog,
response_model=WellLog110,
response_model_exclude_unset=True,
summary="Get the WellLog using osdu schema",
description="""Get the WellLog object using its **id**. {}""".format(REQUIRED_ROLES_READ),
summary="Get the WellLog110 using osdu schema",
description="""Get the WellLog110 object using its **id**. {}""".format(REQUIRED_ROLES_READ),
operation_id="get_welllog_osdu",
responses={
status.HTTP_404_NOT_FOUND: {"description": "WellLog not found"}
status.HTTP_404_NOT_FOUND: {"description": "WellLog110 not found"}
},
)
async def get_welllog_osdu(
welllogid: str, request: Request, ctx: Context = Depends(get_ctx)
) -> WellLog:
) -> WellLog110:
storage_client = await get_storage_record_service(ctx)
welllogid = DMSV3RouterUtils.get_id_without_version(OSDU_WELLLOG_VERSION_REGEX,
welllogid)
......@@ -64,7 +69,7 @@ async def get_welllog_osdu(
id=welllogid, data_partition_id=ctx.partition_id
)
DMSV3RouterUtils.raise_if_not_osdu_right_entity_kind(welllog_record, request.state)
return from_record(WellLog, welllog_record)
return from_record(WellLog110, welllog_record)
@router.delete(
......@@ -76,7 +81,7 @@ async def get_welllog_osdu(
status_code=status.HTTP_204_NO_CONTENT,
response_class=Response,
responses={
status.HTTP_404_NOT_FOUND: {"description": "WellLog not found"},
status.HTTP_404_NOT_FOUND: {"description": "WellLog110 not found"},
status.HTTP_204_NO_CONTENT: {
"description": "Record deleted successfully"
},
......@@ -97,11 +102,11 @@ async def del_osdu_welllog(welllogid: str,
@router.get(
WELL_LOGS_API_BASE_PATH + "/{welllogid}/versions",
response_model=RecordVersions,
summary="Get all versions of the WellLog",
summary="Get all versions of the WellLog110",
description="{}".format(REQUIRED_ROLES_READ),
operation_id="get_osdu_welllog_versions",
responses={
status.HTTP_404_NOT_FOUND: {"description": "WellLog not found"}
status.HTTP_404_NOT_FOUND: {"description": "WellLog110 not found"}
},
)
async def get_osdu_welllog_versions(
......@@ -119,18 +124,18 @@ async def get_osdu_welllog_versions(
@router.get(
WELL_LOGS_API_BASE_PATH + "/{welllogid}/versions/{version}",
response_model=WellLog,
summary="Get the given version of the WellLog using OSDU welllog schema",
description=""""Get the WellLog object using its **id**. {}""".format(REQUIRED_ROLES_READ),
response_model=WellLog110,
summary="Get the given version of the WellLog110 using OSDU welllog schema",
description=""""Get the WellLog110 object using its **id**. {}""".format(REQUIRED_ROLES_READ),
operation_id="get_osdu_welllog_version",
responses={
status.HTTP_404_NOT_FOUND: {"description": "WellLog not found"}
status.HTTP_404_NOT_FOUND: {"description": "WellLog110 not found"}
},
response_model_exclude_unset=True,
)
async def get_osdu_welllog_version(
welllogid: str, version: int, request: Request, ctx: Context = Depends(get_ctx)
) -> WellLog:
) -> WellLog110:
storage_client = await get_storage_record_service(ctx)
welllogid = DMSV3RouterUtils.get_id_without_version(OSDU_WELLLOG_VERSION_REGEX,
welllogid)
......@@ -138,7 +143,7 @@ async def get_osdu_welllog_version(
id=welllogid, version=version, data_partition_id=ctx.partition_id
)
DMSV3RouterUtils.raise_if_not_osdu_right_entity_kind(welllog_record, request.state)
return from_record(WellLog, welllog_record)
return from_record(WellLog110, welllog_record)
@router.post(
......@@ -154,7 +159,7 @@ async def get_osdu_welllog_version(
},
)
async def post_welllog_osdu(
welllogs: List[WellLog] = Body(..., example=load_schema_example("wellLog_v3.json")),
welllogs: List[WellLog110] = Body(..., example=load_schema_example("wellLog_v3.json")),
ctx: Context = Depends(get_ctx)
) -> CreateUpdateRecordsResponse:
......@@ -171,6 +176,13 @@ async def post_welllog_osdu(
status_code=status.HTTP_400_BAD_REQUEST,
detail=f"WellLog[{idx}] should have a curve with a curveID value equal to the ReferenceCurveID value: '{w.data.ReferenceCurveID}'"
)
except SchemaException:
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail=f"WellLog[{idx}] with kind \'{w.kind}\' is not valid against WellLog 1.0.0 schema"
)
storage_client = await get_storage_record_service(ctx)
......
......@@ -3,7 +3,7 @@ from app.model.osdu_model import WellLog110, AbstractLegalTags100, AbstractAcces
Curve110
from app.consistency import welllog_consistency_check, DuplicatedCurveIdException, ReferenceCurveIdNotFoundException
KIND = "osdu:wks:work-product-component--WellLog:1.0.0"
KIND = "osdu:wks:work-product-component--WellLog:1.1.0"
LEGAL = AbstractLegalTags100(legaltags=["legal_tag"], otherRelevantDataCountries=["FR"], status="compliant")
ACL = AbstractAccessControlList100(owners=["data.default.owners@opendes.slb.com"],
viewers=["data.default.viewers@opendes.slb.com"])
......
import pytest
import json
from fastapi import Header, status
from fastapi.testclient import TestClient
from app.auth.auth import require_opendes_authorized_user
from app.clients import SearchServiceClient, StorageRecordServiceClient
from app.helper import traces
from app.middleware import require_data_partition_id
from app.auth.auth import require_opendes_authorized_user
from app.utils import Context
from app.wdms_app import wdms_app, app_injector
from tests.unit.test_utils import create_mock_class, nope_logger_fixture
StorageRecordServiceClientMock = create_mock_class(StorageRecordServiceClient)
......@@ -40,9 +36,7 @@ def client(nope_logger_fixture):
previous_overrides = wdms_app.dependency_overrides
try:
wdms_app.dependency_overrides[
require_opendes_authorized_user
] = bypass_authorization
wdms_app.dependency_overrides[require_opendes_authorized_user] = bypass_authorization
wdms_app.dependency_overrides[require_data_partition_id] = set_default_partition
client = TestClient(wdms_app)
yield client
......@@ -54,97 +48,120 @@ def client(nope_logger_fixture):
wdms_app.trace_exporter = traces.CombinedExporter(service_name="tested-ddms")
@pytest.mark.parametrize("data", [
@pytest.mark.parametrize(
"data",
[
{"ReferenceCurveID": "MD", "Curves": [{"CurveID": "GR"}, {"CurveID": "MD"}]},
{"ReferenceCurveID": "TVD", "Curves": [{"CurveID": "TVD"}, {"CurveID": "INCL"}]},
],
[
{"Curves": [{"CurveID": "MD"}, {"CurveID": "GR"}]},
{"Curves": [{"CurveID": "A"}, {"CurveID": "B"}]}
],
[
{"Curves": []}
[
{"ReferenceCurveID": "MD", "Curves": [{"CurveID": "GR"}, {"CurveID": "MD"}]},
{"ReferenceCurveID": "TVD", "Curves": [{"CurveID": "TVD"}, {"CurveID": "INCL"}]},
],
[{"Curves": [{"CurveID": "MD"}, {"CurveID": "GR"}]}, {"Curves": [{"CurveID": "A"}, {"CurveID": "B"}]}],
[{"Curves": []}],
[{"TopMeasuredDepth": "1000"}, {"Curves": [{"CurveID": "MD"}, {"CurveID": "GR"}]}, {"Curves": []}],
],
[
{"TopMeasuredDepth": "1000"},
{"Curves": [{"CurveID": "MD"}, {"CurveID": "GR"}]},
{"Curves": []}
]
])
)
def test_post_consistent_welllog(client, data):
response = client.post(
url="/ddms/v3/welllogs",
json=[{
"kind": "osdu:wks:work-product-component--WellLog:1.0.0",
"legal": {
"legaltags": ["foo"],
"otherRelevantDataCountries": ["FR"]},
"acl": {
"owners": ["foo@bar.com"],
"viewers": ["foo@bar.com"]},
"data": d} for d in data],
headers={'content-type': 'application/json'})
json=[
{
"kind": "osdu:wks:work-product-component--WellLog:1.1.0",
"legal": {"legaltags": ["foo"], "otherRelevantDataCountries": ["FR"]},
"acl": {"owners": ["foo@bar.com"], "viewers": ["foo@bar.com"]},
"data": d,
}
for d in data
],
headers={"content-type": "application/json"},
)
assert response.status_code == status.HTTP_200_OK
@pytest.mark.parametrize("well_log_data, expected", [
(
[
{"ReferenceCurveID": "MD", "Curves": [{"CurveID": "MD"}, {"CurveID": "GR"}]},
{"ReferenceCurveID": "MD", "Curves": [{"CurveID": "MD"}, {"CurveID": "A"}, {"CurveID": "A"}]}
],
@pytest.mark.parametrize(
"well_log_data, expected",
[
(
status.HTTP_400_BAD_REQUEST,
"All CurveID in WellLog[1] should be unique"
)
),
(
[
{"ReferenceCurveID": "MD", "Curves": [{"CurveID": "MD"}, {"CurveID": "GR"}]},
{"ReferenceCurveID": "MD", "Curves": [{"CurveID": "A"}, {"CurveID": "B"}]}
],
[
{"ReferenceCurveID": "MD", "Curves": [{"CurveID": "MD"}, {"CurveID": "GR"}]},
{"ReferenceCurveID": "MD", "Curves": [{"CurveID": "MD"}, {"CurveID": "A"}, {"CurveID": "A"}]},
],
(status.HTTP_400_BAD_REQUEST,
"All CurveID in WellLog[1] should be unique"),
),
(
status.HTTP_400_BAD_REQUEST,
"WellLog[1] should have a curve with a curveID value equal to the ReferenceCurveID value: 'MD'"
)
),
(
[
{"ReferenceCurveID": "MD", "Curves": [{"CurveID": "MD"}, {"CurveID": "GR"}]},
{"ReferenceCurveID": "MD","Curves": []}
],
[
{"ReferenceCurveID": "MD", "Curves": [{"CurveID": "MD"}, {"CurveID": "GR"}]},
{"ReferenceCurveID": "MD", "Curves": [{"CurveID": "A"}, {"CurveID": "B"}]},
],
(
status.HTTP_400_BAD_REQUEST,
"WellLog[1] should have a curve with a curveID value equal to the ReferenceCurveID value: 'MD'",
),
),
(
status.HTTP_400_BAD_REQUEST,
"WellLog[1] should have a curve with a curveID value equal to the ReferenceCurveID value: 'MD'"
)
),
(
[
{"ReferenceCurveID": "MD", "Curves": [{"CurveID": "MD"}, {"CurveID": "GR"}]},
{"ReferenceCurveID": "MD"}
],
[
{"ReferenceCurveID": "MD", "Curves": [{"CurveID": "MD"}, {"CurveID": "GR"}]},
{"ReferenceCurveID": "MD", "Curves": []},
],
(
status.HTTP_400_BAD_REQUEST,
"WellLog[1] should have a curve with a curveID value equal to the ReferenceCurveID value: 'MD'",
),
),
(
status.HTTP_400_BAD_REQUEST,
"WellLog[1] should have a curve with a curveID value equal to the ReferenceCurveID value: 'MD'"
)
)
])
[{"ReferenceCurveID": "MD", "Curves": [{"CurveID": "MD"}, {"CurveID": "GR"}]}, {"ReferenceCurveID": "MD"}],
(
status.HTTP_400_BAD_REQUEST,
"WellLog[1] should have a curve with a curveID value equal to the ReferenceCurveID value: 'MD'",
),
),
],
)
def test_post_inconsistent_welllog(client, well_log_data, expected):
response = client.post(
url="/ddms/v3/welllogs",
json=[{
"kind": "osdu:wks:work-product-component--WellLog:1.0.0",
"legal": {
"legaltags": ["foo"],
"otherRelevantDataCountries": ["FR"]},
"acl": {
"owners": ["foo@bar.com"],
"viewers": ["foo@bar.com"]},
"data": data} for data in well_log_data],
headers={'content-type': 'application/json'})
json=[
{
"kind": "osdu:wks:work-product-component--WellLog:1.1.0",
"legal": {"legaltags": ["foo"], "otherRelevantDataCountries": ["FR"]},
"acl": {"owners": ["foo@bar.com"], "viewers": ["foo@bar.com"]},
"data": data,
}
for data in well_log_data
],
headers={"content-type": "application/json"},
)
assert response.status_code == expected[0]
assert expected[1] in response.json().get("detail")
def test_post_welllog_check_schema_against_kind(client):
json = [
{
"kind": "osdu:wks:work-product-component--WellLog:1.1.0",
"legal": {"legaltags": ["foo"], "otherRelevantDataCountries": ["FR"]},
"acl": {"owners": ["foo@bar.com"], "viewers": ["foo@bar.com"]},
"data": {"LogSource": "foo"},
},
{
"kind": "osdu:wks:work-product-component--WellLog:1.0.0",
"legal": {"legaltags": ["foo"], "otherRelevantDataCountries": ["FR"]},
"acl": {"owners": ["foo@bar.com"], "viewers": ["foo@bar.com"]},
"data": {"TopMeasuredDepth": "10"},
},
{
"kind": "osdu:wks:work-product-component--WellLog:1.0.0",
"legal": {"legaltags": ["foo"], "otherRelevantDataCountries": ["FR"]},
"acl": {"owners": ["foo@bar.com"], "viewers": ["foo@bar.com"]},
"data": {"ReferenceCurveID": "foo"},
},
]
response = client.post(url="/ddms/v3/welllogs", json=json, headers={"content-type": "application/json"})
assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
assert "WellLog[2] with kind 'osdu:wks:work-product-component--WellLog:1.0.0' is not valid against WellLog 1.0.0 schema" in response.json().get(
"detail"
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment