Thrift: Change Java/C++ server generation

Summary: Servers shouldn't implement iface directly, instead should contain an iface object


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@664785 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Mark Slee 2006-09-05 22:09:57 +00:00
parent f5f2be46a3
commit d2655523ab
5 changed files with 295 additions and 289 deletions

View File

@ -480,8 +480,10 @@ void t_cpp_generator::generate_service(t_service* tservice) {
generate_service_interface(tservice);
generate_service_helpers(tservice);
generate_service_server(tservice);
generate_service_client(tservice);
generate_service_server(tservice);
generate_service_multiface(tservice);
f_service_ <<
ns_close_ << endl <<
@ -536,6 +538,93 @@ void t_cpp_generator::generate_service_interface(t_service* tservice) {
"}; " << endl << endl;
}
/**
* Generates a multiface, which is a single server that just takes a set
* of objects implementing the interface and calls them all, returning the
* value of the last one to be called.
*
* @param tservice The service to generate a multiserver for.
*/
void t_cpp_generator::generate_service_multiface(t_service* tservice) {
// Generate the dispatch methods
vector<t_function*> functions = tservice->get_functions();
vector<t_function*>::iterator f_iter;
string list_type = string("std::vector<boost::shared_ptr<") + service_name_ + "If> >";
// Generate the header portion
f_header_ <<
"class " << service_name_ << "Multiface : " <<
"public " << service_name_ << "If {" << endl <<
" public: " << endl;
indent_up();
f_header_ <<
indent() << service_name_ << "Multiface(" << list_type << "& ifaces) : _ifaces(ifaces) {}" << endl <<
indent() << "virtual ~" << service_name_ << "Multiface() {}" << endl;
indent_down();
// Protected data members
f_header_ <<
" protected:" << endl;
indent_up();
f_header_ <<
indent() << list_type << "& _ifaces;" << endl;
indent_down();
f_header_ <<
indent() << " public:" << endl;
indent_up();
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
t_struct* arglist = (*f_iter)->get_arglist();
const vector<t_field*>& args = arglist->get_members();
vector<t_field*>::const_iterator a_iter;
string call = string("_ifaces[i]->") + (*f_iter)->get_name() + "(";
bool first = true;
for (a_iter = args.begin(); a_iter != args.end(); ++a_iter) {
if (first) {
first = false;
} else {
call += ", ";
}
call += (*a_iter)->get_name();
}
call += ")";
f_header_ <<
indent() << function_signature(*f_iter) << " {" << endl;
indent_up();
f_header_ <<
indent() << "uint32_t sz = _ifaces.size();" << endl <<
indent() << "for (uint32_t i = 0; i < sz; ++i) {" << endl;
if (!(*f_iter)->get_returntype()->is_void()) {
f_header_ <<
indent() << " if (i == sz - 1) {" << endl <<
indent() << " return " << call << ";" << endl <<
indent() << " } else {" << endl <<
indent() << " " << call << ";" << endl <<
indent() << " }" << endl;
} else {
f_header_ <<
indent() << " " << call << ";" << endl;
}
f_header_ <<
indent() << "}" << endl;
indent_down();
f_header_ <<
indent() << "}" << endl <<
endl;
}
indent_down();
f_header_ <<
indent() << "};" << endl <<
endl;
}
/**
* Generates a service client definition.
*
@ -746,17 +835,16 @@ void t_cpp_generator::generate_service_server(t_service* tservice) {
// Generate the header portion
f_header_ <<
"class " << service_name_ << "Server : " <<
"public " << service_name_ << "If, " <<
"public facebook::thrift::TProcessor {" << endl <<
" public: " << endl;
indent_up();
f_header_ <<
indent() <<
service_name_ << "Server(boost::shared_ptr<const facebook::thrift::protocol::TProtocol> protocol) : " <<
"_iprot(protocol), _oprot(protocol) {}" << endl <<
service_name_ << "Server(boost::shared_ptr<" << service_name_ << "If> iface, boost::shared_ptr<const facebook::thrift::protocol::TProtocol> prot) : " <<
"_iface(iface), _iprot(prot), _oprot(prot) {}" << endl <<
indent() <<
service_name_ << "Server(boost::shared_ptr<const facebook::thrift::protocol::TProtocol> iprot, boost::shared_ptr<const facebook::thrift::protocol::TProtocol> oprot) : " <<
"_iprot(iprot), _oprot(oprot) {}" << endl <<
service_name_ << "Server(boost::shared_ptr<" << service_name_ << "If> iface, boost::shared_ptr<const facebook::thrift::protocol::TProtocol> iprot, boost::shared_ptr<const facebook::thrift::protocol::TProtocol> oprot) : " <<
"_iface(iface), _iprot(iprot), _oprot(oprot) {}" << endl <<
indent() << "bool process(boost::shared_ptr<facebook::thrift::transport::TTransport> _itrans, " <<
"boost::shared_ptr<facebook::thrift::transport::TTransport> _otrans);" << endl <<
indent() << "virtual ~" << service_name_ << "Server() {}" << endl;
@ -767,6 +855,7 @@ void t_cpp_generator::generate_service_server(t_service* tservice) {
" protected:" << endl;
indent_up();
f_header_ <<
indent() << "boost::shared_ptr<" << service_name_ << "If> _iface;" << endl <<
indent() << "boost::shared_ptr<const facebook::thrift::protocol::TProtocol> _iprot;" << endl <<
indent() << "boost::shared_ptr<const facebook::thrift::protocol::TProtocol> _oprot;" << endl;
indent_down();
@ -838,109 +927,12 @@ void t_cpp_generator::generate_service_server(t_service* tservice) {
"}" << endl <<
endl;
// Multiserver
generate_service_multiserver(tservice);
// Generate the process subfunctions
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
generate_process_function(tservice, *f_iter);
}
}
/**
* Generates a multiserver, which is a single server that just takes a set
* of objects implementing the interface and calls them all, returning the
* value of the last one to be called.
*
* @param tservice The service to generate a multiserver for.
*/
void t_cpp_generator::generate_service_multiserver(t_service* tservice) {
// Generate the dispatch methods
vector<t_function*> functions = tservice->get_functions();
vector<t_function*>::iterator f_iter;
string list_type = string("std::vector<boost::shared_ptr<") + service_name_ + "If> >";
// Generate the header portion
f_header_ <<
"class " << service_name_ << "MultiServer : " <<
"public " << service_name_ << "Server {" << endl <<
" public: " << endl;
indent_up();
f_header_ <<
indent() <<
service_name_ << "MultiServer(boost::shared_ptr<const facebook::thrift::protocol::TProtocol> protocol, " << list_type << "& servers) : " <<
service_name_ << "Server(protocol), _servers(servers) {}" << endl <<
indent() <<
service_name_ << "MultiServer(boost::shared_ptr<const facebook::thrift::protocol::TProtocol> iprot, boost::shared_ptr<const facebook::thrift::protocol::TProtocol> oprot, " << list_type << "& servers) : " <<
service_name_ << "Server(iprot, oprot), _servers(servers) {}" << endl <<
indent() << "virtual ~" << service_name_ << "MultiServer() {}" << endl;
indent_down();
// Protected data members
f_header_ <<
" protected:" << endl;
indent_up();
f_header_ <<
indent() << list_type << "& _servers;" << endl;
indent_down();
f_header_ <<
indent() << " public:" << endl;
indent_up();
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
t_struct* arglist = (*f_iter)->get_arglist();
const vector<t_field*>& args = arglist->get_members();
vector<t_field*>::const_iterator a_iter;
string call = string("_servers[i]->") + (*f_iter)->get_name() + "(";
bool first = true;
for (a_iter = args.begin(); a_iter != args.end(); ++a_iter) {
if (first) {
first = false;
} else {
call += ", ";
}
call += (*a_iter)->get_name();
}
call += ")";
f_header_ <<
indent() << function_signature(*f_iter) << " {" << endl;
indent_up();
f_header_ <<
indent() << "uint32_t sz = _servers.size();" << endl <<
indent() << "for (uint32_t i = 0; i < sz; ++i) {" << endl;
if (!(*f_iter)->get_returntype()->is_void()) {
f_header_ <<
indent() << " if (i == sz - 1) {" << endl <<
indent() << " return " << call << ";" << endl <<
indent() << " } else {" << endl <<
indent() << " " << call << ";" << endl <<
indent() << " }" << endl;
} else {
f_header_ <<
indent() << " " << call << ";" << endl;
}
f_header_ <<
indent() << "}" << endl;
indent_down();
f_header_ <<
indent() << "}" << endl <<
endl;
}
indent_down();
f_header_ <<
indent() << "};" << endl <<
endl;
}
/**
* Generates a struct and helpers for a function.
*
@ -1019,7 +1011,7 @@ void t_cpp_generator::generate_process_function(t_service* tservice,
f_service_ << "__result.success = ";
}
f_service_ <<
tfunction->get_name() << "(";
"_iface->" << tfunction->get_name() << "(";
bool first = true;
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
if (first) {

View File

@ -42,10 +42,10 @@ class t_cpp_generator : public t_oop_generator {
/** Service-level generation functions */
void generate_service_interface (t_service* tservice);
void generate_service_multiface (t_service* tservice);
void generate_service_helpers (t_service* tservice);
void generate_service_client (t_service* tservice);
void generate_service_server (t_service* tservice);
void generate_service_multiserver(t_service* tservice);
void generate_process_function (t_service* tservice, t_function* tfunction);
void generate_function_helpers (t_function* tfunction);

View File

@ -599,27 +599,29 @@ void t_java_generator::generate_service_server(t_service* tservice) {
// Generate the header portion
f_service_ <<
"public abstract static class Server implements Iface, TProcessor {" << endl;
"public static class Server implements TProcessor {" << endl;
indent_up();
indent(f_service_) <<
"public Server(TProtocol prot)" << endl;
"public Server(Iface iface, TProtocol prot)" << endl;
scope_up(f_service_);
indent(f_service_) <<
"this(prot, prot);" << endl;
"this(iface, prot, prot);" << endl;
scope_down(f_service_);
f_service_ << endl;
indent(f_service_) <<
"public Server(TProtocol iprot, TProtocol oprot)" << endl;
"public Server(Iface iface, TProtocol iprot, TProtocol oprot)" << endl;
scope_up(f_service_);
f_service_ <<
indent() << "_iface = iface;" << endl <<
indent() << "_iprot = iprot;" << endl <<
indent() << "_oprot = oprot;" << endl;
scope_down(f_service_);
f_service_ << endl;
f_service_ <<
indent() << "private Iface _iface;" << endl <<
indent() << "private TProtocol _iprot;" << endl <<
indent() << "private TProtocol _oprot;" << endl << endl;
@ -753,7 +755,7 @@ void t_java_generator::generate_process_function(t_service* tservice,
f_service_ << "__result.success = ";
}
f_service_ <<
tfunction->get_name() << "(";
"_iface." << tfunction->get_name() << "(";
bool first = true;
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
if (first) {

View File

@ -19,10 +19,9 @@ using namespace facebook::thrift::server;
using namespace thrift::test;
class TestServer : public ThriftTestServer {
class TestHandler : public ThriftTestIf {
public:
TestServer(shared_ptr<TProtocol> protocol) :
ThriftTestServer(protocol) {}
TestHandler() {}
void testVoid() {
printf("testVoid()\n");
@ -339,7 +338,9 @@ int main(int argc, char **argv) {
// Dispatcher
shared_ptr<TBinaryProtocol> binaryProtocol(new TBinaryProtocol);
shared_ptr<TestServer> testServer(new TestServer(binaryProtocol));
shared_ptr<TestHandler> testHandler(new TestHandler());
shared_ptr<ThriftTestServer> testServer(new ThriftTestServer(testHandler, binaryProtocol));
// Options
shared_ptr<TServerOptions> serverOptions(new TServerOptions());

View File

@ -16,207 +16,212 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
public class TestServer extends ThriftTest.Server {
public TestServer(TProtocol prot) {
super(prot);
}
public void testVoid() {
System.out.print("testVoid()\n");
}
public class TestServer {
public String testString(String thing) {
System.out.print("testString(\"" + thing + "\")\n");
return thing;
}
public static class TestHandler implements ThriftTest.Iface {
public byte testByte(byte thing) {
System.out.print("testByte(" + thing + ")\n");
return thing;
}
public TestHandler() {}
public void testVoid() {
System.out.print("testVoid()\n");
}
public int testI32(int thing) {
System.out.print("testI32(" + thing + ")\n");
return thing;
}
public String testString(String thing) {
System.out.print("testString(\"" + thing + "\")\n");
return thing;
}
public long testI64(long thing) {
System.out.print("testI64(" + thing + ")\n");
return thing;
}
public byte testByte(byte thing) {
System.out.print("testByte(" + thing + ")\n");
return thing;
}
public int testI32(int thing) {
System.out.print("testI32(" + thing + ")\n");
return thing;
}
public long testI64(long thing) {
System.out.print("testI64(" + thing + ")\n");
return thing;
}
public Xtruct testStruct(Xtruct thing) {
System.out.print("testStruct({" +
"\"" + thing.string_thing + "\", " +
thing.byte_thing + ", " +
thing.i32_thing + ", " +
thing.i64_thing + "})\n");
return thing;
}
public Xtruct testStruct(Xtruct thing) {
System.out.print("testStruct({" +
"\"" + thing.string_thing + "\", " +
thing.byte_thing + ", " +
thing.i32_thing + ", " +
thing.i64_thing + "})\n");
return thing;
}
public Xtruct2 testNest(Xtruct2 nest) {
Xtruct thing = nest.struct_thing;
System.out.print("testNest({" +
nest.byte_thing + ", {" +
"\"" + thing.string_thing + "\", " +
thing.byte_thing + ", " +
thing.i32_thing + ", " +
thing.i64_thing + "}, " +
nest.i32_thing + "})\n");
return nest;
}
public Xtruct2 testNest(Xtruct2 nest) {
Xtruct thing = nest.struct_thing;
System.out.print("testNest({" +
nest.byte_thing + ", {" +
"\"" + thing.string_thing + "\", " +
thing.byte_thing + ", " +
thing.i32_thing + ", " +
thing.i64_thing + "}, " +
nest.i32_thing + "})\n");
return nest;
}
public HashMap<Integer,Integer> testMap(HashMap<Integer,Integer> thing) {
System.out.print("testMap({");
boolean first = true;
for (int key : thing.keySet()) {
if (first) {
first = false;
} else {
System.out.print(", ");
public HashMap<Integer,Integer> testMap(HashMap<Integer,Integer> thing) {
System.out.print("testMap({");
boolean first = true;
for (int key : thing.keySet()) {
if (first) {
first = false;
} else {
System.out.print(", ");
}
System.out.print(key + " => " + thing.get(key));
}
System.out.print(key + " => " + thing.get(key));
System.out.print("})\n");
return thing;
}
System.out.print("})\n");
return thing;
}
public HashSet<Integer> testSet(HashSet<Integer> thing) {
System.out.print("testSet({");
boolean first = true;
for (int elem : thing) {
if (first) {
first = false;
} else {
System.out.print(", ");
public HashSet<Integer> testSet(HashSet<Integer> thing) {
System.out.print("testSet({");
boolean first = true;
for (int elem : thing) {
if (first) {
first = false;
} else {
System.out.print(", ");
}
System.out.print(elem);
}
System.out.print(elem);
System.out.print("})\n");
return thing;
}
System.out.print("})\n");
return thing;
}
public ArrayList<Integer> testList(ArrayList<Integer> thing) {
System.out.print("testList({");
boolean first = true;
for (int elem : thing) {
if (first) {
first = false;
} else {
System.out.print(", ");
public ArrayList<Integer> testList(ArrayList<Integer> thing) {
System.out.print("testList({");
boolean first = true;
for (int elem : thing) {
if (first) {
first = false;
} else {
System.out.print(", ");
}
System.out.print(elem);
}
System.out.print(elem);
}
System.out.print("})\n");
return thing;
}
public int testEnum(int thing) {
System.out.print("testEnum(" + thing + ")\n");
return thing;
}
public long testTypedef(long thing) {
System.out.print("testTypedef(" + thing + ")\n");
return thing;
}
public HashMap<Integer,HashMap<Integer,Integer>> testMapMap(int hello) {
System.out.print("testMapMap(" + hello + ")\n");
HashMap<Integer,HashMap<Integer,Integer>> mapmap =
new HashMap<Integer,HashMap<Integer,Integer>>();
HashMap<Integer,Integer> pos = new HashMap<Integer,Integer>();
HashMap<Integer,Integer> neg = new HashMap<Integer,Integer>();
for (int i = 1; i < 5; i++) {
pos.put(i, i);
neg.put(-i, -i);
System.out.print("})\n");
return thing;
}
mapmap.put(4, pos);
mapmap.put(-4, neg);
public int testEnum(int thing) {
System.out.print("testEnum(" + thing + ")\n");
return thing;
}
return mapmap;
}
public long testTypedef(long thing) {
System.out.print("testTypedef(" + thing + ")\n");
return thing;
}
public HashMap<Long, HashMap<Integer,Insanity>> testInsanity(Insanity argument) {
System.out.print("testInsanity()\n");
public HashMap<Integer,HashMap<Integer,Integer>> testMapMap(int hello) {
System.out.print("testMapMap(" + hello + ")\n");
HashMap<Integer,HashMap<Integer,Integer>> mapmap =
new HashMap<Integer,HashMap<Integer,Integer>>();
HashMap<Integer,Integer> pos = new HashMap<Integer,Integer>();
HashMap<Integer,Integer> neg = new HashMap<Integer,Integer>();
for (int i = 1; i < 5; i++) {
pos.put(i, i);
neg.put(-i, -i);
}
mapmap.put(4, pos);
mapmap.put(-4, neg);
return mapmap;
}
public HashMap<Long, HashMap<Integer,Insanity>> testInsanity(Insanity argument) {
System.out.print("testInsanity()\n");
Xtruct hello = new Xtruct();
hello.string_thing = "Hello2";
hello.byte_thing = 2;
hello.i32_thing = 2;
hello.i64_thing = 2;
Xtruct hello = new Xtruct();
hello.string_thing = "Hello2";
hello.byte_thing = 2;
hello.i32_thing = 2;
hello.i64_thing = 2;
Xtruct goodbye = new Xtruct();
goodbye.string_thing = "Goodbye4";
goodbye.byte_thing = (byte)4;
goodbye.i32_thing = 4;
goodbye.i64_thing = (long)4;
Xtruct goodbye = new Xtruct();
goodbye.string_thing = "Goodbye4";
goodbye.byte_thing = (byte)4;
goodbye.i32_thing = 4;
goodbye.i64_thing = (long)4;
Insanity crazy = new Insanity();
crazy.userMap.put(Numberz.EIGHT, (long)8);
crazy.xtructs.add(goodbye);
Insanity crazy = new Insanity();
crazy.userMap.put(Numberz.EIGHT, (long)8);
crazy.xtructs.add(goodbye);
Insanity looney = new Insanity();
crazy.userMap.put(Numberz.FIVE, (long)5);
crazy.xtructs.add(hello);
Insanity looney = new Insanity();
crazy.userMap.put(Numberz.FIVE, (long)5);
crazy.xtructs.add(hello);
HashMap<Integer,Insanity> first_map = new HashMap<Integer, Insanity>();
HashMap<Integer,Insanity> second_map = new HashMap<Integer, Insanity>();;
HashMap<Integer,Insanity> first_map = new HashMap<Integer, Insanity>();
HashMap<Integer,Insanity> second_map = new HashMap<Integer, Insanity>();;
first_map.put(Numberz.TWO, crazy);
first_map.put(Numberz.THREE, crazy);
first_map.put(Numberz.TWO, crazy);
first_map.put(Numberz.THREE, crazy);
second_map.put(Numberz.SIX, looney);
second_map.put(Numberz.SIX, looney);
HashMap<Long,HashMap<Integer,Insanity>> insane =
new HashMap<Long, HashMap<Integer,Insanity>>();
insane.put((long)1, first_map);
insane.put((long)2, second_map);
HashMap<Long,HashMap<Integer,Insanity>> insane =
new HashMap<Long, HashMap<Integer,Insanity>>();
insane.put((long)1, first_map);
insane.put((long)2, second_map);
return insane;
}
return insane;
}
public Xtruct testMulti(byte arg0, int arg1, long arg2, HashMap<Short,String> arg3, int arg4, long arg5) {
System.out.print("testMulti()\n");
public Xtruct testMulti(byte arg0, int arg1, long arg2, HashMap<Short,String> arg3, int arg4, long arg5) {
System.out.print("testMulti()\n");
Xtruct hello = new Xtruct();;
hello.string_thing = "Hello2";
hello.byte_thing = arg0;
hello.i32_thing = arg1;
hello.i64_thing = arg2;
return hello;
}
public void testException(String arg) throws Xception {
System.out.print("testException("+arg+")\n");
if (arg.equals("Xception")) {
Xception x = new Xception();
x.errorCode = 1001;
x.message = "This is an Xception";
throw x;
Xtruct hello = new Xtruct();;
hello.string_thing = "Hello2";
hello.byte_thing = arg0;
hello.i32_thing = arg1;
hello.i64_thing = arg2;
return hello;
}
return;
}
public Xtruct testMultiException(String arg0, String arg1) throws Xception, Xception2 {
System.out.print("testMultiException(" + arg0 + ", " + arg1 + ")\n");
if (arg0.equals("Xception")) {
Xception x = new Xception();
x.errorCode = 1001;
x.message = "This is an Xception";
} else if (arg0.equals("Xception2")) {
Xception2 x = new Xception2();
x.errorCode = 2002;
x.struct_thing.string_thing = "This is an Xception2";
public void testException(String arg) throws Xception {
System.out.print("testException("+arg+")\n");
if (arg.equals("Xception")) {
Xception x = new Xception();
x.errorCode = 1001;
x.message = "This is an Xception";
throw x;
}
return;
}
public Xtruct testMultiException(String arg0, String arg1) throws Xception, Xception2 {
System.out.print("testMultiException(" + arg0 + ", " + arg1 + ")\n");
if (arg0.equals("Xception")) {
Xception x = new Xception();
x.errorCode = 1001;
x.message = "This is an Xception";
throw x;
} else if (arg0.equals("Xception2")) {
Xception2 x = new Xception2();
x.errorCode = 2002;
x.struct_thing = new Xtruct();
x.struct_thing.string_thing = "This is an Xception2";
throw x;
}
Xtruct result = new Xtruct();
result.string_thing = arg1;
return result;
}
Xtruct result = new Xtruct();
result.string_thing = arg1;
return result;
}
} // class TestHandler
public static void main(String [] args) {
try {
@ -226,20 +231,26 @@ public class TestServer extends ThriftTest.Server {
}
// Processor
TBinaryProtocol binaryProtocol = new TBinaryProtocol();
TestServer testServer = new TestServer(binaryProtocol);
TBinaryProtocol binaryProtocol =
new TBinaryProtocol();
TestHandler testHandler =
new TestHandler();
ThriftTest.Server testServer =
new ThriftTest.Server(testHandler, binaryProtocol);
// Options
TServer.Options serverOptions = new TServer.Options();
TServer.Options serverOptions =
new TServer.Options();
// Transport
ServerSocket serverSocket = new ServerSocket(port);
TServerSocket tServerSocket = new TServerSocket(serverSocket);
ServerSocket serverSocket =
new ServerSocket(port);
TServerSocket tServerSocket =
new TServerSocket(serverSocket);
// Server
TSimpleServer simpleServer = new TSimpleServer(testServer,
serverOptions,
tServerSocket);
TSimpleServer simpleServer =
new TSimpleServer(testServer, serverOptions, tServerSocket);
// Run it
System.out.println("Starting the server on port " + port + "...");