Skip to content

BE: support MessagePackSerde#1741

Merged
germanosin merged 9 commits intokafbat:mainfrom
YeeaaahMan:issues/951
Apr 3, 2026
Merged

BE: support MessagePackSerde#1741
germanosin merged 9 commits intokafbat:mainfrom
YeeaaahMan:issues/951

Conversation

@YeeaaahMan
Copy link
Copy Markdown
Contributor

@YeeaaahMan YeeaaahMan commented Mar 24, 2026

What changes did you make? (Give an overview)
Fixes #951
Add MessagePackSerde which supports msgpack format. https://msgpack.org/

Serialization and de serialization works, new option is available in Messages preview tab.

How Has This Been Tested? (put an "x" (case-sensitive!) next to an item)

  • No need to
  • Manually (please, describe, if necessary)
  • Unit checks
  • Integration checks
  • Covered by existing automation

I used https://msgpack.solder.party/ to define basic objects: string, list, dict.
Then copied HEX representation to the Produce Message dialog.
As result all messages are displayed correctly when MessagePack serde is selected.
Base64-repr MessagePack-repr

Checklist (put an "x" (case-sensitive!) next to all the items, otherwise the build will fail)

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation (e.g. ENVIRONMENT VARIABLES)
  • My changes generate no new warnings (e.g. Sonar is happy)
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged

Summary by CodeRabbit

  • New Features

    • MessagePack support: view, deserialize, and serialize MessagePack-encoded messages as human-readable JSON strings in the UI.
  • Tests

    • Added tests covering MessagePack serialization/deserialization across target types, including success cases and error handling for invalid or empty inputs.

@YeeaaahMan YeeaaahMan requested a review from a team as a code owner March 24, 2026 20:57
@kapybro kapybro Bot added status/triage Issues pending maintainers triage status/triage/manual Manual triage in progress status/triage/completed Automatic triage completed and removed status/triage Issues pending maintainers triage labels Mar 24, 2026
@YeeaaahMan YeeaaahMan mentioned this pull request Mar 24, 2026
2 tasks
@Haarolean
Copy link
Copy Markdown
Member

@YeeaaahMan hi, thanks for your contirbution. As this serde is not quite a popular unlike schem registry or glue and it requires external dependencies, we'd rather see this as a separate standalone serde, as I suggested here.
Would you like to create your own repo and we list the serde as a community one or perhaps I could create a repo in our org so we could share maintenance overhead in the future?

@YeeaaahMan
Copy link
Copy Markdown
Contributor Author

I see. It sounds logical; this should be moved to a separate repository.

I’d prefer to leave this to you, as I’m completely unfamiliar with the Java ecosystem and can’t quite estimate the scope of work right now. Alternatively, we could hop on a call to outline a plan, and then I can try to handle it myself.

In any case, I’d be happy to help at least partially.

Comment thread api/build.gradle Outdated
@Haarolean
Copy link
Copy Markdown
Member

I see. It sounds logical; this should be moved to a separate repository.

I’d prefer to leave this to you, as I’m completely unfamiliar with the Java ecosystem and can’t quite estimate the scope of work right now. Alternatively, we could hop on a call to outline a plan, and then I can try to handle it myself.

In any case, I’d be happy to help at least partially.

discussed with @germanosin — messagepack is quite popular and isn't dependency-heavy, we'll include it as a built-in serde. Please take a look at the inline comment I left, the rest is good to go.

@Haarolean Haarolean added scope/backend Related to backend changes type/feature A brand new feature area/serde Serialization & Deserialization (plugins) and removed status/triage/manual Manual triage in progress labels Mar 25, 2026
@Haarolean Haarolean requested a review from germanosin March 25, 2026 16:36
@YeeaaahMan YeeaaahMan requested a review from Haarolean March 26, 2026 07:16
@Haarolean
Copy link
Copy Markdown
Member

@YeeaaahMan also please add some tests

Copy link
Copy Markdown
Member

@Haarolean Haarolean left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add some tests

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 26, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a new built-in MessagePack serde, registers it in the serde initializer, updates Gradle version catalog and api dependencies for msgpack, and adds unit tests exercising serialization and deserialization across all Serde.Target values.

Changes

