AVROプリミティブ型のためSerdeクラス

デビッド・ブルトン:

私は、キーと値コンバータの両方のアブロスキーマレジストリを使用し、コネクタによって作成された入力トピックを取るJavaでカフカストリームアプリを書いています。コネクタには、次のスキーマを生成します。

key-schema: "int"
value-schema:{
"type": "record",
"name": "User",
"fields": [
    {"name": "firstname", "type": "string"},
    {"name": "lastname",  "type": "string"}
]}

実際には、いくつかのトピックは、キースキーマは、常に「INT」であり、値スキーマは、常にいくつかの種類(ユーザー、製品、など)の記録である、があります。私のコードは次の定義が含まれています

Map<String, String> serdeConfig = Collections.singletonMap("schema.registry.url", schemaRegistryUrl);

Serde<User> userSerde = new SpecificAvroSerde<>();
userSerde.configure(serdeConfig, false);

最初のIでのようなものでトピックを消費しようとしたConsumed.with(Serdes.Integer(), userSerde);が、整数は4つのバイトが、アブロ用途可変長符号化を使用して符号化されることを期待するSerdes.Integer()ので、それは仕事をしませんでした。使い方は、Consumed.with(Serdes.Bytes(), userSerde);働いていたが、私はこれに私のコードを変更するので、私は実際にint型を望んでいたし、バイトではありません

KafkaAvroDeserializer keyDeserializer = new KafkaAvroDeserializer()
KafkaAvroSerializer keySerializer = new KafkaAvroSerializer();
keyDeserializer.configure(serdeConfig, true); 
keySerializer.configure(serdeConfig, true);
Serde<Integer> keySerde = (Serde<Integer>)(Serde)Serdes.serdeFrom(keySerializer, keyDeserializer);

これは、コンパイラが警告を生成し(それが好きではない作られた(Serde<Integer>)(Serde)鋳造)が、それは使用に私を可能に

Consumed.with(keySerde, userSerde);そしてキーとして整数を取得します。これはうまく動作しますし、期待通りに私のアプリが動作している(素晴らしいです!)。しかし、今、私は、キー/値のデフォルトserdeを定義したいと私は仕事にそれを得ることができません。

デフォルト値のserdeを設定することは簡単です:

streamsConfiguration.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, SpecificAvroSerde.class);

しかし、私はデフォルトのキーserdeを定義する方法を見つけ出すことはできません。

私は試した

  1. streamsConfiguration.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, keySerde.getClass().getName()); ランタイムエラーが発生します。org.apache.kafka.common.serialization.Serdes $ WrapperSerdeの公開引数なしのコンストラクタが見つかりませんでした
  2. streamsConfiguration.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, SpecificAvroSerde.class); ランタイムエラーが発生します。java.lang.Integerのはorg.apache.avro.specific.SpecificRecordにキャストすることはできません

私は何をしないのですか?ありがとうございました。

マティアス・J.サックス:

アップデート (バージョン5.5以降)

コンフルエントバージョンは、5.5経由して、プリミティブアブロタイプのネイティブサポートが追加されますPrimitiveAvroSerde(参照https://github.com/confluentinc/schema-registry/blob/5.5.x/avro-serde/src/main/java/io/confluent/kafka/streams /serdes/avro/PrimitiveAvroSerde.java

オリジナルの答え (バージョン5.4およびそれ以前)

これは既知の問題です。SERDESがで動作するので、プリミティブアブロタイプは、コンフルエントのAvroSerdesとうまく動作しませんGenericAvroRecordSpecificAvroRecordだけ。

比較https://github.com/confluentinc/schema-registry/tree/master/avro-serde/src/main/java/io/confluent/kafka/streams/serdes/avroを

したがって、に基づいて、あなた自身のSerdeを構築KafkaAvroSerializerし、KafkaAvroDeserializer正しいアプローチです。デフォルトSerdeとしてコンフィグにこれを渡すことができるようにするには、使用することはできませんSerdes.serdeFrom型情報が原因genricsの型消去のために失われているため。

ただし、拡張することあなた自身のクラスを実装することができますSerdeインターフェースの代わりと設定にカスタムクラスを渡します。

public class MySerde extends Serde<Integer> {
    // use KafkaAvroSerializer and KafkaAvroDeserializer and cast `Object` to `Integer`
}

config.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, MySerde.class);

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=223153&siteId=1
おすすめ