/// <summary> /// Creates a new field for the record /// </summary> /// <param name="jfield">JSON object for the field</param> /// <param name="pos">position number of the field</param> /// <param name="names">list of named schemas already read</param> /// <param name="encspace">enclosing namespace of the records schema</param> /// <returns>new Field object</returns> private static Field createField(JToken jfield, int pos, SchemaNames names, string encspace) { var name = JsonHelper.GetRequiredString(jfield, "name"); var doc = JsonHelper.GetOptionalString(jfield, "doc"); var jorder = JsonHelper.GetOptionalString(jfield, "order"); Field.SortOrder sortorder = Field.SortOrder.ignore; if (null != jorder) { sortorder = (Field.SortOrder)Enum.Parse(typeof(Field.SortOrder), jorder); } var aliases = Field.GetAliases(jfield); var props = Schema.GetProperties(jfield); var defaultValue = jfield["default"]; JToken jtype = jfield["type"]; if (null == jtype) { throw new SchemaParseException($"'type' was not found for field: name at '{jfield.Path}'"); } var schema = Schema.ParseJson(jtype, names, encspace); return(new Field(schema, name, aliases, pos, doc, defaultValue, sortorder, props)); }
/// <summary> /// Parses the messages section of a protocol definition /// </summary> /// <param name="jmessage">messages JSON object</param> /// <param name="names">list of parsed names</param> /// <param name="encspace">enclosing namespace</param> /// <returns></returns> internal static Message Parse(JProperty jmessage, SchemaNames names, string encspace) { string name = jmessage.Name; string doc = JsonHelper.GetOptionalString(jmessage.Value, "doc"); bool? oneway = JsonHelper.GetOptionalBoolean(jmessage.Value, "one-way"); PropertyMap props = Schema.GetProperties(jmessage.Value); RecordSchema schema = RecordSchema.NewInstance(Schema.Type.Record, jmessage.Value as JObject, props, names, encspace); JToken jresponse = jmessage.Value["response"]; var response = Schema.ParseJson(jresponse, names, encspace); JToken jerrors = jmessage.Value["errors"]; UnionSchema uerrorSchema = null; if (null != jerrors) { Schema errorSchema = Schema.ParseJson(jerrors, names, encspace); if (!(errorSchema is UnionSchema)) { throw new AvroException(""); } uerrorSchema = errorSchema as UnionSchema; } return(new Message(name, doc, schema, response, uerrorSchema, oneway)); }
/// <summary> /// Static class to return new instance of schema object /// </summary> /// <param name="jtok">JSON object</param> /// <param name="names">list of named schemas already read</param> /// <param name="encspace">enclosing namespace of the schema</param> /// <returns>new Schema object</returns> internal static Schema ParseJson(JToken jtok, SchemaNames names, string encspace) { if (null == jtok) { throw new ArgumentNullException("j", "j cannot be null."); } if (jtok.Type == JTokenType.String) // primitive schema with no 'type' property or primitive or named type of a record field { string value = (string)jtok; PrimitiveSchema ps = PrimitiveSchema.NewInstance(value); if (null != ps) { return(ps); } NamedSchema schema = null; if (names.TryGetValue(value, null, encspace, out schema)) { return(schema); } throw new SchemaParseException($"Undefined name: {value} at '{jtok.Path}'"); } if (jtok is JArray) // union schema with no 'type' property or union type for a record field { return(UnionSchema.NewInstance(jtok as JArray, null, names, encspace)); } if (jtok is JObject) // JSON object with open/close parenthesis, it must have a 'type' property { JObject jo = jtok as JObject; JToken jtype = jo["type"]; if (null == jtype) { throw new SchemaParseException($"Property type is required at '{jtok.Path}'"); } var props = Schema.GetProperties(jtok); if (jtype.Type == JTokenType.String) { string type = (string)jtype; if (type.Equals("array", StringComparison.Ordinal)) { return(ArraySchema.NewInstance(jtok, props, names, encspace)); } if (type.Equals("map", StringComparison.Ordinal)) { return(MapSchema.NewInstance(jtok, props, names, encspace)); } if (null != jo["logicalType"]) // logical type based on a primitive { return(LogicalSchema.NewInstance(jtok, props, names, encspace)); } Schema schema = PrimitiveSchema.NewInstance((string)type, props); if (null != schema) { return(schema); } return(NamedSchema.NewInstance(jo, props, names, encspace)); } else if (jtype.Type == JTokenType.Array) { return(UnionSchema.NewInstance(jtype as JArray, props, names, encspace)); } else if (jtype.Type == JTokenType.Object && null != jo["logicalType"]) // logical type based on a complex type { return(LogicalSchema.NewInstance(jtok, props, names, encspace)); } } throw new AvroTypeException($"Invalid JSON for schema: {jtok} at '{jtok.Path}'"); }