Skip to content

Commit

Permalink
schema_registry/json: allow alternate form of $schema uris
Browse files Browse the repository at this point in the history
adapt from_uri(uri) -> json_schema_dialect to recognize

http://json-schema.org/draft-0N/schema# and
http://json-schema.org/draft-0N/schema
as draftN dialects.

removed enum values for $schema in the metaschemas since the check for
permitted values is already performed before validation
  • Loading branch information
andijcr committed Jul 5, 2024
1 parent d63c3d1 commit d4c39e0
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 35 deletions.
64 changes: 29 additions & 35 deletions src/v/pandaproxy/schema_registry/json.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@

#include <ranges>
#include <string_view>

namespace pandaproxy::schema_registry {

struct json_schema_definition::impl {
Expand Down Expand Up @@ -80,9 +81,7 @@ namespace {

// from https://json-schema.org/draft-04/schema, this is used to meta-validate a
// jsonschema.
// note: draft5 uses the same metaschema as draft4, so this metaschema is
// adapted to allow http://json-schema.org/draft-05/schema# as one of the
// allowed values for $schema
// note: draft5 uses the same metaschema as draft4
constexpr std::string_view json_draft_4_metaschema = R"json(
{
"id": "http://json-schema.org/draft-04/schema#",
Expand Down Expand Up @@ -117,8 +116,7 @@ constexpr std::string_view json_draft_4_metaschema = R"json(
"type": "string"
},
"$schema": {
"type": "string",
"enum": ["http://json-schema.org/draft-04/schema#","http://json-schema.org/draft-05/schema#"]
"type": "string"
},
"title": {
"type": "string"
Expand Down Expand Up @@ -251,12 +249,6 @@ constexpr std::string_view json_draft_4_metaschema = R"json(
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "id": "http://json-schema.org/draft-06/schema#",
"title": "Core schema meta-schema",
@@ -46,3 +46,4 @@
"type": "string",
- "format": "uri"
+ "format": "uri",
+ "enum": ["http://json-schema.org/draft-06/schema#"]
},
@@ -65,3 +66,4 @@
"type": "number",
- "exclusiveMinimum": 0
Expand Down Expand Up @@ -311,8 +303,7 @@ constexpr std::string_view json_draft_6_metaschema = R"json(
},
"$schema": {
"type": "string",
"format": "uri",
"enum": ["http://json-schema.org/draft-06/schema#"]
"format": "uri"
},
"$ref": {
"type": "string",
Expand Down Expand Up @@ -439,12 +430,6 @@ constexpr std::string_view json_draft_6_metaschema = R"json(
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "id": "http://json-schema.org/draft-07/schema#",
"title": "Core schema meta-schema",
@@ -46,3 +46,4 @@
"type": "string",
- "format": "uri"
+ "format": "uri",
+ "enum": ["http://json-schema.org/draft-07/schema#"]
},
@@ -61,3 +62,3 @@
},
- "default": true,
Expand Down Expand Up @@ -519,8 +504,7 @@ constexpr std::string_view json_draft_7_metaschema = R"json(
},
"$schema": {
"type": "string",
"format": "uri",
"enum": ["http://json-schema.org/draft-07/schema#"]
"format": "uri"
},
"$ref": {
"type": "string",
Expand Down Expand Up @@ -657,27 +641,37 @@ enum class json_schema_dialect {
draft7,
};

constexpr std::string_view to_uri(json_schema_dialect draft) {
constexpr std::string_view
to_uri(json_schema_dialect draft, bool strip = false) {
using enum json_schema_dialect;
switch (draft) {
case draft4:
return "http://json-schema.org/draft-04/schema#";
case draft5:
return "http://json-schema.org/draft-05/schema#";
case draft6:
return "http://json-schema.org/draft-06/schema#";
case draft7:
return "http://json-schema.org/draft-07/schema#";
auto dialect_str = [&]() -> std::string_view {
switch (draft) {
case draft4:
return "http://json-schema.org/draft-04/schema#";
case draft5:
return "http://json-schema.org/draft-05/schema#";
case draft6:
return "http://json-schema.org/draft-06/schema#";
case draft7:
return "http://json-schema.org/draft-07/schema#";
}
}();

if (strip) {
// strip final # from uri
dialect_str.remove_suffix(1);
}

return dialect_str;
}

constexpr std::optional<json_schema_dialect> from_uri(std::string_view uri) {
using enum json_schema_dialect;
return string_switch<std::optional<json_schema_dialect>>{uri}
.match(to_uri(draft4), draft4)
.match(to_uri(draft5), draft5)
.match(to_uri(draft6), draft6)
.match(to_uri(draft7), draft7)
.match_all(to_uri(draft4), to_uri(draft4, true), draft4)
.match_all(to_uri(draft5), to_uri(draft5, true), draft5)
.match_all(to_uri(draft6), to_uri(draft6, true), draft6)
.match_all(to_uri(draft7), to_uri(draft7, true), draft7)
.default_match(std::nullopt);
}

Expand Down
4 changes: 4 additions & 0 deletions src/v/pandaproxy/schema_registry/test/test_json_schema.cc
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ static constexpr auto valid_test_cases = std::to_array<std::string_view>({
"then": true
}
)json",
R"json({"$schema": "http://json-schema.org/draft-07/schema"})json",
R"json({"$schema": "http://json-schema.org/draft-06/schema"})json",
R"json({"$schema": "http://json-schema.org/draft-05/schema"})json",
R"json({"$schema": "http://json-schema.org/draft-04/schema"})json",
});
SEASTAR_THREAD_TEST_CASE(test_make_valid_json_schema) {
for (const auto& data : valid_test_cases) {
Expand Down

0 comments on commit d4c39e0

Please sign in to comment.