Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 6

Apache thrift is a framework for cross language RPC service/client implementation.

Thrift has a small IDL (interface definition language) and comes with an IDL compiler
that generates code to be used to easily build RPC clients and servers that
communicate seamlessly across programming languages.

Since the thrift is distributed in source form so we first need to build the thrift.exe
IDL compiler. Follow this document to generate the compiler exe on windows.

Following is an example usage. We intend to write a C# service and a Java client that
implement the following interface (hello.thrift):

namespace java hello


namespace csharp hello

enum Operation {
ADD = 1,
SUBTRACT = 2,
MULTIPLY = 3,
DIVIDE = 4
}

struct Work {
1: i32 num1 = 0,
2: i32 num2,
3: Operation op,
4: string comment,
}

exception InvalidOperation {
1: i32 what,
2: string why
}

service HelloService {

void ping(),

i32 add(1:i32 num1, 2:i32 num2),

i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch),

string greeting(),

Compile the above thrift file with the thrift compiler to generate both java and c#
code.

thrift.exe -r --gen java hello.thrift


thrift.exe –r –gen csharp hello.thrift

Following is the service (Program.cs):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Thrift;
using Thrift.Transport;
using Thrift.Protocol;
using Thrift.Server;
using hello;

namespace thriftcsserv
{
class Program
{
static void Main(string[] args)
{
try
{
HelloServiceHandler handler = new
HelloServiceHandler();
HelloService.Processor processor = new
HelloService.Processor(handler);
TServerTransport transport = new TServerSocket(34568);
TServer server = new TSimpleServer(processor,
transport);

// Use this for a multithreaded server


// server = new TThreadPoolServer(processor,
serverTransport);

Console.WriteLine("Starting the server...");


server.Serve();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}

public class HelloServiceHandler : HelloService.Iface


{
public void ping()
{ }
public int add(int num1, int num2)
{
return (num1 + num2);
}
public int calculate(int logid, Work w)
{
int val = 0;
switch (w.Op)
{
case Operation.ADD:
val = w.Num1 + w.Num2;
break;
case Operation.SUBTRACT:
val = w.Num1 - w.Num2;
break;
case Operation.MULTIPLY:
val = w.Num1 * w.Num2;
break;
case Operation.DIVIDE:
if (w.Num2 == 0)
{
InvalidOperation io = new
InvalidOperation();
io.What = (int)w.Op.GetTypeCode();
io.Why = "Cannot divide by 0";
throw io;
}
val = w.Num1 / w.Num2;
break;
default:
InvalidOperation io1 = new InvalidOperation();
io1.What = (int)w.Op.GetTypeCode();
io1.Why = "Unknown operation";
throw io1;
}
return val;
}
public string greeting()
{
return "Hello world of RPC using thrift from c#
service";
}
}
}
}
And the HelloClient.java is below:

package hello.client;

import hello.HelloService;
import hello.InvalidOperation;
import hello.Operation;
import hello.Work;

import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;

public class HelloClient {


public static void main(String[] args) {
try {

TTransport transport = new TSocket("localhost", 34568);


TProtocol protocol = new TBinaryProtocol(transport);
HelloService.Client client = new HelloService.Client(protocol);

transport.open();

client.ping();
System.out.println("ping()");

String str = client.greeting();


System.out.println(str);

int sum = client.add(1, 1);


System.out.println("1+1=" + sum);

Work work = new Work();

work.op = Operation.DIVIDE;
work.num1 = 1;
work.num2 = 0;
try {
int quotient = client.calculate(1, work);
System.out.println("Whoa we can divide by 0");
} catch (InvalidOperation io) {
System.out.println("Invalid operation: " + io.why);
}
work.op = Operation.SUBTRACT;
work.num1 = 15;
work.num2 = 10;
try {
int diff = client.calculate(1, work);
System.out.println("15-10=" + diff);
} catch (InvalidOperation io) {
System.out.println("Invalid operation: " + io.why);
}

transport.close();

} catch (TException x) {
x.printStackTrace();
}
}
}

Now run the service and then the client. The o/p is as follows:

ping()
Hello world of RPC using thrift from c# service
1+1=2
Invalid operation: Cannot divide by 0
15-10=5

What we learned?

We can exchange objects and throw exceptions and invoke methods and all of it can
be done using TCP stream socket interface.

We can use the above model to implement C# SDK Connector which can be a windows
RPC service and the SCOM plug-in on DCFM server will be the RPC client. The methods
that we will need are:

1. Push fabrics info (name: url) data to SCOM to dynamically create nodes.
2. Log critical SAN fabric events.

namespace java scom


namespace csharp scom

/*
* Fabric name and url pair. Will be passed from SCOM
* plug-in client to create a UrlViewType node in the
* monitoring tab of SCOM Console, dynamically.
*/
struct Fabric {
1: string name ,
2: string url,
}

/*
* A critical SAN event that is logged into windows
* event log.
*/
struct SANEvent {
1: string sourceName ,
2: string eventId,
3: string severity,
4: string description,
}

enum ErrorCode {
CONNECTION_FAILURE = 1,
AUTH_FAILURE = 2,
}

/*
* SCOM Exception.
*/
exception SCOMConnectorException {
1: i32 what,
2: string why
}

/*
* Service interface.
*/
service SCOMConnectorService {
/*
* Will create or update fabric nodes in monitoring tab
* of SCOM Console. It will be called periodically with
* the then current set of fabric names and url pairs.
*/
void createOrUpdateNodes(list<Fabric> fabrics) throws
(1:SCOMConnectorException err),

/*
* Log SAN critical events to windows event log.
*/
void logSANEvent(SANEvent event) throws (1:SCOMConnectorException err),
}

You might also like