Claus Ibsen created CAMEL-25924:
-----------------------------------
Summary: camel-kafka - the producer sends a Jackson ObjectNode
body as one record per field value, and drops a Jackson 3 scalar node
Key: CAMEL-25924
URL: https://issues.apache.org/jira/browse/CAMEL-25924
Project: Camel
Issue Type: Bug
Components: camel-kafka
Affects Versions: 4.18.0, 4.22.0, 4.23.0
Reporter: Claus Ibsen
Fix For: 4.24.0
With {{useIterator=true}} (the default), the Kafka producer sends a body it can
iterate as one record per element. CAMEL-23883 narrowed this for a Jackson
{{JsonNode}}: only a container node is split, so a scalar node is sent as one
record. Two cases are left.
*1. A Jackson {{ObjectNode}} is split into its field values.* A {{JsonNode}} is
an {{Iterable}} of its elements, and the elements of an object node are the
values of its fields. So a body
{code:json}
{"orderId": 42, "customer": "acme", "total": 9.5}
{code}
as an {{ObjectNode}} (from {{unmarshal}} with {{unmarshalType:
com.fasterxml.jackson.databind.JsonNode}}, or a jq expression that returns an
object) is sent as three records, {{42}}, {{"acme"}} and {{9.5}}, without the
field names. Checked with Jackson 2.22: {{isContainerNode()}} is true for the
object node, and iterating it gives the three values.
*2. A Jackson 3 node is not recognized.* {{isIterable}} checks
{{com.fasterxml.jackson.databind.JsonNode}} only. A Jackson 3
{{tools.jackson.databind.JsonNode}} (camel-jackson3) is an {{Iterable}} too, so
it takes the {{instanceof Iterable}} branch. A Jackson 3 scalar node such as
{{IntNode}} has no elements, so nothing is sent and nothing fails: the case
CAMEL-23883 fixed for Jackson 2. Checked with Jackson 3.2.3: an {{IntNode}} is
an {{Iterable}} of size 0. A Jackson 3 object node is split as in 1.
{code:java}
// KafkaProducer.java:316 on main
private boolean isIterable(Object body) {
if (body instanceof JsonNode node) {
return node.isContainerNode();
}
if (body instanceof Iterable || body instanceof Iterator) {
return true;
}
return false;
}
{code}
*Proposed change*: split only a JSON array ({{isArray()}}), for Jackson 2 and
Jackson 3 nodes (Jackson 3 by its class name, as camel-kafka does not depend on
it), and send an object node or a scalar node as one record. The 4.22 upgrade
guide (CAMEL-23883) says that object nodes are still split, so the change needs
an entry in the 4.24 upgrade guide.
The object node is split in 4.18.0, 4.22.0 and 4.23.0; the Jackson 3 scalar
node is dropped in 4.22.0 and 4.23.0, which have camel-jackson3. Both the sync
and the async send path iterate an empty iterator without sending.
_Claude Code on behalf of davsclaus_
--
This message was sent by Atlassian Jira
(v8.20.10#820010)