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 177686ba2acc CAMEL-26225: camel-arangodb - SAVE_DOCUMENT inserts a 
Collection body as several documents, and a producer without the operation 
option fails to start (#29068)
177686ba2acc is described below

commit 177686ba2acc3cd01af203a73c9f5d0f48cf42be
Author: Andrea Cosentino <[email protected]>
AuthorDate: Tue Nov 3 12:12:33 2026 +0100

    CAMEL-26225: camel-arangodb - SAVE_DOCUMENT inserts a Collection body as 
several documents, and a producer without the operation option fails to start 
(#29068)
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
 .../apache/camel/catalog/components/arangodb.json  |   4 +-
 .../camel/catalog/docs/arangodb-component.adoc     |   6 +
 .../apache/camel/component/arangodb/arangodb.json  |   4 +-
 .../src/main/docs/arangodb-component.adoc          |   6 +
 .../camel/component/arangodb/ArangoDbEndpoint.java |  18 +-
 .../camel/component/arangodb/ArangoDbProducer.java |   6 +-
 .../component/arangodb/ArangoDbProducerTest.java   | 195 +++++++++++++++++++++
 .../ROOT/pages/camel-4x-upgrade-guide-4_24.adoc    |  10 ++
 8 files changed, 239 insertions(+), 10 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/arangodb.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/arangodb.json
index 95771e01e237..7b993b243d96 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/arangodb.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/arangodb.json
@@ -50,8 +50,8 @@
     "CamelArangoDbAqlOptions": { "index": 7, "kind": "header", "displayName": 
"", "group": "advanced", "label": "advanced", "required": false, "javaType": 
"com.arangodb.model.AqlQueryOptions", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "The additional options 
that will be passed to the query API.", "constantName": 
"org.apache.camel.component.arangodb.ArangoDbConstants#AQL_QUERY_OPTIONS" }
   },
   "bodyTypes": {
-    "producerIn": { "carriers": [ "map", "pojo", "list" ], "byOption": [ { 
"option": "operation", "value": "FIND_DOCUMENT_BY_KEY", "carriers": [ "text" ] 
}, { "option": "operation", "value": "DELETE_DOCUMENT", "carriers": [ "text", 
"list" ] }, { "option": "operation", "value": "AQL_QUERY", "carriers": [ "text" 
] }, { "option": "operation", "value": "SAVE_VERTEX", "carriers": [ "map", 
"pojo" ] }, { "option": "operation", "value": "UPDATE_VERTEX", "carriers": [ 
"map", "pojo" ] }, { "option [...]
-    "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option": 
"operation", "value": "SAVE_DOCUMENT", "carriers": [ "pojo" ] }, { "option": 
"operation", "value": "FIND_DOCUMENT_BY_KEY", "carriers": [ "pojo", "null" ] }, 
{ "option": "operation", "value": "UPDATE_DOCUMENT", "carriers": [ "pojo" ] }, 
{ "option": "operation", "value": "DELETE_DOCUMENT", "carriers": [ "pojo" ] }, 
{ "option": "operation", "value": "AQL_QUERY", "carriers": [ "list" ] }, { 
"option": "operation", "valu [...]
+    "producerIn": { "carriers": [ "map", "pojo", "list" ], "byOption": [ { 
"option": "operation", "value": "FIND_DOCUMENT_BY_KEY", "carriers": [ "text" ] 
}, { "option": "operation", "value": "DELETE_DOCUMENT", "carriers": [ "text", 
"list" ] }, { "option": "operation", "value": "AQL_QUERY", "carriers": [ "text" 
] }, { "option": "operation", "value": "SAVE_VERTEX", "carriers": [ "map", 
"pojo" ] }, { "option": "operation", "value": "UPDATE_VERTEX", "carriers": [ 
"map", "pojo" ] }, { "option [...]
+    "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option": 
"operation", "value": "SAVE_DOCUMENT", "carriers": [ "pojo" ] }, { "option": 
"operation", "value": "FIND_DOCUMENT_BY_KEY", "carriers": [ "pojo", "null" ] }, 
{ "option": "operation", "value": "UPDATE_DOCUMENT", "carriers": [ "pojo" ] }, 
{ "option": "operation", "value": "DELETE_DOCUMENT", "carriers": [ "pojo" ] }, 
{ "option": "operation", "value": "AQL_QUERY", "carriers": [ "list" ] }, { 
"option": "operation", "valu [...]
   },
   "properties": {
     "database": { "index": 0, "kind": "path", "displayName": "Database", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "database name" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/arangodb-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/arangodb-component.adoc
index 5c2f11e54c3a..9f5e4f6ec1d0 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/arangodb-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/arangodb-component.adoc
@@ -40,6 +40,9 @@ include::partial$component-endpoint-options.adoc[]
 include::partial$component-endpoint-headers.adoc[]
 // component options: END
 
+The `operation` option must be set, on the endpoint or on the component 
configuration: there is no default
+operation, and a route that sends to an arangodb endpoint without it fails to 
start.
+
 == Examples
 
 === Producer Examples
@@ -90,6 +93,9 @@ myObject.addAttribute("a", "Foo");
 myObject.addAttribute("b", 42);
 ----
 
+A `Collection` body, such as a `List` of documents, saves each of them as a 
document, with or without the
+`CamelArangoDbMultiInsert` header, and the body after the operation is a 
`MultiDocumentEntity`.
+
 ==== Query a collection
 
 [tabs]
diff --git 
a/components/camel-arangodb/src/generated/resources/META-INF/org/apache/camel/component/arangodb/arangodb.json
 
b/components/camel-arangodb/src/generated/resources/META-INF/org/apache/camel/component/arangodb/arangodb.json
index 95771e01e237..7b993b243d96 100644
--- 
a/components/camel-arangodb/src/generated/resources/META-INF/org/apache/camel/component/arangodb/arangodb.json
+++ 
b/components/camel-arangodb/src/generated/resources/META-INF/org/apache/camel/component/arangodb/arangodb.json
@@ -50,8 +50,8 @@
     "CamelArangoDbAqlOptions": { "index": 7, "kind": "header", "displayName": 
"", "group": "advanced", "label": "advanced", "required": false, "javaType": 
"com.arangodb.model.AqlQueryOptions", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "The additional options 
that will be passed to the query API.", "constantName": 
"org.apache.camel.component.arangodb.ArangoDbConstants#AQL_QUERY_OPTIONS" }
   },
   "bodyTypes": {
-    "producerIn": { "carriers": [ "map", "pojo", "list" ], "byOption": [ { 
"option": "operation", "value": "FIND_DOCUMENT_BY_KEY", "carriers": [ "text" ] 
}, { "option": "operation", "value": "DELETE_DOCUMENT", "carriers": [ "text", 
"list" ] }, { "option": "operation", "value": "AQL_QUERY", "carriers": [ "text" 
] }, { "option": "operation", "value": "SAVE_VERTEX", "carriers": [ "map", 
"pojo" ] }, { "option": "operation", "value": "UPDATE_VERTEX", "carriers": [ 
"map", "pojo" ] }, { "option [...]
-    "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option": 
"operation", "value": "SAVE_DOCUMENT", "carriers": [ "pojo" ] }, { "option": 
"operation", "value": "FIND_DOCUMENT_BY_KEY", "carriers": [ "pojo", "null" ] }, 
{ "option": "operation", "value": "UPDATE_DOCUMENT", "carriers": [ "pojo" ] }, 
{ "option": "operation", "value": "DELETE_DOCUMENT", "carriers": [ "pojo" ] }, 
{ "option": "operation", "value": "AQL_QUERY", "carriers": [ "list" ] }, { 
"option": "operation", "valu [...]
+    "producerIn": { "carriers": [ "map", "pojo", "list" ], "byOption": [ { 
"option": "operation", "value": "FIND_DOCUMENT_BY_KEY", "carriers": [ "text" ] 
}, { "option": "operation", "value": "DELETE_DOCUMENT", "carriers": [ "text", 
"list" ] }, { "option": "operation", "value": "AQL_QUERY", "carriers": [ "text" 
] }, { "option": "operation", "value": "SAVE_VERTEX", "carriers": [ "map", 
"pojo" ] }, { "option": "operation", "value": "UPDATE_VERTEX", "carriers": [ 
"map", "pojo" ] }, { "option [...]
+    "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option": 
"operation", "value": "SAVE_DOCUMENT", "carriers": [ "pojo" ] }, { "option": 
"operation", "value": "FIND_DOCUMENT_BY_KEY", "carriers": [ "pojo", "null" ] }, 
{ "option": "operation", "value": "UPDATE_DOCUMENT", "carriers": [ "pojo" ] }, 
{ "option": "operation", "value": "DELETE_DOCUMENT", "carriers": [ "pojo" ] }, 
{ "option": "operation", "value": "AQL_QUERY", "carriers": [ "list" ] }, { 
"option": "operation", "valu [...]
   },
   "properties": {
     "database": { "index": 0, "kind": "path", "displayName": "Database", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "database name" },
diff --git a/components/camel-arangodb/src/main/docs/arangodb-component.adoc 
b/components/camel-arangodb/src/main/docs/arangodb-component.adoc
index 5c2f11e54c3a..9f5e4f6ec1d0 100644
--- a/components/camel-arangodb/src/main/docs/arangodb-component.adoc
+++ b/components/camel-arangodb/src/main/docs/arangodb-component.adoc
@@ -40,6 +40,9 @@ include::partial$component-endpoint-options.adoc[]
 include::partial$component-endpoint-headers.adoc[]
 // component options: END
 
+The `operation` option must be set, on the endpoint or on the component 
configuration: there is no default
+operation, and a route that sends to an arangodb endpoint without it fails to 
start.
+
 == Examples
 
 === Producer Examples
@@ -90,6 +93,9 @@ myObject.addAttribute("a", "Foo");
 myObject.addAttribute("b", 42);
 ----
 
+A `Collection` body, such as a `List` of documents, saves each of them as a 
document, with or without the
+`CamelArangoDbMultiInsert` header, and the body after the operation is a 
`MultiDocumentEntity`.
+
 ==== Query a collection
 
 [tabs]
diff --git 
a/components/camel-arangodb/src/main/java/org/apache/camel/component/arangodb/ArangoDbEndpoint.java
 
b/components/camel-arangodb/src/main/java/org/apache/camel/component/arangodb/ArangoDbEndpoint.java
index 937a9b7debdb..1a709db8b0eb 100644
--- 
a/components/camel-arangodb/src/main/java/org/apache/camel/component/arangodb/ArangoDbEndpoint.java
+++ 
b/components/camel-arangodb/src/main/java/org/apache/camel/component/arangodb/ArangoDbEndpoint.java
@@ -65,8 +65,10 @@ import org.apache.camel.util.ObjectHelper;
                                           @BodyType.When(option = "operation", 
value = "DELETE_EDGE",
                                                          carriers = 
Carrier.TEXT) },
                                   description = "By the operation: the 
document to save or update as a Map or a POJO (a"
-                                                + " List of them with the 
CamelArangoDbMultiInsert or CamelArangoDbMultiUpdate"
-                                                + " header), the key as text 
to find or delete (a List of keys with"
+                                                + " Collection of them saves 
several, with or without the"
+                                                + " CamelArangoDbMultiInsert 
header, and a List of them with the"
+                                                + " CamelArangoDbMultiUpdate 
header updates several), the key as text to find"
+                                                + " or delete (a List of keys 
with"
                                                 + " CamelArangoDbMultiDelete), 
and the AQL query as text unless the"
                                                 + " CamelArangoDbAqlQuery 
header has it. JSON text, bytes or a stream is not a"
                                                 + " document: unmarshal it to 
a Map first. The key of an update is the"
@@ -99,9 +101,11 @@ import org.apache.camel.util.ObjectHelper;
                                                           javaType = 
"com.arangodb.entity.EdgeUpdateEntity"),
                                            @BodyType.When(option = 
"operation", value = "DELETE_EDGE", carriers = Carrier.VALUE,
                                                           javaType = 
"java.lang.Boolean") },
-                                   description = "By the operation, which must 
be set: the result entity of the ArangoDB"
+                                   description = "By the operation, which must 
be set (the producer fails to start"
+                                                 + " without it): the result 
entity of the ArangoDB"
                                                  + " driver 
(DocumentCreateEntity, DocumentUpdateEntity,"
-                                                 + " DocumentDeleteEntity, or 
a MultiDocumentEntity for the multi headers)"
+                                                 + " DocumentDeleteEntity, or 
a MultiDocumentEntity for the multi headers"
+                                                 + " and a Collection saved)"
                                                  + " for the document writes; 
the document found as a BaseDocument (or"
                                                  + " BaseEdgeDocument), or of 
the class in the CamelArangoDbResultClassType"
                                                  + " header, or null when 
there is none; a List of the AQL results, empty for"
@@ -145,6 +149,12 @@ public class ArangoDbEndpoint extends DefaultEndpoint 
implements EndpointService
     }
 
     public Producer createProducer() {
+        // there is no default operation, nor a header for it: fail when the 
route starts, not on each message
+        if (configuration.getOperation() == null) {
+            throw new IllegalArgumentException(
+                    "The operation option must be set on the arangodb 
endpoint, or on the component configuration,"
+                                               + " for example 
operation=SAVE_DOCUMENT: the producer has no default operation");
+        }
         return new ArangoDbProducer(this);
     }
 
diff --git 
a/components/camel-arangodb/src/main/java/org/apache/camel/component/arangodb/ArangoDbProducer.java
 
b/components/camel-arangodb/src/main/java/org/apache/camel/component/arangodb/ArangoDbProducer.java
index 7e0e7a5e924d..26bc657dd8c9 100644
--- 
a/components/camel-arangodb/src/main/java/org/apache/camel/component/arangodb/ArangoDbProducer.java
+++ 
b/components/camel-arangodb/src/main/java/org/apache/camel/component/arangodb/ArangoDbProducer.java
@@ -120,8 +120,10 @@ public class ArangoDbProducer extends DefaultProducer {
                 ArangoCollection collection = calculateDocumentCollection();
                 boolean isMultiInsert = 
exchange.getMessage().getHeader(MULTI_INSERT, false, Boolean.class);
 
-                // save multiple document
-                if (isMultiInsert) {
+                // save multiple documents: with the header, or for a 
Collection body, which ArangoDB always inserts
+                // as several documents (insertDocument would insert them, 
then fail to read the reply, so a retry
+                // would insert them again)
+                if (isMultiInsert || exchange.getMessage().getBody() 
instanceof Collection) {
                     Collection<Object> objects = 
exchange.getMessage().getMandatoryBody(Collection.class);
                     return collection.insertDocuments(objects);
                 }
diff --git 
a/components/camel-arangodb/src/test/java/org/apache/camel/component/arangodb/ArangoDbProducerTest.java
 
b/components/camel-arangodb/src/test/java/org/apache/camel/component/arangodb/ArangoDbProducerTest.java
new file mode 100644
index 000000000000..1cb201da7825
--- /dev/null
+++ 
b/components/camel-arangodb/src/test/java/org/apache/camel/component/arangodb/ArangoDbProducerTest.java
@@ -0,0 +1,195 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.arangodb;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import com.arangodb.ArangoDB;
+import com.arangodb.Protocol;
+import com.arangodb.entity.DocumentCreateEntity;
+import com.arangodb.entity.MultiDocumentEntity;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpServer;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.spi.Registry;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * The producer against a fake of the document API of ArangoDB, which, like 
the server, inserts a JSON array as several
+ * documents and replies with an array.
+ */
+class ArangoDbProducerTest extends CamelTestSupport {
+
+    private static final String DOCUMENT_API = 
"/_db/testDb/_api/document/coll";
+
+    private final List<String> requests = new CopyOnWriteArrayList<>();
+    private HttpServer server;
+
+    @Override
+    protected void setupResources() throws Exception {
+        super.setupResources();
+        server = HttpServer.create(new InetSocketAddress("localhost", 0), 0);
+        server.createContext("/", this::reply);
+        server.start();
+    }
+
+    @Override
+    protected void cleanupResources() throws Exception {
+        if (server != null) {
+            server.stop(0);
+        }
+        super.cleanupResources();
+    }
+
+    @Override
+    protected void bindToRegistry(Registry registry) {
+        registry.bind("arangoDB", newClient());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                
from("direct:save").to("arangodb:testDb?documentCollection=coll&operation=SAVE_DOCUMENT");
+            }
+        };
+    }
+
+    @Test
+    void saveDocumentOfAListInsertsTheDocumentsOnce() {
+        List<Map<String, Object>> documents = List.of(Map.of("name", "foo"), 
Map.of("name", "bar"));
+
+        Exchange result = template.request("direct:save", exchange -> 
exchange.getMessage().setBody(documents));
+
+        // the server inserted the documents, so the exchange must not fail, 
or a retry would insert them again
+        assertNull(result.getException(), () -> "the exchange failed with " + 
result.getException());
+        MultiDocumentEntity<?> created = 
assertInstanceOf(MultiDocumentEntity.class, result.getMessage().getBody());
+        assertEquals(2, created.getDocuments().size());
+        assertEquals(1, requests.size(), requests::toString);
+        assertTrue(requests.get(0).startsWith("POST " + DOCUMENT_API + " ["), 
requests.get(0));
+    }
+
+    @Test
+    void saveDocumentOfOneDocumentInsertsOne() {
+        Exchange result = template.request("direct:save", exchange -> 
exchange.getMessage().setBody(Map.of("name", "foo")));
+
+        assertNull(result.getException(), () -> "the exchange failed with " + 
result.getException());
+        assertInstanceOf(DocumentCreateEntity.class, 
result.getMessage().getBody());
+        assertEquals(1, requests.size(), requests::toString);
+        assertTrue(requests.get(0).startsWith("POST " + DOCUMENT_API + " {"), 
requests.get(0));
+    }
+
+    @Test
+    void routeWithoutOperationFailsToStart() throws Exception {
+        try (CamelContext camel = new DefaultCamelContext()) {
+            camel.getRegistry().bind("arangoDB", newClient());
+            camel.addRoutes(saveRoute());
+
+            Exception error = assertThrows(Exception.class, camel::start);
+
+            Throwable cause = error;
+            while (cause.getCause() != null) {
+                cause = cause.getCause();
+            }
+            assertInstanceOf(IllegalArgumentException.class, cause, () -> "the 
context failed with " + error);
+            assertTrue(cause.getMessage().contains("The operation option must 
be set"), cause.getMessage());
+        }
+        assertTrue(requests.isEmpty(), requests::toString);
+    }
+
+    @Test
+    void operationOfTheComponentConfigurationIsEnough() throws Exception {
+        try (CamelContext camel = new DefaultCamelContext()) {
+            camel.getRegistry().bind("arangoDB", newClient());
+            camel.getComponent("arangodb", 
ArangoDbComponent.class).getConfiguration()
+                    .setOperation(ArangoDbOperation.SAVE_DOCUMENT);
+            camel.addRoutes(saveRoute());
+            camel.start();
+
+            try (ProducerTemplate producer = camel.createProducerTemplate()) {
+                Object body = producer.requestBody("direct:save", 
Map.of("name", "foo"));
+
+                assertInstanceOf(DocumentCreateEntity.class, body);
+            }
+        }
+    }
+
+    /**
+     * A route that sends to an arangodb endpoint without the operation option.
+     */
+    private static RouteBuilder saveRoute() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                
from("direct:save").to("arangodb:testDb?documentCollection=coll");
+            }
+        };
+    }
+
+    private ArangoDB newClient() {
+        // HTTP/1.1, which the JDK HTTP server speaks
+        return new ArangoDB.Builder()
+                .host("localhost", server.getAddress().getPort())
+                .protocol(Protocol.HTTP_JSON)
+                .build();
+    }
+
+    private void reply(HttpExchange http) throws IOException {
+        String body = new String(http.getRequestBody().readAllBytes(), 
StandardCharsets.UTF_8).trim();
+        String path = http.getRequestURI().getPath();
+        requests.add(http.getRequestMethod() + " " + path + " " + body);
+
+        int status;
+        String reply;
+        if ("POST".equals(http.getRequestMethod()) && 
DOCUMENT_API.equals(path)) {
+            status = 202;
+            // the tests send one document, or an array of two
+            reply = body.startsWith("[") ? "[" + created(1) + "," + created(2) 
+ "]" : created(1);
+        } else {
+            status = 404;
+            reply = 
"{\"error\":true,\"code\":404,\"errorNum\":1203,\"errorMessage\":\"unknown path 
" + path + "\"}";
+        }
+        byte[] bytes = reply.getBytes(StandardCharsets.UTF_8);
+        http.getResponseHeaders().add("Content-Type", "application/json; 
charset=utf-8");
+        http.sendResponseHeaders(status, bytes.length);
+        try (OutputStream out = http.getResponseBody()) {
+            out.write(bytes);
+        }
+    }
+
+    private static String created(int key) {
+        return "{\"_id\":\"coll/" + key + "\",\"_key\":\"" + key + 
"\",\"_rev\":\"_r" + key + "\"}";
+    }
+}
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 b75ab007c613..fca9a0dfcd2f 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
@@ -4593,6 +4593,16 @@ credentials. A deployment that counted on the inherited 
list as a restriction ha
 A consumer whose `requestUriPattern` is `/` now also uses its own keys, 
certificates and asynchronous MDN settings when
 another consumer created the shared server connection; before, it used the 
first consumer's.
 
+=== camel-arangodb - the operation option is required, and a Collection body 
is saved as several documents
+
+A route that sends to an `arangodb` endpoint without the `operation` option, 
set on the endpoint or on the component
+configuration, now fails to start with a message that names the option. 
Before, the route started and each message
+failed with `Operation not supported. Value: null`.
+
+The `SAVE_DOCUMENT` operation now inserts a `Collection` body, such as a 
`List` of documents, as several documents, as
+it does with the `CamelArangoDbMultiInsert` header, and the body after it is a 
`MultiDocumentEntity`. Before, without
+the header, ArangoDB inserted the documents and the exchange then failed, so a 
redelivery inserted them again.
+
 === camel-ftp, camel-sftp, camel-ftps, camel-mina-sftp - sendNoop also applies 
to the consumer
 
 The `sendNoop` option now also applies to the check a consumer makes before 
each poll, not only to the pre-write check

Reply via email to