My Avro schema is -
{Schema: {"type":"record","name":"Header","namespace":"EMployee.schema","fields":[{"name":"changeTypes","default":null,"type":["null",{"type":"array","items":["null","string"]}]},{"name":"correlationId","default":null,"type":["null","string"]},{"name":"entityId","default":null,"type":["null","string"]},{"name":"entityType","default":null,"type":["null","string"]},{"name":"eventTimestamp","default":null,"type":["null","string"]},{"name":"eventType","default":null,"type":["null","string"]},{"name":"originalEventType","default":null,"type":["null","string"]},{"name":"originalSourceSystem","default":null,"type":["null","string"]},{"name":"sourceId","default":null,"type":["null","string"]},{"name":"sourceSystem","default":null,"type":["null","string"]}]},
contents: { changeTypes: System.Collections.Generic.List`1[System.String], correlationId: c4f6c7fb001546c5ad436376a502ff31, entityId: 1, entityType: Employee, eventTimestamp: 4/14/2024 4:19:45 PM, eventType: createEmployee, originalEventType: Create, originalSourceSystem: Workday, sourceId: 2, sourceSystem: Workday, }}
If we inspect the schema contents, the value of changeType
is System.Collections.Generic.List
1[System.String]. I am using the method below to assign values to the
GenericRecord` object. However, when I post it to the Redpanda topic, it throws an error.
Cannot find a match for System.Collections.Generic.List`1[System.String] in ["null",{"type":"array","items":["null","string"]}] in field changeTypes in field header.
my code is -
static object ConvertToAvroCompatibleType(Avro.Schema schema, object value)
{
if (schema is Avro.UnionSchema unionSchema)
{
var actualSchema = unionSchema.Schemas.FirstOrDefault(s => s.Tag != Avro.Schema.Type.Null);
if (actualSchema == null)
{
return null;
}
return ConvertToAvroCompatibleType(actualSchema, value);
}
else
{
switch (schema.Tag)
{
case Avro.Schema.Type.String:
return value?.ToString();
case Avro.Schema.Type.Int:
return value is int ? (int)value : 0;
case Avro.Schema.Type.Array:
var arraySchema = (ArraySchema)schema;
var avroArray = new List<string>();
if (value is IEnumerable enumerable)
{
foreach (var item in enumerable)
{
avroArray.Add(item?.ToString());
}
return avroArray;
}
else
{
return null;
}
default:
return null;
}
}
}
Can anyone help me with how I should pass an array into a GenericRecord? Or could you advise on what the issue might be in this context?
static object ConvertToAvroCompatibleType(Avro.Schema schema, object value)
{
if (schema is Avro.UnionSchema unionSchema)
{
var actualSchema = unionSchema.Schemas.FirstOrDefault(s => s.Tag != Avro.Schema.Type.Null);
if (actualSchema == null)
{
return null;
}
return ConvertToAvroCompatibleType(actualSchema, value);
}
else
{
switch (schema.Tag)
{
case Avro.Schema.Type.String:
return value?.ToString();
case Avro.Schema.Type.Int:
return value is int ? (int)value : 0;
case Avro.Schema.Type.Array:
var arraySchema = (ArraySchema)schema;
var avroArray = new List<string>();
if (value is IEnumerable enumerable)
{
foreach (var item in enumerable)
{
avroArray.Add(item?.ToString());
}
return avroArray;
}
else
{
return null;
}
default:
return null;
}
}
}
I resolved this issue:- instead of returning 'return avroArray' I used 'return avroArray.ToArray()'. and it's working.