From 3c05b603139bbb0fada2bdd2737db79ddea6a65a Mon Sep 17 00:00:00 2001 From: German Osin Date: Wed, 15 Sep 2021 14:02:06 +0300 Subject: [PATCH] ISSUE-876 Fixed array types to oneof for js support (#880) --- .../jsonschema/AvroJsonSchemaConverter.java | 15 +++++++++++- .../ui/util/jsonschema/ObjectFieldSchema.java | 22 +++--------------- .../AvroJsonSchemaConverterTest.java | 23 ++++++++++--------- 3 files changed, 29 insertions(+), 31 deletions(-) diff --git a/kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/jsonschema/AvroJsonSchemaConverter.java b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/jsonschema/AvroJsonSchemaConverter.java index 707b11dbf6..e6cff30893 100644 --- a/kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/jsonschema/AvroJsonSchemaConverter.java +++ b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/jsonschema/AvroJsonSchemaConverter.java @@ -67,6 +67,10 @@ public class AvroJsonSchemaConverter implements JsonSchemaConverter { } private FieldSchema createUnionSchema(Schema schema, Map definitions) { + + final boolean nullable = schema.getTypes().stream() + .anyMatch(t -> t.getType().equals(Schema.Type.NULL)); + final Map fields = schema.getTypes().stream() .filter(t -> !t.getType().equals(Schema.Type.NULL)) .map(f -> Tuples.of( @@ -80,7 +84,16 @@ public class AvroJsonSchemaConverter implements JsonSchemaConverter { Tuple2::getT2 )); - return new ObjectFieldSchema(fields, Collections.emptyList(), true); + if (nullable) { + return new OneOfFieldSchema( + List.of( + new SimpleFieldSchema(new SimpleJsonType(JsonType.Type.NULL)), + new ObjectFieldSchema(fields, Collections.emptyList()) + ) + ); + } else { + return new ObjectFieldSchema(fields, Collections.emptyList()); + } } private FieldSchema createObjectSchema(String name, Schema schema, diff --git a/kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/jsonschema/ObjectFieldSchema.java b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/jsonschema/ObjectFieldSchema.java index 3fe1f26fcd..296c5e0715 100644 --- a/kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/jsonschema/ObjectFieldSchema.java +++ b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/jsonschema/ObjectFieldSchema.java @@ -15,18 +15,11 @@ import reactor.util.function.Tuples; public class ObjectFieldSchema implements FieldSchema { private final Map properties; private final List required; - private final boolean nullable; public ObjectFieldSchema(Map properties, List required) { - this(properties, required, false); - } - - public ObjectFieldSchema(Map properties, - List required, boolean nullable) { this.properties = properties; this.required = required; - this.nullable = nullable; } public Map getProperties() { @@ -46,18 +39,9 @@ public class ObjectFieldSchema implements FieldSchema { Tuple2::getT2 )); final ObjectNode objectNode = mapper.createObjectNode(); - if (this.nullable) { - objectNode.set( - "type", - mapper.createArrayNode() - .add(JsonType.Type.OBJECT.getName()) - .add(JsonType.Type.NULL.getName()) - ); - } else { - objectNode.setAll( - new SimpleJsonType(JsonType.Type.OBJECT).toJsonNode(mapper) - ); - } + objectNode.setAll( + new SimpleJsonType(JsonType.Type.OBJECT).toJsonNode(mapper) + ); objectNode.set("properties", mapper.valueToTree(nodes)); if (!required.isEmpty()) { objectNode.set("required", mapper.valueToTree(required)); diff --git a/kafka-ui-api/src/test/java/com/provectus/kafka/ui/util/jsonschema/AvroJsonSchemaConverterTest.java b/kafka-ui-api/src/test/java/com/provectus/kafka/ui/util/jsonschema/AvroJsonSchemaConverterTest.java index 58daa739cf..edcc9c559b 100644 --- a/kafka-ui-api/src/test/java/com/provectus/kafka/ui/util/jsonschema/AvroJsonSchemaConverterTest.java +++ b/kafka-ui-api/src/test/java/com/provectus/kafka/ui/util/jsonschema/AvroJsonSchemaConverterTest.java @@ -87,13 +87,14 @@ public class AvroJsonSchemaConverterTest { + "{\"$ref\":\"#/definitions/RecordInnerMessage\"}}," + "\"required\":[\"record\"],\"definitions\":" + "{\"RecordInnerMessage\":{\"type\":\"object\",\"" - + "properties\":{\"long_text\":{\"type\":[\"object\", \"null\"]," - + "\"properties\":{\"string\":{\"type\":\"string\"}}}," - + "\"array\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}}," - + "\"id\":{\"type\":\"integer\"},\"text\":{\"type\":\"string\"}," - + "\"map\":{\"type\":\"object\",\"additionalProperties\":" - + "{\"type\":\"integer\"}},\"order\":{\"type\":\"string\"," - + "\"enum\":[\"SPADES\",\"HEARTS\",\"DIAMONDS\",\"CLUBS\"]}}," + + "properties\":{\"long_text\":{\"oneOf\":[{\"type\":\"null\"}," + + "{\"type\":\"object\",\"properties\":{\"string\":" + + "{\"type\":\"string\"}}}]},\"array\":{\"type\":\"array\",\"items\":" + + "{\"type\":\"string\"}},\"id\":{\"type\":\"integer\"},\"text\":" + + "{\"type\":\"string\"},\"map\":{\"type\":\"object\"," + + "\"additionalProperties\":{\"type\":\"integer\"}}," + + "\"order\":{\"enum\":[\"SPADES\",\"HEARTS\",\"DIAMONDS\",\"CLUBS\"]," + + "\"type\":\"string\"}}," + "\"required\":[\"id\",\"text\",\"order\",\"array\",\"map\"]}}}"; final JsonSchema convertRecord = converter.convert(basePath, recordSchema); @@ -151,10 +152,10 @@ public class AvroJsonSchemaConverterTest { "{\"$id\":\"http://example.com/Message\"," + "\"$schema\":\"https://json-schema.org/draft/2020-12/schema\"," + "\"type\":\"object\",\"properties\":{\"text\":" - + "{\"type\":[\"object\", \"null\"],\"properties\":{\"string\":" - + "{\"type\":\"string\"}}},\"value\":{\"type\":[\"object\", \"null\"]," - + "\"properties\":{\"string\":{\"type\":\"string\"}," - + "\"long\":{\"type\":\"integer\"}}}}}"; + + "{\"oneOf\":[{\"type\":\"null\"},{\"type\":\"object\"," + + "\"properties\":{\"string\":{\"type\":\"string\"}}}]},\"value\":" + + "{\"oneOf\":[{\"type\":\"null\"},{\"type\":\"object\"," + + "\"properties\":{\"string\":{\"type\":\"string\"},\"long\":{\"type\":\"integer\"}}}]}}}"; final JsonSchema convert = converter.convert(basePath, recordSchema); Assertions.assertEquals(