v5.1.0
three-formats-one-scenarioProtobuf joins Avro at full parity, and one Java case can now seed a whole multi-topic scenario — with per-record JSON, Avro or Protobuf encoding.
Highlights
- 01
Protobuf, at parity with Avro
A
Read the guide →com.google.protobuf.Messagevalue is auto-detected and published through Confluent'sKafkaProtobufSerializeragainst the samemock://wiretapregistry; typed reads come back as the generated class (orDynamicMessagewith no generated class at all); assertions render payloads as proto3 canonical JSON; and@KafkaSeed(protoMessage = …)publishes the same plain-JSON fixtures Protobuf-encoded — where Avro takes a schema file, Protobuf takes the generated class, which already carries its descriptor. - 02
Programmatic multi-topic seeding
A fixture file seeds one topic.
Read the guide →@KafkaSeed(multiSources = …)runs aKafkaSeedSourcethat builds a whole scenario in Java —Map<topic, List<SeedEvent>>— so a value generated once (an order id, a correlation id) is reused across every topic it appears in. Map keys create their topics if absent and join per-method cleanup, exactly like fixtures. - 03
Per-event envelopes, per-record encoding
Every
Read the guide →SeedEventcarries a value, an optional key, and its own headers — different events on one topic can differ. The value type decides the encoding per record: POJO to JSON, Avro record to Avro, Protobuf message to Protobuf,tombstone(key)to a real null-valued record. One source can span all three formats across topics; mixing formats on a single topic is refused. - 04
Nothing you did not ask for
Read the guide →protobuf-java/-utilare optional dependencies ofwiretap-core, exactly like Avro: a JSON-only or Avro-only suite inherits no protobuf jars, every probe is reflective, and a missing dependency fails with the exact coordinates to add. Bean overrides retargetKafkaProtobuf*factories to the mock registry just as they doKafkaAvro*.
Full notes
Added
- Protobuf support at full parity with Avro: publish auto-detection of
com.google.protobuf.Messagevia Confluent'sKafkaProtobufSerializeragainst the mock registry; typed reads into the generated class (specific.protobuf.value.type) orDynamicMessage; assertions over proto3 canonical JSON (JsonFormat— a protobuftoString()is the text format, not JSON);@KafkaSeed(protoMessage = …)fixture seeding through proto3's JSON mapping (camelCase or snake_case, unknown fields rejected for fixed-field messages); and bean overrides retargetingKafkaProtobuf*serdes.protobuf-java/-utilare optional onwiretap-core;kafka-protobuf-serializeris the test-scope encoding dependency. @KafkaSeed(multiSources = …): programmaticKafkaSeedSourceclasses that seed several topics at once, returningMap<topic, List<SeedEvent>>. The per-file attributes (value/locations/topic/avroSchema/protoMessage/placeholders) are refused on the same annotation — the map keys decide the topics.SeedEvent(immutableof/tombstone/key/headerbuilder with per-event headers and per-record encoding by value type) andKafkaSeedContext(uuid(),now(),today(),binding(name),objectMapper()) — what a source builds records with.
Fixed
SeedRecord.isTombstone()now answers honestly for a record carrying an encoded (Avro or Protobuf) value whose JSON node is an unread placeholder.- The seeder's producer and serializer closes are isolated from one another, so one close failing can no longer skip the others.