diff --git a/modules/hello-world/pages/overview.adoc b/modules/hello-world/pages/overview.adoc index 00bc12e..9b1736c 100644 --- a/modules/hello-world/pages/overview.adoc +++ b/modules/hello-world/pages/overview.adoc @@ -6,7 +6,7 @@ = .NET Analytics SDK -The .NET Analytics SDK allows you to connect to an Enterprise Analytics cluster from Java. +The .NET Analytics SDK allows you to connect to an Enterprise Analytics cluster using C#. For connecting to a Couchbase Server Cluster -- self-managed, or Capella Operational -- see our xref:dotnet-sdk:hello-world:overview.adoc[.NET Operational SDK]. diff --git a/modules/hello-world/pages/start-using-sdk.adoc b/modules/hello-world/pages/start-using-sdk.adoc index bfe224e..719e8e3 100644 --- a/modules/hello-world/pages/start-using-sdk.adoc +++ b/modules/hello-world/pages/start-using-sdk.adoc @@ -20,87 +20,56 @@ Install and configure an xref:enterprise-analytics:intro:intro.adoc[Enterprise A // After creating the cluster, add your IP address to the list of allowed IP addresses. // TODO: Link to https://docs.couchbase.com/columnar/admin/ip-allowed-list.html -[#minimum-java-version] -=== Minimum Java Version +[#minimum-dotnet-version] +=== Minimum .NET Version -The {name-sdk} requires Java 8 or later. -We recommend using the most recent long-term support (LTS) version of OpenJDK. +The {name-sdk} requires .NET 8 or later. +We recommend using the most recent long-term support (LTS) version of .NET. -TIP: Remember to keep your Java installation up to date with the latest patches. +== Adding the SDK to an Existing Project -[maven-project-template] -== Maven Project Template +Add the NuGet package to your `*.csproj` file, or add it using the command line: -The SDK's source code repository includes an -https://github.com/couchbaselabs/couchbase-analytics-jvm-clients/tree/main/couchbase-analytics-java-client/examples/maven-project-template[example Maven project] -you can copy to get started quickly. +[source,shell] +---- +dotnet add package Couchbase.AnalyticsClient +---- -== Adding the SDK to an Existing Project +[source,xml] +---- + +---- -Declare a dependency on the SDK using its xref:project-docs:sdk-full-installation.adoc[]. -To see log messages from the SDK, xref:howtos:logging.adoc[include an SLF4J binding in your project]. [quickstart] == Connecting and Executing a Query -[source,java] +[source,csharp] ---- -import com.couchbase.analytics.client.java.Cluster; -import com.couchbase.analytics.client.java.Credential; -import com.couchbase.analytics.client.java.QueryResult; - -import java.util.List; - -public class Example { - public static void main(String[] args) { - var connectionString = "https://:" + PORT; - var username = "..."; - var password = "..."; - - try (Cluster cluster = Cluster.newInstance( - connectionString, - Credential.of(username, password), - // The third parameter is optional. - // This example sets the default query timeout to 2 minutes. - clusterOptions -> clusterOptions - .timeout(it -> it.queryTimeout(Duration.ofMinutes(2))) - )) { - - // Execute a query and buffer all result rows in client memory. - QueryResult result = cluster.executeQuery("select 1"); - result.rows().forEach(row -> System.out.println("Got row: " + row)); - - // Execute a query and process rows as they arrive from server. - cluster.executeStreamingQuery( - "select 1", - row -> System.out.println("Got row: " + row) - ); - - // Execute a streaming query with positional arguments. - cluster.executeStreamingQuery( - "select ?=1", - row -> System.out.println("Got row: " + row), - options -> options - .parameters(List.of(1)) - ); - - // Execute a streaming query with named arguments. - cluster.executeStreamingQuery( - "select $foo=1", - row -> System.out.println("Got row: " + row), - options -> options - .parameters(Map.of("foo", 1)) - ); - } - } +using Couchbase.AnalyticsClient; +using Couchbase.AnalyticsClient.HTTP; +using Couchbase.AnalyticsClient.Options; + +var credential = Credential.Create("username", "password"); + +var cluster = Cluster.Create( + connectionString: "https://analytics.my-couchbase.example.com:18095", + credential: credential) +); + +var result = await cluster.ExecuteQueryAsync("SELECT i from ARRAY_RANGE(1, 100) AS i;").ConfigureAwait(false); + +await foreach (var row in result.ConfigureAwait(false)) +{ + Console.WriteLine(row.ContentAs()); } ---- === Connection String -The `connStr` in the above example should take the form of "https://:" + PORT +The `connectionString` in the above example should take the form of "https://:" + PORT include::{version-common}@analytics-sdk:shared:partial$connstr.adoc[tag=connstr] diff --git a/modules/howtos/pages/logging.adoc b/modules/howtos/pages/logging.adoc index 150ab14..f8abd8e 100644 --- a/modules/howtos/pages/logging.adoc +++ b/modules/howtos/pages/logging.adoc @@ -1,6 +1,6 @@ = Logging :page-toclevels: 2 -:description: Configuring logging with the Columnar Java SDK. +:description: Configuring logging with the .NET Analytics SDK. [abstract] {description} @@ -10,186 +10,52 @@ The {name-sdk} emits log messages that can help with troubleshooting. == Logging -The {name-sdk} uses https://www.slf4j.org[SLF4J], a logging façade that lets you use any logging framework that has an SLF4J binding. -This includes popular Java logging frameworks like Log4j, Logback, and `java.util.logging` (JUL). +An `ILoggerFactory` can be provided to the `ClusterOptions` when creating a `Cluster`. -To see log messages from the Couchbase SDK, add an SLF4J binding as a dependency of your project. - -[slf4j-api-versions] -.SLF4J API versions +[example-usage] +.Using Serilog [NOTE] ==== -At the time of writing, there are two different versions of the SLF4J API: - -*Version 2* is the modern version of SLF4J. -It is actively maintained, and recommended for most users. - -*Version 1.7* is no longer maintained, but you can still use it if your preferred SLF4J binding does not support version 2. - -The Couchbase SDK is compatible with both versions of the SLF4J API. -The SDK's Maven POM has a dependency on version 1.7, but you can override this by using version 2 in your project. -==== - -[log4j2] -=== Using Log4j 2 - -Log4j 2 is a popular and flexible logging framework. -This section shows how to configure your project to use Log4j 2 with the Couchbase SDK. - -First, add an https://logging.apache.org/log4j/2.x/log4j-slf4j-impl.html[SLF4J binding for Log4j 2] as a dependency of your project. -The following example uses the binding for SLF4J API version 2. - -[{tabs}] -==== -Maven:: -+ --- -Add these as children of the `dependencies` element. - -.`*pom.xml*` -[source,xml] ----- - - org.apache.logging.log4j - log4j-slf4j2-impl - 2.22.0 - - - - - org.slf4j - slf4j-api - 2.0.9 - ----- - -TIP: An alternate way to ensure Maven uses the correct version of the SLF4J API is to declare the dependency on `log4j-slf4j2-impl` *before* the dependency on the Couchbase SDK. -See the Maven documentation on https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Transitive_Dependencies[Transitive Dependencies] to learn more about how Maven resolves transitive dependency version conflicts. --- -Gradle:: -+ --- -.`*build.gradle*` -[source,groovy] ----- -// Add this to the `dependencies` section: -implementation("org.apache.logging.log4j:log4j-slf4j2-impl:2.22.0") ----- -NOTE: Gradle automatically uses the correct SLF4J API 2.x dependency required by `log4j-slf4j2-impl`, even though the Couchbase SDK declares a dependency on SLF4J API 1.7. --- -==== - -[configuring-log4j] -==== Configuring Log4j 2 output - -Log4j 2 needs a configuration file to tell it which messages to log, where to write them, and how each message should be formatted. -Here's an example `log4j2.xml` configuration file you can use to get started. -It tells Log4j 2 to log messages to the console, and sets some reasonable logging levels. +Using `Serilog` and wiring it to the SDK's `Microsoft.Extensions.Logging` API: -TIP: If your project uses the https://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html[Maven Standard Directory Layout], this file should live in the `src/main/resources` directory. -This makes it available at runtime as a class path resource. - -.src/main/resources/log4j2.xml -[source,xml] +[source,csharp] ---- - - - - - - - - - - +Log.Logger = new LoggerConfiguration() + .MinimumLevel.Is(LogEventLevel.Debug) + .Enrich.FromLogContext() + .WriteTo.Console() + .WriteTo.File( + path: "Logs/my-logs.log", + rollingInterval: RollingInterval.Day, + shared: true) + .CreateLogger(); - - +var loggerFactory = LoggerFactory.Create(builder => +{ + builder.ClearProviders(); + builder.AddSerilog(); +}); - - - - - - ----- +var clusterOptions = new ClusterOptions().WithLogging(loggerFactory); -Consult the https://logging.apache.org/log4j/2.x/manual/configuration.html[Log4J 2 configuration documentation^] for more information and advanced configuration options. - -[jul] -=== Using `java.util.logging` (JUL) - -If `java.util.logging` (JUL) is your preferred logging framework, add the `slf4j-jdk14` SLF4J binding as dependency of your project. - -[{tabs}] -==== -Maven:: -+ --- -Add these as children of the `dependencies` element. +var credential = Credential.Create("username", "password"); -.`*pom.xml*` -[source,xml] +var cluster = Cluster.Create( + connectionString: "https://analytics.my-couchbase.example.com:18095", + credential: credential, + clusterOptions: clusterOptions +); ---- - - org.slf4j - slf4j-jdk14 - 2.0.9 - - - - - org.slf4j - slf4j-api - 2.0.9 - ----- - -TIP: An alternate way to ensure Maven uses the correct version of the SLF4J API is to declare the dependency on `slf4j-jdk14` *before* the dependency on the Couchbase SDK. -See the Maven documentation on https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Transitive_Dependencies[Transitive Dependencies] to learn more about how Maven resolves transitive dependency version conflicts. --- -Gradle:: -+ --- -.`*build.gradle*` -[source,groovy] ----- -// Add this to your `dependencies` section: -implementation("org.slf4j:slf4j-jdk14:2.0.9") ----- -NOTE: Gradle automatically uses the correct SLF4J API 2.x dependency required by `slf4j-jdk14`, even though the Couchbase SDK declares a dependency on SLF4J API 1.7. --- ==== -[configuring-the-jdk-logger] -==== Configuring a JUL Logger - -By default, JUL logs INFO level and above. -If you want to set it to DEBUG (or the JUL equivalent: FINE) you can do it like this programmatically: - -[source,java] +.Using minimal logging without 3rd party sinks +[source,csharp] ---- -// Make sure to do this as soon as your application starts, -// and before calling `Cluster.newInstance()`. -Logger logger = Logger.getLogger("com.couchbase.client"); -logger.setLevel(Level.FINE); -for (Handler h : logger.getParent().getHandlers()) { - if (h instanceof ConsoleHandler) { - h.setLevel(Level.FINE); - } -} +var loggerFactory = LoggerFactory.Create(builder => +{ + builder.ClearProviders(); + builder.SetMinimumLevel(LogLevel.Debug); + builder.AddConsole(); +}); ---- - -TIP: We do not recommend using JUL in production. -Dedicated logging frameworks like Log4j 2 and Logback are more configurable, and tend to perform better than JUL. diff --git a/modules/howtos/pages/managing-connections.adoc b/modules/howtos/pages/managing-connections.adoc index 03dae06..91860ab 100644 --- a/modules/howtos/pages/managing-connections.adoc +++ b/modules/howtos/pages/managing-connections.adoc @@ -25,44 +25,29 @@ This page is a wider look at the topic. The examples below use these imports: -[source,java] +[source,csharp] ---- -import com.couchbase.analytics.client.java.Cluster; -import com.couchbase.analytics.client.java.Credential; -import com.couchbase.analytics.client.java.QueryResult; +using Couchbase.AnalyticsClient; +using Couchbase.AnalyticsClient.HTTP; +using Couchbase.AnalyticsClient.Options; ---- A connection to an Enterprise Analytics cluster is represented by a `Cluster` object. A `Cluster` provides access to databases, scopes, and collections, as well as various Analytics services and management interfaces. -The simplest way to create a `Cluster` object is to call `Cluster.newInstance()` with a <>, username, and password: +The simplest way to create a `Cluster` object is to call `Cluster.Create()` with a <>, username, and password: - - -[source,java] +[source,csharp] ---- -public class Example { - public static void main(String[] args) { - var connectionString = "https://192.168.5.5:18095"; - var username = "..."; - var password = "..."; +var credential = Credential.Create("username", "password"); - try (Cluster cluster = Cluster.newInstance( - connectionString, - Credential.of(username, password) - )) { - // Interact with the cluster here - } - } -} +var cluster = Cluster.Create( + connectionString: "https://analytics.my-couchbase.example.com:18095", + credential: credential); ---- -WARNING: The above example uses a `try-with-resources` block to ensure the `Cluster` instance gets closed at the end. -It's important to either use a `try-with-resources` block, or make sure to call `cluster.close()` when you're done with the cluster. - NOTE: Capella's root certificate is *not* signed by a well known Certificate Authority. However, the certificate is bundled with the SDK, and is automatically trusted unless you specify a different certificate to trust. - == Connection Strings @@ -70,51 +55,6 @@ include::{version-common}@analytics-sdk:shared:partial$connstr.adoc[tag=more-con -// For Columnar, as for all Capella products, connection must be made with Transport Layer Security (TLS) -- for full encryption of client-side traffic -- -// for which the `couchbases://` schema is used as the root of the connection string (note the trailing *s*). - -//// -==== Without Load Balancer - -.Simple connection string ----- -https://192.168.5.5:18095 ----- - -.Simple connection string without TLS (local testing) ----- -http://192.168.5.5:8095 ----- - - -==== With Load Balancer - -.Simple connection string ----- -https://192.168.5.5:443 ----- - -.Simple connection string without TLS (local testing) ----- -http://192.168.5.5:80 ----- -//// - - -//// -In a production environment, your connection string should include the addresses of multiple server nodes in case some are currently unavailable. -Multiple addresses may be specified in a connection string by delimiting them with commas: - -.Connection string with two seed nodes ----- -nodeA.example.com,nodeB.example.com ----- - -TIP: You don't need to include the address of every node in the cluster. -The client fetches the full address list from the first node it is able to contact. -//// - - .Connection string with two parameters ---- http://localhost:8095?timeout.connect_timeout=30s&timeout.query_timeout=2m @@ -123,158 +63,6 @@ http://localhost:8095?timeout.connect_timeout=30s&timeout.query_timeout=2m The full list of recognized parameters is documented in the xref:ref:client-settings.adoc[client settings reference]. -//// -Any client setting with a system property name may also be specified as a connection string parameter (without the `com.couchbase.env.` prefix). - -WARNING: When creating a `Cluster` using a custom `ClusterEnvironment`, *_connection string parameters are ignored_*, since client settings are frozen when the cluster environment is built. -//// - - -//// -=== Cluster Environment - -A `ClusterEnvironment` manages shared resources like thread pools, timers, and schedulers. -It also holds the client settings. -One way to customize the client's behavior is to build your own `ClusterEnvironment` with custom settings: - -[source,scala] ----- -include::devguide:example$scala/ManagingConnections.scala[tag=env,indent=0] ----- - -This is a verbose example for simplicity, and the user may prefer to use `flatMap` or a for-comprehension to combine the multiple `Try`. - -Note there are `com.couchbase.client.scala.env` and `com.couchbase.client.core.env` versions of all environment parameters: be sure to import the `.scala` versions. - -TIP: If you create a `Cluster` without specifying a custom environment, the client creates a default environment used exclusively by that `Cluster`. -This default `ClusterEnvironment` is managed completely by the Scala SDK, and is automatically shut down when the associated `Cluster` is disconnected. -//// - - -//// -=== Connection Lifecycle - -Most of the high-level classes in the Scala SDK are designed to be safe for concurrent use by multiple threads. -You will get the best performance if you share and reuse instances of `ClusterEnvironment`, `Cluster`, `Bucket`, `Scope`, and `Collection`, all of which are thread-safe. - -We recommend creating a single `Cluster` instance when your application starts up, and sharing this instance throughout your application. -If you know at startup time which buckets, scopes, and collections your application will use, we recommend obtaining them from the `Cluster` at startup time and sharing those instances throughout your application as well. - -Before your application stops, gracefully shut down the client by calling the `disconnect()` method of each `Cluster` you created. -If you created any `ClusterEnvironment` instances, call their `shutdown()` method after disconnecting the associated clusters. -//// - - - -//// -[#multiple-clusters] -=== Connecting to Multiple Clusters - -If a single application needs to connect to multiple Couchbase Server clusters, we recommend creating a single `ClusterEnvironment` and sharing it between the `Clusters`. -We will use a for-comprehension here to avoid excessive `Try` juggling. - -[source,scala] ----- -include::devguide:example$scala/ManagingConnections.scala[tag=shared,indent=0] ----- - -Remember, whenever you manually create a `ClusterEnvironment` like this, the SDK will not shut it down when you call `Cluster.disconnect()`. -Instead you are responsible for shutting it down after disconnecting all clusters that share the environment. -//// - - - - -//// -=== Waiting for Bootstrap Completion - -Opening resources is asynchronous. -That is, the call to `cluster.bucket` or `Cluster.connect` will complete instantly, and opening that resource will continue in the background. - -You can force waiting for the resource to be opened with a call to `waitUntilReady`, which is available on both the `Cluster` and `Bucket`. -Here is an example of using it on the bucket: - -[source,scala] ----- -include::devguide:example$scala/ManagingConnections.scala[tag=wait-until-ready,indent=0] ----- - -If not present, then the first Key Value (KV) operation on the bucket will wait for it to be ready. -Any issues opening that bucket (for instance, if it does not exist), will result in an error being raised from that data operation. - -Other timeout issues may occur when using the SDK located geographically separately from the Couchbase Server cluster -- -this is xref:project-docs:compatibility.adoc#network-requirements[not recommended in production deployments], but often occurs during development. -See the <> below for some suggestions of settings adjustments. -//// - - -//// -== Alternate Addresses and Custom Ports - -If your Couchbase Server cluster is running in a containerized, port mapped, or otherwise NAT'd environment like Docker or Kubernetes, a client running outside that environment may need additional information in order to connect the cluster. -Both the client and server require special configuration in this case. - -On the server side, each server node must be configured to advertise its external address as well as any custom port mapping. -This is done with the https://docs.couchbase.com/server/6.5/cli/cbcli/couchbase-cli-setting-alternate-address.html[`setting-alternate-address` CLI command] introduced in Couchbase Server 6.5. -A node configured in this way will advertise two addresses: one for connecting from the same network, and another for connecting from an external network. - -On the client side, the externally visible ports must be used when connecting. -If the external ports are not the default, you can specify custom ports using the overloaded `Cluster.connect()` method that takes a set of `SeedNode` objects instead of a connection string. - -[source,scala] ----- -include::devguide:example$scala/ManagingConnections.scala[tag=seed-nodes,indent=0] ----- - -TIP: In a deployment that uses multi-dimensional scaling, a custom KV port is only applicable for nodes running the KV service. -A custom manager port may be specified regardless of which services are running on the node. - -In many cases the client is able to automatically select the correct set of addresses to use when connecting to a cluster that advertises multiple addresses. -If the detection heuristic fails in your environment, you can override it by setting the `io.networkResolution` client setting to `default` if the client and server are on the same network, or `external` if they're on different networks. - -NOTE: Any TLS certificates must be set up at the point where the connections are being made. -//// - - - - - -//// -// DNS-SRV - -include::{version-common}@sdk:shared:partial$dnssrv-pars.adoc[tag=dnssrv] - -DNS SRV bootstrapping is enabled by default in the {name-sdk}. -In order to make the SDK use the SRV records, you need to pass in the hostname from your records (here `example.com`): - -[source,scala] ----- -include::devguide:example$scala/ManagingConnections.scala[tag=dnssrv,indent=0] ----- - -[source,scala] ----- -ClusterEnvironment env = ClusterEnvironment.builder().ioConfig(IoConfig.enableDnsSrv(true)).build(); ----- - -If the DNS SRV records could not be loaded properly you'll get the exception logged and the given host name will be used as a A record lookup. - ----- -WARNING: DNS SRV lookup failed, proceeding with normal bootstrap. -javax.naming.NameNotFoundException: DNS name not found [response code 3]; - remaining name '_couchbase._tcp.example.com' - at com.sun.jndi.dns.DnsClient.checkResponseCode(DnsClient.java:651) - at com.sun.jndi.dns.DnsClient.isMatchResponse(DnsClient.java:569) ----- - -Also, if you pass in more than one node, DNS SRV bootstrap will not be initiated: - ----- -INFO: DNS SRV enabled, but less or more than one seed node given. -Proceeding with normal bootstrap. ----- -//// - == Local Development @@ -287,10 +75,5 @@ As this may not always be possible during development, read the guidance on work === Troubleshooting Connections to Cloud -//// -Some DNS caching providers (notably, home routers) can’t handle an SRV record that’s large -- if you have DNS-SRV issues with such a set-up, reduce your DNS-SRV to only include three records. -[_For development only, not production._]. -//// - Our xref:troubleshooting-connections.adoc[Troubleshooting Connections] page will help you to diagnose some problems encountered if your test cluster is in a remote data center, but you are developing on a local laptop -- as well as introducing the SDK doctor tool. diff --git a/modules/howtos/pages/sqlpp-queries-with-sdk.adoc b/modules/howtos/pages/sqlpp-queries-with-sdk.adoc index 05ca8b0..63a04bd 100644 --- a/modules/howtos/pages/sqlpp-queries-with-sdk.adoc +++ b/modules/howtos/pages/sqlpp-queries-with-sdk.adoc @@ -36,17 +36,23 @@ Create a collection to work upon by xref:columnar:intro:examples.adoc#travel-sam Execute a query and buffer all result rows in client memory: .Scope Level -[source,java] +[source,csharp] ---- -QueryResult result = scope.executeQuery("select 1"); -result.rows().forEach(row -> System.out.println("Got row: " + row)); +IQueryResult result = await scope.ExecuteQueryAsync("select 1").ConfigureAwait(false); +await foreach (var row in result.ConfigureAwait(false)) +{ + Console.WriteLine("Got row: " + row.ContentAs()); +} ---- .Cluster Level -[source,java] +[source,csharp] ---- -QueryResult result = cluster.executeQuery("select 1"); -result.rows().forEach(row -> System.out.println("Got row: " + row)); +IQueryResult result = await cluster.ExecuteQueryAsync("select 1").ConfigureAwait(false); +await foreach (var row in result.ConfigureAwait(false)) +{ + Console.WriteLine("Got row: " + row.ContentAs()); +} ---- @@ -57,29 +63,28 @@ Supplying parameters as individual arguments to the query allows the query engin Execute a streaming query with positional arguments: .Positional Parameters -[source,java] +[source,csharp] ---- -cluster.executeStreamingQuery( - "select ?=1", - row -> System.out.println("Got row: " + row), - options -> options - .parameters(List.of(1)) -); +var result = await cluster.ExecuteQueryAsync("select ?=1", options => options.WithPositionalParameter(1)).ConfigureAwait(false); +await foreach (var row in result.ConfigureAwait(false)) +{ + Console.WriteLine("Got row: " + row.ContentAs()); +} ---- Execute a streaming query with named arguments: .Named Parameters -[source,java] +[source,csharp] ---- -cluster.executeStreamingQuery( - "select $foo=1", - row -> System.out.println("Got row: " + row), - options -> options - .parameters(Map.of("foo", 1)) -); +var result = await cluster.ExecuteQueryAsync("select $foo=1", options => options.WithNamedParameter("foo", 1)).ConfigureAwait(false); +await foreach (var row in result.ConfigureAwait(false)) +{ + Console.WriteLine("Got row: " + row.ContentAs()); +} ---- +WARNING: Helper methods `WithNamedParameter` and `WithPositionalParameter` take 1 parameter, and add it to the existing collection in the options. The methods `WithNamedParameters` and `WithPositionalParameters` (note the plural) take a collection of parameters, and replace all the parameters in the existing collection. == Further Information diff --git a/modules/project-docs/pages/.third-party-integrations.adoc b/modules/project-docs/pages/.third-party-integrations.adoc deleted file mode 100644 index 9dbbe03..0000000 --- a/modules/project-docs/pages/.third-party-integrations.adoc +++ /dev/null @@ -1,42 +0,0 @@ -= 3^rd^ Party Integrations -:description: The Columnar Java SDK is often used with unofficial and third party tools and applications to integrate into broader language and platform ecosystems, and across data lakes in heterogeneous environments. - - - - -[abstract] -{description} - - -include::{version-common}@columnar-sdk:shared:partial$integrations.adoc[tag=intro] - - -include::{version-common}@columnar-sdk:shared:partial$integrations.adoc[tag=official] - -Couchbase supports integrating with xref:3.5@spark-connector:ROOT:java-api.adoc[Spark]. - - -include::{version-common}@columnar-sdk:shared:partial$integrations.adoc[tag=important] - -Many dataflow tools integrate with Couchbase, including https://github.com/apache/nifi/tree/main/nifi-nar-bundles/nifi-couchbase-bundle[Apache NiFi], -https://wildfly-extras.github.io/wildfly-camel/#_camel_couchbase[Apache Camel], -and https://github.com/couchbaselabs/flink-connector-couchbase[Apache Flink]. -Why not make development easier, and use https://blog.couchbase.com/create-a-zeppelin-interpreter-for-couchbase/[Apache Zeppelin]? - - -include::{version-common}@columnar-sdk:shared:partial$integrations.adoc[tag=other] - - - - - - - -//// -https://github.com/differentway/couchmove[Couchmove] is an open-source Java migration tool for Couchbase, inspired by Flyway. -It can help you "track, manage and apply changes, in your Couchbase buckets." -The philosophy of the project claims to "strongly favor simplicity and convention over configuration". - -In CouchMove you write your migrations in {sqlpp_url}[{sqlpp} (formerly N1QL)], while in https://github.com/couchbaselabs/CouchVersion[CouchVersion] you can write them using the Java SDK, which essentially allow you to create more complex migrations. -CouchVersion provides a new approach for adding changes (change sets) based on Java classes and methods with appropriate annotations. -//// \ No newline at end of file diff --git a/modules/project-docs/pages/analytics-sdk-release-notes.adoc b/modules/project-docs/pages/analytics-sdk-release-notes.adoc index dfc9415..05eb976 100644 --- a/modules/project-docs/pages/analytics-sdk-release-notes.adoc +++ b/modules/project-docs/pages/analytics-sdk-release-notes.adoc @@ -1,5 +1,5 @@ = Analytics SDK Release Notes -:description: Release notes, brief installation instructions, and download archive for the Enterprise Analytics Java Client. +:description: Release notes, brief installation instructions, and download archive for the Enterprise Analytics .NET Client. :navtitle: Release Notes :page-toclevels: 2 :page-aliases: sdk-release-notes.adoc @@ -8,7 +8,7 @@ [abstract] {description} -Version {sdk_dot_minor} of the Java Analytics SDK implements the {sdk_api} xref:compatibility.adoc#api-version[SDK API]. +Version {sdk_dot_minor} of the .NET Analytics SDK implements the {sdk_api} xref:compatibility.adoc#api-version[SDK API]. See the xref:compatibility.html#couchbase-feature-availability-matrix[compatibility pages] for more information on feature compatibility with different versions of Enterprise Analytics. @@ -20,7 +20,7 @@ See the xref:project-docs:sdk-full-installation.adoc[Maven Coordinates] guide fo [#latest-release] -== Java Analytics SDK 1.0 Releases +== .NET Analytics SDK 1.0 Releases We always recommend using the latest version of the SDK -- it contains all of the latest security patches and support for new and upcoming features. All patch releases for each dot minor release should be API compatible, and safe to upgrade; @@ -29,8 +29,8 @@ any changes to expected behavior are noted in the release notes that follow. === Version 1.0.0 (10 July 2025) -https://docs.couchbase.com/sdk-api/couchbase-analytics-java-client-1.0.0[API Reference] +https://docs.couchbase.com/sdk-api/analytics-dotnet-client-1.0.0[API Reference] -This is the first General Availability (GA) release of the new Analytics Java SDK. +This is the first General Availability (GA) release of the new Analytics .NET SDK. It supports executing queries against Enterprise Analytics clusters, with additional features planned for future releases. // end::all[] diff --git a/modules/project-docs/pages/compatibility.adoc b/modules/project-docs/pages/compatibility.adoc index 70a92fb..7e4f56d 100644 --- a/modules/project-docs/pages/compatibility.adoc +++ b/modules/project-docs/pages/compatibility.adoc @@ -9,18 +9,18 @@ Plus notes on Cloud, networks, and AWS Lambda. {description} -The {sdk_dot_minor} {name-sdk} requires Java 8 or later to be installed. -We recommend using the most recent long-term support (LTS) version of OpenJDK. +The {sdk_dot_minor} {name-sdk} requires .NET 8 or later to be installed. +We recommend using the most recent long-term support (LTS) version of .NET. -TIP: Remember to keep your Java installation up to date with the latest patches. +TIP: Remember to keep your .NET installation up to date with the latest patches. == Platform Compatibility -=== JDK Version Compatibility +=== .NET Version Compatibility -include::{sdk_api}@analytics-sdk:shared:partial$compatibility.adoc[tag=jdk-version] +include::{sdk_api}@analytics-sdk:shared:partial$compatibility.adoc[tag=dotnet-version] @@ -28,7 +28,7 @@ include::{sdk_api}@analytics-sdk:shared:partial$compatibility.adoc[tag=jdk-versi === OS Compatibility -include::{sdk_api}@analytics-sdk:shared:partial$compatibility.adoc[tag=os-compat-jvm] +include::{sdk_api}@analytics-sdk:shared:partial$compatibility.adoc[tag=os-compat-dotnet] diff --git a/modules/project-docs/pages/deployment.adoc b/modules/project-docs/pages/deployment.adoc index 142acc2..21f014e 100644 --- a/modules/project-docs/pages/deployment.adoc +++ b/modules/project-docs/pages/deployment.adoc @@ -42,7 +42,7 @@ The {name-sdk} docs note whenever a shortcut is being taken, but here is a non-e The best way to accommodate developing an application that is to be deployed to production is to use the platform's default approach for configuration files. -For the Java Analytics SDK, that is to keep a separate properties file for your development and production environments. +For the .NET Analytics SDK, that is to keep a separate properties file for your development and production environments. diff --git a/modules/project-docs/pages/get-involved.adoc b/modules/project-docs/pages/get-involved.adoc index b9a20ca..f732367 100644 --- a/modules/project-docs/pages/get-involved.adoc +++ b/modules/project-docs/pages/get-involved.adoc @@ -4,8 +4,8 @@ == Contributing -Couchbase welcomes community contributions to the Java Analytics SDK. -The https://github.com/couchbaselabs/couchbase-analytics-jvm-clients/tree/main[Java SDK source code^] is available on GitHub. -Please see the https://github.com/couchbase/couchbase-jvm-clients/blob/master/CONTRIBUTING.md[CONTRIBUTING^] file for further information. +Couchbase welcomes community contributions to the .NET Analytics SDK. +The https://github.com/couchbaselabs/analytics-dotnet-client/tree/main[.NET SDK source code^] is available on GitHub. +Please see the https://github.com/couchbaselabs/analytics-dotnet-client/blob/main/CONTRIBUTING.md[CONTRIBUTING^] file for further information. include::{version-common}@analytics-sdk:shared:partial$contrib.adoc[tag=contrib] diff --git a/modules/project-docs/pages/sdk-full-installation.adoc b/modules/project-docs/pages/sdk-full-installation.adoc index b9ee3a3..7717ba3 100644 --- a/modules/project-docs/pages/sdk-full-installation.adoc +++ b/modules/project-docs/pages/sdk-full-installation.adoc @@ -1,6 +1,6 @@ -= Maven Coordinates -:page-toclevels: 2 -:description: How to get the {name-sdk} from Maven Central. +=== Install the SDK +:page-toclevels: 1 +:description: How to install the {name-sdk} from NuGet. :page-partial: @@ -12,105 +12,20 @@ == Getting the SDK -Couchbase publishes all stable artifacts to https://central.sonatype.com/artifact/com.couchbase.client/couchbase-analytics-java-client[Maven Central]. +Couchbase publishes all stable artifacts to https://www.nuget.org/profiles/couchbase[NuGet]. -Use your favorite dependency management tool to include the SDK in your project: +Install using your preferred method: -[{tabs}] -==== -Maven:: -+ --- -For https://maven.apache.org[Maven], add this to the `dependencies` section of your project's `pom.xml` file: - -[source,xml,subs="attributes+"] ----- - - com.couchbase.client - couchbase-analytics-java-client - {sdk_current_version} - ----- -Refer to the https://maven.apache.org/guides/introduction/introduction-to-the-pom.html/[Maven Documentation] for more information regarding the structure of the `pom.xml` file. --- -Gradle (Kotlin):: -+ --- -For a https://gradle.org/[Gradle] script written in Kotlin, add this line to the `dependencies` section of your project's `build.gradle.kts` file: - -[source,kotlin,subs="attributes+"] +=== .NET CLI +[source,shell,subs="attributes+"] ---- -implementation("com.couchbase.client:couchbase-analytics-java-client:{sdk_current_version}") +dotnet add package Couchbase.AnalyticsClient --version {sdk_current_version} ---- --- -Gradle (Groovy):: -+ --- -For a https://gradle.org/[Gradle] script written in Groovy, add this line to the `dependencies` section of your project's `build.gradle` file: - -[source,groovy,subs="attributes+"] ----- -implementation 'com.couchbase.client:couchbase-analytics-java-client:{sdk_current_version}' ----- --- -==== - -[snapshots] -== Using a Snapshot Version - -Couchbase publishes pre-release snapshot artifacts to the Sonatype OSS Snapshot Repository. -If you wish to use a snapshot version, you'll need to tell your build tool about this repository. - -[{tabs}] -==== -Maven:: -+ --- -.`*pom.xml*` -[source,xml] ----- - - - sonatype-snapshots - https://oss.sonatype.org/content/repositories/snapshots - false - true - - ----- --- -Gradle (Kotlin):: -+ --- -.`*build.gradle.kts*` -[source,kotlin] ----- -repositories { - mavenCentral() - maven { - url = uri("https://oss.sonatype.org/content/repositories/snapshots") - mavenContent { snapshotsOnly() } - } -} ----- --- -Gradle (Groovy):: -+ --- -.`*build.gradle*` -[source,groovy] ----- -repositories { - mavenCentral() - maven { - url "https://oss.sonatype.org/content/repositories/snapshots" - mavenContent { snapshotsOnly() } - } -} +=== Add to .csproj +[source,xml,subs="attributes+"] ---- --- -==== - -CAUTION: Couchbase does not provide support for snapshot artifacts. -We don't recommend using them unless you're working closely with Couchbase Support to verify a particular issue has been resolved prior to release. + + + +---- \ No newline at end of file diff --git a/modules/project-docs/pages/sdk-licenses.adoc b/modules/project-docs/pages/sdk-licenses.adoc index 737485a..c252fbe 100644 --- a/modules/project-docs/pages/sdk-licenses.adoc +++ b/modules/project-docs/pages/sdk-licenses.adoc @@ -7,7 +7,7 @@ {description} Dependencies carry their own licenses. -The Java Analytics Client is distributed as source under the https://www.apache.org/licenses/LICENSE-2.0[Apache License, Version 2.0]. +The .NET Analytics Client is distributed as source under the https://www.apache.org/licenses/LICENSE-2.0[Apache License, Version 2.0]. == Binary Distribution diff --git a/modules/ref/pages/client-settings.adoc b/modules/ref/pages/client-settings.adoc index f71319b..a9734d2 100644 --- a/modules/ref/pages/client-settings.adoc +++ b/modules/ref/pages/client-settings.adoc @@ -11,33 +11,30 @@ Client settings can be configured by writing code, or by including parameters in [#configure-with-code] == Configure with Code -To configure SDK client settings by writing code, provide a configuration callback when creating the `Cluster` instance. Here's an example that configures several settings by passing the optional third argument to `Cluster.newInstance()`: +To configure SDK client settings by writing code, provide a configuration when creating the `Cluster` instance. Here's an example that configures several settings by passing the optional third argument to `Cluster.Create()`: -[source,java] +[source,csharp] ---- -Cluster cluster = Cluster.newInstance( - connectionString, - Credential.of(username, password), - clusterOptions -> clusterOptions // <1> - .timeout(timeoutOptions -> timeoutOptions // <2> - .connectTimeout(Duration.ofSeconds(30)) - .queryTimeout(Duration.ofMinutes(2)) - ) // <3> - .security(securityOptions -> securityOptions // <4> - .cipherSuites(List.of("MY_APPROVED_CIPHER_SUITE")) - ) +var credential = Credential.Create("username", "password"); + +var cluster = Cluster.Create( + connectionString: "https://analytics.my-couchbase.example.com:18095?max_retries=5", + credential: credential, + configureOptions: options => options + .WithTimeoutOptions(timeoutOpts => timeoutOpts + .WithQueryTimeout(TimeSpan.FromSeconds(15))) + .WithSecurityOptions(securityOpts => securityOpts + .WithTrustOnlyCapella()) ); ---- -<1> The parameter type is `Consumer`. +<1> The parameter type is `Func`. The SDK passes a `ClusterOptions` object to your consumer. Configure the options by calling methods on the given object. -<2> The same callback pattern extends to the sub-builders for different categories. For example, `ClusterOptions.timeout()` takes a `Consumer`. - -<3> The `*Options` classes are mutable builders. -Every method returns the same builder, allowing for method call chaining. +<2> The `*Options` classes are immutable record types. +Every method returns the same record, allowing for method call chaining, but returns a new copy. -<4> Most users won't need to configure security settings, but it's shown here for completeness. +<3> Most users won't need to configure security settings, but it's shown here for completeness. TIP: You don't need to call every method in the above example; call only the methods where you want to override the client setting's default value. @@ -65,7 +62,7 @@ TIP: If your application reads the connection string from a config file (or othe For client settings that represent durations, the connection string parameter's value is specified using the following format: -> A duration string is a possibly signed sequence of decimal numbers, each with optional fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m". Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". +> A duration string is a possibly signed sequence of decimal numbers, each with optional fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m". Valid time units are "us", "ms", "s", "m", "h". The SDK rejects non-positive timeout durations. @@ -128,7 +125,7 @@ Leave this at the default value unless you have special security compliance requ When specifying this as a connection string parameter, the value is a comma-delimited list with no whitespace. -Consult your JVM reference documentation for a list of supported cipher suite names. +Consult your .NET SDK reference documentation for a list of supported cipher suite names. |[[security.trust_only_non_prod]]`security.trust_only_non_prod` |N/A @@ -156,36 +153,23 @@ Don't do this unless connecting to a server running locally on your development [#deserializer] === Deserializer -The SDK uses a component called a `Deserializer` to convert query result rows into Java objects. The default implementation is `JacksonDeserializer`, a thin wrapper around a https://github.com/FasterXML/jackson[Jackson] `ObjectMapper`. +The SDK uses a component called a `Deserializer` to convert query result rows into .NET objects. The default implementation is `StjJsonDeserializer`, a thin wrapper using System.Text.Json. -By default, a Jackson `ObjectMapper` throws an exception if it encounters a JSON field that does not match the structure of the target class. -Here's an example that shows how to configure the `ObjectMapper` with different behavior: +By default, a System.Text.Json `JsonSerializer` throws an exception if it encounters a JSON field that does not match the structure of the target class. +Here's an example that shows how to configure the `JsonSerializer` with different behavior: -[source,java] +[source,csharp] ---- -ObjectMapper mapper = JsonMapper.builder() - .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) // <1> - .build(); - -Cluster cluster = Cluster.connect( +var cluster = Cluster.Create( connectionString, - Credential.of(username, password), + Credential.Create(username, password), clusterOptions -> clusterOptions - .deserializer(new JacksonDeserializer(mapper)) + .WithDeserializer(new StjJsonDeserializer()) ); ---- -<1> Ignore unknown properties instead of throwing exception. This cluster option specifies the _default_ deserializer. You can override the deserializer for a specific query by setting the `deserializer` query option when executing the query. -TIP: If you prefer not to work with the `Deserializer` interface, you can always call `row.bytes()` to get a row's content as a raw byte array. +TIP: If you prefer not to work with the `Deserializer` interface, you can always call `row.ContentAs()` to get a row's content as a raw byte array. Then you can process the byte array however you like. - - -//// -==== Custom deserializers - -Implement the `Deserializer` interface to add support for other JSON processing libraries. -The SDK source code repository includes https://github.com/couchbase/couchbase-jvm-clients/tree/master/columnar-java-client/src/test/java/com/couchbase/columnar/client/java/examples/codec[examples for Gson and DSL-JSON] that you can copy into your own project or use as a starting point for other libraries. -//// diff --git a/modules/ref/pages/error-codes.adoc b/modules/ref/pages/error-codes.adoc index 3608dea..4353e45 100644 --- a/modules/ref/pages/error-codes.adoc +++ b/modules/ref/pages/error-codes.adoc @@ -1,5 +1,5 @@ = Error Messages -:description: The standardized error codes returned by the Columnar Java SDK, from Capella connection to {sqlpp} query. +:description: The standardized error codes returned by the Analytics .NET SDK, from Capella connection to {sqlpp} query. :nav-title: Error Codes [abstract] @@ -11,6 +11,6 @@ -The {name-sdk} passes through the Analytics error codes from Columnar. +The {name-sdk} passes through the Analytics error codes from Enterprise Analytics. For a full list of error codes, see xref:{version-server}@server:analytics:error-codes.adoc[Analytics Error Codes].