You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iggy.apache.org by pi...@apache.org on 2026/01/29 20:31:01 UTC
(iggy) 01/01: Always include user_headers in JSON response (empty array when none)
This is an automated email from the ASF dual-hosted git repository.
piotr pushed a commit to branch non_string_header_key
in repository https://gitbox.apache.org/repos/asf/iggy.git
commit fe92af98b5644ce6cb9ce3407ed48134b7cdaa1e
Author: spetz <pi...@gmail.com>
AuthorDate: Thu Jan 29 21:25:05 2026 +0100
Always include user_headers in JSON response (empty array when none)
---
core/common/src/types/message/iggy_message.rs | 41 +++++++++---
.../main/java/org/apache/iggy/message/Message.java | 72 ++++++++--------------
2 files changed, 58 insertions(+), 55 deletions(-)
diff --git a/core/common/src/types/message/iggy_message.rs b/core/common/src/types/message/iggy_message.rs
index f34b2b272..49fe0b89b 100644
--- a/core/common/src/types/message/iggy_message.rs
+++ b/core/common/src/types/message/iggy_message.rs
@@ -545,24 +545,25 @@ impl Serialize for IggyMessage {
use base64::{Engine as _, engine::general_purpose::STANDARD};
use serde::ser::SerializeStruct;
- let field_count = 2 + self.user_headers.is_some() as usize;
-
- let mut state = serializer.serialize_struct("IggyMessage", field_count)?;
+ let mut state = serializer.serialize_struct("IggyMessage", 3)?;
state.serialize_field("header", &self.header)?;
let base64_payload = STANDARD.encode(&self.payload);
state.serialize_field("payload", &base64_payload)?;
- if self.user_headers.is_some() {
+ let entries: Vec<HeaderEntry> = if self.user_headers.is_some() {
let headers_map = self.user_headers_map().map_err(serde::ser::Error::custom)?;
if let Some(map) = headers_map {
- let entries: Vec<HeaderEntry> = map
- .into_iter()
+ map.into_iter()
.map(|(key, value)| HeaderEntry { key, value })
- .collect();
- state.serialize_field("user_headers", &entries)?;
+ .collect()
+ } else {
+ Vec::new()
}
- }
+ } else {
+ Vec::new()
+ };
+ state.serialize_field("user_headers", &entries)?;
state.end()
}
@@ -732,6 +733,28 @@ mod tests {
assert_eq!(original.payload, decoded.payload);
}
+ #[test]
+ fn test_json_serialization_without_headers() {
+ let original = IggyMessage::builder()
+ .id(1)
+ .payload(Bytes::from("test"))
+ .build()
+ .expect("Message creation should not fail");
+
+ let json = serde_json::to_string(&original).expect("JSON serialization should not fail");
+
+ assert!(json.contains("\"user_headers\":[]"));
+
+ let deserialized: IggyMessage =
+ serde_json::from_str(&json).expect("JSON deserialization should not fail");
+
+ assert_eq!(original.header.id, deserialized.header.id);
+ assert_eq!(original.payload, deserialized.payload);
+
+ let headers_map = deserialized.user_headers_map().unwrap();
+ assert!(headers_map.map(|m| m.is_empty()).unwrap_or(true));
+ }
+
#[test]
fn test_json_serialization_with_headers() {
let mut headers = HashMap::new();
diff --git a/foreign/java/java-sdk/src/main/java/org/apache/iggy/message/Message.java b/foreign/java/java-sdk/src/main/java/org/apache/iggy/message/Message.java
index 4143b52b5..414062504 100644
--- a/foreign/java/java-sdk/src/main/java/org/apache/iggy/message/Message.java
+++ b/foreign/java/java-sdk/src/main/java/org/apache/iggy/message/Message.java
@@ -23,6 +23,7 @@ import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSetter;
import com.fasterxml.jackson.annotation.Nulls;
+
import java.math.BigInteger;
import java.util.Base64;
import java.util.Collections;
@@ -30,19 +31,13 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
-public record Message(
- MessageHeader header,
- byte[] payload,
- Map<HeaderKey, HeaderValue> userHeaders
-) {
+public record Message(MessageHeader header, byte[] payload, Map<HeaderKey, HeaderValue> userHeaders) {
@JsonCreator
public static Message fromJson(
- @JsonProperty("header") MessageHeader header,
- @JsonProperty("payload") String base64Payload,
- @JsonProperty(value = "user_headers", required = false) @JsonSetter(
- nulls = Nulls.AS_EMPTY
- ) List<HeaderEntry> userHeadersList
- ) {
+ @JsonProperty("header") MessageHeader header,
+ @JsonProperty("payload") String base64Payload,
+ @JsonProperty(value = "user_headers", required = false) @JsonSetter(nulls = Nulls.AS_EMPTY)
+ List<HeaderEntry> userHeadersList) {
byte[] decodedPayload = Base64.getDecoder().decode(base64Payload);
Map<HeaderKey, HeaderValue> headersMap = new HashMap<>();
if (userHeadersList != null) {
@@ -57,51 +52,40 @@ public record Message(
return of(payload, Collections.emptyMap());
}
- public static Message of(
- String payload,
- Map<HeaderKey, HeaderValue> userHeaders
- ) {
+ public static Message of(String payload, Map<HeaderKey, HeaderValue> userHeaders) {
final byte[] payloadBytes = payload.getBytes();
final long userHeadersLength = getUserHeadersSize(userHeaders);
final MessageHeader msgHeader = new MessageHeader(
- BigInteger.ZERO,
- MessageId.serverGenerated(),
- BigInteger.ZERO,
- BigInteger.ZERO,
- BigInteger.ZERO,
- userHeadersLength,
- (long) payloadBytes.length
- );
+ BigInteger.ZERO,
+ MessageId.serverGenerated(),
+ BigInteger.ZERO,
+ BigInteger.ZERO,
+ BigInteger.ZERO,
+ userHeadersLength,
+ (long) payloadBytes.length);
return new Message(msgHeader, payloadBytes, userHeaders);
}
public Message withUserHeaders(Map<HeaderKey, HeaderValue> userHeaders) {
- Map<HeaderKey, HeaderValue> mergedHeaders = mergeUserHeaders(
- userHeaders
- );
+ Map<HeaderKey, HeaderValue> mergedHeaders = mergeUserHeaders(userHeaders);
long userHeadersLength = getUserHeadersSize(mergedHeaders);
MessageHeader updatedHeader = new MessageHeader(
- header.checksum(),
- header.id(),
- header.offset(),
- header.timestamp(),
- header.originTimestamp(),
- userHeadersLength,
- (long) payload.length
- );
+ header.checksum(),
+ header.id(),
+ header.offset(),
+ header.timestamp(),
+ header.originTimestamp(),
+ userHeadersLength,
+ (long) payload.length);
return new Message(updatedHeader, payload, mergedHeaders);
}
public int getSize() {
long userHeadersLength = getUserHeadersSize(userHeaders);
- return Math.toIntExact(
- MessageHeader.SIZE + payload.length + userHeadersLength
- );
+ return Math.toIntExact(MessageHeader.SIZE + payload.length + userHeadersLength);
}
- private Map<HeaderKey, HeaderValue> mergeUserHeaders(
- Map<HeaderKey, HeaderValue> userHeaders
- ) {
+ private Map<HeaderKey, HeaderValue> mergeUserHeaders(Map<HeaderKey, HeaderValue> userHeaders) {
if (userHeaders.isEmpty()) {
return this.userHeaders;
}
@@ -110,16 +94,12 @@ public record Message(
return userHeaders;
}
- Map<HeaderKey, HeaderValue> mergedHeaders = new HashMap<>(
- this.userHeaders
- );
+ Map<HeaderKey, HeaderValue> mergedHeaders = new HashMap<>(this.userHeaders);
mergedHeaders.putAll(userHeaders);
return mergedHeaders;
}
- private static long getUserHeadersSize(
- Map<HeaderKey, HeaderValue> userHeaders
- ) {
+ private static long getUserHeadersSize(Map<HeaderKey, HeaderValue> userHeaders) {
if (userHeaders.isEmpty()) {
return 0L;
}