Cohort / File(s) Summary
Dependency Management
api/build.gradle, gradle/libs.versions.toml
Added msgpack version (0.9.11) to the version catalog and added implementation libs.msgpack.core and implementation libs.msgpack.jackson to api/build.gradle.
MessagePack Serde Implementation
api/src/main/java/io/kafbat/ui/serdes/builtin/MessagePackSerde.java
New MessagePackSerde (NAME = "MessagePack") implementing built-in serde behavior. Always reports canDeserialize/canSerialize = true. Deserializer unpacks MessagePack bytes to a JSON string and returns DeserializeResult type STRING; serializer parses JSON string to JsonNode and writes MessagePack bytes. Errors surface as IllegalArgumentException with predefined messages.
Serde Registry
api/src/main/java/io/kafbat/ui/serdes/SerdesInitializer.java
Registered MessagePackSerde.NAME -> MessagePackSerde.class in the default built-in serde registry.
Tests
api/src/test/java/io/kafbat/ui/serdes/builtin/MessagePackSerdeTest.java
Added JUnit5 parameterized tests over all Serde.Target values validating schema, canDeserialize/canSerialize, successful deserialization/serialization cases, and expected exceptions on invalid inputs.

Sequence Diagram(s)

sequenceDiagram
  participant Client as Client
  participant Registry as SerdeRegistry
  participant Serde as MessagePackSerde
  participant Unpacker as MessageUnpacker
  participant Mapper as ObjectMapper

  Client->>Registry: request serde (by name or auto-select)
  Registry->>Serde: return MessagePackSerde instance

  alt Deserialization
    Client->>Serde: provide MessagePack bytes
    Serde->>Unpacker: create unpacker from bytes
    Unpacker-->>Serde: unpack Value
    Serde->>Mapper: convert Value -> JSON string
    Serde-->>Client: return DeserializeResult(type=STRING, payload=string)
  else Serialization
    Client->>Serde: provide JSON string
    Serde->>Mapper: parse JSON -> JsonNode
    Serde->>Mapper: write JsonNode -> MessagePack bytes
    Serde-->>Client: return MessagePack bytes
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I nibbled bytes and folded packs so neat,
Turned JSON carrots into tiny treat.
The registry hopped, the mapper danced in light,
Tests blinked green — I burrowed home tonight. 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'BE: support MessagePackSerde' clearly and concisely summarizes the main objective: adding MessagePack serialization/deserialization support to the backend, which is the primary focus of all code changes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
api/src/test/java/io/kafbat/ui/serdes/builtin/MessagePackSerdeTest.java (1)

59-67: Add one malformed-payload test for error-path regression safety.

Current tests cover only valid bytes; adding an invalid payload assertion will lock down failure behavior.

Proposed test addition
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;

 import io.kafbat.ui.serde.api.DeserializeResult;
 import io.kafbat.ui.serde.api.Serde;
 import io.kafbat.ui.serdes.PropertyResolverImpl;
 import io.kafbat.ui.serdes.RecordHeadersImpl;
 import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.EnumSource;
@@
   `@ParameterizedTest`
   `@EnumSource`
   void deserializesDataAsMessagePackBytes(Serde.Target type) {
     var deserializer = msgPackSerde.deserializer("anyTopic", type);
     var result = deserializer.deserialize(new RecordHeadersImpl(), TEST_BYTES);
     assertThat(result.getResult()).isEqualTo(TEST_STRING);
     assertThat(result.getType()).isEqualTo(DeserializeResult.Type.STRING);
     assertThat(result.getAdditionalProperties()).isEmpty();
   }
