oscerd opened a new pull request, #29070: URL: https://github.com/apache/camel/pull/29070
Fixes [CAMEL-26228](https://issues.apache.org/jira/browse/CAMEL-26228), found while adding the catalog body types (CAMEL-24961). ## 1. CREATE_NODE with no body **Was:** `CREATE_NODE` built `Map.of("props", body)`, which threw a bare `NullPointerException` when the body was null. The JSON text `null` failed the same way, wrapped as a parse error. **Now:** Both fail with an `InvalidPayloadException` that says CREATE_NODE needs the properties of the node as a Map or as JSON text, before anything is sent to Neo4j. The error for text that is not a JSON object no longer puts the body in its message, since the body holds the properties of the node, which can be sensitive. ## 2. VECTOR_SIMILARITY_SEARCH with a List<Double> or text vector **Was:** The body was converted with `getBody(float[].class)`. A `List<Double>` (or a `double[]`) failed with a misleading type conversion error (`argument type mismatch`), and text such as `0.75,0.65` converted to null, so `Map.of(...)` threw a `NullPointerException`. **Now:** The vector can be a `Neo4jEmbedding`, a `float[]`, or a `List` (any `Collection`) or an array of numbers, each element converted with `floatValue()`. A list or an array with an element that is not a number fails with an `InvalidPayloadException` that names the index and the type of the element, not its value. Another body still goes through the type converters, and fails with an `InvalidPayloadException` that lists the accepted vectors when it does not convert, such as text. ## 3. A Cypher retrieve whose first column is not a node **Was:** Every record was mapped with `record.get(0).asNode()`, so `RETRIEVE_NODES_AND_UPDATE_WITH_CYPHER_QUERY` with a query that returns a property, a count or a path first failed with `Cannot coerce STRING to Node`. **Now:** A record whose first column is a node still gives the properties of that node. Any other record is given as a `Map` of its columns, such as `{name=Ethan, age=41}`. ## 4. The similarity search drops the score **Was:** The query yields `node, score`, but the body kept only the properties of each node. **Now:** Each `Map` of the body also has the score of the hit, as a `Double` under the `score` key. It replaces a property of the node named `score`; the records in the `CamelNeo4jQueryResultListNeo4jNodes` header keep both. The `text` key that the `neo4j:rag` transformer reads is unchanged. ## 5. Header metadata **Was:** `CamelNeo4jQueryResultListNeo4jNodes` was described as "Query execution time in Milliseconds", with type `Long`. `CamelNeo4jQueryResultRetrieveSize` and the four counters of the write operations were declared `Long`, while the producer sets an `Integer`. `CamelNeo4jQueryResult` was described as "Query Result", while it holds the text of the query that ran, and the example of `CamelNeo4jMatchProperties` (`{name: 'Alice'}`) is not JSON that the producer can parse. The `CamelNeo4jLabel` header and the `query` option were never read. **Now:** The descriptions and types say what the producer sets: `Integer`, and `java.util.List<org.neo4j.driver.Record>` for the records. `CamelNeo4jLabel` and `query` are deprecated with a deprecation note, not removed: `CREATE_VECTOR` takes the label from the `label` option (`Embedding` when it is not set), and the Cypher operations take the query from the body. The embeddings example of the component page no longer sets `CamelNeo4jLabel`. ## Tests `Neo4jProducerBodyTest` (18 tests) runs the producer against a fake `Driver` made of JDK proxies and the driver's own records and nodes, so no Neo4j server is needed. It covers CREATE_NODE with no body, with the JSON text `null`, with a Map or JSON body, and with text that is not JSON; the similarity search with a `List<Double>`, a `List<Float>`, a `double[]`, a `Double[]`, a `float[]` and a `Neo4jEmbedding`, with text, and with a List of text; the score of each hit; Cypher queries whose first column is a node, a property or a count; the Java type of the headers against their metadata; and the deprecation of the header and the option. With the change of `src/main` reverted, 13 of the 18 tests fail on the old behaviour (`NullPointerException`, `TypeConversionException`, `Cannot coerce ... to Node`, no `score`, the `Long` metadata, the body in the message). The 5 that pass are the cases that already worked: the search with a `List<Float>`, a `float[]` and a `Neo4jEmbedding`, CREATE_NODE with a Map or JSON body, and a Cypher query whose first column is a node. The ITs gain a similarity search with a `List<Double>`, a check of the `score` of each hit, a Cypher query that returns properties, and CREATE_NODE without a body. They need Neo4j and were not run here. Module: 25 tests, 0 failures. ## Docs and generated files The component page documents the bodies of CREATE_NODE and VECTOR_SIMILARITY_SEARCH, the records of a Cypher query whose first column is not a node, and the `score` key, and the embeddings example no longer sets the `CamelNeo4jLabel` header. `neo4j.json` and the component page are regenerated and copied to the catalog. The header and option metadata also change the generated endpoint DSL. The upgrade guide gets an entry for the changes users may notice. ## Not changed - The `CamelNeo4jLabel` header is deprecated rather than read again. `CREATE_VECTOR` read it until CAMEL-21719, which moved the label to the `label` option with `Embedding` as the default, so reading it again would revert that change, and it would put a header value into the Cypher text, where the label is not a bound parameter. - The `query` option is deprecated rather than used: making it the query of the Cypher operations would be a new feature, with an open question (the option or the body first). - Text is not parsed as a vector (such as `0.75,0.65` or a JSON array): it fails clearly, as the issue proposes. - The score goes into each `Map` rather than into a header, so it stays with its node; it replaces a node property named `score`. - The deprecated `Neo4jConstants.Headers` class keeps its old metadata, since the endpoint documents `Neo4jHeaders`. - `LangChain4jEmbeddingsComponentNeo4jTargetIT` in camel-langchain4j-embeddings still sets `Neo4jHeaders.LABEL`, now deprecated; it had no effect there before either. 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]
