blob: 34c9dfb5287b66c6c02bb522762629bf4c6c673e [file] [log] [blame]
Marc Slemko6be374b2006-08-04 03:16:25 +00001#include <concurrency/ThreadManager.h>
2#include <concurrency/PosixThreadFactory.h>
3#include <protocol/TBinaryProtocol.h>
4#include <server/TSimpleServer.h>
5#include <server/TThreadPoolServer.h>
Mark Sleeb9acf982006-10-10 01:57:32 +00006#include <server/TNonblockingServer.h>
Marc Slemko6be374b2006-08-04 03:16:25 +00007#include <transport/TServerSocket.h>
Mark Sleed788b2e2006-09-07 01:26:35 +00008#include <transport/TBufferedTransportFactory.h>
Mark Slee95771002006-06-07 06:53:25 +00009#include "ThriftTest.h"
Marc Slemko6be374b2006-08-04 03:16:25 +000010
11#include <iostream>
12#include <stdexcept>
13#include <sstream>
14
Mark Sleee8540632006-05-30 09:24:40 +000015using namespace std;
16
Marc Slemko6be374b2006-08-04 03:16:25 +000017using namespace facebook::thrift;
18using namespace facebook::thrift::protocol;
19using namespace facebook::thrift::transport;
20using namespace facebook::thrift::server;
21
Marc Slemkobf4fd192006-08-15 21:29:39 +000022using namespace thrift::test;
23
Mark Sleed2655522006-09-05 22:09:57 +000024class TestHandler : public ThriftTestIf {
Mark Sleee8540632006-05-30 09:24:40 +000025 public:
Mark Sleed2655522006-09-05 22:09:57 +000026 TestHandler() {}
Mark Sleee8540632006-05-30 09:24:40 +000027
28 void testVoid() {
29 printf("testVoid()\n");
30 }
31
32 string testString(string thing) {
33 printf("testString(\"%s\")\n", thing.c_str());
34 return thing;
35 }
36
Mark Sleed3d733a2006-09-01 22:19:06 +000037 int8_t testByte(int8_t thing) {
Mark Sleee8540632006-05-30 09:24:40 +000038 printf("testByte(%d)\n", (int)thing);
39 return thing;
40 }
41
Mark Sleee8540632006-05-30 09:24:40 +000042 int32_t testI32(int32_t thing) {
43 printf("testI32(%d)\n", thing);
44 return thing;
45 }
46
Mark Sleee8540632006-05-30 09:24:40 +000047 int64_t testI64(int64_t thing) {
Mark Sleed3d733a2006-09-01 22:19:06 +000048 printf("testI64(%ld)\n", thing);
Mark Sleee8540632006-05-30 09:24:40 +000049 return thing;
50 }
51
Mark Sleec98d0502006-09-06 02:42:25 +000052 double testDouble(double thing) {
53 printf("testDouble(%lf)\n", thing);
54 return thing;
55 }
56
Mark Sleee8540632006-05-30 09:24:40 +000057 Xtruct testStruct(Xtruct thing) {
Mark Sleed788b2e2006-09-07 01:26:35 +000058 printf("testStruct({\"%s\", %d, %d, %ld})\n", thing.string_thing.c_str(), (int)thing.byte_thing, thing.i32_thing, thing.i64_thing);
Mark Sleee8540632006-05-30 09:24:40 +000059 return thing;
60 }
61
62 Xtruct2 testNest(Xtruct2 nest) {
63 Xtruct thing = nest.struct_thing;
Mark Sleed788b2e2006-09-07 01:26:35 +000064 printf("testNest({%d, {\"%s\", %d, %d, %ld}, %d})\n", (int)nest.byte_thing, thing.string_thing.c_str(), (int)thing.byte_thing, thing.i32_thing, thing.i64_thing, nest.i32_thing);
Mark Sleee8540632006-05-30 09:24:40 +000065 return nest;
66 }
67
68 map<int32_t, int32_t> testMap(map<int32_t, int32_t> thing) {
69 printf("testMap({");
70 map<int32_t, int32_t>::const_iterator m_iter;
71 bool first = true;
72 for (m_iter = thing.begin(); m_iter != thing.end(); ++m_iter) {
73 if (first) {
74 first = false;
75 } else {
76 printf(", ");
77 }
78 printf("%d => %d", m_iter->first, m_iter->second);
79 }
80 printf("})\n");
81 return thing;
82 }
83
84 set<int32_t> testSet(set<int32_t> thing) {
85 printf("testSet({");
86 set<int32_t>::const_iterator s_iter;
87 bool first = true;
88 for (s_iter = thing.begin(); s_iter != thing.end(); ++s_iter) {
89 if (first) {
90 first = false;
91 } else {
92 printf(", ");
93 }
94 printf("%d", *s_iter);
95 }
96 printf("})\n");
97 return thing;
98 }
99
Mark Sleeb9acf982006-10-10 01:57:32 +0000100 vector<int32_t> testList(vector<int32_t> thing) {
Mark Sleee8540632006-05-30 09:24:40 +0000101 printf("testList({");
Mark Sleeb9acf982006-10-10 01:57:32 +0000102 vector<int32_t>::const_iterator l_iter;
Mark Sleee8540632006-05-30 09:24:40 +0000103 bool first = true;
104 for (l_iter = thing.begin(); l_iter != thing.end(); ++l_iter) {
105 if (first) {
106 first = false;
107 } else {
108 printf(", ");
109 }
110 printf("%d", *l_iter);
111 }
112 printf("})\n");
113 return thing;
114 }
115
Mark Slee95771002006-06-07 06:53:25 +0000116 Numberz testEnum(Numberz thing) {
Mark Sleee8540632006-05-30 09:24:40 +0000117 printf("testEnum(%d)\n", thing);
118 return thing;
119 }
120
Mark Slee95771002006-06-07 06:53:25 +0000121 UserId testTypedef(UserId thing) {
Mark Sleed3d733a2006-09-01 22:19:06 +0000122 printf("testTypedef(%ld)\n", thing);
Mark Sleee8540632006-05-30 09:24:40 +0000123 return thing;
124 }
125
126 map<int32_t, map<int32_t,int32_t> > testMapMap(int32_t hello) {
127 printf("testMapMap(%d)\n", hello);
128 map<int32_t, map<int32_t,int32_t> > mapmap;
129
130 map<int32_t,int32_t> pos;
131 map<int32_t,int32_t> neg;
132 for (int i = 1; i < 5; i++) {
133 pos.insert(make_pair(i,i));
134 neg.insert(make_pair(-i,-i));
135 }
136
137 mapmap.insert(make_pair(4, pos));
138 mapmap.insert(make_pair(-4, neg));
139
140 return mapmap;
141 }
142
143 map<UserId, map<Numberz,Insanity> > testInsanity(Insanity argument) {
144 printf("testInsanity()\n");
145
146 Xtruct hello;
147 hello.string_thing = "Hello2";
148 hello.byte_thing = 2;
Mark Sleee8540632006-05-30 09:24:40 +0000149 hello.i32_thing = 2;
Mark Sleee8540632006-05-30 09:24:40 +0000150 hello.i64_thing = 2;
151
152 Xtruct goodbye;
153 goodbye.string_thing = "Goodbye4";
154 goodbye.byte_thing = 4;
Mark Sleee8540632006-05-30 09:24:40 +0000155 goodbye.i32_thing = 4;
Mark Sleee8540632006-05-30 09:24:40 +0000156 goodbye.i64_thing = 4;
157
158 Insanity crazy;
159 crazy.userMap.insert(make_pair(EIGHT, 8));
160 crazy.xtructs.push_back(goodbye);
161
162 Insanity looney;
163 crazy.userMap.insert(make_pair(FIVE, 5));
164 crazy.xtructs.push_back(hello);
165
166 map<Numberz, Insanity> first_map;
167 map<Numberz, Insanity> second_map;
168
169 first_map.insert(make_pair(TWO, crazy));
170 first_map.insert(make_pair(THREE, crazy));
171
172 second_map.insert(make_pair(SIX, looney));
173
174 map<UserId, map<Numberz,Insanity> > insane;
175 insane.insert(make_pair(1, first_map));
176 insane.insert(make_pair(2, second_map));
177
178 printf("return");
179 printf(" = {");
180 map<UserId, map<Numberz,Insanity> >::const_iterator i_iter;
181 for (i_iter = insane.begin(); i_iter != insane.end(); ++i_iter) {
Mark Sleed3d733a2006-09-01 22:19:06 +0000182 printf("%ld => {", i_iter->first);
Mark Sleee8540632006-05-30 09:24:40 +0000183 map<Numberz,Insanity>::const_iterator i2_iter;
184 for (i2_iter = i_iter->second.begin();
185 i2_iter != i_iter->second.end();
186 ++i2_iter) {
187 printf("%d => {", i2_iter->first);
188 map<Numberz, UserId> userMap = i2_iter->second.userMap;
189 map<Numberz, UserId>::const_iterator um;
190 printf("{");
191 for (um = userMap.begin(); um != userMap.end(); ++um) {
Mark Sleed3d733a2006-09-01 22:19:06 +0000192 printf("%d => %ld, ", um->first, um->second);
Mark Sleee8540632006-05-30 09:24:40 +0000193 }
194 printf("}, ");
195
Mark Sleeb9acf982006-10-10 01:57:32 +0000196 vector<Xtruct> xtructs = i2_iter->second.xtructs;
197 vector<Xtruct>::const_iterator x;
Mark Sleee8540632006-05-30 09:24:40 +0000198 printf("{");
199 for (x = xtructs.begin(); x != xtructs.end(); ++x) {
Mark Sleed788b2e2006-09-07 01:26:35 +0000200 printf("{\"%s\", %d, %d, %ld}, ", x->string_thing.c_str(), (int)x->byte_thing, x->i32_thing, x->i64_thing);
Mark Sleee8540632006-05-30 09:24:40 +0000201 }
202 printf("}");
203
204 printf("}, ");
205 }
206 printf("}, ");
207 }
208 printf("}\n");
209
210 return insane;
211 }
Marc Slemkoe6889de2006-08-12 00:32:53 +0000212
Mark Sleed3d733a2006-09-01 22:19:06 +0000213 Xtruct testMulti(int8_t arg0, int32_t arg1, int64_t arg2, std::map<int16_t, std::string> arg3, Numberz arg4, UserId arg5) {
Marc Slemkoe6889de2006-08-12 00:32:53 +0000214 printf("testMulti()\n");
215
216 Xtruct hello;
217 hello.string_thing = "Hello2";
218 hello.byte_thing = arg0;
219 hello.i32_thing = arg1;
220 hello.i64_thing = (int64_t)arg2;
221
222 return hello;
223 }
Marc Slemkobf4fd192006-08-15 21:29:39 +0000224
Mark Sleed3d733a2006-09-01 22:19:06 +0000225 void testException(std::string arg) throw(Xception) {
Marc Slemkobf4fd192006-08-15 21:29:39 +0000226 printf("testException(%s)\n", arg.c_str());
Mark Sleed3d733a2006-09-01 22:19:06 +0000227 if (arg.compare("Xception") == 0) {
Marc Slemkobf4fd192006-08-15 21:29:39 +0000228 Xception e;
229 e.errorCode = 1001;
230 e.message = "This is an Xception";
231 throw e;
232 } else {
233 Xtruct result;
234 result.string_thing = arg;
235 return;
236 }
237 }
238
Mark Sleed3d733a2006-09-01 22:19:06 +0000239 Xtruct testMultiException(std::string arg0, std::string arg1) throw(Xception, Xception2) {
Marc Slemkobf4fd192006-08-15 21:29:39 +0000240
Marc Slemko71d4e472006-08-15 22:34:04 +0000241 printf("testMultiException(%s, %s)\n", arg0.c_str(), arg1.c_str());
Marc Slemkobf4fd192006-08-15 21:29:39 +0000242
Mark Sleef5f2be42006-09-05 21:05:31 +0000243 if (arg0.compare("Xception") == 0) {
Marc Slemkobf4fd192006-08-15 21:29:39 +0000244 Xception e;
245 e.errorCode = 1001;
246 e.message = "This is an Xception";
247 throw e;
Mark Sleef5f2be42006-09-05 21:05:31 +0000248 } else if (arg0.compare("Xception2") == 0) {
Marc Slemkobf4fd192006-08-15 21:29:39 +0000249 Xception2 e;
250 e.errorCode = 2002;
251 e.struct_thing.string_thing = "This is an Xception2";
252 throw e;
253 } else {
254 Xtruct result;
255 result.string_thing = arg1;
256 return result;
257 }
258 }
Mark Sleee8540632006-05-30 09:24:40 +0000259};
260
261int main(int argc, char **argv) {
Marc Slemko6be374b2006-08-04 03:16:25 +0000262
Mark Sleee8540632006-05-30 09:24:40 +0000263 int port = 9090;
Marc Slemko6be374b2006-08-04 03:16:25 +0000264 string serverType = "simple";
265 string protocolType = "binary";
266 size_t workerCount = 4;
267
268 ostringstream usage;
269
270 usage <<
271 argv[0] << " [--port=<port number>] [--server-type=<server-type>] [--protocol-type=<protocol-type>] [--workers=<worker-count>]" << endl <<
272
Marc Slemkobf4fd192006-08-15 21:29:39 +0000273 "\t\tserver-type\t\ttype of server, \"simple\" or \"thread-pool\". Default is " << serverType << endl <<
Marc Slemko6be374b2006-08-04 03:16:25 +0000274
275 "\t\tprotocol-type\t\ttype of protocol, \"binary\", \"ascii\", or \"xml\". Default is " << protocolType << endl <<
276
277 "\t\tworkers\t\tNumber of thread pools workers. Only valid for thread-pool server type. Default is " << workerCount << endl;
278
279 map<string, string> args;
280
Mark Sleef5f2be42006-09-05 21:05:31 +0000281 for (int ix = 1; ix < argc; ix++) {
Marc Slemko6be374b2006-08-04 03:16:25 +0000282 string arg(argv[ix]);
Mark Sleef5f2be42006-09-05 21:05:31 +0000283 if (arg.compare(0,2, "--") == 0) {
Marc Slemko6be374b2006-08-04 03:16:25 +0000284 size_t end = arg.find_first_of("=", 2);
Mark Sleef5f2be42006-09-05 21:05:31 +0000285 if (end != string::npos) {
Marc Slemko6be374b2006-08-04 03:16:25 +0000286 args[string(arg, 2, end - 2)] = string(arg, end + 1);
287 } else {
288 args[string(arg, 2, end - 2)] = "true";
289 }
290 ix++;
291 } else {
292 throw invalid_argument("Unexcepted command line token: "+arg);
293 }
Mark Sleee8540632006-05-30 09:24:40 +0000294 }
Marc Slemko6be374b2006-08-04 03:16:25 +0000295
296 try {
297
Mark Sleef5f2be42006-09-05 21:05:31 +0000298 if (!args["port"].empty()) {
Marc Slemko6be374b2006-08-04 03:16:25 +0000299 port = atoi(args["port"].c_str());
300 }
301
Mark Sleef5f2be42006-09-05 21:05:31 +0000302 if (!args["server-type"].empty()) {
303 serverType = args["server-type"];
304 if (serverType == "simple") {
305 } else if (serverType == "thread-pool") {
Mark Sleeb9acf982006-10-10 01:57:32 +0000306 } else if (serverType == "nonblocking") {
Marc Slemko6be374b2006-08-04 03:16:25 +0000307 } else {
Marc Slemko6be374b2006-08-04 03:16:25 +0000308 throw invalid_argument("Unknown server type "+serverType);
309 }
310 }
311
Mark Sleef5f2be42006-09-05 21:05:31 +0000312 if (!args["protocol-type"].empty()) {
Marc Slemko6be374b2006-08-04 03:16:25 +0000313 protocolType = args["protocol-type"];
Mark Sleef5f2be42006-09-05 21:05:31 +0000314 if (protocolType == "binary") {
315 } else if (protocolType == "ascii") {
Marc Slemko6be374b2006-08-04 03:16:25 +0000316 throw invalid_argument("ASCII protocol not supported");
Mark Sleef5f2be42006-09-05 21:05:31 +0000317 } else if (protocolType == "xml") {
Marc Slemko6be374b2006-08-04 03:16:25 +0000318 throw invalid_argument("XML protocol not supported");
319 } else {
320 throw invalid_argument("Unknown protocol type "+protocolType);
321 }
322 }
323
Mark Sleef5f2be42006-09-05 21:05:31 +0000324 if (!args["workers"].empty()) {
Marc Slemko6be374b2006-08-04 03:16:25 +0000325 workerCount = atoi(args["workers"].c_str());
326 }
Mark Sleef5f2be42006-09-05 21:05:31 +0000327 } catch (exception& e) {
Marc Slemko6be374b2006-08-04 03:16:25 +0000328 cerr << e.what() << endl;
329 cerr << usage;
330 }
331
Mark Sleee8540632006-05-30 09:24:40 +0000332 // Dispatcher
Marc Slemko6be374b2006-08-04 03:16:25 +0000333 shared_ptr<TBinaryProtocol> binaryProtocol(new TBinaryProtocol);
334
Mark Sleed2655522006-09-05 22:09:57 +0000335 shared_ptr<TestHandler> testHandler(new TestHandler());
336
Mark Slee018b6992006-09-07 21:31:12 +0000337 shared_ptr<ThriftTestProcessor> testProcessor(new ThriftTestProcessor(testHandler, binaryProtocol));
Mark Sleee8540632006-05-30 09:24:40 +0000338
Mark Sleee8540632006-05-30 09:24:40 +0000339 // Transport
Marc Slemko6be374b2006-08-04 03:16:25 +0000340 shared_ptr<TServerSocket> serverSocket(new TServerSocket(port));
Mark Sleee8540632006-05-30 09:24:40 +0000341
Mark Sleed788b2e2006-09-07 01:26:35 +0000342 // Factory
343 shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
344
345 // Options
346 shared_ptr<TServerOptions> serverOptions(new TServerOptions());
347
Mark Sleed3d733a2006-09-01 22:19:06 +0000348 if (serverType == "simple") {
Mark Sleee8540632006-05-30 09:24:40 +0000349
Marc Slemko6be374b2006-08-04 03:16:25 +0000350 // Server
Mark Slee018b6992006-09-07 21:31:12 +0000351 TSimpleServer simpleServer(testProcessor,
Mark Sleed788b2e2006-09-07 01:26:35 +0000352 serverSocket,
353 transportFactory,
354 serverOptions
355 );
Marc Slemko6be374b2006-08-04 03:16:25 +0000356
357 printf("Starting the server on port %d...\n", port);
Mark Slee794993d2006-09-20 01:56:10 +0000358 simpleServer.serve();
Marc Slemko6be374b2006-08-04 03:16:25 +0000359
Mark Sleed3d733a2006-09-01 22:19:06 +0000360 } else if (serverType == "thread-pool") {
Marc Slemko6be374b2006-08-04 03:16:25 +0000361
Mark Sleef5f2be42006-09-05 21:05:31 +0000362 shared_ptr<ThreadManager> threadManager =
363 ThreadManager::newSimpleThreadManager(workerCount);
Marc Slemko6be374b2006-08-04 03:16:25 +0000364
Mark Sleef5f2be42006-09-05 21:05:31 +0000365 shared_ptr<PosixThreadFactory> threadFactory =
366 shared_ptr<PosixThreadFactory>(new PosixThreadFactory());
Marc Slemko6be374b2006-08-04 03:16:25 +0000367
368 threadManager->threadFactory(threadFactory);
369
370 threadManager->start();
371
Mark Slee018b6992006-09-07 21:31:12 +0000372 TThreadPoolServer threadPoolServer(testProcessor,
Marc Slemko6be374b2006-08-04 03:16:25 +0000373 serverSocket,
Mark Sleed788b2e2006-09-07 01:26:35 +0000374 transportFactory,
375 threadManager,
376 serverOptions);
Marc Slemko6be374b2006-08-04 03:16:25 +0000377
378 printf("Starting the server on port %d...\n", port);
Mark Slee794993d2006-09-20 01:56:10 +0000379 threadPoolServer.serve();
Mark Sleeb9acf982006-10-10 01:57:32 +0000380
381 } else if (serverType == "nonblocking") {
382
383 TNonblockingServer nonblockingServer(testProcessor,
384 serverOptions,
385 port);
386 printf("Starting the nonblocking server on port %d...\n", port);
387 nonblockingServer.serve();
388
Marc Slemko6be374b2006-08-04 03:16:25 +0000389 }
390
Mark Sleee8540632006-05-30 09:24:40 +0000391 printf("done.\n");
392 return 0;
393}