You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by gn...@apache.org on 2026/03/19 19:39:50 UTC
(camel) 03/05: CAMEL-23218: Improve docs with migration guide and enhance test coverage
This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a commit to branch CAMEL-23218
in repository https://gitbox.apache.org/repos/asf/camel.git
commit a361743933cc4b01f8cedb22ec78c91a07be19d5
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Thu Mar 19 16:27:29 2026 +0100
CAMEL-23218: Improve docs with migration guide and enhance test coverage
- Add migration table showing how to convert view options to SQL++ equivalents
- Document both query modes (SQL++ recommended, Views deprecated)
- Add test for fullDocument=false (raw query result) mode
- Verify HEADER_ID is set correctly in SQL++ consumer
- Trim upgrade guide to focus on deprecation notice only
Co-Authored-By: Claude Opus 4.6 <no...@anthropic.com>
---
.../src/main/docs/couchbase-component.adoc | 71 +++++++++++++++++++++-
.../couchbase/integration/ConsumeSqlQueryIT.java | 46 +++++++++++---
.../ROOT/pages/camel-4x-upgrade-guide-4_19.adoc | 9 ++-
3 files changed, 111 insertions(+), 15 deletions(-)
diff --git a/components/camel-couchbase/src/main/docs/couchbase-component.adoc b/components/camel-couchbase/src/main/docs/couchbase-component.adoc
index 6032f18f8bf3..ea909aab8339 100644
--- a/components/camel-couchbase/src/main/docs/couchbase-component.adoc
+++ b/components/camel-couchbase/src/main/docs/couchbase-component.adoc
@@ -44,10 +44,14 @@ include::partial$component-endpoint-options.adoc[]
include::partial$component-endpoint-headers.adoc[]
// component options: END
-== Consuming with SQL++ (N1QL) queries
+== Consuming documents
-Since Couchbase Server 7.0, the recommended way to query documents is using SQL++ (formerly N1QL) instead of
-MapReduce Views, which are deprecated since Couchbase 7.0 and do not work with the Magma storage backend
+The consumer supports two query modes for polling documents from Couchbase:
+
+=== SQL++ queries (recommended)
+
+Since Couchbase Server 7.0, the recommended way to query documents is using SQL++ (formerly N1QL).
+MapReduce Views are deprecated since Couchbase 7.0 and do not work with the Magma storage backend
(default since Couchbase 8.0).
To use SQL++ queries, set the `statement` endpoint option:
@@ -66,6 +70,67 @@ the document ID. When `false`, the query result row is used directly as the mess
NOTE: SQL++ queries require a primary index or appropriate secondary index on the bucket/collection.
Create one with: `CREATE PRIMARY INDEX ON \`myBucket\`` or via the Couchbase SDK.
+=== MapReduce Views (deprecated)
+
+The consumer can also poll documents using MapReduce Views via the `designDocumentName` and `viewName`
+endpoint options. This mode is deprecated and will be removed in a future release.
+
+[source,java]
+----
+from("couchbase:http://localhost?bucket=myBucket&username=user&password=pass"
+ + "&designDocumentName=myDoc&viewName=myView&limit=10")
+ .to("direct:result");
+----
+
+=== Migrating from Views to SQL++
+
+The following table shows how to migrate from MapReduce View options to equivalent SQL++ queries:
+
+[cols="1,1,2",options="header"]
+|===
+| View option | SQL++ equivalent | Example
+
+| `designDocumentName` + `viewName`
+| `statement`
+| The view's map function determines what is emitted. Write an equivalent SQL++ query with a `WHERE` clause.
+
+| `limit=10`
+| `LIMIT 10` in the query
+| `SELECT META().id AS \__id, * FROM \`bucket\` LIMIT 10`
+
+| `skip=5`
+| `OFFSET 5` in the query
+| `SELECT META().id AS \__id, * FROM \`bucket\` LIMIT 10 OFFSET 5`
+
+| `descending=true`
+| `ORDER BY ... DESC` in the query
+| `SELECT META().id AS \__id, * FROM \`bucket\` ORDER BY META().id DESC`
+
+| `rangeStartKey` / `rangeEndKey`
+| `WHERE` clause in the query
+| `SELECT META().id AS \__id, * FROM \`bucket\` WHERE META().id >= 'start' AND META().id \<= 'end'`
+
+| `fullDocument=true`
+| Works the same way
+| When `true`, the consumer fetches the full document via KV get regardless of query mode.
+|===
+
+For example, a view-based consumer like:
+
+[source,java]
+----
+from("couchbase:http://localhost?bucket=myBucket&username=user&password=pass"
+ + "&designDocumentName=myDoc&viewName=myView&limit=10&descending=true")
+----
+
+Can be migrated to:
+
+[source,java]
+----
+from("couchbase:http://localhost?bucket=myBucket&username=user&password=pass"
+ + "&statement=SELECT META().id AS __id, * FROM `myBucket` ORDER BY META().id DESC LIMIT 10")
+----
+
== Couchbase SDK compatibility
Using collections and scopes is supported only for Couchbase Server 7.0 and later.
diff --git a/components/camel-couchbase/src/test/java/org/apache/camel/component/couchbase/integration/ConsumeSqlQueryIT.java b/components/camel-couchbase/src/test/java/org/apache/camel/component/couchbase/integration/ConsumeSqlQueryIT.java
index d97cd6f4e4ef..d8bd01a37b01 100644
--- a/components/camel-couchbase/src/test/java/org/apache/camel/component/couchbase/integration/ConsumeSqlQueryIT.java
+++ b/components/camel-couchbase/src/test/java/org/apache/camel/component/couchbase/integration/ConsumeSqlQueryIT.java
@@ -23,7 +23,9 @@ import com.couchbase.client.java.Cluster;
import com.couchbase.client.java.manager.bucket.BucketSettings;
import com.couchbase.client.java.manager.bucket.BucketType;
import com.couchbase.client.java.manager.query.CreatePrimaryQueryIndexOptions;
+import org.apache.camel.Exchange;
import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.couchbase.CouchbaseConstants;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.test.infra.common.TestUtils;
import org.apache.camel.test.infra.couchbase.services.CouchbaseService;
@@ -39,6 +41,9 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
import org.junit.jupiter.api.extension.RegisterExtension;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
@DisabledIfSystemProperty(named = "ci.env.name", matches = ".*",
disabledReason = "Too resource intensive for most systems to run reliably")
@Tags({ @Tag("couchbase-71") })
@@ -79,11 +84,33 @@ public class ConsumeSqlQueryIT extends CamelTestSupport {
}
@Test
- public void testConsumeWithSqlQuery() throws Exception {
- MockEndpoint mock = getMockEndpoint("mock:result");
- mock.expectedMessageCount(10);
+ public void testConsumeWithSqlQueryAndFullDocument() throws Exception {
+ MockEndpoint mock = getMockEndpoint("mock:fullDoc");
+ mock.expectedMinimumMessageCount(10);
+
+ MockEndpoint.assertIsSatisfied(context, 30, TimeUnit.SECONDS);
+
+ // Verify headers are set correctly
+ for (Exchange exchange : mock.getReceivedExchanges()) {
+ String id = exchange.getIn().getHeader(CouchbaseConstants.HEADER_ID, String.class);
+ assertNotNull(id, "Document ID header should be set");
+ assertTrue(id.startsWith("DocumentID_"), "Document ID should match inserted documents");
+ }
+ }
+
+ @Test
+ public void testConsumeWithSqlQueryRawResult() throws Exception {
+ MockEndpoint mock = getMockEndpoint("mock:raw");
+ mock.expectedMinimumMessageCount(5);
MockEndpoint.assertIsSatisfied(context, 30, TimeUnit.SECONDS);
+
+ // With fullDocument=false, body should be the SQL++ query result row (a JSON string)
+ for (Exchange exchange : mock.getReceivedExchanges()) {
+ Object body = exchange.getIn().getBody();
+ assertNotNull(body, "Body should not be null");
+ assertTrue(body instanceof String, "Body should be a String (JSON row)");
+ }
}
@AfterEach
@@ -107,10 +134,15 @@ public class ConsumeSqlQueryIT extends CamelTestSupport {
return new RouteBuilder() {
@Override
public void configure() {
- String query = "SELECT META().id AS __id, * FROM `" + bucketName + "` LIMIT 10";
- from(getConnectionUri() + "&statement=" + query)
- .log("message received via SQL++")
- .to("mock:result");
+ // SQL++ with fullDocument=true (default) — fetches complete document via KV get
+ String fullDocQuery = "SELECT META().id AS __id, * FROM `" + bucketName + "` LIMIT 10";
+ from(getConnectionUri() + "&statement=" + fullDocQuery)
+ .to("mock:fullDoc");
+
+ // SQL++ with fullDocument=false — uses raw query result row as body
+ String rawQuery = "SELECT META().id AS __id, * FROM `" + bucketName + "` LIMIT 5";
+ from(getConnectionUri() + "&statement=" + rawQuery + "&fullDocument=false")
+ .to("mock:raw");
}
};
}
diff --git a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_19.adoc b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_19.adoc
index 39fdb2a5cdd2..bd1f030c5aca 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_19.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_19.adoc
@@ -401,13 +401,12 @@ HttpRequest request = context.getRequest();
=== camel-couchbase
-The consumer now supports SQL++ (N1QL) queries as an alternative to the deprecated MapReduce Views.
-Use the new `statement` endpoint option to specify a SQL++ query. When `statement` is set, the consumer
-uses `scope.query()` instead of `bucket.viewQuery()`.
-
The `designDocumentName` and `viewName` endpoint options are now deprecated. MapReduce Views were
deprecated in Couchbase Server 7.0 and do not work with the Magma storage backend (default since
-Couchbase Server 8.0). Users should migrate to SQL++ queries using the `statement` option.
+Couchbase Server 8.0).
+
+A new `statement` endpoint option has been added to support SQL++ (N1QL) queries as the recommended
+alternative. See the component documentation for migration guidance.
=== camel-ftp