Connect to Apache Cassandra with C#
In this article, we will introduce how to connect to Cassandra by using C#. Firstly we will walk through installing and configuring a C# development environment and then provide simple examples for connecting, with and without TLS to the remote Cassandra server.
Please refer to our support documentation here for general information on connecting to your Cassandra Cluster first.
Download and install Visual Studio
Go to visualstudio to download and install Visual Studio.
Once installed create a new Console C# project.
Install Cassandra C# driver
Install Cassandra C# Driver using your choice of package manager, here is an example using NuGet.
In the search bar, search for and select NuGet package manager
Search for and install CassandraCSharpDriver in the NuGet Package manager window.
If you unfold the Packages folder in the sidebar, you should now see CassandraCSharpDriver in the list of packages installed.
Connecting without TLS
Replace Program.cs with the following example.
Replace Public IP’s, Data Centre, username and password with your required configuration.
Run the code by clicking on the green arrow in the toolbar.
Write Sample Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
using System; using Cassandra; namespace Instaclustr.Cassandra.ConnectionSample { class CassandraConnectSample { public static void Main(string[] args) { Console.WriteLine("Hello Cassandra!"); var cluster = Cluster.Builder() .AddContactPoints(<PUBLIC IP1>, <PUBLIC IP2>, <PUBLIC IP3>,..) .WithPort(9042) .WithLoadBalancingPolicy(new DCAwareRoundRobinPolicy("<Data Centre (e.g AWS_VPC_US_EAST_1)>")) .WithAuthProvider(new PlainTextAuthProvider(<Username>, <Password>)) .Build(); var session = cluster.Connect(); Console.WriteLine("Connected to cluster: " + cluster.Metadata.ClusterName); var keyspaceNames = session .Execute("SELECT * FROM system_schema.keyspaces") .Select(row => row.GetValue<string>("keyspace_name")); Console.WriteLine("Found keyspaces:"); foreach (var name in keyspaceNames) { Console.WriteLine("- {0}", name); } } } } |
The output should not have any errors and look something like this.
1 2 3 4 5 6 7 8 9 10 |
Connected to cluster: SampleCassandraCluster Found keyspaces: - system_auth - system_schema - system_distributed - system - instaclustr - system_traces Press any key to close this window . . . |
Connecting with TLS via windows
In order to connect to your TLS enabled cluster with C# please first contact our support with a request here.
After the connection has been enabled by us, TLS needs to configured on your client machine to connect to the cluster.
The CA certificates can be downloaded from your clusters Connection Info page.
Write Sample Code
Replace Program.cs with the following example.
Replace the public IP’s, username, password and path to your cluster-ca-certificate.der with your required configuration.
Run the code by clicking on the green arrow in the toolbar.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
using System; using System.Linq; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; using Cassandra; namespace Instaclustr { public class CassandraConnectSample { private static readonly string[] ContactPoints = { "<Public IP1>", "<Public IP2>", "<Public IP3>" }; private const string RootCertificatePath = @"path\to\cluster-ca-certificate.der"; private const string Username = "<Cluster Username>"; private const string Password = "<Cluster Password>"; public static void Main() { var serverCertificateValidator = new CustomTrustStoreCertificateValidator(new X509Certificate2(RootCertificatePath)); var sslOptions = new SSLOptions( // TLSv1.2 is required as of October 9, 2019. // See: https://www.instaclustr.com/removing-support-for-outdated-encryption-mechanisms/ SslProtocols.Tls12, // Disable revocation checking (the default validation result and therefore this parameter is not used). false, // Custom validator avoids need to trust the CA system-wide. (sender, certificate, chain, errors) => serverCertificateValidator.Validate(certificate) ); var cluster = Cluster.Builder() .AddContactPoints(ContactPoints) .WithSSL(sslOptions) .WithAuthProvider(new PlainTextAuthProvider(Username, Password)) .Build(); var session = cluster.Connect(); Console.WriteLine("Connected to cluster: " + cluster.Metadata.ClusterName); var keyspaceNames = session .Execute("SELECT * FROM system_schema.keyspaces") .Select(row => row.GetValue<string>("keyspace_name")); Console.WriteLine("Found keyspaces:"); foreach (var name in keyspaceNames) { Console.WriteLine("- {0}", name); } } private class CustomTrustStoreCertificateValidator { private readonly X509Certificate2 rootCertificate; public CustomTrustStoreCertificateValidator(X509Certificate2 rootCertificate) { this.rootCertificate = rootCertificate; } public bool Validate(X509Certificate serverCertificate) { Console.WriteLine(serverCertificate.ToString()); var chain = new X509Chain(); // .NET v3 // chain.ChainPolicy = new X509ChainPolicy() // { // RevocationMode = X509RevocationMode.NoCheck, // VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority, // ExtraStore = { rootCertificate } // }; // .NET v5 chain.ChainPolicy = new X509ChainPolicy() { RevocationMode = X509RevocationMode.NoCheck, TrustMode = X509ChainTrustMode.CustomRootTrust, CustomTrustStore = { rootCertificate } }; var isValidChain = chain.Build(new X509Certificate2(serverCertificate)); if (!isValidChain) { foreach (var chainStatus in chain.ChainStatus) { Console.Error.WriteLine("Chain failed validation: {0} ({1})", chainStatus.Status, chainStatus.StatusInformation); } return false; } // Chain is ordered from [0]:leaf -> intermediate -> [^1]:root. var chainRootCertificate = chain.ChainElements[chain.ChainElements.Count - 1].Certificate; var isExpectedRoot = chainRootCertificate.RawData.SequenceEqual(rootCertificate.RawData); // For .NET v3, the AllowUnknownCertificateAuthority flag permits both PartialChain and UntrustedRoot errors for a successful result. // We must manually check the root certificate to ensure it is the one we expect. // This is no longer required in .NET v5 with CustomRootTrust support. if (!isExpectedRoot) { Console.Error.WriteLine("Partial chain passed validation, but the expected root certificate was not in the chain."); return false; } return true; } } } } |