He desarrollado un par de C ++ aplicaciones que producen y consumen los mensajes Kafka (usando cppkafka) incrustación de mensajes Protobuf3. Ambos funcionan bien. correspondiente código del productor es:
std::string kafkaString;
cppkafka::MessageBuilder *builder;
...
solidList->SerializeToString(&kafkaString);
builder->payload(kafkaString);
protobuf objetos son serializados a cuerda y insertan como Kafka carga útil. Todo funciona bien hasta este punto. Ahora, estoy tratando de desarrollar un consumidor para que en Java. El código en cuestión debe ser:
KafkaConsumer<Long, String> consumer=new KafkaConsumer<Long, String>(properties);
....
ConsumerRecords<Long, String> records = consumer.poll(100);
for (ConsumerRecord<Long, String> record : records) {
SolidList solidList = SolidList.parseFrom(record.value());
...
pero eso no funciona en tiempo de compilación: parseFrom se queja: El método parseFrom (ByteBuffer) en el tipo Solidlist.SolidList no es aplicable a los argumentos (String) . Por lo tanto, trate de usar un ByteBuffer:
KafkaConsumer<Long, ByteBuffer> consumer=new KafkaConsumer<Long, ByteBuffer>(properties);
....
ConsumerRecords<Long, ByteBuffer> records = consumer.poll(100);
for (ConsumerRecord<Long, ByteBuffer> record : records) {
SolidList solidList = SolidList.parseFrom(record.value());
...
Ahora, el error está en tiempo de ejecución, todavía en parseFrom (): Excepción en el hilo "principal" java.lang.ClassCastException: java.lang.String no puede ser echado a java.nio.ByteBuffer . Sé que es un java.lang.String !!! Por lo tanto, yo vuelva a la original, y tratar de usarlo como una matriz de bytes:
SolidList solidList = SolidList.parseFrom(record.value().getBytes());
Ahora, el error está en tiempo de ejecución: Excepción en hilo com.google.protobuf.InvalidProtocolBufferException $ InvalidWireTypeException "principal": la etiqueta mensaje del Protocolo tenía alambre tipo válido. .
La documentación protobuf para la serialización C ++: SerializeToString bool (cadena de salida) const ;: serializa el mensaje y almacena los bytes de la cadena dada. Tenga en cuenta que los bytes son binarios, no de texto ; sólo utilizamos la clase string como un contenedor conveniente. *
TL; DR: En consecuencia, ¿cómo debo interpretar la protobuf C ++ "bytes binarios" en Java?
Esto parece relacionado (es todo lo contrario), pero no sirve de ayuda: Protobuf de Java a C ++ serialización [binario]
Gracias por adelantado.
Tratar implementar un deserializador y pasarlo a KafkaConsumer constructor como valor deserializer. Se podría tener este aspecto:
class SolidListDeserializer implements Deserializer<SolidList> {
public SolidList deserialize(final String topic, byte[] data) {
return SolidList.parseFrom(data);
}
...
}
...
KafkaConsumer<Long, SolidList> consumer = new KafkaConsumer<>(props, new LongDeserializer(), new SolidListDeserializer())