Skip to content

Commit 946eee1

Browse files
committed
feat: cover search relationship RDF and report APIs
1 parent d6bfbb7 commit 946eee1

4 files changed

Lines changed: 147 additions & 0 deletions

File tree

platform-api/src/openmetadata_demo_api/catalog.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,19 @@
101101
"createStorageService",
102102
"createContainer",
103103
}
104+
SEARCH_RELATIONSHIP_PREFIXES = ("search/", "rdf/", "reports/")
105+
SEARCH_RELATIONSHIP_OPERATIONS = {
106+
"searchSchemaEntityRelationship",
107+
"searchEntityRelationship",
108+
"searchEntityRelationshipWithDirection",
109+
}
110+
SEARCH_RELATIONSHIP_PREREQUISITES = {
111+
"createDatabaseService",
112+
"createDatabase",
113+
"createDBSchema",
114+
"createTable",
115+
"createDashboardService",
116+
}
104117
CORE_SERVICE_PREREQUISITES = {
105118
"createApiService",
106119
"createDashboardService",
@@ -460,6 +473,17 @@ def scenarios() -> dict[str, Scenario]:
460473
if _is_lineage_query_profile_usage_operation(operation)
461474
),
462475
),
476+
"lineage-search-relationships": scenario_from_operations(
477+
"lineage-search-relationships",
478+
"Search, aggregation, indexing, RDF, relationship traversal, and reports",
479+
tuple(
480+
operation
481+
for operation in all_operations
482+
if str(operation["source"]["file"]).startswith(SEARCH_RELATIONSHIP_PREFIXES)
483+
or operation["operation_id"] in SEARCH_RELATIONSHIP_OPERATIONS
484+
or operation["operation_id"] in SEARCH_RELATIONSHIP_PREREQUISITES
485+
),
486+
),
463487
}
464488

465489

platform-api/src/openmetadata_demo_api/request_fixtures.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@
6363
"assets": [DEMO_ENTITY_REFERENCE],
6464
},
6565
"AlertType": "Notification",
66+
"AggregationRequest": {
67+
"query": "",
68+
"index": "table_search_index",
69+
"fieldName": "service.name.keyword",
70+
"size": 10,
71+
},
6672
"AssetType": "Inline",
6773
"BulkColumnUpdateRequest": {
6874
"columnName": "demo",
@@ -199,6 +205,13 @@
199205
"stepName": "metadata",
200206
"message": "Dry-run progress",
201207
},
208+
"PreviewSearchRequest": {
209+
"query": "orders",
210+
"index": "table_search_index",
211+
"searchSettings": {},
212+
"from": 0,
213+
"size": 10,
214+
},
202215
"RecognizerFeedback": {
203216
"entityLink": "<#E::table::demo.demo.demo.demo::columns::id>",
204217
"tagFQN": "PII.Sensitive",
@@ -221,6 +234,14 @@
221234
"ReportDataType": "entityReportData",
222235
"RestoreEntity": {"id": DEMO_ID},
223236
"SearchIndexSampleData": {"messages": ['{"id": 1}']},
237+
"SparqlQuery": {
238+
"query": (
239+
"SELECT ?subject ?predicate ?object WHERE { ?subject ?predicate ?object } LIMIT 10"
240+
),
241+
"format": "json",
242+
"timeout": 30000,
243+
"inference": "none",
244+
},
224245
"String": "demo",
225246
"TableData": {"columns": ["id"], "rows": [[1]]},
226247
"TableJoins": {"startDate": "2026-01-01", "dayCount": 1},
@@ -250,6 +271,14 @@
250271
"description": "Updated by the dry-run demo",
251272
},
252273
"ValidateGlossaryTagsRequest": {"dryRun": True, "glossaryTags": []},
274+
"VectorSearchRequest": {
275+
"query": "orders",
276+
"filters": {"entityType": ["table"]},
277+
"size": 10,
278+
"from": 0,
279+
"k": 1000,
280+
"threshold": 0.0,
281+
},
253282
"VoteRequest": {"updatedVoteType": "votedUp"},
254283
"WebAnalyticEventData": {"timestamp": 1, "eventType": "PageView"},
255284
"WebAnalyticEventType": "PageView",
@@ -274,6 +303,10 @@
274303
"metadata.generated.schema.api.addTagToAssetsRequest",
275304
"AddTagToAssetsRequest",
276305
),
306+
"AggregationRequest": (
307+
"metadata.generated.schema.search.aggregationRequest",
308+
"AggregationRequest",
309+
),
277310
"BulkAssets": ("metadata.generated.schema.api.bulkAssets", "BulkAssets"),
278311
"BulkColumnUpdateRequest": (
279312
"metadata.generated.schema.api.data.bulkColumnUpdateRequest",
@@ -361,6 +394,10 @@
361394
"metadata.generated.schema.entity.services.ingestionPipelines.progressUpdate",
362395
"ProgressUpdate",
363396
),
397+
"PreviewSearchRequest": (
398+
"metadata.generated.schema.api.search.previewSearchRequest",
399+
"PreviewSearchRequest",
400+
),
364401
"RecognizerFeedback": (
365402
"metadata.generated.schema.type.recognizerFeedback",
366403
"RecognizerFeedback",
@@ -375,6 +412,10 @@
375412
"metadata.generated.schema.entity.data.searchIndex",
376413
"SearchIndexSampleData",
377414
),
415+
"SparqlQuery": (
416+
"metadata.generated.schema.api.rdf.sparqlQuery",
417+
"SparqlQuery",
418+
),
378419
"TableData": ("metadata.generated.schema.entity.data.table", "TableData"),
379420
"TableJoins": ("metadata.generated.schema.entity.data.table", "TableJoins"),
380421
"TableProfilerConfig": (
@@ -433,6 +474,15 @@
433474
}
434475
)
435476