+
+  `@Test`
+  void throwsOnMalformedMessagePackPayload() {
+    var deserializer = msgPackSerde.deserializer("anyTopic", Serde.Target.VALUE);
+    assertThatThrownBy(() -> deserializer.deserialize(new RecordHeadersImpl(), new byte[] {(byte) 0xc1}))
+        .isInstanceOf(IllegalArgumentException.class)
+        .hasMessageContaining("Failed to deserialize MessagePack payload");
+  }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api/src/test/java/io/kafbat/ui/serdes/builtin/MessagePackSerdeTest.java`
around lines 59 - 67, Add a new parameterized test in MessagePackSerdeTest
(alongside deserializesDataAsMessagePackBytes) that uses
msgPackSerde.deserializer("anyTopic", type) to deserialize a deliberately
malformed byte array (e.g., invalid MessagePack bytes) via
deserializer.deserialize(new RecordHeadersImpl(), MALFORMED_BYTES) and assert
the failure path: result.getType() equals DeserializeResult.Type.FAIL,
result.getResult() is null, and result.getAdditionalProperties() is not empty
(or contains an error key/message) to lock down error behavior for malformed
payloads.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@api/src/test/java/io/kafbat/ui/serdes/builtin/MessagePackSerdeTest.java`:
- Around line 59-67: Add a new parameterized test in MessagePackSerdeTest
(alongside deserializesDataAsMessagePackBytes) that uses
msgPackSerde.deserializer("anyTopic", type) to deserialize a deliberately
malformed byte array (e.g., invalid MessagePack bytes) via
deserializer.deserialize(new RecordHeadersImpl(), MALFORMED_BYTES) and assert
the failure path: result.getType() equals DeserializeResult.Type.FAIL,
result.getResult() is null, and result.getAdditionalProperties() is not empty
(or contains an error key/message) to lock down error behavior for malformed
payloads.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 976bed64-d085-4669-8310-91864bc55026

📥 Commits

Reviewing files that changed from the base of the PR and between fa99ebc and 5ddcd64.

📒 Files selected for processing (5)
  • api/build.gradle
  • api/src/main/java/io/kafbat/ui/serdes/SerdesInitializer.java
  • api/src/main/java/io/kafbat/ui/serdes/builtin/MessagePackSerde.java
  • api/src/test/java/io/kafbat/ui/serdes/builtin/MessagePackSerdeTest.java
  • gradle/libs.versions.toml

@YeeaaahMan
Copy link
Copy Markdown
Contributor Author

I found some inconsistencies in the serializer's behavior and removed it.
Deserialization works correctly, and unit tests have been added.

If we decide to add a serializer (used in the "Produce Message" dialog), the logic should be:

String -> JSON object -> msgpack.to_bytes(data) -> bytes

This would require a new dependency: org.msgpack.jackson-dataformat-msgpack. But is it worth it?

My main goal was to provide a convenient way to view messages in msgpack format, and the current deserializer handles that perfectly. Any other functionality can be added later.

Guys, what do you think?

@Haarolean
Copy link
Copy Markdown
Member

I found some inconsistencies in the serializer's behavior and removed it. Deserialization works correctly, and unit tests have been added.

If we decide to add a serializer (used in the "Produce Message" dialog), the logic should be:

String -> JSON object -> msgpack.to_bytes(data) -> bytes

This would require a new dependency: org.msgpack.jackson-dataformat-msgpack. But is it worth it?

My main goal was to provide a convenient way to view messages in msgpack format, and the current deserializer handles that perfectly. Any other functionality can be added later.

Guys, what do you think?

I don't mind either personally. We could start with deserialization and implement serialization in a separate task later if requested

@YeeaaahMan
Copy link
Copy Markdown
Contributor Author

Serialization was added. Many corner cases were tested and covered by unit tests.
Checked on UI: it's impossible to add invalid data in various simple scenarios, output is ok.
https://github.com/user-attachments/assets/0ee65cd0-d525-4b7c-8f7b-8651284dddb7

De-serialization also is ok.

Ready to merge.

@YeeaaahMan YeeaaahMan requested a review from Haarolean March 28, 2026 20:13
@Haarolean
Copy link
Copy Markdown
Member

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 30, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Comment thread api/src/main/java/io/kafbat/ui/serdes/builtin/MessagePackSerde.java
@YeeaaahMan YeeaaahMan requested a review from Haarolean March 31, 2026 17:52
@Haarolean Haarolean added this to the 1.5 milestone Mar 31, 2026
@github-project-automation github-project-automation Bot moved this from Todo to PR Approved in Release 1.5 Mar 31, 2026
@germanosin germanosin enabled auto-merge (squash) April 3, 2026 10:48
@germanosin germanosin merged commit a0b33aa into kafbat:main Apr 3, 2026
16 of 17 checks passed
@github-project-automation github-project-automation Bot moved this from PR Approved to Done in Release 1.5 Apr 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/serde Serialization & Deserialization (plugins) scope/backend Related to backend changes status/triage/completed Automatic triage completed type/feature A brand new feature

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Serde: Support MessagePack

3 participants