blob: 1608a57c58cd08e1ce496d4bd2215adbdb339d27 [file] [log] [blame]
Jake Farrellb95b0ff2012-03-22 21:49:10 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19module thrift_test_server;
20
21import core.thread : dur, Thread;
22import std.algorithm;
23import std.exception : enforce;
24import std.getopt;
25import std.parallelism : totalCPUs;
26import std.string;
27import std.stdio;
28import std.typetuple : TypeTuple, staticMap;
29import thrift.base;
30import thrift.codegen.processor;
31import thrift.protocol.base;
32import thrift.protocol.binary;
33import thrift.protocol.compact;
34import thrift.protocol.json;
35import thrift.server.base;
36import thrift.server.transport.socket;
37import thrift.server.transport.ssl;
38import thrift.transport.base;
39import thrift.transport.buffered;
40import thrift.transport.framed;
41import thrift.transport.http;
42import thrift.transport.ssl;
43import thrift.util.hashset;
44import test_utils;
45
46import thrift_test_common;
47import thrift.test.ThriftTest_types;
48import thrift.test.ThriftTest;
49
50class TestHandler : ThriftTest {
51 this(bool trace) {
52 trace_ = trace;
53 }
54
55 override void testVoid() {
56 if (trace_) writeln("testVoid()");
57 }
58
59 override string testString(string thing) {
60 if (trace_) writefln("testString(\"%s\")", thing);
61 return thing;
62 }
63
64 override byte testByte(byte thing) {
65 if (trace_) writefln("testByte(%s)", thing);
66 return thing;
67 }
68
69 override int testI32(int thing) {
70 if (trace_) writefln("testI32(%s)", thing);
71 return thing;
72 }
73
74 override long testI64(long thing) {
75 if (trace_) writefln("testI64(%s)", thing);
76 return thing;
77 }
78
79 override double testDouble(double thing) {
80 if (trace_) writefln("testDouble(%s)", thing);
81 return thing;
82 }
83
Jens Geyer8bcfdd92014-12-14 03:14:26 +010084 override string testBinary(string thing) {
85 if (trace_) writefln("testBinary(\"%s\")", thing);
86 return thing;
87 }
88
Jake Farrellb95b0ff2012-03-22 21:49:10 +000089 override Xtruct testStruct(ref const(Xtruct) thing) {
90 if (trace_) writefln("testStruct({\"%s\", %s, %s, %s})",
91 thing.string_thing, thing.byte_thing, thing.i32_thing, thing.i64_thing);
92 return thing;
93 }
94
95 override Xtruct2 testNest(ref const(Xtruct2) nest) {
96 auto thing = nest.struct_thing;
97 if (trace_) writefln("testNest({%s, {\"%s\", %s, %s, %s}, %s})",
98 nest.byte_thing, thing.string_thing, thing.byte_thing, thing.i32_thing,
99 thing.i64_thing, nest.i32_thing);
100 return nest;
101 }
102
103 override int[int] testMap(int[int] thing) {
104 if (trace_) writefln("testMap({%s})", thing);
105 return thing;
106 }
107
108 override HashSet!int testSet(HashSet!int thing) {
109 if (trace_) writefln("testSet({%s})",
110 join(map!`to!string(a)`(thing[]), ", "));
111 return thing;
112 }
113
114 override int[] testList(int[] thing) {
115 if (trace_) writefln("testList(%s)", thing);
116 return thing;
117 }
118
119 override Numberz testEnum(Numberz thing) {
120 if (trace_) writefln("testEnum(%s)", thing);
121 return thing;
122 }
123
124 override UserId testTypedef(UserId thing) {
125 if (trace_) writefln("testTypedef(%s)", thing);
126 return thing;
127 }
128
129 override string[string] testStringMap(string[string] thing) {
130 if (trace_) writefln("testStringMap(%s)", thing);
131 return thing;
132 }
133
134 override int[int][int] testMapMap(int hello) {
135 if (trace_) writefln("testMapMap(%s)", hello);
136 return testMapMapReturn;
137 }
138
139 override Insanity[Numberz][UserId] testInsanity(ref const(Insanity) argument) {
140 if (trace_) writeln("testInsanity()");
141 return testInsanityReturn;
142 }
143
144 override Xtruct testMulti(byte arg0, int arg1, long arg2, string[short] arg3,
145 Numberz arg4, UserId arg5)
146 {
147 if (trace_) writeln("testMulti()");
148 return Xtruct("Hello2", arg0, arg1, arg2);
149 }
150
151 override void testException(string arg) {
152 if (trace_) writefln("testException(%s)", arg);
153 if (arg == "Xception") {
154 auto e = new Xception();
155 e.errorCode = 1001;
156 e.message = arg;
157 throw e;
158 } else if (arg == "ApplicationException") {
159 throw new TException();
160 }
161 }
162
163 override Xtruct testMultiException(string arg0, string arg1) {
164 if (trace_) writefln("testMultiException(%s, %s)", arg0, arg1);
165
166 if (arg0 == "Xception") {
167 auto e = new Xception();
168 e.errorCode = 1001;
169 e.message = "This is an Xception";
170 throw e;
171 } else if (arg0 == "Xception2") {
172 auto e = new Xception2();
173 e.errorCode = 2002;
174 e.struct_thing.string_thing = "This is an Xception2";
175 throw e;
176 } else {
177 return Xtruct(arg1);
178 }
179 }
180
181 override void testOneway(int sleepFor) {
182 if (trace_) writefln("testOneway(%s): Sleeping...", sleepFor);
183 Thread.sleep(dur!"seconds"(sleepFor));
184 if (trace_) writefln("testOneway(%s): done sleeping!", sleepFor);
185 }
186
187private:
188 bool trace_;
189}
190
191void main(string[] args) {
192 ushort port = 9090;
193 ServerType serverType;
194 ProtocolType protocolType;
195 size_t numIOThreads = 1;
196 TransportType transportType;
197 bool ssl;
198 bool trace;
199 size_t taskPoolSize = totalCPUs;
200
201 getopt(args, "port", &port, "protocol", &protocolType, "server-type",
202 &serverType, "ssl", &ssl, "num-io-threads", &numIOThreads,
203 "task-pool-size", &taskPoolSize, "trace", &trace,
204 "transport", &transportType);
205
206 if (serverType == ServerType.nonblocking ||
207 serverType == ServerType.pooledNonblocking
208 ) {
209 enforce(transportType == TransportType.framed,
210 "Need to use framed transport with non-blocking server.");
211 enforce(!ssl, "The non-blocking server does not support SSL yet.");
212
213 // Don't wrap the contents into another layer of framing.
214 transportType = TransportType.raw;
215 }
216
217 version (ThriftTestTemplates) {
218 // Only exercise the specialized template code paths if explicitly enabled
219 // to reduce memory consumption on regular test suite runs – there should
220 // not be much that can go wrong with that specifically anyway.
221 alias TypeTuple!(TBufferedTransport, TFramedTransport, TServerHttpTransport)
222 AvailableTransports;
223 alias TypeTuple!(
224 staticMap!(TBinaryProtocol, AvailableTransports),
225 staticMap!(TCompactProtocol, AvailableTransports)
226 ) AvailableProtocols;
227 } else {
228 alias TypeTuple!() AvailableTransports;
229 alias TypeTuple!() AvailableProtocols;
230 }
231
232 TProtocolFactory protocolFactory;
233 final switch (protocolType) {
234 case ProtocolType.binary:
235 protocolFactory = new TBinaryProtocolFactory!AvailableTransports;
236 break;
237 case ProtocolType.compact:
238 protocolFactory = new TCompactProtocolFactory!AvailableTransports;
239 break;
240 case ProtocolType.json:
241 protocolFactory = new TJsonProtocolFactory!AvailableTransports;
242 break;
243 }
244
245 auto processor = new TServiceProcessor!(ThriftTest, AvailableProtocols)(
246 new TestHandler(trace));
247
248 TServerSocket serverSocket;
249 if (ssl) {
250 auto sslContext = new TSSLContext();
251 sslContext.serverSide = true;
252 sslContext.loadCertificate("./server-certificate.pem");
253 sslContext.loadPrivateKey("./server-private-key.pem");
254 sslContext.ciphers = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH";
255 serverSocket = new TSSLServerSocket(port, sslContext);
256 } else {
257 serverSocket = new TServerSocket(port);
258 }
259
260 auto transportFactory = createTransportFactory(transportType);
261
262 auto server = createServer(serverType, numIOThreads, taskPoolSize,
263 processor, serverSocket, transportFactory, protocolFactory);
264
265 writefln("Starting %s/%s %s ThriftTest server %son port %s...", protocolType,
266 transportType, serverType, ssl ? "(using SSL) ": "", port);
267 server.serve();
268 writeln("done.");
269}