477+
JAVA_SOURCE_REQUESTS = MappingProxyType(
478+
{
479+
"VectorSearchRequest": (
480+
"openmetadata-service/src/main/java/org/openmetadata/service/search/vector/"
481+
"utils/DTOs.java"
482+
)
483+
}
484+
)
485+
436486

437487
def fixture_for(model_name: str) -> Any:
438488
return REQUEST_FIXTURES[model_name]

platform-api/tests/test_request_fixtures.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from openmetadata_demo_api.request_fixtures import (
44
DEMO_ID,
5+
JAVA_SOURCE_REQUESTS,
56
PYDANTIC_PARAMETER_ENUMS,
67
PYDANTIC_REQUEST_MODELS,
78
REQUEST_FIXTURES,
@@ -31,6 +32,15 @@ def test_java_and_jakarta_request_fixtures_have_transport_valid_shapes() -> None
3132
]
3233
assert REQUEST_FIXTURES["String"] == "demo"
3334
assert REQUEST_FIXTURES["UUID"] == DEMO_ID
35+
assert JAVA_SOURCE_REQUESTS["VectorSearchRequest"].endswith("vector/utils/DTOs.java")
36+
assert REQUEST_FIXTURES["VectorSearchRequest"] == {
37+
"query": "orders",
38+
"filters": {"entityType": ["table"]},
39+
"size": 10,
40+
"from": 0,
41+
"k": 1000,
42+
"threshold": 0.0,
43+
}
3444

3545

3646
def test_required_parameter_enum_fixtures_are_valid_rc1_values() -> None:

platform-api/tests/test_runtime.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,3 +1015,66 @@ def test_lineage_query_profile_usage_requests_are_validated_and_placeholder_free
10151015
"CreateQueryCostRecordRequest",
10161016
"CreateTableProfileRequest",
10171017
} <= models
1018+
1019+
1020+
def test_search_relationship_rdf_report_scenario_covers_source_routes() -> None:
1021+
prefixes = ("search/", "rdf/", "reports/")
1022+
relationship_operations = {
1023+
"searchSchemaEntityRelationship",
1024+
"searchEntityRelationship",
1025+
"searchEntityRelationshipWithDirection",
1026+
}
1027+
prerequisites = {
1028+
"createDatabaseService",
1029+
"createDatabase",
1030+
"createDBSchema",
1031+
"createTable",
1032+
"createDashboardService",
1033+
}
1034+
expected = {
1035+
operation["operation_id"]
1036+
for operation in load_operations()
1037+
if str(operation["source"]["file"]).startswith(prefixes)
1038+
or operation["operation_id"] in relationship_operations
1039+
}
1040+
scenario = scenarios()["lineage-search-relationships"]
1041+
1042+
assert {step.operation_id for step in scenario.operation_steps} == expected | prerequisites
1043+
assert len(scenario.run()) == len(expected | prerequisites)
1044+
assert {
1045+
"searchEntitiesWithQuery",
1046+
"previewSearch",
1047+
"aggregateSearchRequest",
1048+
"vectorSearch",
1049+
"querySparqlPost",
1050+
"getFullLineage",
1051+
"exportGlossaryAsOntology",
1052+
"createOrUpdateReport",
1053+
} <= expected
1054+
ordered = [step.operation_id for step in scenario.ordered_steps()]
1055+
assert ordered.index("createTable") < ordered.index("searchEntityRelationship")
1056+
assert ordered.index("createDashboardService") < ordered.index("createOrUpdateReport")
1057+
1058+
1059+
def test_search_relationship_rdf_report_requests_are_validated_and_placeholder_free() -> None:
1060+
scenario = scenarios()["lineage-search-relationships"]
1061+
1062+
assert not {
1063+
str(value["_model"])
1064+
for step in scenario.operation_steps
1065+
for value in _nested_mappings(step.request)
1066+
if "_model" in value
1067+
}
1068+
vector = next(
1069+
step.request["body"]
1070+
for step in scenario.operation_steps
1071+
if step.operation_id == "vectorSearch"
1072+
)
1073+
assert vector["query"] == "orders"
1074+
assert vector["filters"]["entityType"] == ("table",)
1075+
assert (vector["size"], vector["from"], vector["k"], vector["threshold"]) == (
1076+
10,
1077+
0,
1078+
1000,
1079+
0.0,
1080+
)

0 commit comments

Comments
 (0)