我有一个Kafka Producer的java代码,它将一个GenericRecord作为值发送给kafka代理。我必须通过c#客户端(Kafka使用者)使用此消息。我已经通过SchemaRegistry注册了java类的模式,并正确地在C#客户端接收模式。但是,当我使用Microsoft Avro Deserializer来解析我的bytes数组时,创建的AvroRecord不包含显示我的消息的方法。以下是Java Kafka Producer的代码:
public class OrderProducerAvro {
public static void main(String[] args) {
Properties props = new Properties();
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServerCoordinates);
props.put(ProducerConfig.ACKS_CONFIG, "1");
props.put(ProducerConfig.RETRIES_CONFIG, "3");
props.put(KafkaAvroSerializerConfig.SCHEMA_REGISTRY_URL_CONFIG, "http://10.250.33.228:8081");
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,
io.confluent.kafka.serializers.KafkaAvroSerializer.class);
int numberOfMessages = 10;
Random rand = new Random();
try (KafkaProducer<String, GenericRecord> producer = new KafkaProducer<>(props)) {
while (numberOfMessages-- > 0) {
//Order order = new Order(numberOfMessages, rand.nextInt(1000), rand.nextInt(2000), LocalDateTime.now().toInstant(ZoneOffset.UTC).toEpochMilli());
Order order = new Order();
order.setOrderName("XYZ");
Schema schema = ReflectData.get().getSchema(order.getClass());
GenericRecord avroRecord = new GenericData.Record(schema);
schema.getFields().forEach(r -> avroRecord.put(r.name(), order.getOrderName() + rand.nextInt(2000)));
producer.send(new ProducerRecord<>("POCtopic1", UUID.randomUUID().toString(), avroRecord));
System.out.println("Sending msg: " + avroRecord);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("Producer dies here!!!");
}
}
以下是Order类的代码:
public class Order {
public String getOrderName() {
return orderName;
}
public void setOrderName(String orderName) {
this.orderName = orderName;
}
String orderName;
}
AvroDeserializer的c#客户端代码是:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Confluent.Kafka.Serialization;
using Microsoft.Hadoop.Avro.Schema;
using Microsoft.Hadoop.Avro;
using System.Runtime.Serialization;
using Microsoft.Hadoop.Avro.Container;
using System.IO;
namespace ConsoleApplication2
{
class AvroDes : IDeserializer<AvroRecord>
{
String schema;
public AvroDes(String s)
{
this.schema = s;
}
public AvroRecord Deserialize(byte[] data)
{
if (data == null)
{
throw new ArgumentException();
}
// Console.Write(schema);
var serializer = AvroSerializer.CreateGeneric(schema);
var memStream = new MemoryStream();
memStream.Write(data, 0, data.Length);
memStream.Position = 0;
// var rootSchema = serializer.ReaderSchema as RecordSchema;
AvroRecord actual = (AvroRecord)serializer.Deserialize(memStream);
return actual;
}
}
}
Order类的架构是:
{"type":"record","name":"Order","namespace":"amit.poc.order","fields":[{"name":"orderName","type":"string"}]}
我希望通过这样的方式得到Java Kafka Producer(即“XYZ”)发送的名称: -
actual.orderName
请帮助我,或者只是建议我在c#中开发卡夫卡消费者的其他方式
注意: - 我正在使用Microsoft.Hadoop.Avro dll for c#client