This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 2fa665b8a08b CAMEL-26300: camel-milvus, camel-neo4j, camel-qdrant,
camel-weaviate - the embeddings transformers name a missing embedding header,
and neo4j:rag converts a text that is not a String (#29214)
2fa665b8a08b is described below
commit 2fa665b8a08b791b12474765bbf1b670c4d4641a
Author: Andrea Cosentino <[email protected]>
AuthorDate: Thu Nov 5 13:02:55 2026 +0100
CAMEL-26300: camel-milvus, camel-neo4j, camel-qdrant, camel-weaviate - the
embeddings transformers name a missing embedding header, and neo4j:rag converts
a text that is not a String (#29214)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
.../apache/camel/catalog/docs/neo4j-component.adoc | 1 +
.../camel/catalog/transformers/neo4j-rag.json | 2 +-
.../MilvusEmbeddingsDataTypeTransformer.java | 5 +++++
.../MilvusEmbeddingsDataTypeTransformerTest.java | 24 ++++++++++++++++++++--
.../org/apache/camel/transformer/neo4j-rag.json | 2 +-
.../camel-neo4j/src/main/docs/neo4j-component.adoc | 1 +
.../Neo4jEmbeddingDataTypeTransformer.java | 5 +++++
.../Neo4jReverseEmbeddingsDataTypeTransformer.java | 24 +++++++++++++++++++---
.../Neo4jEmbeddingDataTypeTransformerTest.java | 7 ++++++-
...4jReverseEmbeddingsDataTypeTransformerTest.java | 24 ++++++++++++++++++++++
.../QdrantEmbeddingsDataTypeTransformer.java | 5 +++++
.../QdrantEmbeddingsDataTypeTransformerTest.java | 7 +++++--
.../WeaviateEmbeddingsDataTypeTransformer.java | 5 +++++
.../WeaviateEmbeddingsDataTypeTransformerTest.java | 18 +++++++++++-----
.../ROOT/pages/camel-4x-upgrade-guide-4_24.adoc | 10 +++++++++
15 files changed, 125 insertions(+), 15 deletions(-)
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/neo4j-component.adoc
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/neo4j-component.adoc
index 7ba9d57c13e0..298fe2010758 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/neo4j-component.adoc
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/neo4j-component.adoc
@@ -376,6 +376,7 @@ You can enhance the Camel LangChain4j chat RAG experience
by integrating Neo4j s
To achieve this, use the `neo4j:embeddings` DataType to generate embeddings
from the prompt. These embeddings will then be utilized for the similarity
search operation.
Next, use the `neo4j:rag` DataType to convert the retrieved embeddings into a
List<String> for RAG. This list can be directly used with the
`LangChain4jRagAggregatorStrategy` from the LangChain4j chat component.
+Each element is the `text` property of a node: a value of another type, such
as a number, is converted to a String, and a node without the property gives an
empty String.
NOTE: The retrieved embeddings must be ingested in Neo4j as LangChain4j
embeddings.
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/transformers/neo4j-rag.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/transformers/neo4j-rag.json
index f565fc62d544..8072ca4ede62 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/transformers/neo4j-rag.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/transformers/neo4j-rag.json
@@ -16,7 +16,7 @@
"list"
],
"javaType": "java.util.List<java.util.Map<java.lang.String,
java.lang.Object>>",
- "description": "The rows of a VECTOR_SIMILARITY_SEARCH, whose text keys
are kept. A null body fails"
+ "description": "The rows of a VECTOR_SIMILARITY_SEARCH, whose text
values are kept as String: a value of another type, such as a number, is
converted, and a row without text gives an empty String. A null body fails"
},
"transformerOut": {
"carriers": [
diff --git
a/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/transform/MilvusEmbeddingsDataTypeTransformer.java
b/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/transform/MilvusEmbeddingsDataTypeTransformer.java
index ea346133dfbd..55517fe71f95 100644
---
a/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/transform/MilvusEmbeddingsDataTypeTransformer.java
+++
b/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/transform/MilvusEmbeddingsDataTypeTransformer.java
@@ -56,6 +56,11 @@ public class MilvusEmbeddingsDataTypeTransformer extends
Transformer {
@Override
public void transform(Message message, DataType fromType, DataType toType)
{
Embedding embedding =
message.getHeader(CamelLangchain4jAttributes.CAMEL_LANGCHAIN4J_EMBEDDING_VECTOR,
Embedding.class);
+ if (embedding == null) {
+ throw new IllegalArgumentException(
+ "Missing embedding vector header '" +
CamelLangchain4jAttributes.CAMEL_LANGCHAIN4J_EMBEDDING_VECTOR
+ + "'. Ensure the
langchain4j-embeddings component is called before this transformer.");
+ }
String textFieldName =
message.getHeader(MilvusHeaders.TEXT_FIELD_NAME, () -> "text", String.class);
String vectorFieldName =
message.getHeader(MilvusHeaders.VECTOR_FIELD_NAME, () -> "vector",
String.class);
String collectionName =
message.getHeader(MilvusHeaders.COLLECTION_NAME, () -> "embeddings",
String.class);
diff --git
a/components/camel-ai/camel-milvus/src/test/java/org/apache/camel/component/milvus/transform/MilvusEmbeddingsDataTypeTransformerTest.java
b/components/camel-ai/camel-milvus/src/test/java/org/apache/camel/component/milvus/transform/MilvusEmbeddingsDataTypeTransformerTest.java
index 945fee6f11d3..f074e1833bac 100644
---
a/components/camel-ai/camel-milvus/src/test/java/org/apache/camel/component/milvus/transform/MilvusEmbeddingsDataTypeTransformerTest.java
+++
b/components/camel-ai/camel-milvus/src/test/java/org/apache/camel/component/milvus/transform/MilvusEmbeddingsDataTypeTransformerTest.java
@@ -67,10 +67,30 @@ class MilvusEmbeddingsDataTypeTransformerTest {
}
}
+ @Test
+ void aMessageWithoutTheEmbeddingFailsWithAClearMessage() throws Exception {
+ // CAMEL-26300: an IllegalArgumentException that names the missing
header, as pgvector:embeddings gives, instead of
+ // a NullPointerException
+ try (DefaultCamelContext context = new DefaultCamelContext()) {
+ context.start();
+
+ for (MilvusAction action : new MilvusAction[] {
MilvusAction.INSERT, MilvusAction.UPSERT }) {
+ assertThatThrownBy(() -> transform(context,
TextSegment.from("hello"), action, null))
+ .as(action.name())
+ .isInstanceOf(IllegalArgumentException.class)
+
.hasMessageContaining("CamelLangChain4jEmbeddingsVector");
+ }
+ }
+ }
+
private Object transform(DefaultCamelContext context, Object body,
MilvusAction action) throws Exception {
+ return transform(context, body, action, new Embedding(new float[] {
0.1f, 0.2f, 0.3f }));
+ }
+
+ private Object transform(DefaultCamelContext context, Object body,
MilvusAction action, Embedding embedding)
+ throws Exception {
Exchange exchange = new DefaultExchange(context);
-
exchange.getMessage().setHeader(CamelLangchain4jAttributes.CAMEL_LANGCHAIN4J_EMBEDDING_VECTOR,
- new Embedding(new float[] { 0.1f, 0.2f, 0.3f }));
+
exchange.getMessage().setHeader(CamelLangchain4jAttributes.CAMEL_LANGCHAIN4J_EMBEDDING_VECTOR,
embedding);
exchange.getMessage().setHeader(MilvusHeaders.ACTION, action);
exchange.getMessage().setBody(body);
transformer.transform(exchange.getMessage(), DataType.ANY,
DataType.ANY);
diff --git
a/components/camel-ai/camel-neo4j/src/generated/resources/META-INF/services/org/apache/camel/transformer/neo4j-rag.json
b/components/camel-ai/camel-neo4j/src/generated/resources/META-INF/services/org/apache/camel/transformer/neo4j-rag.json
index f565fc62d544..8072ca4ede62 100644
---
a/components/camel-ai/camel-neo4j/src/generated/resources/META-INF/services/org/apache/camel/transformer/neo4j-rag.json
+++
b/components/camel-ai/camel-neo4j/src/generated/resources/META-INF/services/org/apache/camel/transformer/neo4j-rag.json
@@ -16,7 +16,7 @@
"list"
],
"javaType": "java.util.List<java.util.Map<java.lang.String,
java.lang.Object>>",
- "description": "The rows of a VECTOR_SIMILARITY_SEARCH, whose text keys
are kept. A null body fails"
+ "description": "The rows of a VECTOR_SIMILARITY_SEARCH, whose text
values are kept as String: a value of another type, such as a number, is
converted, and a row without text gives an empty String. A null body fails"
},
"transformerOut": {
"carriers": [
diff --git a/components/camel-ai/camel-neo4j/src/main/docs/neo4j-component.adoc
b/components/camel-ai/camel-neo4j/src/main/docs/neo4j-component.adoc
index 7ba9d57c13e0..298fe2010758 100644
--- a/components/camel-ai/camel-neo4j/src/main/docs/neo4j-component.adoc
+++ b/components/camel-ai/camel-neo4j/src/main/docs/neo4j-component.adoc
@@ -376,6 +376,7 @@ You can enhance the Camel LangChain4j chat RAG experience
by integrating Neo4j s
To achieve this, use the `neo4j:embeddings` DataType to generate embeddings
from the prompt. These embeddings will then be utilized for the similarity
search operation.
Next, use the `neo4j:rag` DataType to convert the retrieved embeddings into a
List<String> for RAG. This list can be directly used with the
`LangChain4jRagAggregatorStrategy` from the LangChain4j chat component.
+Each element is the `text` property of a node: a value of another type, such
as a number, is converted to a String, and a node without the property gives an
empty String.
NOTE: The retrieved embeddings must be ingested in Neo4j as LangChain4j
embeddings.
diff --git
a/components/camel-ai/camel-neo4j/src/main/java/org/apache/camel/component/neo4j/transformer/Neo4jEmbeddingDataTypeTransformer.java
b/components/camel-ai/camel-neo4j/src/main/java/org/apache/camel/component/neo4j/transformer/Neo4jEmbeddingDataTypeTransformer.java
index 8c92dbd27627..2d04a792ee61 100644
---
a/components/camel-ai/camel-neo4j/src/main/java/org/apache/camel/component/neo4j/transformer/Neo4jEmbeddingDataTypeTransformer.java
+++
b/components/camel-ai/camel-neo4j/src/main/java/org/apache/camel/component/neo4j/transformer/Neo4jEmbeddingDataTypeTransformer.java
@@ -44,6 +44,11 @@ public class Neo4jEmbeddingDataTypeTransformer extends
Transformer {
public void transform(Message message, DataType fromType, DataType toType)
{
final Embedding embedding
=
message.getHeader(CamelLangchain4jAttributes.CAMEL_LANGCHAIN4J_EMBEDDING_VECTOR,
Embedding.class);
+ if (embedding == null) {
+ throw new IllegalArgumentException(
+ "Missing embedding vector header '" +
CamelLangchain4jAttributes.CAMEL_LANGCHAIN4J_EMBEDDING_VECTOR
+ + "'. Ensure the
langchain4j-embeddings component is called before this transformer.");
+ }
final TextSegment text = message.getBody(TextSegment.class);
diff --git
a/components/camel-ai/camel-neo4j/src/main/java/org/apache/camel/component/neo4j/transformer/Neo4jReverseEmbeddingsDataTypeTransformer.java
b/components/camel-ai/camel-neo4j/src/main/java/org/apache/camel/component/neo4j/transformer/Neo4jReverseEmbeddingsDataTypeTransformer.java
index 7f533fabd633..f54bf388b554 100644
---
a/components/camel-ai/camel-neo4j/src/main/java/org/apache/camel/component/neo4j/transformer/Neo4jReverseEmbeddingsDataTypeTransformer.java
+++
b/components/camel-ai/camel-neo4j/src/main/java/org/apache/camel/component/neo4j/transformer/Neo4jReverseEmbeddingsDataTypeTransformer.java
@@ -21,6 +21,7 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
+import org.apache.camel.Exchange;
import org.apache.camel.Message;
import org.apache.camel.spi.BodyType;
import org.apache.camel.spi.BodyType.Carrier;
@@ -36,20 +37,37 @@ import org.apache.camel.spi.Transformer;
description = "Prepares the similarity search LangChain4j
embeddings to become a List of String for LangChain4j RAG")
@BodyTypes(transformerIn = @BodyType(value = Carrier.LIST,
javaType =
"java.util.List<java.util.Map<java.lang.String, java.lang.Object>>",
- description = "The rows of a
VECTOR_SIMILARITY_SEARCH, whose text keys are kept. A"
- + " null body fails"),
+ description = "The rows of a
VECTOR_SIMILARITY_SEARCH, whose text values are kept as"
+ + " String: a value of
another type, such as a number, is converted, and a"
+ + " row without text gives
an empty String. A null body fails"),
transformerOut = @BodyType(value = Carrier.LIST, javaType =
"java.util.List<java.lang.String>"))
public class Neo4jReverseEmbeddingsDataTypeTransformer extends Transformer {
@Override
public void transform(Message message, DataType fromType, DataType toType)
{
final List<Map<String, Object>> embeddings =
message.getBody(List.class);
+ final Exchange exchange = message.getExchange();
List<String> result = embeddings.stream()
- .map(embedding -> (String) embedding.getOrDefault("text", ""))
+ .map(embedding -> toText(exchange, embedding.get("text")))
.collect(Collectors.toList());
message.setBody(result);
}
+
+ /**
+ * The text of a row. The text of a node is a String, but a value of
another type, such as a number, is converted
+ * instead of cast, and a row without text gives an empty String.
+ */
+ private static String toText(Exchange exchange, Object value) {
+ if (value == null) {
+ return "";
+ }
+ if (value instanceof String text) {
+ return text;
+ }
+ String text =
exchange.getContext().getTypeConverter().convertTo(String.class, exchange,
value);
+ return text != null ? text : "";
+ }
}
diff --git
a/components/camel-ai/camel-neo4j/src/test/java/org/apache/camel/component/neo4j/transformer/Neo4jEmbeddingDataTypeTransformerTest.java
b/components/camel-ai/camel-neo4j/src/test/java/org/apache/camel/component/neo4j/transformer/Neo4jEmbeddingDataTypeTransformerTest.java
index f55dbee8151f..440163614d8b 100644
---
a/components/camel-ai/camel-neo4j/src/test/java/org/apache/camel/component/neo4j/transformer/Neo4jEmbeddingDataTypeTransformerTest.java
+++
b/components/camel-ai/camel-neo4j/src/test/java/org/apache/camel/component/neo4j/transformer/Neo4jEmbeddingDataTypeTransformerTest.java
@@ -33,6 +33,7 @@ import static
org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
class Neo4jEmbeddingDataTypeTransformerTest {
@@ -61,7 +62,11 @@ class Neo4jEmbeddingDataTypeTransformerTest {
// a null body fails, and so does a message without the embedding
assertThrows(NullPointerException.class, () -> transform(context,
null, true));
- assertThrows(NullPointerException.class, () -> transform(context,
TextSegment.from("hello"), false));
+ // CAMEL-26300: with an IllegalArgumentException that names the
header, as pgvector:embeddings gives, instead
+ // of a NullPointerException
+ IllegalArgumentException noEmbedding
+ = assertThrows(IllegalArgumentException.class, () ->
transform(context, TextSegment.from("hello"), false));
+
assertTrue(noEmbedding.getMessage().contains("CamelLangChain4jEmbeddingsVector"),
noEmbedding.getMessage());
}
}
diff --git
a/components/camel-ai/camel-neo4j/src/test/java/org/apache/camel/component/neo4j/transformer/Neo4jReverseEmbeddingsDataTypeTransformerTest.java
b/components/camel-ai/camel-neo4j/src/test/java/org/apache/camel/component/neo4j/transformer/Neo4jReverseEmbeddingsDataTypeTransformerTest.java
index 3ebbba00bdba..dabc020e428a 100644
---
a/components/camel-ai/camel-neo4j/src/test/java/org/apache/camel/component/neo4j/transformer/Neo4jReverseEmbeddingsDataTypeTransformerTest.java
+++
b/components/camel-ai/camel-neo4j/src/test/java/org/apache/camel/component/neo4j/transformer/Neo4jReverseEmbeddingsDataTypeTransformerTest.java
@@ -16,6 +16,8 @@
*/
package org.apache.camel.component.neo4j.transformer;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -55,4 +57,26 @@ class Neo4jReverseEmbeddingsDataTypeTransformerTest {
assertThrows(NullPointerException.class,
() -> transformer.transform(empty.getMessage(), DataType.ANY,
DataType.ANY));
}
+
+ @Test
+ void aTextThatIsNotAStringIsConverted() throws Exception {
+ // CAMEL-26300: a text value of another type, such as a number or
bytes, is converted to a String instead of
+ // failing with a ClassCastException, and a null text gives an empty
String, as a row without text does
+ Map<String, Object> nullText = new HashMap<>();
+ nullText.put("id", "4");
+ nullText.put("text", null);
+
+ try (DefaultCamelContext context = new DefaultCamelContext()) {
+ context.start();
+ Exchange exchange = new DefaultExchange(context);
+ exchange.getMessage().setBody(List.of(
+ Map.of("id", "1", "text", 42L),
+ Map.of("id", "2", "text", 0.5d),
+ Map.of("id", "3", "text",
"hello".getBytes(StandardCharsets.UTF_8)),
+ nullText,
+ Map.of("id", "5", "text", "hello")));
+ transformer.transform(exchange.getMessage(), DataType.ANY,
DataType.ANY);
+ assertEquals(List.of("42", "0.5", "hello", "", "hello"),
exchange.getMessage().getBody());
+ }
+ }
}
diff --git
a/components/camel-ai/camel-qdrant/src/main/java/org/apache/camel/component/qdrant/transform/QdrantEmbeddingsDataTypeTransformer.java
b/components/camel-ai/camel-qdrant/src/main/java/org/apache/camel/component/qdrant/transform/QdrantEmbeddingsDataTypeTransformer.java
index d95c43dabcbb..e0e3893e18cb 100644
---
a/components/camel-ai/camel-qdrant/src/main/java/org/apache/camel/component/qdrant/transform/QdrantEmbeddingsDataTypeTransformer.java
+++
b/components/camel-ai/camel-qdrant/src/main/java/org/apache/camel/component/qdrant/transform/QdrantEmbeddingsDataTypeTransformer.java
@@ -53,6 +53,11 @@ public class QdrantEmbeddingsDataTypeTransformer extends
Transformer {
@Override
public void transform(Message message, DataType fromType, DataType toType)
{
Embedding embedding =
message.getHeader(CamelLangchain4jAttributes.CAMEL_LANGCHAIN4J_EMBEDDING_VECTOR,
Embedding.class);
+ if (embedding == null) {
+ throw new IllegalArgumentException(
+ "Missing embedding vector header '" +
CamelLangchain4jAttributes.CAMEL_LANGCHAIN4J_EMBEDDING_VECTOR
+ + "'. Ensure the
langchain4j-embeddings component is called before this transformer.");
+ }
TextSegment text = message.getBody(TextSegment.class);
Common.PointId id
= message.getHeader(QdrantHeaders.POINT_ID, () ->
PointIdFactory.id(UUID.randomUUID()), Common.PointId.class);
diff --git
a/components/camel-ai/camel-qdrant/src/test/java/org/apache/camel/component/qdrant/transform/QdrantEmbeddingsDataTypeTransformerTest.java
b/components/camel-ai/camel-qdrant/src/test/java/org/apache/camel/component/qdrant/transform/QdrantEmbeddingsDataTypeTransformerTest.java
index 9fb40a88e7b1..d71ab6e3d461 100644
---
a/components/camel-ai/camel-qdrant/src/test/java/org/apache/camel/component/qdrant/transform/QdrantEmbeddingsDataTypeTransformerTest.java
+++
b/components/camel-ai/camel-qdrant/src/test/java/org/apache/camel/component/qdrant/transform/QdrantEmbeddingsDataTypeTransformerTest.java
@@ -101,11 +101,14 @@ class QdrantEmbeddingsDataTypeTransformerTest {
}
}
- // a message without the embedding fails
+ // CAMEL-26300: a message without the embedding fails with an
IllegalArgumentException that names the header, as
+ // pgvector:embeddings gives, instead of a NullPointerException
Exchange exchange = new DefaultExchange(context);
exchange.getMessage().setBody(TextSegment.from("hello"));
assertThatThrownBy(() -> new
QdrantEmbeddingsDataTypeTransformer().transform(exchange.getMessage(),
- DataType.ANY,
DataType.ANY)).isInstanceOf(NullPointerException.class);
+ DataType.ANY, DataType.ANY))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("CamelLangChain4jEmbeddingsVector");
}
}
}
diff --git
a/components/camel-ai/camel-weaviate/src/main/java/org/apache/camel/component/weaviate/transform/WeaviateEmbeddingsDataTypeTransformer.java
b/components/camel-ai/camel-weaviate/src/main/java/org/apache/camel/component/weaviate/transform/WeaviateEmbeddingsDataTypeTransformer.java
index 8444e610c849..6d83a9ed28cc 100644
---
a/components/camel-ai/camel-weaviate/src/main/java/org/apache/camel/component/weaviate/transform/WeaviateEmbeddingsDataTypeTransformer.java
+++
b/components/camel-ai/camel-weaviate/src/main/java/org/apache/camel/component/weaviate/transform/WeaviateEmbeddingsDataTypeTransformer.java
@@ -54,6 +54,11 @@ public class WeaviateEmbeddingsDataTypeTransformer extends
Transformer {
@Override
public void transform(Message message, DataType fromType, DataType toType)
{
Embedding embedding =
message.getHeader(CamelLangchain4jAttributes.CAMEL_LANGCHAIN4J_EMBEDDING_VECTOR,
Embedding.class);
+ if (embedding == null) {
+ throw new IllegalArgumentException(
+ "Missing embedding vector header '" +
CamelLangchain4jAttributes.CAMEL_LANGCHAIN4J_EMBEDDING_VECTOR
+ + "'. Ensure the
langchain4j-embeddings component is called before this transformer.");
+ }
String textFieldName =
message.getHeader(WeaviateVectorDbHeaders.TEXT_FIELD_NAME, () -> "text",
String.class);
String collectionName =
message.getHeader(WeaviateVectorDbHeaders.COLLECTION_NAME, () -> "embeddings",
String.class);
String keyName = message.getHeader(WeaviateVectorDbHeaders.KEY_NAME,
() -> "id", String.class);
diff --git
a/components/camel-ai/camel-weaviate/src/test/java/org/apache/camel/component/weaviate/transform/WeaviateEmbeddingsDataTypeTransformerTest.java
b/components/camel-ai/camel-weaviate/src/test/java/org/apache/camel/component/weaviate/transform/WeaviateEmbeddingsDataTypeTransformerTest.java
index 06d014acf254..83c70c7d7287 100644
---
a/components/camel-ai/camel-weaviate/src/test/java/org/apache/camel/component/weaviate/transform/WeaviateEmbeddingsDataTypeTransformerTest.java
+++
b/components/camel-ai/camel-weaviate/src/test/java/org/apache/camel/component/weaviate/transform/WeaviateEmbeddingsDataTypeTransformerTest.java
@@ -151,11 +151,19 @@ class WeaviateEmbeddingsDataTypeTransformerTest {
noAction.setBody(TextSegment.from("hello"));
assertThatThrownBy(() -> new
WeaviateEmbeddingsDataTypeTransformer().transform(noAction, DataType.ANY,
DataType.ANY)).isInstanceOf(IllegalStateException.class);
- Message noEmbedding = new DefaultExchange(context).getMessage();
- noEmbedding.setHeader(WeaviateVectorDbHeaders.ACTION,
WeaviateVectorDbAction.CREATE);
- noEmbedding.setBody(TextSegment.from("hello"));
- assertThatThrownBy(() -> new
WeaviateEmbeddingsDataTypeTransformer().transform(noEmbedding, DataType.ANY,
- DataType.ANY)).isInstanceOf(NullPointerException.class);
+ // CAMEL-26300: without the embedding, an IllegalArgumentException
that names the header, as
+ // pgvector:embeddings gives, instead of a NullPointerException
+ for (WeaviateVectorDbAction action :
List.of(WeaviateVectorDbAction.CREATE, WeaviateVectorDbAction.UPDATE_BY_ID,
+ WeaviateVectorDbAction.QUERY)) {
+ Message noEmbedding = new
DefaultExchange(context).getMessage();
+ noEmbedding.setHeader(WeaviateVectorDbHeaders.ACTION, action);
+ noEmbedding.setBody(TextSegment.from("hello"));
+ assertThatThrownBy(() -> new
WeaviateEmbeddingsDataTypeTransformer().transform(noEmbedding, DataType.ANY,
+ DataType.ANY))
+ .as(action.name())
+ .isInstanceOf(IllegalArgumentException.class)
+
.hasMessageContaining("CamelLangChain4jEmbeddingsVector");
+ }
}
}
}
diff --git
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
index 9721138d273a..5b081f718d75 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
@@ -4145,6 +4145,16 @@ became `café` in the headers and the body map. A
charset that the request or
that sends ISO-8859-1 form data without declaring a charset now gets U+FFFD
replacement characters instead of its
text, and must declare its charset (for example
`application/x-www-form-urlencoded; charset=ISO-8859-1`).
+=== camel-milvus, camel-neo4j, camel-qdrant, camel-weaviate - the embeddings
transformers without the embedding header, and the text of neo4j:rag
+
+The `milvus:embeddings`, `neo4j:embeddings`, `qdrant:embeddings` and
`weaviate:embeddings` data type transformers now
+fail with an `IllegalArgumentException` that names the
`CamelLangChain4jEmbeddingsVector` header when the message does
+not have it, as `pgvector:embeddings` does. Before, they failed with a
`NullPointerException`.
+
+The `neo4j:rag` data type transformer now converts a `text` value that is not
a `String`, such as a number, to a
+`String`, and gives an empty String for a `null` text, as for a row without
text. Before, a value of another type
+failed with a `ClassCastException`, and a `null` text gave a `null` element.
+
=== camel-undertow - rest-dsl and plain consumers on the same port are both
served
When rest-dsl consumers and plain `undertow:` consumers use the same port,
both kinds are now served. Before, only the