我正在尝试与salesforces集成新的grpc更改数据捕获事件总线。事件通过grpc发送给客户端,并带有avro编码的消息,说明对记录的更改,因此客户端必须使用提供且无法更改的avro模式对消息进行解码。
对于具有两种联合类型字段的对象,我能够轻松解码avro编码的消息,但具有三种类型的字段会引发异常。
这是Account avro模式的Name字段:
{
      "name": "Name",
      "type": [
        "null",
        "string",
        {
          "type": "record",
          "name": "Switchable_PersonName",
          "fields": [
            {
              "name": "Salutation",
              "type": [
                "null",
                "string"
              ],
              "default": null
            },
            {
              "name": "FirstName",
              "type": [
                "null",
                "string"
              ],
              "default": null
            },
            {
              "name": "LastName",
              "type": [
                "null",
                "string"
              ],
              "default": null
            },
            {
              "name": "MiddleName",
              "type": [
                "null",
                "string"
              ],
              "default": null
            },
            {
              "name": "InformalName",
              "type": [
                "null",
                "string"
              ],
              "default": null
            },
            {
              "name": "Suffix",
              "type": [
                "null",
                "string"
              ],
              "default": null
            }
          ]
        }
      ],
      "doc": "Data:Switchable_PersonName",
      "default": null
    },
正如您所看到的,名称可以是null、字符串或名为Switchable_PersonName的对象。
使用avrogen-cli工具,我能够将avro模式转换为AccountChangeEvent、ChangeEventHeader、ChangeType、Address、Switchable_PersonName的具体c#类。AccountChangeEvent类中的Name字段创建为:
private object _Name;
这是我对avro消息进行解码的方法:
public static void DeserializeAccountConcrete(byte[] payload)
    {
        var accSchema = Avro.Schema.Parse(File.ReadAllText("./avro/AccountGRPCSchema.avsc"));
        var unionSchema = accSchema as Avro.UnionSchema;
        var cache = new ClassCache();
        cache.LoadClassCache(typeof(AccountChangeEvent), unionSchema);
        cache.LoadClassCache(typeof(Switchable_PersonName), unionSchema);
        cache.LoadClassCache(typeof(Address), unionSchema);
        var reader = new ReflectReader<AccountChangeEvent>(accSchema, accSchema, cache);
        using var accStream = new MemoryStream(payload);
        accStream.Seek(0, SeekOrigin.Begin);
        var accDecoder = new BinaryDecoder(accStream);
        var accEvent = reader.Read(accDecoder);
        Console.WriteLine(accEvent.Name);
        Console.WriteLine("Event " + accEvent.ChangeEventHeader.changeType);
    }
这种反序列化对其他架构有效,但对Account架构失败,引发此异常。
Avro.AvroException:联合记录类型com.sface.eventbus.Switchable_PersonName的类未注册。请创建ClassCache对象并调用LoadClassCache
查看avro的文档,我的实现看起来是正确的,但似乎不是。
我已将字段类型更改为
private com.sforce.eventbus.Switchable_PersonName _Name;
以及可能依赖于此字段的任何其他代码,但仍然会抛出相同的错误。我是avro的新手,因此可能有很多事情我不知道或做得不对。