Commit 9dea1de0 authored by fabian serin's avatar fabian serin
Browse files

Merge branch 'master' of...

Merge branch 'master' of https://community.opengroup.org/osdu/platform/domain-data-mgmt-services/wellbore/wellbore-domain-services into fserin/search_trajectory_by_wellbore
parents e100d81e d5c1f84a
...@@ -164,10 +164,13 @@ basic_dependencies = [ ...@@ -164,10 +164,13 @@ basic_dependencies = [
] ]
wdms_app.include_router(probes.router) wdms_app.include_router(probes.router)
wdms_app.include_router(about.router, prefix=DDMS_V2_PATH) wdms_app.include_router(about.router, tags=["Wellbore DDMS"])
# hidden from swagger but maintained for backward compatibility with /ddms/v2 APIs
wdms_app.include_router(about.router, prefix=DDMS_V2_PATH, tags=["Wellbore DDMS"], include_in_schema=False)
wdms_app.include_router(ddms_v2.router, prefix=DDMS_V2_PATH, tags=["Wellbore DDMS"], include_in_schema=False)
ddms_v2_routes_groups = [ ddms_v2_routes_groups = [
(ddms_v2, "Wellbore DDMS"),
(well_ddms_v2, "Well"), (well_ddms_v2, "Well"),
(wellbore_ddms_v2, "Wellbore"), (wellbore_ddms_v2, "Wellbore"),
(logset_ddms_v2, "Logset"), (logset_ddms_v2, "Logset"),
......
...@@ -32,6 +32,7 @@ spec: ...@@ -32,6 +32,7 @@ spec:
- operation: - operation:
notPaths: notPaths:
- {{ include "os-wellbore-ddms.prefix" . }}/ - {{ include "os-wellbore-ddms.prefix" . }}/
- {{ include "os-wellbore-ddms.prefix" . }}/about
- {{ include "os-wellbore-ddms.prefix" . }}/ddms/v2/about - {{ include "os-wellbore-ddms.prefix" . }}/ddms/v2/about
- {{ include "os-wellbore-ddms.prefix" . }}/docs - {{ include "os-wellbore-ddms.prefix" . }}/docs
- {{ include "os-wellbore-ddms.prefix" . }}/openapi.json - {{ include "os-wellbore-ddms.prefix" . }}/openapi.json
......
...@@ -23,22 +23,6 @@ ...@@ -23,22 +23,6 @@
"title": "AboutResponse", "title": "AboutResponse",
"type": "object" "type": "object"
}, },
"AboutResponseUser": {
"additionalProperties": false,
"description": "The base model forbids fields which are not declared initially in the pydantic model",
"properties": {
"email": {
"title": "Email",
"type": "string"
},
"tenant": {
"title": "Tenant",
"type": "string"
}
},
"title": "AboutResponseUser",
"type": "object"
},
"AbstractAccessControlList100": { "AbstractAccessControlList100": {
"additionalProperties": false, "additionalProperties": false,
"description": "The access control tags associated with this entity.", "description": "The access control tags associated with this entity.",
...@@ -3406,35 +3390,6 @@ ...@@ -3406,35 +3390,6 @@
"title": "UpdateSessionStateValue", "title": "UpdateSessionStateValue",
"type": "string" "type": "string"
}, },
"V1AboutResponse": {
"additionalProperties": false,
"description": "The base model forbids fields which are not declared initially in the pydantic model",
"properties": {
"dmsInfo": {
"$ref": "#/components/schemas/V1DmsInfo"
},
"user": {
"$ref": "#/components/schemas/AboutResponseUser"
}
},
"title": "V1AboutResponse",
"type": "object"
},
"V1DmsInfo": {
"additionalProperties": false,
"description": "The base model forbids fields which are not declared initially in the pydantic model",
"properties": {
"kinds": {
"items": {
"type": "string"
},
"title": "Kinds",
"type": "array"
}
},
"title": "V1DmsInfo",
"type": "object"
},
"ValidationError": { "ValidationError": {
"properties": { "properties": {
"loc": { "loc": {
...@@ -8494,6 +8449,27 @@ ...@@ -8494,6 +8449,27 @@
}, },
"openapi": "3.0.2", "openapi": "3.0.2",
"paths": { "paths": {
"/about": {
"get": {
"operationId": "get_about_about_get",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AboutResponse"
}
}
},
"description": "Successful Response"
}
},
"summary": "Get About",
"tags": [
"Wellbore DDMS"
]
}
},
"/alpha/ddms/v2/logs/{record_id}/data": { "/alpha/ddms/v2/logs/{record_id}/data": {
"get": { "get": {
"description": "Returns the data according to the specified query parameters. Multiple media types response are available (\"application/json\", text/csv\", \"application/x-parquet\"). The desired format can be specify in \"Accept\" header. The default is Parquet. When bulk statistics are requested using \"describe\" parameter, the response is always provided in JSON.\n<p>Required roles: 'users.datalake.viewers' or 'users.datalake.editors' or 'users.datalake.admins'.\n\"In addition, users must be a member of data groups to access the data.</p>\n", "description": "Returns the data according to the specified query parameters. Multiple media types response are available (\"application/json\", text/csv\", \"application/x-parquet\"). The desired format can be specify in \"Accept\" header. The default is Parquet. When bulk statistics are requested using \"describe\" parameter, the response is always provided in JSON.\n<p>Required roles: 'users.datalake.viewers' or 'users.datalake.editors' or 'users.datalake.admins'.\n\"In addition, users must be a member of data groups to access the data.</p>\n",
...@@ -11119,24 +11095,6 @@ ...@@ -11119,24 +11095,6 @@
] ]
} }
}, },
"/ddms/v2/about": {
"get": {
"operationId": "get_about_ddms_v2_about_get",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AboutResponse"
}
}
},
"description": "Successful Response"
}
},
"summary": "Get About"
}
},
"/ddms/v2/dipsets": { "/ddms/v2/dipsets": {
"post": { "post": {
"description": "<p>Required roles: 'users.datalake.editors' or 'users.datalake.admins'.</p>", "description": "<p>Required roles: 'users.datalake.editors' or 'users.datalake.admins'.</p>",
...@@ -13961,56 +13919,6 @@ ...@@ -13961,56 +13919,6 @@
] ]
} }
}, },
"/ddms/v2/status": {
"get": {
"operationId": "about_ddms_v2_status_get",
"parameters": [
{
"description": "identifier of the data partition to query",
"in": "header",
"name": "data-partition-id",
"required": false,
"schema": {
"description": "identifier of the data partition to query",
"minLength": 1,
"title": "data partition id",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/V1AboutResponse"
}
}
},
"description": "Successful Response"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
"description": "Validation Error"
}
},
"security": [
{
"HTTPBearer": []
}
],
"summary": "Get the status of the service",
"tags": [
"Wellbore DDMS"
]
}
},
"/ddms/v2/trajectories": { "/ddms/v2/trajectories": {
"post": { "post": {
"description": "<p>Required roles: 'users.datalake.editors' or 'users.datalake.admins'.</p>", "description": "<p>Required roles: 'users.datalake.editors' or 'users.datalake.admins'.</p>",
...@@ -14805,29 +14713,6 @@ ...@@ -14805,29 +14713,6 @@
] ]
} }
}, },
"/ddms/v2/version": {
"get": {
"operationId": "get_version_ddms_v2_version_get",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/VersionDetailsResponse"
}
}
},
"description": "Successful Response"
}
},
"security": [
{
"HTTPBearer": []
}
],
"summary": "Get Version"
}
},
"/ddms/v2/wellbores": { "/ddms/v2/wellbores": {
"post": { "post": {
"description": "<p>Required roles: 'users.datalake.editors' or 'users.datalake.admins'.</p>", "description": "<p>Required roles: 'users.datalake.editors' or 'users.datalake.admins'.</p>",
...@@ -19599,6 +19484,32 @@ ...@@ -19599,6 +19484,32 @@
"log-recognition" "log-recognition"
] ]
} }
},
"/version": {
"get": {
"operationId": "get_version_version_get",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/VersionDetailsResponse"
}
}
},
"description": "Successful Response"
}
},
"security": [
{
"HTTPBearer": []
}
],
"summary": "Get Version",
"tags": [
"Wellbore DDMS"
]
}
} }
} }
} }
\ No newline at end of file
...@@ -19,7 +19,7 @@ def build_request_about() -> RequestRunner: ...@@ -19,7 +19,7 @@ def build_request_about() -> RequestRunner:
rq_proto = Request( rq_proto = Request(
name='about', name='about',
method='GET', method='GET',
url='{{base_url}}/ddms/v2/about', url='{{base_url}}/about',
headers={ headers={
'accept': 'application/json', 'accept': 'application/json',
'Connection': '{{header_connection}}', 'Connection': '{{header_connection}}',
......
...@@ -19,7 +19,7 @@ def build_request_version() -> RequestRunner: ...@@ -19,7 +19,7 @@ def build_request_version() -> RequestRunner:
rq_proto = Request( rq_proto = Request(
name='version', name='version',
method='GET', method='GET',
url='{{base_url}}/ddms/v2/version', url='{{base_url}}/version',
headers={ headers={
'accept': 'application/json', 'accept': 'application/json',
'Connection': '{{header_connection}}', 'Connection': '{{header_connection}}',
......
...@@ -19,19 +19,13 @@ import jwt ...@@ -19,19 +19,13 @@ import jwt
payload = {} payload = {}
wellbore_api_group_prefix = 'ddms/v2'
def build_url(base_url: str, path: str):
return f"{base_url}/{wellbore_api_group_prefix}{path}"
@pytest.fixture @pytest.fixture
def skip_if_gcp_environment(base_url): def skip_if_gcp_environment(base_url):
""" """
In GCP environment there is no AuthorizationPolicy set. Certain tests may fail on GCP In GCP environment there is no AuthorizationPolicy set. Certain tests may fail on GCP
and this fixture aims to skip a test case when targeted environment is GCP. and this fixture aims to skip a test case when targeted environment is GCP.
""" """
response = requests.request("GET", build_url(base_url, "/about"), verify=False) response = requests.request("GET", f"{base_url}/about", verify=False)
assert response.status_code == 200 assert response.status_code == 200
about_response = response.json() about_response = response.json()
...@@ -41,7 +35,7 @@ def skip_if_gcp_environment(base_url): ...@@ -41,7 +35,7 @@ def skip_if_gcp_environment(base_url):
# Test for expired token # Test for expired token
def test_expired_token_returns_40X(base_url, check_cert, token): def test_expired_token_returns_40X(base_url, check_cert, token):
url = build_url(base_url, "/about") url = f"{base_url}/about"
token_expired = jwt.encode({"email":"nobody@example.com", "exp":datetime.datetime.utcnow() - datetime.timedelta(seconds=300)}, key="secret", algorithm="HS256") token_expired = jwt.encode({"email":"nobody@example.com", "exp":datetime.datetime.utcnow() - datetime.timedelta(seconds=300)}, key="secret", algorithm="HS256")
headers = { headers = {
'Authorization': f"Bearer {token_expired}" 'Authorization': f"Bearer {token_expired}"
...@@ -59,7 +53,7 @@ def test_notoken_paths_returns_20X_docs(base_url, check_cert, token): ...@@ -59,7 +53,7 @@ def test_notoken_paths_returns_20X_docs(base_url, check_cert, token):
assert 'content-security-policy' in response.headers assert 'content-security-policy' in response.headers
# Test for no token on some paths where JWT token is NOT required due to the AuthorizationPolicy # Test for no token on some paths where JWT token is NOT required due to the AuthorizationPolicy
@pytest.mark.parametrize("path", ["docs", "openapi.json", f"{wellbore_api_group_prefix}/about"]) @pytest.mark.parametrize("path", ["docs", "openapi.json", "about"])
def test_notoken_paths_returns_20X(base_url, check_cert, token, path): def test_notoken_paths_returns_20X(base_url, check_cert, token, path):
url = f"{base_url}/{path}" url = f"{base_url}/{path}"
...@@ -71,7 +65,7 @@ def test_notoken_paths_returns_20X(base_url, check_cert, token, path): ...@@ -71,7 +65,7 @@ def test_notoken_paths_returns_20X(base_url, check_cert, token, path):
@pytest.mark.parametrize("path", ["version", "nonExistingPath"]) @pytest.mark.parametrize("path", ["version", "nonExistingPath"])
def test_notoken_returns_40X(base_url, check_cert, token, skip_if_gcp_environment, path): def test_notoken_returns_40X(base_url, check_cert, token, skip_if_gcp_environment, path):
url = build_url(base_url, f"/{path}") url = f"{base_url}/{path}"
headers = {} headers = {}
response = requests.request("GET", url, headers=headers, data=payload, verify=check_cert) response = requests.request("GET", url, headers=headers, data=payload, verify=check_cert)
assert response.status_code == 403 assert response.status_code == 403
...@@ -80,7 +74,7 @@ def test_notoken_returns_40X(base_url, check_cert, token, skip_if_gcp_environmen ...@@ -80,7 +74,7 @@ def test_notoken_returns_40X(base_url, check_cert, token, skip_if_gcp_environmen
# Test for invalid token # Test for invalid token
def test_invalid_token_returns_40X(base_url, check_cert, token): def test_invalid_token_returns_40X(base_url, check_cert, token):
url = build_url(base_url, "/about") url = f"{base_url}/about"
blank = {} blank = {}
token_invalid = token[0:len(token) - 10] token_invalid = token[0:len(token) - 10]
headers = { headers = {
...@@ -93,7 +87,7 @@ def test_invalid_token_returns_40X(base_url, check_cert, token): ...@@ -93,7 +87,7 @@ def test_invalid_token_returns_40X(base_url, check_cert, token):
# Test for unauthorized issuer # Test for unauthorized issuer
def test_invalid_issuer_token_returns_40X(base_url, check_cert, token): def test_invalid_issuer_token_returns_40X(base_url, check_cert, token):
url = build_url(base_url, "/about") url = f"{base_url}/about"
blank = {} blank = {}
token_no_iss = jwt.encode({"email": "nobody@example.com"}, key="secret", algorithm="HS256") token_no_iss = jwt.encode({"email": "nobody@example.com"}, key="secret", algorithm="HS256")
headers = { headers = {
......
...@@ -23,6 +23,8 @@ from tests.unit.test_utils import ctx_fixture ...@@ -23,6 +23,8 @@ from tests.unit.test_utils import ctx_fixture
# Initialize traces exporter in app, like it is in app's startup decorator # Initialize traces exporter in app, like it is in app's startup decorator
wdms_app.trace_exporter = traces.CombinedExporter(service_name='tested-ddms') wdms_app.trace_exporter = traces.CombinedExporter(service_name='tested-ddms')
# parametrized for backward compatibility with /ddms/v2 APIs
PathPrefixParams = [DDMS_V2_PATH, '']
@pytest.fixture @pytest.fixture
def client(ctx_fixture): def client(ctx_fixture):
...@@ -42,13 +44,13 @@ def client_with_authenticated_user(): ...@@ -42,13 +44,13 @@ def client_with_authenticated_user():
wdms_app.dependency_overrides = {} wdms_app.dependency_overrides = {}
def build_url(path: str): def build_url(prefix: str, path: str):
return DDMS_V2_PATH + path return prefix + path
@pytest.mark.parametrize("path_prefix", PathPrefixParams)
def test_about_contains_build_n_version(client, path_prefix):
def test_about_contains_build_n_version(client): response = client.get(build_url(path_prefix, "/about"))
response = client.get(build_url("/about"))
assert response.status_code == 200 assert response.status_code == 200
response_json = response.json() response_json = response.json()
...@@ -56,27 +58,30 @@ def test_about_contains_build_n_version(client): ...@@ -56,27 +58,30 @@ def test_about_contains_build_n_version(client):
assert response_json['version'] assert response_json['version']
@pytest.mark.parametrize("path_prefix", PathPrefixParams)
@pytest.mark.parametrize("cloud_provider", ['Azure', 'gcp', 'unknown', 'aws', None]) @pytest.mark.parametrize("cloud_provider", ['Azure', 'gcp', 'unknown', 'aws', None])
def test_about_with_cloud_provider(client, cloud_provider): def test_about_with_cloud_provider(client, cloud_provider, path_prefix):
Config.cloud_provider.value = cloud_provider Config.cloud_provider.value = cloud_provider
response = client.get(build_url("/about")) response = client.get(build_url(path_prefix, "/about"))
assert response.status_code == 200 assert response.status_code == 200
json_response = response.json() json_response = response.json()
assert json_response['cloudEnvironment'] == cloud_provider assert json_response['cloudEnvironment'] == cloud_provider
def test_version_requires_authentication(client): @pytest.mark.parametrize("path_prefix", PathPrefixParams)
response = client.get(build_url("/version")) def test_version_requires_authentication(client, path_prefix):
response = client.get(build_url(path_prefix, "/version"))
assert response.status_code == 403 assert response.status_code == 403
def test_version_properly_read_details(client_with_authenticated_user, monkeypatch): @pytest.mark.parametrize("path_prefix", PathPrefixParams)
def test_version_properly_read_details(client_with_authenticated_user, monkeypatch, path_prefix):
# override value of build details # override value of build details
Config.build_details.value = 'key1=value1; key2=value2' Config.build_details.value = 'key1=value1; key2=value2'
response = client_with_authenticated_user.get(build_url("/version")) response = client_with_authenticated_user.get(build_url(path_prefix, "/version"))
assert response.status_code == 200 assert response.status_code == 200
response_json = response.json() response_json = response.json()
assert response_json['details']['key1'] == 'value1' assert response_json['details']['key1'] == 'value1'
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment