From d5a67c757a17baacad6a93ccf28ae96c29c5ae1e Mon Sep 17 00:00:00 2001 From: Pavel Bodiachevskii Date: Sat, 13 Apr 2024 14:47:17 +0400 Subject: [PATCH] feat(avro schema): initial commit https://github.com/asyncapi/jasyncapi/issues/185 --- .../v3/schema/avro/AvroArraySchema.java | 15 + .../v3/schema/avro/AvroEnumSchema.java | 60 ++++ .../v3/schema/avro/AvroFixedSchema.java | 37 +++ .../v3/schema/avro/AvroMapSchema.java | 15 + .../v3/schema/avro/AvroRecordFieldSchema.java | 157 ++++++++++ .../v3/schema/avro/AvroRecordSchema.java | 52 ++++ .../asyncapi/v3/schema/avro/AvroSchema.java | 33 ++ .../v3/schema/avro/AvroSchemaType.java | 75 +++++ .../json/v3/schema/avro/ApplicationEvent.avsc | 27 ++ .../json/v3/schema/avro/DocumentInfo.avsc | 18 ++ .../json/v3/schema/avro/MyResponse.avsc | 13 + .../json/v3/schema/avro/SchemaBuilder.avsc | 284 ++++++++++++++++++ .../avro/TestRecordWithLogicalTypes.avsc | 50 +++ .../avro/TestRecordWithMapsAndArrays.avsc | 23 ++ .../json/v3/schema/avro/TestUnionRecord.avsc | 23 ++ .../json/v3/schema/avro/foo.Bar.avsc | 21 ++ .../json/v3/schema/avro/full_record_v1.avsc | 29 ++ .../json/v3/schema/avro/full_record_v2.avsc | 29 ++ .../json/v3/schema/avro/logical-uuid.avsc | 30 ++ .../logical_types_with_multiple_fields.avsc | 30 ++ .../regression_error_field_in_record.avsc | 22 ++ .../v3/schema/avro/schema-location-read.json | 28 ++ .../v3/schema/avro/schema-location-write.json | 28 ++ .../json/v3/schema/avro/schema-location.json | 14 + .../json/v3/schema/avro/simple_record.avsc | 8 + .../schema/avro/union_and_fixed_fields.avsc | 18 ++ 26 files changed, 1139 insertions(+) create mode 100644 asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroArraySchema.java create mode 100644 asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroEnumSchema.java create mode 100644 asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroFixedSchema.java create mode 100644 asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroMapSchema.java create mode 100644 asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroRecordFieldSchema.java create mode 100644 asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroRecordSchema.java create mode 100644 asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroSchema.java create mode 100644 asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroSchemaType.java create mode 100644 asyncapi-core/src/test/resources/json/v3/schema/avro/ApplicationEvent.avsc create mode 100644 asyncapi-core/src/test/resources/json/v3/schema/avro/DocumentInfo.avsc create mode 100644 asyncapi-core/src/test/resources/json/v3/schema/avro/MyResponse.avsc create mode 100644 asyncapi-core/src/test/resources/json/v3/schema/avro/SchemaBuilder.avsc create mode 100644 asyncapi-core/src/test/resources/json/v3/schema/avro/TestRecordWithLogicalTypes.avsc create mode 100644 asyncapi-core/src/test/resources/json/v3/schema/avro/TestRecordWithMapsAndArrays.avsc create mode 100644 asyncapi-core/src/test/resources/json/v3/schema/avro/TestUnionRecord.avsc create mode 100644 asyncapi-core/src/test/resources/json/v3/schema/avro/foo.Bar.avsc create mode 100644 asyncapi-core/src/test/resources/json/v3/schema/avro/full_record_v1.avsc create mode 100644 asyncapi-core/src/test/resources/json/v3/schema/avro/full_record_v2.avsc create mode 100644 asyncapi-core/src/test/resources/json/v3/schema/avro/logical-uuid.avsc create mode 100644 asyncapi-core/src/test/resources/json/v3/schema/avro/logical_types_with_multiple_fields.avsc create mode 100644 asyncapi-core/src/test/resources/json/v3/schema/avro/regression_error_field_in_record.avsc create mode 100644 asyncapi-core/src/test/resources/json/v3/schema/avro/schema-location-read.json create mode 100644 asyncapi-core/src/test/resources/json/v3/schema/avro/schema-location-write.json create mode 100644 asyncapi-core/src/test/resources/json/v3/schema/avro/schema-location.json create mode 100644 asyncapi-core/src/test/resources/json/v3/schema/avro/simple_record.avsc create mode 100644 asyncapi-core/src/test/resources/json/v3/schema/avro/union_and_fixed_fields.avsc diff --git a/asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroArraySchema.java b/asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroArraySchema.java new file mode 100644 index 00000000..498c066b --- /dev/null +++ b/asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroArraySchema.java @@ -0,0 +1,15 @@ +package com.asyncapi.v3.schema.avro; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.jetbrains.annotations.NotNull; + +/** + * @see Arrays + */ +public class AvroArraySchema { + + @NotNull + @JsonProperty("items") + private String items; + +} diff --git a/asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroEnumSchema.java b/asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroEnumSchema.java new file mode 100644 index 00000000..abac9386 --- /dev/null +++ b/asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroEnumSchema.java @@ -0,0 +1,60 @@ +package com.asyncapi.v3.schema.avro; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.List; + +/** + * Avro Enum Schema + * + * @see Enums + */ +public class AvroEnumSchema { + + @NotNull + @JsonProperty("name") + private String name = ""; + + @Nullable + @JsonProperty("namespace") + private String namespace; + + /** + * A JSON string providing documentation to the user of this schema (optional). + */ + @Nullable + private String doc; + + /** + * A JSON array, listing symbols, as JSON strings (required). + *

+ * All symbols in an enum must be unique; duplicates are prohibited. + *

+ * Every symbol must match the regular expression [A-Za-z_][A-Za-z0-9_]* (the same requirement as for names). + */ + @NotNull + private List<@NotNull String> symbols = Collections.emptyList(); + + /** + * A JSON array of strings, providing alternate names for this record (optional). + */ + @Nullable + @JsonProperty("aliases") + private List<@NotNull String> aliases; + + /** + * A default value for this enumeration, used during resolution when the reader encounters a symbol + * from the writer that isn't defined in the reader's schema (optional). + *

+ * The value provided here must be a JSON string that's a member of the symbols array. + *

+ * See documentation on schema resolution for how this gets used. + */ + @Nullable + @JsonProperty("default") + private String defaultValue; + +} diff --git a/asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroFixedSchema.java b/asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroFixedSchema.java new file mode 100644 index 00000000..f329d988 --- /dev/null +++ b/asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroFixedSchema.java @@ -0,0 +1,37 @@ +package com.asyncapi.v3.schema.avro; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +/** + * @see Arrays + */ +public class AvroFixedSchema { + + @NotNull + @JsonProperty("name") + private String name; + + /** + * A JSON string that qualifies the name. + */ + @Nullable + @JsonProperty("namespace") + private String namespace; + + /** + * A JSON array of strings, providing alternate names for this record (optional). + */ + @Nullable + private List<@NotNull String> aliases; + + /** + * An integer, specifying the number of bytes per value (required). + */ + @NotNull + private Integer size; + +} diff --git a/asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroMapSchema.java b/asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroMapSchema.java new file mode 100644 index 00000000..519ad91f --- /dev/null +++ b/asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroMapSchema.java @@ -0,0 +1,15 @@ +package com.asyncapi.v3.schema.avro; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.jetbrains.annotations.NotNull; + +/** + * @see Maps + */ +public class AvroMapSchema { + + @NotNull + @JsonProperty("values") + private String values; + +} diff --git a/asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroRecordFieldSchema.java b/asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroRecordFieldSchema.java new file mode 100644 index 00000000..a53a54d4 --- /dev/null +++ b/asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroRecordFieldSchema.java @@ -0,0 +1,157 @@ +package com.asyncapi.v3.schema.avro; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.List; + +/** + * Avro Record Field. + * + * @author Pavel Bodiachevskii + * @version 3.0.0 + * @see Avro Record + */ +public class AvroRecordFieldSchema extends AvroSchema { + + public AvroRecordFieldSchema() { + super(AvroSchemaType.RECORD); + } + + /** + * Field type. + */ + @NotNull + @JsonProperty("type") + private Object type; + + /** + * A JSON string providing the name of the record (required). + */ + @NotNull + @JsonProperty("name") + private String name = ""; + + /** + * Specifies how this field impacts sort ordering of this record (optional). + */ + @Nullable("order") + private Order order = Order.ASCENDING; + + /** + * A JSON string providing documentation to the user of this schema (optional). + */ + @Nullable + @JsonProperty("doc") + private String doc; + + /** + * A JSON array of strings, providing alternate names for this record (optional). + */ + @Nullable + @JsonProperty("aliases") + private List<@NotNull String> aliases; + + /** + * A default value for this field, used when reading instances that lack this field (optional). + *

+ * Permitted values depend on the field's schema type, according to the table below. + *

+ * Default values for union fields correspond to the first schema in the union. + *

+ * Default values for bytes and fixed fields are JSON strings, where Unicode code points 0-255 are mapped to unsigned 8-bit byte values 0-255. + * + *

+     * 
+     *   
+     *     
+     *     
+     *     
+     *   
+     *   
+     *     
+     *     
+     *     
+     *   
+     *   
+     *     
+     *     
+     *     
+     *   
+     *   
+     *     
+     *     
+     *     
+     *   
+     *   
+     *     
+     *     
+     *     
+     *   
+     *   
+     *     
+     *     
+     *     
+     *   
+     *   
+     *     
+     *     
+     *     
+     *   
+     *   
+     *     
+     *     
+     *     
+     *   
+     *   
+     *     
+     *     
+     *     
+     *   
+     *   
+     *     
+     *     
+     *     
+     *   
+     *   
+     *     
+     *     
+     *     
+     *   
+     *   
+     *     
+     *     
+     *     
+     *   
+     * 
avro typejson typeexample
nullnullnull
booleanbooleantrue
int, longinteger1
float, doublenumber1.1
bytesstring"\u00FF"
stringstring"foo"
recordobject{"a": 1}
enumstring"FOO"
arrayarray[1]
mapobject{"a": 1}
fixedstring"\u00ff"
+ *
+ */ + @Nullable + @JsonProperty("default") + private Object defaultValue; + + /** + * Specifies how this field impacts sort ordering of this record. + *

+ * Valid values are "ascending" (the default), "descending", or "ignore". + *

+ * For more details on how this is used, see the the sort order section. + * + * @see Order + */ + public enum Order { + + @JsonProperty("ascending") + ASCENDING, + + @JsonProperty("descending") + DESCENDING, + + @JsonProperty("ignore") + IGNORE + + } + +} diff --git a/asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroRecordSchema.java b/asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroRecordSchema.java new file mode 100644 index 00000000..464ba693 --- /dev/null +++ b/asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroRecordSchema.java @@ -0,0 +1,52 @@ +package com.asyncapi.v3.schema.avro; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.List; + +/** + * Avro Record. + * + * @author Pavel Bodiachevskii + * @version 3.0.0 + * @see Avro Record + */ +public class AvroRecordSchema extends AvroSchema { + + public AvroRecordSchema() { + super(AvroSchemaType.RECORD); + } + + /** + * A JSON string providing the name of the record (required). + */ + @NotNull + private String name = ""; + + /** + * A JSON string that qualifies the name. + */ + @Nullable + private String namespace; + + /** + * A JSON string providing documentation to the user of this schema (optional). + */ + @Nullable + private String doc; + + /** + * A JSON array of strings, providing alternate names for this record (optional). + */ + @Nullable + private List<@NotNull String> aliases; + + /** + * A JSON array, listing fields (required). + */ + @NotNull + private List<@NotNull AvroRecordFieldSchema> fields = Collections.emptyList(); + +} diff --git a/asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroSchema.java b/asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroSchema.java new file mode 100644 index 00000000..9273f76d --- /dev/null +++ b/asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroSchema.java @@ -0,0 +1,33 @@ +package com.asyncapi.v3.schema.avro; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import lombok.Data; +import org.jetbrains.annotations.NotNull; + +/** + * Apache Avro Schema. + * + * @author Pavel Bodiachevskii + * @version 3.0.0 + * @see Avro Specification + */ +@Data +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.EXISTING_PROPERTY, + property = "type", + visible = true +) +@JsonSubTypes.Type(value = AvroSchema.class, names = { + "null", "boolean", "int", "long", "float", "double", "bytes", "string" +}) +public class AvroSchema { + + /** + * Avro Schema type. + */ + @NotNull + private AvroSchemaType type; + +} diff --git a/asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroSchemaType.java b/asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroSchemaType.java new file mode 100644 index 00000000..2dbe8ba1 --- /dev/null +++ b/asyncapi-core/src/main/java/com/asyncapi/v3/schema/avro/AvroSchemaType.java @@ -0,0 +1,75 @@ +package com.asyncapi.v3.schema.avro; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyDescription; +import org.jetbrains.annotations.NotNull; + +/** + * Apache Avro Schema types. + * + * @author Pavel Bodiachevskii + * @version 3.0.0 + * @see Avro Schema Primitive Types + * @see Avro Schema Complex Types + */ +public enum AvroSchemaType { + + /* + Primitive Types. + */ + + @JsonProperty("null") + @JsonPropertyDescription("no value") + NULL, + + @JsonProperty("boolean") + @JsonPropertyDescription("a binary value") + BOOLEAN, + + @JsonProperty("int") + @JsonPropertyDescription("32-bit signed integer") + INT, + + @JsonProperty("long") + @JsonPropertyDescription("64-bit signed integer") + LONG, + + @JsonProperty("float") + @JsonPropertyDescription("single precision (32-bit) IEEE 754 floating-point number") + FLOAT, + + @JsonProperty("double") + @JsonPropertyDescription("double precision (64-bit) IEEE 754 floating-point number") + DOUBLE, + + @JsonProperty("bytes") + @JsonPropertyDescription("sequence of 8-bit unsigned bytes") + BYTES, + + @JsonProperty("string") + @JsonPropertyDescription("unicode character sequence") + STRING, + + /* + Complex Types. + */ + + @JsonProperty("record") + RECORD, + + @JsonProperty("enum") + ENUM, + + @JsonProperty("array") + ARRAY, + + @JsonProperty("map") + MAP, + + @JsonProperty("unions") + UNIONS, + + @JsonProperty("fixed") + FIXED; + +} diff --git a/asyncapi-core/src/test/resources/json/v3/schema/avro/ApplicationEvent.avsc b/asyncapi-core/src/test/resources/json/v3/schema/avro/ApplicationEvent.avsc new file mode 100644 index 00000000..7f27d31b --- /dev/null +++ b/asyncapi-core/src/test/resources/json/v3/schema/avro/ApplicationEvent.avsc @@ -0,0 +1,27 @@ +{ + "namespace": "model", + "type": "record", + "doc": "", + "name": "ApplicationEvent", + "fields": [ + { + "name": "applicationId", + "type": "string", + "doc": "Application ID" + }, + { + "name": "status", + "type": "string", + "doc": "Application Status" + }, + { + "name": "documents", + "type": ["null", { + "type": "array", + "items": "model.DocumentInfo" + }], + "doc": "", + "default": null + } + ] +} \ No newline at end of file diff --git a/asyncapi-core/src/test/resources/json/v3/schema/avro/DocumentInfo.avsc b/asyncapi-core/src/test/resources/json/v3/schema/avro/DocumentInfo.avsc new file mode 100644 index 00000000..7f6383f5 --- /dev/null +++ b/asyncapi-core/src/test/resources/json/v3/schema/avro/DocumentInfo.avsc @@ -0,0 +1,18 @@ +{ + "namespace": "model", + "type": "record", + "doc": "", + "name": "DocumentInfo", + "fields": [ + { + "name": "documentId", + "type": "string", + "doc": "Document ID" + }, + { + "name": "filePath", + "type": "string", + "doc": "Document Path" + } + ] +} \ No newline at end of file diff --git a/asyncapi-core/src/test/resources/json/v3/schema/avro/MyResponse.avsc b/asyncapi-core/src/test/resources/json/v3/schema/avro/MyResponse.avsc new file mode 100644 index 00000000..c67a6eba --- /dev/null +++ b/asyncapi-core/src/test/resources/json/v3/schema/avro/MyResponse.avsc @@ -0,0 +1,13 @@ +{ + "namespace": "model", + "type": "record", + "doc": "", + "name": "MyResponse", + "fields": [ + { + "name": "isSuccessful", + "type": "boolean", + "doc": "Indicator for successful or unsuccessful call" + } + ] +} \ No newline at end of file diff --git a/asyncapi-core/src/test/resources/json/v3/schema/avro/SchemaBuilder.avsc b/asyncapi-core/src/test/resources/json/v3/schema/avro/SchemaBuilder.avsc new file mode 100644 index 00000000..af11831b --- /dev/null +++ b/asyncapi-core/src/test/resources/json/v3/schema/avro/SchemaBuilder.avsc @@ -0,0 +1,284 @@ +{ + "type" : "record", + "name" : "recordAll", + "fields" : [ { + "name" : "requiredBoolean", + "type" : "boolean" + }, { + "name" : "requiredBooleanWithDefault", + "type" : "boolean", + "default" : true + }, { + "name" : "optionalBoolean", + "type" : [ "null", "boolean" ], + "default" : null + }, { + "name" : "optionalBooleanWithDefault", + "type" : [ "boolean", "null" ], + "default" : true + }, { + "name" : "requiredInt", + "type" : "int" + }, { + "name" : "optionalInt", + "type" : [ "null", "int" ], + "default" : null + }, { + "name" : "optionalIntWithDefault", + "type" : [ "int", "null" ], + "default" : 1 + }, { + "name" : "requiredLong", + "type" : "long" + }, { + "name" : "optionalLong", + "type" : [ "null", "long" ], + "default" : null + }, { + "name" : "optionalLongWithDefault", + "type" : [ "long", "null" ], + "default" : 1 + }, { + "name" : "requiredFloat", + "type" : "float" + }, { + "name" : "optionalFloat", + "type" : [ "null", "float" ], + "default" : null + }, { + "name" : "optionalFloatWithDefault", + "type" : [ "float", "null" ], + "default" : 1.0 + }, { + "name" : "requiredDouble", + "type" : "double" + }, { + "name" : "optionalDouble", + "type" : [ "null", "double" ], + "default" : null + }, { + "name" : "optionalDoubleWithDefault", + "type" : [ "double", "null" ], + "default" : 1.0 + }, { + "name" : "requiredBytes", + "type" : "bytes" + }, { + "name" : "optionalBytes", + "type" : [ "null", "bytes" ], + "default" : null + }, { + "name" : "optionalBytesWithDefault", + "type" : [ "bytes", "null" ], + "default" : "A" + }, { + "name" : "requiredString", + "type" : "string" + }, { + "name" : "optionalString", + "type" : [ "null", "string" ], + "default" : null + }, { + "name" : "optionalStringWithDefault", + "type" : [ "string", "null" ], + "default" : "a" + }, { + "name" : "requiredRecord", + "type" : { + "type" : "record", + "name" : "nestedRequiredRecord", + "fields" : [ { + "name" : "nestedRequiredBoolean", + "type" : "boolean" + } ] + } + }, { + "name" : "optionalRecord", + "type" : [ "null", { + "type" : "record", + "name" : "nestedOptionalRecord", + "fields" : [ { + "name" : "nestedRequiredBoolean", + "type" : "boolean" + } ] + } ], + "default" : null + }, { + "name" : "optionalRecordWithDefault", + "type" : [ { + "type" : "record", + "name" : "nestedOptionalRecordWithDefault", + "fields" : [ { + "name" : "nestedRequiredBoolean", + "type" : "boolean" + } ] + }, "null" ], + "default" : { + "nestedRequiredBoolean" : true + } + }, { + "name" : "requiredEnum", + "type" : { + "type" : "enum", + "name" : "requiredEnum", + "symbols" : [ "a", "b" ] + } + }, { + "name" : "optionalEnum", + "type" : [ "null", { + "type" : "enum", + "name" : "optionalEnum", + "symbols" : [ "a", "b" ] + } ], + "default" : null + }, { + "name" : "optionalEnumWithDefault", + "type" : [ { + "type" : "enum", + "name" : "optionalEnumWithDefault", + "symbols" : [ "a", "b" ] + }, "null" ], + "default" : "b" + }, { + "name" : "requiredArray", + "type" : { + "type" : "array", + "items" : "string" + } + }, { + "name" : "optionalArray", + "type" : [ "null", { + "type" : "array", + "items" : "string" + } ], + "default" : null + }, { + "name" : "optionalArrayWithDefault", + "type" : [ { + "type" : "array", + "items" : "string" + }, "null" ], + "default" : [ "a" ] + }, { + "name" : "requiredMap", + "type" : { + "type" : "map", + "values" : "string" + } + }, { + "name" : "optionalMap", + "type" : [ "null", { + "type" : "map", + "values" : "string" + } ], + "default" : null + }, { + "name" : "optionalMapWithDefault", + "type" : [ { + "type" : "map", + "values" : "string" + }, "null" ], + "default" : { + "a" : "b" + } + }, { + "name" : "requiredFixed", + "type" : { + "type" : "fixed", + "name" : "requiredFixed", + "size" : 1 + } + }, { + "name" : "optionalFixed", + "type" : [ "null", { + "type" : "fixed", + "name" : "optionalFixed", + "size" : 1 + } ], + "default" : null + }, { + "name" : "optionalFixedWithDefault", + "type" : [ { + "type" : "fixed", + "name" : "optionalFixedWithDefault", + "size" : 1 + }, "null" ], + "default" : "A" + }, { + "name" : "unionType", + "type" : [ "long", "null" ] + }, { + "name" : "unionBooleanWithDefault", + "type" : [ "boolean", "int" ], + "default" : true + }, { + "name" : "unionIntWithDefault", + "type" : [ "int", "null" ], + "default" : 1 + }, { + "name" : "unionLongWithDefault", + "type" : [ "long", "int" ], + "default" : 1 + }, { + "name" : "unionFloatWithDefault", + "type" : [ "float", "int" ], + "default" : 1.0 + }, { + "name" : "unionDoubleWithDefault", + "type" : [ "double", "int" ], + "default" : 1.0 + }, { + "name" : "unionBytesWithDefault", + "type" : [ "bytes", "int" ], + "default" : "A" + }, { + "name" : "unionStringWithDefault", + "type" : [ "string", "int" ], + "default" : "a" + }, { + "name" : "unionRecordWithDefault", + "type" : [ { + "type" : "record", + "name" : "nestedUnionRecordWithDefault", + "fields" : [ { + "name" : "nestedRequiredBoolean", + "type" : "boolean" + } ] + }, "int" ], + "default" : { + "nestedRequiredBoolean" : true + } + }, { + "name" : "unionEnumWithDefault", + "type" : [ { + "type" : "enum", + "name" : "nestedUnionEnumWithDefault", + "symbols" : [ "a", "b" ] + }, "int" ], + "default" : "b" + }, { + "name" : "unionArrayWithDefault", + "type" : [ { + "type" : "array", + "items" : "string" + }, "int" ], + "default" : [ "a" ] + }, { + "name" : "unionMapWithDefault", + "type" : [ { + "type" : "map", + "values" : "string" + }, "int" ], + "default" : { + "a" : "b" + } + }, { + "name" : "unionFixedWithDefault", + "type" : [ { + "type" : "fixed", + "name" : "nestedUnionFixedWithDefault", + "size" : 1 + }, "int" ], + "default" : "A" + } ] +} \ No newline at end of file diff --git a/asyncapi-core/src/test/resources/json/v3/schema/avro/TestRecordWithLogicalTypes.avsc b/asyncapi-core/src/test/resources/json/v3/schema/avro/TestRecordWithLogicalTypes.avsc new file mode 100644 index 00000000..065b448d --- /dev/null +++ b/asyncapi-core/src/test/resources/json/v3/schema/avro/TestRecordWithLogicalTypes.avsc @@ -0,0 +1,50 @@ +{ + "type" : "record", + "name" : "TestRecordWithLogicalTypes", + "doc" : "Schema for TestRecordWithLogicalTypes and TestRecordWithoutLogicalTypes, see TestSpecificLogicalTypes", + "namespace" : "org.apache.avro.specific", + "fields" : [ { + "name" : "b", + "type" : "boolean" + }, { + "name" : "i32", + "type" : "int" + }, { + "name" : "i64", + "type" : "long" + }, { + "name" : "f32", + "type" : "float" + }, { + "name" : "f64", + "type" : "double" + }, { + "name" : "s", + "type" : [ "null", "string" ], + "default" : null + }, { + "name" : "d", + "type" : { + "type" : "int", + "logicalType" : "date" + } + }, { + "name" : "t", + "type" : { + "type" : "int", + "logicalType" : "time-millis" + } + }, { + "name" : "ts", + "type" : { + "type" : "long", + "logicalType" : "timestamp-millis" + } + }, { + "name" : "bd", + "type" : { + "type" : "bytes", + "logicalType" : "big-decimal" + } + } ] +} diff --git a/asyncapi-core/src/test/resources/json/v3/schema/avro/TestRecordWithMapsAndArrays.avsc b/asyncapi-core/src/test/resources/json/v3/schema/avro/TestRecordWithMapsAndArrays.avsc new file mode 100644 index 00000000..24487c98 --- /dev/null +++ b/asyncapi-core/src/test/resources/json/v3/schema/avro/TestRecordWithMapsAndArrays.avsc @@ -0,0 +1,23 @@ +{ + "type": "record", + "name": "TestRecordWithMapsAndArrays", + "namespace": "org.apache.avro.specific", + "fields": [ + { + "name": "arr", + "type": { + "type": "array", + "items": "string", + "default": [] + } + }, + { + "name": "map", + "type": { + "type": "map", + "values": "long", + "default": {} + } + } + ] +} \ No newline at end of file diff --git a/asyncapi-core/src/test/resources/json/v3/schema/avro/TestUnionRecord.avsc b/asyncapi-core/src/test/resources/json/v3/schema/avro/TestUnionRecord.avsc new file mode 100644 index 00000000..a6b0bb39 --- /dev/null +++ b/asyncapi-core/src/test/resources/json/v3/schema/avro/TestUnionRecord.avsc @@ -0,0 +1,23 @@ +[ + "null", + { + "namespace": "org.apache.avro.specific", + "type": "record", + "name": "TestUnionRecord", + "fields": [ + { + "name": "amount", + "type": [ + "null", + { + "type": "bytes", + "logicalType": "decimal", + "precision": 31, + "scale": 8 + } + ], + "default": null + } + ] + } +] \ No newline at end of file diff --git a/asyncapi-core/src/test/resources/json/v3/schema/avro/foo.Bar.avsc b/asyncapi-core/src/test/resources/json/v3/schema/avro/foo.Bar.avsc new file mode 100644 index 00000000..c0d7396e --- /dev/null +++ b/asyncapi-core/src/test/resources/json/v3/schema/avro/foo.Bar.avsc @@ -0,0 +1,21 @@ +{ + "fields" : [ + { + "name" : "title", + "type" : "string" + }, + { + "name" : "created_at", + "type" : [ + "null", + { + "logicalType" : "timestamp-millis", + "type" : "long" + } + ] + } + ], + "name" : "Bar", + "namespace" : "foo", + "type" : "record" +} \ No newline at end of file diff --git a/asyncapi-core/src/test/resources/json/v3/schema/avro/full_record_v1.avsc b/asyncapi-core/src/test/resources/json/v3/schema/avro/full_record_v1.avsc new file mode 100644 index 00000000..66a80597 --- /dev/null +++ b/asyncapi-core/src/test/resources/json/v3/schema/avro/full_record_v1.avsc @@ -0,0 +1,29 @@ +{ + "type" : "record", + "name" : "FullRecordV1", + "doc" : "Test schema changes: this is the 'old' schema the SpecificRecord expects to see", + "namespace" : "org.apache.avro.specific.test", + "fields" : [ { + "name" : "b", + "type" : "boolean" + }, { + "name" : "i32", + "type" : "int" + }, { + "name" : "i64", + "type" : "long" + }, { + "name" : "f32", + "type" : "float" + }, { + "name" : "f64", + "type" : "double" + }, { + "name" : "s", + "type" : [ "null", "string" ], + "default" : null + }, { + "name" : "h", + "type" : [ "null", "string" ] + } ] +} diff --git a/asyncapi-core/src/test/resources/json/v3/schema/avro/full_record_v2.avsc b/asyncapi-core/src/test/resources/json/v3/schema/avro/full_record_v2.avsc new file mode 100644 index 00000000..fd809e6c --- /dev/null +++ b/asyncapi-core/src/test/resources/json/v3/schema/avro/full_record_v2.avsc @@ -0,0 +1,29 @@ +{ + "type" : "record", + "name" : "FullRecordV2", + "doc" : "Test schema changes: this is the 'new' schema actually used to write data", + "namespace" : "org.apache.avro.specific.test", + "fields" : [ { + "name" : "b", + "type" : "boolean" + }, { + "name" : "i64", + "type" : "int" + }, { + "name" : "i32", + "type" : "int" + }, { + "name" : "f64", + "type" : "long" + }, { + "name" : "f32", + "type" : [ "float", "null" ] + }, { + "name" : "newfield", + "type" : "string" + }, { + "name" : "h", + "type" : "bytes" + }, + { "name" : "myMap", "type" : { "type" : "map", "values" : "string" } }] +} diff --git a/asyncapi-core/src/test/resources/json/v3/schema/avro/logical-uuid.avsc b/asyncapi-core/src/test/resources/json/v3/schema/avro/logical-uuid.avsc new file mode 100644 index 00000000..31881474 --- /dev/null +++ b/asyncapi-core/src/test/resources/json/v3/schema/avro/logical-uuid.avsc @@ -0,0 +1,30 @@ +{ + "namespace": "schema.common", + "type": "record", + "name": "Action", + "fields": [ + { + "name": "name", + "type": "string" + }, + { + "name": "guid", + "type": { "type": "string", "logicalType": "uuid" } + }, + { + "name": "time", + "type": { + "type": "long", + "logicalType": "timestamp-millis" + } + }, + { + "name": "requestId", + "type": [ + "null", + "string" + ], + "default": null + } + ] +} \ No newline at end of file diff --git a/asyncapi-core/src/test/resources/json/v3/schema/avro/logical_types_with_multiple_fields.avsc b/asyncapi-core/src/test/resources/json/v3/schema/avro/logical_types_with_multiple_fields.avsc new file mode 100644 index 00000000..a373524e --- /dev/null +++ b/asyncapi-core/src/test/resources/json/v3/schema/avro/logical_types_with_multiple_fields.avsc @@ -0,0 +1,30 @@ +{ + "namespace": "schema.common", + "type": "record", + "name": "Action", + "fields": [ + { + "name": "name", + "type": "string" + }, + { + "name": "uuid", + "type": "string" + }, + { + "name": "time", + "type": { + "type": "long", + "logicalType": "timestamp-millis" + } + }, + { + "name": "requestId", + "type": [ + "null", + "string" + ], + "default": null + } + ] +} \ No newline at end of file diff --git a/asyncapi-core/src/test/resources/json/v3/schema/avro/regression_error_field_in_record.avsc b/asyncapi-core/src/test/resources/json/v3/schema/avro/regression_error_field_in_record.avsc new file mode 100644 index 00000000..c01875bf --- /dev/null +++ b/asyncapi-core/src/test/resources/json/v3/schema/avro/regression_error_field_in_record.avsc @@ -0,0 +1,22 @@ +{ + "type" : "record", + "name" : "RecordWithErrorField", + "doc" : "With custom coders in Avro 1.9, previously successful records with error fields now fail to compile.", + "namespace" : "org.apache.avro.specific.test", + "fields" : [ { + "name" : "s", + "type" : [ "null", "string" ], + "default" : null + }, { + "name": "e", + "type": [ "null", { + "type" : "error", + "name" : "TestError", + "fields" : [ { + "name" : "message", + "type" : "string" + } ] + } ], + "default": null + } ] +} \ No newline at end of file diff --git a/asyncapi-core/src/test/resources/json/v3/schema/avro/schema-location-read.json b/asyncapi-core/src/test/resources/json/v3/schema/avro/schema-location-read.json new file mode 100644 index 00000000..e94c027f --- /dev/null +++ b/asyncapi-core/src/test/resources/json/v3/schema/avro/schema-location-read.json @@ -0,0 +1,28 @@ +{ + "type": "record", + "name": "table", + "fields": [{ + "name": "location", + "type": ["null", { + "type": "map", + "values": ["null", { + "type": "record", + "name": "r7", + "fields": [{ + "name": "lat", + "type": "float", + "field-id": 1 + }, { + "name": "long_r2", + "type": ["null", "float"], + "default": null, + "field-id": 2 + }] + }], + "key-id": 6, + "value-id": 7 + }], + "default": null, + "field-id": 5 + }] +} \ No newline at end of file diff --git a/asyncapi-core/src/test/resources/json/v3/schema/avro/schema-location-write.json b/asyncapi-core/src/test/resources/json/v3/schema/avro/schema-location-write.json new file mode 100644 index 00000000..3b811fb9 --- /dev/null +++ b/asyncapi-core/src/test/resources/json/v3/schema/avro/schema-location-write.json @@ -0,0 +1,28 @@ +{ + "type": "record", + "name": "table", + "fields": [{ + "name": "location", + "type": ["null", { + "type": "map", + "values": ["null", { + "type": "record", + "name": "r7", + "fields": [{ + "name": "lat", + "type": "float", + "field-id": 1 + }, { + "name": "long", + "type": ["null", "float"], + "default": null, + "field-id": 2 + }] + }], + "key-id": 6, + "value-id": 7 + }], + "default": null, + "field-id": 5 + }] +} \ No newline at end of file diff --git a/asyncapi-core/src/test/resources/json/v3/schema/avro/schema-location.json b/asyncapi-core/src/test/resources/json/v3/schema/avro/schema-location.json new file mode 100644 index 00000000..e791630a --- /dev/null +++ b/asyncapi-core/src/test/resources/json/v3/schema/avro/schema-location.json @@ -0,0 +1,14 @@ +{ + "type": "record", + "name": "r7", + "fields": [{ + "name": "lat", + "type": "float", + "field-id": 1 + }, { + "name": "long", + "type": ["null", "float"], + "default": null, + "field-id": 2 + }] +} \ No newline at end of file diff --git a/asyncapi-core/src/test/resources/json/v3/schema/avro/simple_record.avsc b/asyncapi-core/src/test/resources/json/v3/schema/avro/simple_record.avsc new file mode 100644 index 00000000..39e35347 --- /dev/null +++ b/asyncapi-core/src/test/resources/json/v3/schema/avro/simple_record.avsc @@ -0,0 +1,8 @@ +{ + "type": "record", + "name": "SimpleRecord", + "fields" : [ + {"name": "value", "type": "int"}, + {"name": "nullableValue", "type": ["null","int"], "doc" : "doc"} + ] +} \ No newline at end of file diff --git a/asyncapi-core/src/test/resources/json/v3/schema/avro/union_and_fixed_fields.avsc b/asyncapi-core/src/test/resources/json/v3/schema/avro/union_and_fixed_fields.avsc new file mode 100644 index 00000000..01884575 --- /dev/null +++ b/asyncapi-core/src/test/resources/json/v3/schema/avro/union_and_fixed_fields.avsc @@ -0,0 +1,18 @@ +{ + "type" : "record", + "name" : "UnionAndFixedFields", + "doc" : "Schema for UnionAndFixedFields designed to trigger fixed compiler warnings in generated code", + "namespace" : "org.apache.avro.specific", + "fields" : [ { + "name" : "u", + "type" : [ "boolean", "int", "long", "float", "string" ] + }, + { + "name" : "l", + "type" : [ "string", { "type": "long", "logicalType": "timestamp-millis" } ] + }, + { + "name" : "f", + "type" : {"type": "fixed", "size": 16, "name": "md5"} + } ] +} \ No newline at end of file