blob: f743aea08fa1dfa43e21deaffb2ccf52622952d5 [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>
6#include <transport/TServerSocket.h>
Mark Sleed788b2e2006-09-07 01:26:35 +00007#include <transport/TBufferedTransportFactory.h>
Mark Slee95771002006-06-07 06:53:25 +00008#include "ThriftTest.h"
Marc Slemko6be374b2006-08-04 03:16:25 +00009
10#include <iostream>
11#include <stdexcept>
12#include <sstream>
13
Mark Sleee8540632006-05-30 09:24:40 +000014using namespace std;
15
Marc Slemko6be374b2006-08-04 03:16:25 +000016using namespace facebook::thrift;
17using namespace facebook::thrift::protocol;
18using namespace facebook::thrift::transport;
19using namespace facebook::thrift::server;
20
Marc Slemkobf4fd192006-08-15 21:29:39 +000021using namespace thrift::test;
22
Mark Sleed2655522006-09-05 22:09:57 +000023class TestHandler : public ThriftTestIf {
Mark Sleee8540632006-05-30 09:24:40 +000024 public:
Mark Sleed2655522006-09-05 22:09:57 +000025 TestHandler() {}
Mark Sleee8540632006-05-30 09:24:40 +000026
27 void testVoid() {
28 printf("testVoid()\n");
29 }
30
31 string testString(string thing) {
32 printf("testString(\"%s\")\n", thing.c_str());
33 return thing;
34 }
35
Mark Sleed3d733a2006-09-01 22:19:06 +000036 int8_t testByte(int8_t thing) {
Mark Sleee8540632006-05-30 09:24:40 +000037 printf("testByte(%d)\n", (int)thing);
38 return thing;
39 }
40
Mark Sleee8540632006-05-30 09:24:40 +000041 int32_t testI32(int32_t thing) {
42 printf("testI32(%d)\n", thing);
43 return thing;
44 }
45
Mark Sleee8540632006-05-30 09:24:40 +000046 int64_t testI64(int64_t thing) {
Mark Sleed3d733a2006-09-01 22:19:06 +000047 printf("testI64(%ld)\n", thing);
Mark Sleee8540632006-05-30 09:24:40 +000048 return thing;
49 }
50
Mark Sleec98d0502006-09-06 02:42:25 +000051 double testDouble(double thing) {
52 printf("testDouble(%lf)\n", thing);
53 return thing;
54 }
55
Mark Sleee8540632006-05-30 09:24:40 +000056 Xtruct testStruct(Xtruct thing) {
Mark Sleed788b2e2006-09-07 01:26:35 +000057 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 +000058 return thing;
59 }
60
61 Xtruct2 testNest(Xtruct2 nest) {
62 Xtruct thing = nest.struct_thing;
Mark Sleed788b2e2006-09-07 01:26:35 +000063 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 +000064 return nest;
65 }
66
67 map<int32_t, int32_t> testMap(map<int32_t, int32_t> thing) {
68 printf("testMap({");
69 map<int32_t, int32_t>::const_iterator m_iter;
70 bool first = true;
71 for (m_iter = thing.begin(); m_iter != thing.end(); ++m_iter) {
72 if (first) {
73 first = false;
74 } else {
75 printf(", ");
76 }
77 printf("%d => %d", m_iter->first, m_iter->second);
78 }
79 printf("})\n");
80 return thing;
81 }
82
83 set<int32_t> testSet(set<int32_t> thing) {
84 printf("testSet({");
85 set<int32_t>::const_iterator s_iter;
86 bool first = true;
87 for (s_iter = thing.begin(); s_iter != thing.end(); ++s_iter) {
88 if (first) {
89 first = false;
90 } else {
91 printf(", ");
92 }
93 printf("%d", *s_iter);
94 }
95 printf("})\n");
96 return thing;
97 }
98
99 list<int32_t> testList(list<int32_t> thing) {
100 printf("testList({");
101 list<int32_t>::const_iterator l_iter;
102 bool first = true;
103 for (l_iter = thing.begin(); l_iter != thing.end(); ++l_iter) {
104 if (first) {
105 first = false;
106 } else {
107 printf(", ");
108 }
109 printf("%d", *l_iter);
110 }
111 printf("})\n");
112 return thing;
113 }
114
Mark Slee95771002006-06-07 06:53:25 +0000115 Numberz testEnum(Numberz thing) {
Mark Sleee8540632006-05-30 09:24:40 +0000116 printf("testEnum(%d)\n", thing);
117 return thing;
118 }
119
Mark Slee95771002006-06-07 06:53:25 +0000120 UserId testTypedef(UserId thing) {
Mark Sleed3d733a2006-09-01 22:19:06 +0000121 printf("testTypedef(%ld)\n", thing);
Mark Sleee8540632006-05-30 09:24:40 +0000122 return thing;
123 }
124
125 map<int32_t, map<int32_t,int32_t> > testMapMap(int32_t hello) {
126 printf("testMapMap(%d)\n", hello);
127 map<int32_t, map<int32_t,int32_t> > mapmap;
128
129 map<int32_t,int32_t> pos;
130 map<int32_t,int32_t> neg;
131 for (int i = 1; i < 5; i++) {
132 pos.insert(make_pair(i,i));
133 neg.insert(make_pair(-i,-i));
134 }
135
136 mapmap.insert(make_pair(4, pos));
137 mapmap.insert(make_pair(-4, neg));
138
139 return mapmap;
140 }
141
142 map<UserId, map<Numberz,Insanity> > testInsanity(Insanity argument) {
143 printf("testInsanity()\n");
144
145 Xtruct hello;
146 hello.string_thing = "Hello2";
147 hello.byte_thing = 2;
Mark Sleee8540632006-05-30 09:24:40 +0000148 hello.i32_thing = 2;
Mark Sleee8540632006-05-30 09:24:40 +0000149 hello.i64_thing = 2;
150
151 Xtruct goodbye;
152 goodbye.string_thing = "Goodbye4";
153 goodbye.byte_thing = 4;
Mark Sleee8540632006-05-30 09:24:40 +0000154 goodbye.i32_thing = 4;
Mark Sleee8540632006-05-30 09:24:40 +0000155 goodbye.i64_thing = 4;
156
157 Insanity crazy;
158 crazy.userMap.insert(make_pair(EIGHT, 8));
159 crazy.xtructs.push_back(goodbye);
160
161 Insanity looney;
162 crazy.userMap.insert(make_pair(FIVE, 5));
163 crazy.xtructs.push_back(hello);
164
165 map<Numberz, Insanity> first_map;
166 map<Numberz, Insanity> second_map;
167
168 first_map.insert(make_pair(TWO, crazy));
169 first_map.insert(make_pair(THREE, crazy));
170
171 second_map.insert(make_pair(SIX, looney));
172
173 map<UserId, map<Numberz,Insanity> > insane;
174 insane.insert(make_pair(1, first_map));
175 insane.insert(make_pair(2, second_map));
176
177 printf("return");
178 printf(" = {");
179 map<UserId, map<Numberz,Insanity> >::const_iterator i_iter;
180 for (i_iter = insane.begin(); i_iter != insane.end(); ++i_iter) {
Mark Sleed3d733a2006-09-01 22:19:06 +0000181 printf("%ld => {", i_iter->first);
Mark Sleee8540632006-05-30 09:24:40 +0000182 map<Numberz,Insanity>::const_iterator i2_iter;
183 for (i2_iter = i_iter->second.begin();
184 i2_iter != i_iter->second.end();
185 ++i2_iter) {
186 printf("%d => {", i2_iter->first);
187 map<Numberz, UserId> userMap = i2_iter->second.userMap;
188 map<Numberz, UserId>::const_iterator um;
189 printf("{");
190 for (um = userMap.begin(); um != userMap.end(); ++um) {
Mark Sleed3d733a2006-09-01 22:19:06 +0000191 printf("%d => %ld, ", um->first, um->second);
Mark Sleee8540632006-05-30 09:24:40 +0000192 }
193 printf("}, ");
194
195 list<Xtruct> xtructs = i2_iter->second.xtructs;
196 list<Xtruct>::const_iterator x;
197 printf("{");
198 for (x = xtructs.begin(); x != xtructs.end(); ++x) {
Mark Sleed788b2e2006-09-07 01:26:35 +0000199 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 +0000200 }
201 printf("}");
202
203 printf("}, ");
204 }
205 printf("}, ");
206 }
207 printf("}\n");
208
209 return insane;
210 }
Marc Slemkoe6889de2006-08-12 00:32:53 +0000211
Mark Sleed3d733a2006-09-01 22:19:06 +0000212 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 +0000213 printf("testMulti()\n");
214
215 Xtruct hello;
216 hello.string_thing = "Hello2";
217 hello.byte_thing = arg0;
218 hello.i32_thing = arg1;
219 hello.i64_thing = (int64_t)arg2;
220
221 return hello;
222 }
Marc Slemkobf4fd192006-08-15 21:29:39 +0000223
Mark Sleed3d733a2006-09-01 22:19:06 +0000224 void testException(std::string arg) throw(Xception) {
Marc Slemkobf4fd192006-08-15 21:29:39 +0000225 printf("testException(%s)\n", arg.c_str());
Mark Sleed3d733a2006-09-01 22:19:06 +0000226 if (arg.compare("Xception") == 0) {
Marc Slemkobf4fd192006-08-15 21:29:39 +0000227 Xception e;
228 e.errorCode = 1001;
229 e.message = "This is an Xception";
230 throw e;
231 } else {
232 Xtruct result;
233 result.string_thing = arg;
234 return;
235 }
236 }
237
Mark Sleed3d733a2006-09-01 22:19:06 +0000238 Xtruct testMultiException(std::string arg0, std::string arg1) throw(Xception, Xception2) {
Marc Slemkobf4fd192006-08-15 21:29:39 +0000239
Marc Slemko71d4e472006-08-15 22:34:04 +0000240 printf("testMultiException(%s, %s)\n", arg0.c_str(), arg1.c_str());
Marc Slemkobf4fd192006-08-15 21:29:39 +0000241
Mark Sleef5f2be42006-09-05 21:05:31 +0000242 if (arg0.compare("Xception") == 0) {
Marc Slemkobf4fd192006-08-15 21:29:39 +0000243 Xception e;
244 e.errorCode = 1001;
245 e.message = "This is an Xception";
246 throw e;
Mark Sleef5f2be42006-09-05 21:05:31 +0000247 } else if (arg0.compare("Xception2") == 0) {
Marc Slemkobf4fd192006-08-15 21:29:39 +0000248 Xception2 e;
249 e.errorCode = 2002;
250 e.struct_thing.string_thing = "This is an Xception2";
251 throw e;
252 } else {
253 Xtruct result;
254 result.string_thing = arg1;
255 return result;
256 }
257 }
Mark Sleee8540632006-05-30 09:24:40 +0000258};
259
260int main(int argc, char **argv) {
Marc Slemko6be374b2006-08-04 03:16:25 +0000261
Mark Sleee8540632006-05-30 09:24:40 +0000262 int port = 9090;
Marc Slemko6be374b2006-08-04 03:16:25 +0000263 string serverType = "simple";
264 string protocolType = "binary";
265 size_t workerCount = 4;
266
267 ostringstream usage;
268
269 usage <<
270 argv[0] << " [--port=<port number>] [--server-type=<server-type>] [--protocol-type=<protocol-type>] [--workers=<worker-count>]" << endl <<
271
Marc Slemkobf4fd192006-08-15 21:29:39 +0000272 "\t\tserver-type\t\ttype of server, \"simple\" or \"thread-pool\". Default is " << serverType << endl <<
Marc Slemko6be374b2006-08-04 03:16:25 +0000273
274 "\t\tprotocol-type\t\ttype of protocol, \"binary\", \"ascii\", or \"xml\". Default is " << protocolType << endl <<
275
276 "\t\tworkers\t\tNumber of thread pools workers. Only valid for thread-pool server type. Default is " << workerCount << endl;
277
278 map<string, string> args;
279
Mark Sleef5f2be42006-09-05 21:05:31 +0000280 for (int ix = 1; ix < argc; ix++) {
Marc Slemko6be374b2006-08-04 03:16:25 +0000281 string arg(argv[ix]);
Mark Sleef5f2be42006-09-05 21:05:31 +0000282 if (arg.compare(0,2, "--") == 0) {
Marc Slemko6be374b2006-08-04 03:16:25 +0000283 size_t end = arg.find_first_of("=", 2);
Mark Sleef5f2be42006-09-05 21:05:31 +0000284 if (end != string::npos) {
Marc Slemko6be374b2006-08-04 03:16:25 +0000285 args[string(arg, 2, end - 2)] = string(arg, end + 1);
286 } else {
287 args[string(arg, 2, end - 2)] = "true";
288 }
289 ix++;
290 } else {
291 throw invalid_argument("Unexcepted command line token: "+arg);
292 }
Mark Sleee8540632006-05-30 09:24:40 +0000293 }
Marc Slemko6be374b2006-08-04 03:16:25 +0000294
295 try {
296
Mark Sleef5f2be42006-09-05 21:05:31 +0000297 if (!args["port"].empty()) {
Marc Slemko6be374b2006-08-04 03:16:25 +0000298 port = atoi(args["port"].c_str());
299 }
300
Mark Sleef5f2be42006-09-05 21:05:31 +0000301 if (!args["server-type"].empty()) {
302 serverType = args["server-type"];
303 if (serverType == "simple") {
304 } else if (serverType == "thread-pool") {
Marc Slemko6be374b2006-08-04 03:16:25 +0000305 } else {
Marc Slemko6be374b2006-08-04 03:16:25 +0000306 throw invalid_argument("Unknown server type "+serverType);
307 }
308 }
309
Mark Sleef5f2be42006-09-05 21:05:31 +0000310 if (!args["protocol-type"].empty()) {
Marc Slemko6be374b2006-08-04 03:16:25 +0000311 protocolType = args["protocol-type"];
Mark Sleef5f2be42006-09-05 21:05:31 +0000312 if (protocolType == "binary") {
313 } else if (protocolType == "ascii") {
Marc Slemko6be374b2006-08-04 03:16:25 +0000314 throw invalid_argument("ASCII protocol not supported");
Mark Sleef5f2be42006-09-05 21:05:31 +0000315 } else if (protocolType == "xml") {
Marc Slemko6be374b2006-08-04 03:16:25 +0000316 throw invalid_argument("XML protocol not supported");
317 } else {
318 throw invalid_argument("Unknown protocol type "+protocolType);
319 }
320 }
321
Mark Sleef5f2be42006-09-05 21:05:31 +0000322 if (!args["workers"].empty()) {
Marc Slemko6be374b2006-08-04 03:16:25 +0000323 workerCount = atoi(args["workers"].c_str());
324 }
Mark Sleef5f2be42006-09-05 21:05:31 +0000325 } catch (exception& e) {
Marc Slemko6be374b2006-08-04 03:16:25 +0000326 cerr << e.what() << endl;
327 cerr << usage;
328 }
329
Mark Sleee8540632006-05-30 09:24:40 +0000330 // Dispatcher
Marc Slemko6be374b2006-08-04 03:16:25 +0000331 shared_ptr<TBinaryProtocol> binaryProtocol(new TBinaryProtocol);
332
Mark Sleed2655522006-09-05 22:09:57 +0000333 shared_ptr<TestHandler> testHandler(new TestHandler());
334
335 shared_ptr<ThriftTestServer> testServer(new ThriftTestServer(testHandler, binaryProtocol));
Mark Sleee8540632006-05-30 09:24:40 +0000336
Mark Sleee8540632006-05-30 09:24:40 +0000337 // Transport
Marc Slemko6be374b2006-08-04 03:16:25 +0000338 shared_ptr<TServerSocket> serverSocket(new TServerSocket(port));
Mark Sleee8540632006-05-30 09:24:40 +0000339
Mark Sleed788b2e2006-09-07 01:26:35 +0000340 // Factory
341 shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
342
343 // Options
344 shared_ptr<TServerOptions> serverOptions(new TServerOptions());
345
Mark Sleed3d733a2006-09-01 22:19:06 +0000346 if (serverType == "simple") {
Mark Sleee8540632006-05-30 09:24:40 +0000347
Marc Slemko6be374b2006-08-04 03:16:25 +0000348 // Server
349 TSimpleServer simpleServer(testServer,
Mark Sleed788b2e2006-09-07 01:26:35 +0000350 serverSocket,
351 transportFactory,
352 serverOptions
353 );
Marc Slemko6be374b2006-08-04 03:16:25 +0000354
355 printf("Starting the server on port %d...\n", port);
356 simpleServer.run();
357
Mark Sleed3d733a2006-09-01 22:19:06 +0000358 } else if (serverType == "thread-pool") {
Marc Slemko6be374b2006-08-04 03:16:25 +0000359
Mark Sleef5f2be42006-09-05 21:05:31 +0000360 shared_ptr<ThreadManager> threadManager =
361 ThreadManager::newSimpleThreadManager(workerCount);
Marc Slemko6be374b2006-08-04 03:16:25 +0000362
Mark Sleef5f2be42006-09-05 21:05:31 +0000363 shared_ptr<PosixThreadFactory> threadFactory =
364 shared_ptr<PosixThreadFactory>(new PosixThreadFactory());
Marc Slemko6be374b2006-08-04 03:16:25 +0000365
366 threadManager->threadFactory(threadFactory);
367
368 threadManager->start();
369
370 TThreadPoolServer threadPoolServer(testServer,
Marc Slemko6be374b2006-08-04 03:16:25 +0000371 serverSocket,
Mark Sleed788b2e2006-09-07 01:26:35 +0000372 transportFactory,
373 threadManager,
374 serverOptions);
Marc Slemko6be374b2006-08-04 03:16:25 +0000375
376 printf("Starting the server on port %d...\n", port);
377 threadPoolServer.run();
378 }
379
Mark Sleee8540632006-05-30 09:24:40 +0000380 printf("done.\n");
381 return 0;
382}