From 423fc5ce85be84d9ed3b3a86f1b7d92389f5e403 Mon Sep 17 00:00:00 2001 From: Ram Narayan Balaji <81347100+yan-3005@users.noreply.github.com> Date: Tue, 30 Sep 2025 15:38:28 +0530 Subject: [PATCH] Fix TypeResource to handle indefinition references (#23592) --- .../service/util/SchemaFieldExtractor.java | 11 ++++- .../resources/metadata/TypeResourceTest.java | 49 +++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/util/SchemaFieldExtractor.java b/openmetadata-service/src/main/java/org/openmetadata/service/util/SchemaFieldExtractor.java index 35619cd9f4f..80283c735bb 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/util/SchemaFieldExtractor.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/util/SchemaFieldExtractor.java @@ -425,7 +425,16 @@ public class SchemaFieldExtractor { } private static String determineReferenceType(String refUri) { - // Pattern to extract the definition name if present + // Handle internal schema references first (e.g., #/definitions/column, + // #/definitions/tableConstraint, etc.) + if (refUri.startsWith("#/definitions/")) { + String definitionName = refUri.substring("#/definitions/".length()); + LOG.debug("Found internal schema reference: {}", definitionName); + // Return the definition name as the type - this preserves the actual type name + return definitionName; + } + + // Pattern to extract the definition name if present from external files Pattern definitionPattern = Pattern.compile("^(?:.*/)?basic\\.json#/definitions/([\\w-]+)$"); Matcher matcher = definitionPattern.matcher(refUri); if (matcher.find()) { diff --git a/openmetadata-service/src/test/java/org/openmetadata/service/resources/metadata/TypeResourceTest.java b/openmetadata-service/src/test/java/org/openmetadata/service/resources/metadata/TypeResourceTest.java index d634c3f6a29..db5ca6e6cd0 100644 --- a/openmetadata-service/src/test/java/org/openmetadata/service/resources/metadata/TypeResourceTest.java +++ b/openmetadata-service/src/test/java/org/openmetadata/service/resources/metadata/TypeResourceTest.java @@ -14,6 +14,7 @@ package org.openmetadata.service.resources.metadata; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.openmetadata.common.utils.CommonUtil.listOrEmpty; import static org.openmetadata.service.util.EntityUtil.fieldAdded; @@ -505,6 +506,54 @@ public class TypeResourceTest extends EntityResourceTest { } } + @Test + void test_getEntityTypeFields_internalSchemaReferences() throws HttpResponseException { + // Test that internal schema references like #/definitions/column are handled correctly + WebTarget target = getCollection().path("/fields/table"); + List> fields = TestUtils.get(target, List.class, ADMIN_AUTH_HEADERS); + + // Find the columns field + Map columnsField = + fields.stream() + .filter(field -> "columns".equals(field.get("name"))) + .findFirst() + .orElse(null); + + // Verify columns field exists and has correct type + assertNotNull(columnsField, "columns field should be present"); + assertEquals( + "array", + columnsField.get("type"), + "columns field should be of type array, not array"); + + // Verify that nested column properties are exposed + boolean hasColumnName = + fields.stream().anyMatch(field -> "columns.name".equals(field.get("name"))); + boolean hasColumnDescription = + fields.stream().anyMatch(field -> "columns.description".equals(field.get("name"))); + boolean hasColumnDataType = + fields.stream().anyMatch(field -> "columns.dataType".equals(field.get("name"))); + + assertTrue(hasColumnName, "columns.name field should be exposed"); + assertTrue(hasColumnDescription, "columns.description field should be exposed"); + assertTrue(hasColumnDataType, "columns.dataType field should be exposed"); + + // Test other internal schema references + Map dataModelField = + fields.stream() + .filter(field -> "dataModel".equals(field.get("name"))) + .findFirst() + .orElse(null); + + assertNotNull(dataModelField, "dataModel field should be present"); + assertEquals("dataModel", dataModelField.get("type"), "dataModel should be of type object"); + + // Verify nested dataModel properties are exposed + boolean hasDataModelColumns = + fields.stream().anyMatch(field -> "dataModel.columns".equals(field.get("name"))); + assertTrue(hasDataModelColumns, "dataModel.columns field should be exposed"); + } + @Override public void assertFieldChange(String fieldName, Object expected, Object actual) { if (expected == actual) {