You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by rs...@apache.org on 2021/10/06 10:47:59 UTC
[avro] branch master updated: AVRO-2633: C# include schema doc
(#1070)
This is an automated email from the ASF dual-hosted git repository.
rskraba pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/avro.git
The following commit(s) were added to refs/heads/master by this push:
new a86dde2 AVRO-2633: C# include schema doc (#1070)
a86dde2 is described below
commit a86dde293841a5f7856c11c799ca6561e6745419
Author: tom-j-irvine <66...@users.noreply.github.com>
AuthorDate: Wed Oct 6 04:47:52 2021 -0600
AVRO-2633: C# include schema doc (#1070)
* AVRO-2633 - csharp include schema doc
* AVRO-2633 - update tests for doc attribute
updated TestRecordDoc to test both the parsing and reserializtion - thanks @BarryDahlberg
updated the doc serialization logic to preserve empty strings (and only eliminate nulls)
Co-authored-by: Tom Irvine <to...@simplement.us>
Co-authored-by: RyanSkraba <ry...@skraba.com>
---
lang/csharp/src/apache/main/Schema/JsonHelper.cs | 15 ++++++++++++++-
lang/csharp/src/apache/main/Schema/NamedSchema.cs | 10 ++++++----
lang/csharp/src/apache/main/Schema/Schema.cs | 2 +-
lang/csharp/src/apache/main/Schema/SchemaName.cs | 17 +++++++++++++----
lang/csharp/src/apache/test/Schema/SchemaTests.cs | 15 ++++++++++++---
5 files changed, 46 insertions(+), 13 deletions(-)
diff --git a/lang/csharp/src/apache/main/Schema/JsonHelper.cs b/lang/csharp/src/apache/main/Schema/JsonHelper.cs
index 87887f5..1ca51cb 100644
--- a/lang/csharp/src/apache/main/Schema/JsonHelper.cs
+++ b/lang/csharp/src/apache/main/Schema/JsonHelper.cs
@@ -98,7 +98,7 @@ namespace Avro
}
/// <summary>
- /// Writes JSON property name and value if value is not null
+ /// Writes JSON property name and value if value is not null or empty
/// </summary>
/// <param name="writer">JSON writer</param>
/// <param name="key">property name</param>
@@ -110,5 +110,18 @@ namespace Avro
writer.WriteValue(value);
}
+
+ /// <summary>
+ /// Write JSON property name and value, if value is not null
+ /// </summary>
+ /// <param name="writer">JSON writer</param>
+ /// <param name="key">property name</param>
+ /// <param name="value">property value</param>
+ internal static void writeIfNotNull(JsonTextWriter writer, string key, string value)
+ {
+ if (value == null) return;
+ writer.WritePropertyName(key);
+ writer.WriteValue(value);
+ }
}
}
diff --git a/lang/csharp/src/apache/main/Schema/NamedSchema.cs b/lang/csharp/src/apache/main/Schema/NamedSchema.cs
index ca54440..fe9d214 100644
--- a/lang/csharp/src/apache/main/Schema/NamedSchema.cs
+++ b/lang/csharp/src/apache/main/Schema/NamedSchema.cs
@@ -78,6 +78,7 @@ namespace Avro
internal static NamedSchema NewInstance(JObject jo, PropertyMap props, SchemaNames names, string encspace)
{
string type = JsonHelper.GetRequiredString(jo, "type");
+ string doc = JsonHelper.GetOptionalString(jo, "doc");
switch (type)
{
case "fixed":
@@ -90,7 +91,7 @@ namespace Avro
return RecordSchema.NewInstance(Type.Error, jo, props, names, encspace);
default:
NamedSchema result;
- if (names.TryGetValue(type, null, encspace, out result))
+ if (names.TryGetValue(type, null, encspace, doc, out result))
return result;
return null;
}
@@ -128,7 +129,8 @@ namespace Avro
{
String n = JsonHelper.GetOptionalString(jtok, "name"); // Changed this to optional string for anonymous records in messages
String ns = JsonHelper.GetOptionalString(jtok, "namespace");
- return new SchemaName(n, ns, encspace);
+ String d = JsonHelper.GetOptionalString(jtok, "doc");
+ return new SchemaName(n, ns, encspace, d);
}
/// <summary>
@@ -136,7 +138,7 @@ namespace Avro
/// </summary>
/// <param name="jtok">JSON object to read</param>
/// <param name="space">namespace of the name this alias is for</param>
- /// <param name="encspace">enclosing namespace of the name this alias is for</param>
+ /// <param name="encspace">enclosing namespace of the name this alias is for</param>
/// <returns>List of SchemaName that represents the list of alias. If no 'aliases' specified, then it returns null.</returns>
protected static IList<SchemaName> GetAliases(JToken jtok, string space, string encspace)
{
@@ -153,7 +155,7 @@ namespace Avro
if (jalias.Type != JTokenType.String)
throw new SchemaParseException($"Aliases must be of format JSON array of strings at '{jtok.Path}'");
- aliases.Add(new SchemaName((string)jalias, space, encspace));
+ aliases.Add(new SchemaName((string)jalias, space, encspace, null));
}
return aliases;
}
diff --git a/lang/csharp/src/apache/main/Schema/Schema.cs b/lang/csharp/src/apache/main/Schema/Schema.cs
index 94b96db..d14b016 100644
--- a/lang/csharp/src/apache/main/Schema/Schema.cs
+++ b/lang/csharp/src/apache/main/Schema/Schema.cs
@@ -166,7 +166,7 @@ namespace Avro
if (null != ps) return ps;
NamedSchema schema = null;
- if (names.TryGetValue(value, null, encspace, out schema)) return schema;
+ if (names.TryGetValue(value, null, encspace, null, out schema)) return schema;
throw new SchemaParseException($"Undefined name: {value} at '{jtok.Path}'");
}
diff --git a/lang/csharp/src/apache/main/Schema/SchemaName.cs b/lang/csharp/src/apache/main/Schema/SchemaName.cs
index ced24ee..20cc1b4 100644
--- a/lang/csharp/src/apache/main/Schema/SchemaName.cs
+++ b/lang/csharp/src/apache/main/Schema/SchemaName.cs
@@ -21,7 +21,7 @@ using System.Collections.Generic;
namespace Avro
{
/// <summary>
- /// Class to store schema name, namespace and enclosing namespace
+ /// Class to store schema name, namespace, enclosing namespace and documentation
/// </summary>
public class SchemaName
{
@@ -44,6 +44,11 @@ namespace Avro
public String EncSpace { get; private set; }
/// <summary>
+ /// Documentation for the schema
+ /// </summary>
+ public String Documentation { get; private set; }
+
+ /// <summary>
/// Namespace.Name of the schema
/// </summary>
public String Fullname { get { return fullName; } }
@@ -59,7 +64,8 @@ namespace Avro
/// <param name="name">name of the schema</param>
/// <param name="space">namespace of the schema</param>
/// <param name="encspace">enclosing namespace of the schema</param>
- public SchemaName(String name, String space, String encspace)
+ /// <param name="documentation">documentation o fthe schema</param>
+ public SchemaName(String name, String space, String encspace, String documentation)
{
if (name == null)
{ // anonymous
@@ -81,6 +87,7 @@ namespace Avro
this.Name = parts[parts.Length - 1];
this.EncSpace = encspace;
}
+ this.Documentation = documentation;
fullName = string.IsNullOrEmpty(Namespace) ? this.Name : Namespace + "." + this.Name;
}
@@ -104,6 +111,7 @@ namespace Avro
if (null != this.Name) // write only if not anonymous
{
JsonHelper.writeIfNotNullOrEmpty(writer, "name", this.Name);
+ JsonHelper.writeIfNotNull(writer, "doc", this.Documentation);
if (!String.IsNullOrEmpty(this.Space))
JsonHelper.writeIfNotNullOrEmpty(writer, "namespace", this.Space);
else if (!String.IsNullOrEmpty(this.EncSpace)) // need to put enclosing name space for code generated classes
@@ -210,11 +218,12 @@ namespace Avro
/// <param name="name">name of the schema</param>
/// <param name="space">namespace of the schema</param>
/// <param name="encspace">enclosing namespace of the schema</param>
+ /// <param name="documentation">documentation for the schema</param>
/// <param name="schema">schema object found</param>
/// <returns>true if name is found in the map, false otherwise</returns>
- public bool TryGetValue(string name, string space, string encspace, out NamedSchema schema)
+ public bool TryGetValue(string name, string space, string encspace, string documentation, out NamedSchema schema)
{
- SchemaName schemaname = new SchemaName(name, space, encspace);
+ SchemaName schemaname = new SchemaName(name, space, encspace, documentation);
return Names.TryGetValue(schemaname, out schema);
}
diff --git a/lang/csharp/src/apache/test/Schema/SchemaTests.cs b/lang/csharp/src/apache/test/Schema/SchemaTests.cs
index 7145670..93a86a9 100644
--- a/lang/csharp/src/apache/test/Schema/SchemaTests.cs
+++ b/lang/csharp/src/apache/test/Schema/SchemaTests.cs
@@ -69,8 +69,12 @@ namespace Avro.Test
typeof(SchemaParseException), Description = "No fields")]
[TestCase("{\"type\":\"record\",\"name\":\"LongList\", \"fields\": \"hi\"}",
typeof(SchemaParseException), Description = "Fields not an array")]
- [TestCase("[{\"type\": \"record\",\"name\": \"Test\",\"namespace\":\"ns1\",\"fields\": [{\"name\": \"f\",\"type\": \"long\"}]}," +
+ [TestCase("[{\"type\": \"record\",\"name\": \"Test\",\"namespace\":\"ns1\",\"fields\": [{\"name\": \"f\",\"type\": \"long\"}]}," +
"{\"type\": \"record\",\"name\": \"Test\",\"namespace\":\"ns2\",\"fields\": [{\"name\": \"f\",\"type\": \"long\"}]}]")]
+
+ // Doc
+ [TestCase("{\"type\": \"record\",\"name\": \"Test\",\"doc\": \"Test Doc\",\"fields\": [{\"name\": \"f\",\"type\": \"long\"}]}")]
+
// Enum
[TestCase("{\"type\": \"enum\", \"name\": \"Test\", \"symbols\": [\"A\", \"B\"]}")]
[TestCase("{\"type\": \"enum\", \"name\": \"Status\", \"symbols\": \"Normal Caution Critical\"}",
@@ -218,6 +222,11 @@ namespace Avro.Test
var rs = Schema.Parse(s) as RecordSchema;
Assert.IsNotNull(rs);
Assert.AreEqual(expectedDoc, rs.Documentation);
+
+ var roundTrip = Schema.Parse(rs.ToString()) as RecordSchema;
+
+ Assert.IsNotNull(roundTrip);
+ Assert.AreEqual(expectedDoc, roundTrip.Documentation);
}
[TestCase("{\"type\": \"enum\", \"name\": \"Test\", \"symbols\": [\"A\", \"B\"]}",
@@ -250,7 +259,7 @@ namespace Avro.Test
}
[TestCase("{\"type\": \"enum\", \"name\": \"Test\", \"symbols\": [\"Unknown\", \"A\", \"B\"], \"default\": \"Unknown\" }", "Unknown")]
- public void TestEnumDefault(string s, string expectedToken)
+ public void TestEnumDefault(string s, string expectedToken)
{
var es = Schema.Parse(s) as EnumSchema;
Assert.IsNotNull(es);
@@ -348,7 +357,7 @@ namespace Avro.Test
[TestCase("a", "o.a.h", ExpectedResult = "o.a.h.a")]
public string testFullname(string s1, string s2)
{
- var name = new SchemaName(s1, s2, null);
+ var name = new SchemaName(s1, s2, null, null);
return name.Fullname;
}