Tuesday, December 28, 2010

[nosql] Connecting Cassandra with C# by Thrift

At first , English is not my mother language , so don't blame me about it :P

Cassandra recommended user use a higher-level client to communicate with Cassandra in their application , for C# , such as FluentCassandra or Aquiles, but you still can use the lowest-level official API - Thrift to accessing Cassandra.

In here , I choose Thrift to work with Cassandra , so let's start it.

Cassandra 建議使用者在它們的程式內用高階API與Cassandrar進行溝通,以C#來說,像是FluentCassandraAquiles。但是你也可以用官方出的最低階API - Thrift 來與Cassandra溝通。

這邊我選擇使用Thrift來存取Cassandra,下面一步步來介紹(然後我懶得寫中文了)。


Step 1 : Download Thrift


To Thrift Download Page get the latest stable release , for me , that is thrift-0.5.0.tar.gz (use for making thrift.dll) and Thrift compiler for Windows (thrift-0.5.0.exe) (for making Apache.Cassandra.dll).



Step 2 : Gnerate Thrift DLL


Unzip thrift-0.5.0.tar.gz (or new version) , find Thrift.csproj(or Thrift.sln) in \thrift\lib\csharp\src\
cassandra_06

In Visual Studio , right click on [Thrift] -> [Build] , then you will get Thrift.dll in \bin\Debug\ (if no error)

cassandra_07
cassandra_08


Step 3 : Generate Apache.Cassandra DLL


Copy Thrift compiler for Windows (thrift-0.5.0.exe) to Cassandra Folder\interface\ , execute following command
  thrift-0.5.0.exe --gen csharp cassandra.thrift  

In principle, it should be generate a new folder called "gen-csharp", but dunno why , I had an error when I running it with version 0.6.8 , so I change cassandra version to 0.7.0 rc3 , then it passed.

cassandra_9


After get C# source code , using Visual Studio create a new Class Libary project , then add all files in gen-csharp\Apache\Cassandra\  folder. Now build the project , maybe you will got 19~26 error, but don't worry, just some word-casing problem , do some upper case job can fixed it.
(EX: .count -> .Count )

cassandra_10

Step 4 : Connecting Cassandra with C#


Add Thrift.dll and Apache.Cassandra.dll to your refence , you can use windows forms/console application/web application/or other , it doesn't matter .

Ok , it's my C# example with Cassandra 0.7.0 rc3.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Apache.Cassandra;
using Thrift.Transport;
using Thrift.Protocol;

namespace Cassandra_Console
{
    class Program
    {
        static void Main(string[] args)
        {
            TTransport frameTransport = new TFramedTransport(new TSocket("localhost", 9160));
            TProtocol protocol = new TBinaryProtocol(transport);
            TProtocol frameProtocol = new TBinaryProtocol(frameTransport);

            Cassandra.Client client = new Cassandra.Client(frameProtocol, frameProtocol);

            frameTransport.Open();
            Console.WriteLine("Opening connection");

            //for 0.7.0 , need select keyspace at first
            client.set_keyspace("Keyspace1");   
            Console.WriteLine("keyspace set to Keyspace1");

            System.Text.Encoding utf8Encoding = System.Text.Encoding.UTF8;

            long timeStamp = DateTime.Now.Millisecond;

            ColumnPath nameColumnPath = new ColumnPath()
            {
                Column_family = "Standard2",
                Column = utf8Encoding.GetBytes("name")
            };

            ColumnParent nameColumnParent = new ColumnParent()
            {
                Column_family = "Standard2"
            };

            Column nameColume = new Column()
            {
                Name = utf8Encoding.GetBytes("name"),
                Value = utf8Encoding.GetBytes("Died Liu"),
                Timestamp=timeStamp
            };

            Console.WriteLine("Inserting name columns");
            
            //insert data
            client.insert(utf8Encoding.GetBytes("died"),
                          nameColumnParent,
                          nameColume,
                          ConsistencyLevel.ONE);

            //using the key to get column 'name'
            ColumnOrSuperColumn returnedColumn = client.get(utf8Encoding.GetBytes("died"), nameColumnPath, ConsistencyLevel.ONE);
            Console.WriteLine("Column Data in Keyspace1/Standard1: name: {0}, value: {1}",
                              utf8Encoding.GetString(returnedColumn.Column.Name),
                              utf8Encoding.GetString(returnedColumn.Column.Value));

            Console.WriteLine("Closing connection");
            frameTransport.Close();

            Console.ReadLine();

        }
    }
}

And the result like it.

cassandra_11

NOTICE :
1) Cassandra 0.7.0 rc3 doesn't have default keyspace (EX:Keyspace1) , you need to create it by yourself.
2) If you using Cassandra 0.7.0 rc3 at Windows , make sure your JAVA_HOME doesn't have space or other symbol (EX:Program Files), it will make Cassandra can't running.

No comments:

Post a Comment