From 233aa8d2b20ef591c52d1c513d34e738d84d7256 Mon Sep 17 00:00:00 2001 From: Jonas Keeling Date: Tue, 27 Feb 2024 13:36:00 +0100 Subject: [PATCH] fix: resolving references in subjects_schema_post Method subjects_schema_post was using the dependencies of the schema in body to parse all the schemas that are matched. This leads to error if both schemas don't share dependencies. --- karapace/schema_registry_apis.py | 5 +- ...est_dependencies_compatibility_protobuf.py | 72 +++++++++++++++++++ 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/karapace/schema_registry_apis.py b/karapace/schema_registry_apis.py index 85560ec5a..f3377d567 100644 --- a/karapace/schema_registry_apis.py +++ b/karapace/schema_registry_apis.py @@ -1126,12 +1126,13 @@ async def subjects_schema_post( # Match schemas based on version from latest to oldest for schema_version in sorted(subject_data.values(), key=lambda item: item.version, reverse=True): + other_references, other_dependencies = self.schema_registry.resolve_references(schema_version.references) try: parsed_typed_schema = ParsedTypedSchema.parse( schema_version.schema.schema_type, schema_version.schema.schema_str, - references=schema_version.references, - dependencies=new_schema_dependencies, + references=other_references, + dependencies=other_dependencies, ) except InvalidSchema as e: failed_schema_id = schema_version.schema_id diff --git a/tests/integration/test_dependencies_compatibility_protobuf.py b/tests/integration/test_dependencies_compatibility_protobuf.py index 51f5c558c..2bacbdf7b 100644 --- a/tests/integration/test_dependencies_compatibility_protobuf.py +++ b/tests/integration/test_dependencies_compatibility_protobuf.py @@ -669,3 +669,75 @@ async def test_protobuf_customer_update_when_having_references(registry_async_cl res = await registry_async_client.post(f"subjects/{subject_customer}/versions", json=body) assert res.status_code == 200 + + +async def test_protobuf_schema_lookup_with_other_version_having_references(registry_async_client: Client) -> None: + subject = create_subject_name_factory("test_protobuf_subject_check")() + + schema = trim_margin( + """ + |syntax = "proto3"; + |message Foo { + | string bar = 1; + |} + |""" + ) + + body = { + "schemaType": "PROTOBUF", + "schema": schema, + } + res = await registry_async_client.post(f"subjects/{subject}/versions", json=body) + assert res.status_code == 200 + old_id = res.json()["id"] + + subject_dependency = create_subject_name_factory("test_protobuf_subject_check_dependency")() + + dependency = trim_margin( + """ + |syntax = "proto3"; + |message Dependency { + | string foo = 1; + |} + |""" + ) + + body = { + "schemaType": "PROTOBUF", + "schema": dependency, + } + res = await registry_async_client.post(f"subjects/{subject_dependency}/versions", json=body) + assert res.status_code == 200 + + new_schema = trim_margin( + """ + |syntax = "proto3"; + |import "dependency.proto"; + |message Foo { + | string bar = 1; + | Dependency dep = 2; + |} + |""" + ) + + body = { + "schemaType": "PROTOBUF", + "schema": new_schema, + "references": [ + { + "name": "dependency.proto", + "subject": subject_dependency, + "version": -1, + } + ], + } + res = await registry_async_client.post(f"subjects/{subject}/versions", json=body) + assert res.status_code == 200 + + body = { + "schemaType": "PROTOBUF", + "schema": schema, + } + res = await registry_async_client.post(f"subjects/{subject}", json=body) + assert res.status_code == 200 + assert res.json()["id"] == old_id