oscerd opened a new pull request, #29215:
URL: https://github.com/apache/camel/pull/29215

   Fixes the camel-jackson family (Jackson 2 and 3, with their Avro and 
Protobuf modules) part of 
[CAMEL-26300](https://issues.apache.org/jira/browse/CAMEL-26300), found by the 
runtime tests of the body types of the data type transformers (CAMEL-25928). 
CAMEL-26300 is fixed with one PR per component.
   
   Fixes the camel-jackson items of 
[CAMEL-26300](https://issues.apache.org/jira/browse/CAMEL-26300), found by the 
runtime tests of the body types of the data type transformers (CAMEL-25928). 
Each fix is made in the Jackson 2 and the Jackson 3 module alike: camel-jackson 
and camel-jackson3, camel-jackson-avro and camel-jackson3-avro, 
camel-jackson-protobuf and camel-jackson3-protobuf.
   
   ## 1. application-json rejects a Map, a List, plain text, bytes or a stream 
without a content class
   
   **Was:** `JsonDataTypeTransformer` kept a JSON object or array given as a 
String, and wrote any other body with Jackson, for the class of the 
`X-Content-Class` exchange property, else the class of a POJO body, else 
`JsonNode`. A `Map`, a `List`, other text, bytes or a stream has no class of 
its own (they are `java.*` classes), so it was written with the root type 
`JsonNode`, and Jackson refused it ("Incompatible types: declared root type 
JsonNode"). The stream cache of Camel is taken for a POJO, so Jackson tried to 
write the stream itself as a bean, which fails.
   
   **Now:** without the `X-Content-Class` exchange property:
   
   - a `Map` is written as a JSON object, and a `List` (or another 
`Collection`) as a JSON array, by Jackson without a root type;
   - text, bytes or a stream (an `InputStream`, a `Reader` or the stream cache) 
is read as text with the type converters: a JSON object or array is kept as it 
is, as a String body was before, and other text becomes a JSON string (`Hello` 
gives `"Hello"`). These bodies are not given to Jackson as they are, so bytes 
do not become Base64 and a stream is not written as a bean.
   
   A JSON object or array as a String, a `JsonNode`, a POJO and a null body 
give the same JSON as before, and with the `X-Content-Class` exchange property 
set the transformer still writes only a body of that class (or JSON object or 
array text).
   
   ## 2. application-x-java-object, avro-x-java-object and 
protobuf-x-java-object throw a NullPointerException on a null body
   
   **Was:** with the `X-Content-Class` exchange property set, 
`JsonPojoDataTypeTransformer` checked whether the body is already of that class 
with `message.getBody().getClass()`, which threw a `NullPointerException` for a 
null body. The Avro and Protobuf transformers extend it.
   
   **Now:** the check is `contentType.isInstance(body)`, so a null body goes on 
to be read, and fails as other bodies without JSON (or Avro or Protobuf binary) 
do: a `CamelExecutionException` whose cause is an `InvalidPayloadException` 
("No body available"). The body types already said that a null body fails, and 
are unchanged for this.
   
   ## 3. Jackson 2 avro-x-java-object and protobuf-x-java-object fail on a 
JsonNode body
   
   **Was:** with the Avro or Protobuf schema set, the Jackson 2 
`AvroPojoDataTypeTransformer` and `ProtobufPojoDataTypeTransformer` read a 
`JsonNode` body with a reader that has the schema. Jackson 2 gives the schema 
to the parser of the tree, which does not take one, so they failed with an 
`UnsupportedOperationException` ("TreeTraversingParser does not support schema 
of type 'avro'"), not wrapped in a `CamelExecutionException`. With Jackson 3 
the same call reads the node, so camel-jackson3 worked.
   
   **Now:** the Jackson 2 transformers read the `JsonNode` with a reader 
without the schema, so the node is read into the class of the `X-Content-Class` 
exchange property, as with camel-jackson3. The body types of both versions now 
name the `JsonNode` among the bodies read into that class.
   
   ## 4. camel-jackson3-avro and camel-jackson3-protobuf let JacksonException 
through unwrapped
   
   **Was:** `AvroBinaryDataTypeTransformer`, `AvroStructDataTypeTransformer`, 
`ProtobufBinaryDataTypeTransformer` and `ProtobufStructDataTypeTransformer` of 
camel-jackson3-avro and camel-jackson3-protobuf caught `IOException` (and 
`InvalidPayloadException`), as their Jackson 2 counterparts do. The errors of 
Jackson 3 are `JacksonException`, a `RuntimeException`, so they went through 
unwrapped, for example for malformed JSON text.
   
   **Now:** these four transformers also catch `JacksonException` and wrap it 
in a `CamelExecutionException`, as the camel-jackson3 JSON transformers do 
since CAMEL-24064. The `x-java-object` transformers inherit the `transform` of 
camel-jackson3, which wraps it already.
   
   ## 5. avro-x-struct does not take JSON text, but protobuf-x-struct does
   
   **Was:** `AvroStructDataTypeTransformer` read every body without the 
`X-Content-Class` exchange property as Avro binary with the schema, so JSON 
text was decoded as Avro: it failed, or gave a wrong `JsonNode` (the existing 
`shouldHandleJsonString` test only checked the class of the result). 
`ProtobufStructDataTypeTransformer` reads a JSON object or array given as a 
String as JSON.
   
   **Now:** `AvroStructDataTypeTransformer` reads a JSON object or array given 
as a String as JSON, with the same check and in the same place as 
`ProtobufStructDataTypeTransformer`, in both versions. Its body types now list 
text, as those of `protobuf-x-struct` do.
   
   ## Tests
   
   New or changed tests, the same in the Jackson 2 and the Jackson 3 module of 
each pair:
   
   - `JsonDataTypeTransformerTest`: a `Map` and a `List` (with a POJO and a 
`Map` in it) give a JSON object and array; JSON as bytes, an `InputStream`, a 
`Reader` and the stream cache is kept as it is; other text, as a String and as 
bytes, becomes a JSON string; `theBodyTypesSayTheBody` checks the new carriers 
with each of these bodies, and that with the `X-Content-Class` property a `Map` 
still fails.
   - `JsonPojoDataTypeTransformerTest`, and the `x-java-object` tests of Avro 
and Protobuf: a null body with the `X-Content-Class` property fails with a 
`CamelExecutionException` caused by an `InvalidPayloadException`.
   - `AvroPojoDataTypeTransformerTest` and 
`ProtobufPojoDataTypeTransformerTest`: a `JsonNode` body with the schema set is 
read into the class, also in `theBodyTypesSayTheBody`.
   - `AvroStructDataTypeTransformerTest`: `shouldHandleJsonString` now checks 
the values read from the JSON text (in camel-jackson3-avro it sends JSON text 
again, instead of Avro binary), `theBodyTypesSayTheBody` takes JSON text, and 
malformed JSON fails with a `CamelExecutionException`.
   - The camel-jackson3 `avro-binary`, `protobuf-binary` and 
`protobuf-x-struct` tests: malformed JSON fails with a 
`CamelExecutionException`.
   
   Without the fix, 26 of these 31 tests fail: with the old "Incompatible 
types" error of `application-json`, a `NullPointerException`, the 
`UnsupportedOperationException` of the Jackson 2 tree parser, a wrong name read 
from the JSON text by Jackson 2 Avro (or an unwrapped 
`MismatchedInputException` by Jackson 3), an unwrapped `StreamReadException`, 
or the old carriers. The 5 that pass are the Jackson 2 `avro-x-struct` 
malformed JSON test (Jackson 2 already wrapped this error) and the two 
`JsonNode` cases of each of the Jackson 3 `avro-x-java-object` and 
`protobuf-x-java-object` tests, which Jackson 3 already read and which keep 
both versions alike.
   
   Module tests: camel-jackson 113, camel-jackson3 123, camel-jackson-avro 33, 
camel-jackson3-avro 33, camel-jackson-protobuf 31 and camel-jackson3-protobuf 
32, all passing.
   
   ## Docs and generated files
   
   - The body types of `application-json` (both versions) now list text, bytes, 
a stream, a Map, a List, a POJO and a null body, and say what each gives; those 
of `avro-x-struct` list text; those of `avro-x-java-object` and 
`protobuf-x-java-object` name the `JsonNode`. The regenerated transformer JSON 
of the six modules and the catalog copies of `application-json`, 
`avro-x-java-object`, `avro-x-struct` and `protobuf-x-java-object` (which the 
catalog takes from the Jackson 2 modules) have the new body types.
   - The components have no doc page for the transformers: their body types are 
what the catalog shows.
   - Upgrade guide entry for 4.24, as more bodies now give JSON and some 
failures change their exception.
   
   ## Not changed
   
   - A file (a `java.io.File`, a `Path` or the `GenericFile` of the file 
consumers) is not read by `application-json`: the issue names text, bytes and a 
stream, and a `Path` is written today by Jackson as its URI, which is left as 
it is. Numbers, booleans and other values without a content class also still 
fail, as before.
   - Text that is no JSON object or array becomes a JSON string even when it is 
a JSON number, boolean or `null`, as the transformer only recognises an object 
or an array as JSON text, as it did before for a String body.
   - A `Map` entry with a null or empty value is left out of the JSON, as the 
mapper of the transformer already does for the properties of a POJO 
(`NON_EMPTY` inclusion), and a `Map` holding `java.time` values fails with 
Jackson 2, as a POJO with such fields does.
   - A null body still fails in the `x-java-object` transformers, as their body 
types say, rather than being kept as null: there is no JSON to read into the 
class.
   - The Jackson 3 `x-java-object` transformers still pass the schema when they 
read a `JsonNode`; Jackson 3 does not use it for a tree.
   
   For main only, as the other CAMEL-26300 fixes.
   
   Main only, as the other fixes of the CAMEL-24961 follow-ups.
   
   _Claude Code on behalf of Andrea Cosentino (oscerd)_
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to