blob: 26d49d2c5d85933900f5415003aafaf9f05beb2d [file] [log] [blame]
Jake Farrell27274222011-11-10 20:32:44 +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 *)
19
20unit TestServer;
21
22interface
23
24uses
25 SysUtils,
26 Generics.Collections,
27 Thrift.Console,
28 Thrift.Server,
29 Thrift.Transport,
30 Thrift.Protocol,
31 Thrift.Protocol.JSON,
32 Thrift.Collections,
33 Thrift.Utils,
34 Thrift.Test,
35 Thrift,
36 TestConstants,
37 Contnrs;
38
39type
40 TTestServer = class
41 public
42 type
43
44 ITestHandler = interface( TThriftTest.Iface )
45 procedure SetServer( AServer : IServer );
46 end;
47
48 TTestHandlerImpl = class( TInterfacedObject, ITestHandler )
49 private
50 FServer : IServer;
51 protected
52 procedure testVoid();
Jake Farrell7ae13e12011-10-18 14:35:26 +000053 function testString(thing: string): string;
54 function testByte(thing: ShortInt): ShortInt;
55 function testI32(thing: Integer): Integer;
56 function testI64(thing: Int64): Int64;
57 function testDouble(thing: Double): Double;
58 function testStruct(thing: IXtruct): IXtruct;
59 function testNest(thing: IXtruct2): IXtruct2;
60 function testMap(thing: IThriftDictionary<Integer, Integer>): IThriftDictionary<Integer, Integer>;
61 function testStringMap(thing: IThriftDictionary<string, string>): IThriftDictionary<string, string>;
62 function testSet(thing: IHashSet<Integer>): IHashSet<Integer>;
63 function testList(thing: IThriftList<Integer>): IThriftList<Integer>;
64 function testEnum(thing: TNumberz): TNumberz;
65 function testTypedef(thing: Int64): Int64;
66 function testMapMap(hello: Integer): IThriftDictionary<Integer, IThriftDictionary<Integer, Integer>>;
67 function testInsanity(argument: IInsanity): IThriftDictionary<Int64, IThriftDictionary<TNumberz, IInsanity>>;
68 function testMulti(arg0: ShortInt; arg1: Integer; arg2: Int64; arg3: IThriftDictionary<SmallInt, string>; arg4: TNumberz; arg5: Int64): IXtruct;
69 procedure testException(arg: string);
70 function testMultiException(arg0: string; arg1: string): IXtruct;
71 procedure testOneway(secondsToSleep: Integer);
Jake Farrell27274222011-11-10 20:32:44 +000072
73 procedure testStop;
74
75 procedure SetServer( AServer : IServer );
76 end;
77
78 class procedure Execute( args: array of string);
79 end;
80
81implementation
82
83{ TTestServer.TTestHandlerImpl }
84
85procedure TTestServer.TTestHandlerImpl.SetServer(AServer: IServer);
86begin
87 FServer := AServer;
88end;
89
90function TTestServer.TTestHandlerImpl.testByte(thing: ShortInt): ShortInt;
91begin
92 Console.WriteLine('testByte("' + IntToStr( thing) + '")');
93 Result := thing;
94end;
95
96function TTestServer.TTestHandlerImpl.testDouble(thing: Double): Double;
97begin
98 Console.WriteLine('testDouble("' + FloatToStr( thing ) + '")');
99 Result := thing;
100end;
101
102function TTestServer.TTestHandlerImpl.testEnum(thing: TNumberz): TNumberz;
103begin
104 Console.WriteLine('testEnum(' + IntToStr( Integer( thing)) + ')');
105 Result := thing;
106end;
107
108procedure TTestServer.TTestHandlerImpl.testException(arg: string);
109var
110 x : TXception;
111begin
112 Console.WriteLine('testException(' + arg + ')');
113 if ( arg = 'Xception') then
114 begin
115 x := TXception.Create;
116 x.ErrorCode := 1001;
117 x.Message_ := 'This is an Xception';
Jake Farrellac102562011-11-23 14:30:41 +0000118 x.UpdateMessageProperty;
Jake Farrell27274222011-11-10 20:32:44 +0000119 raise x;
120 end;
121end;
122
123function TTestServer.TTestHandlerImpl.testI32(thing: Integer): Integer;
124begin
125 Console.WriteLine('testI32("' + IntToStr( thing) + '")');
126 Result := thing;
127end;
128
129function TTestServer.TTestHandlerImpl.testI64(thing: Int64): Int64;
130begin
131 Console.WriteLine('testI64("' + IntToStr( thing) + '")');
132 Result := thing;
133end;
134
135function TTestServer.TTestHandlerImpl.testInsanity(
136 argument: IInsanity): IThriftDictionary<Int64, IThriftDictionary<TNumberz, IInsanity>>;
137var
138 hello, goodbye : IXtruct;
139 crazy : IInsanity;
140 looney : IInsanity;
141 first_map : IThriftDictionary<TNumberz, IInsanity>;
142 second_map : IThriftDictionary<TNumberz, IInsanity>;
143 insane : IThriftDictionary<Int64, IThriftDictionary<TNumberz, IInsanity>>;
144
145begin
146
147 Console.WriteLine('testInsanity()');
148 hello := TXtructImpl.Create;
149 hello.String_thing := 'hello';
150 hello.Byte_thing := 2;
151 hello.I32_thing := 2;
152 hello.I64_thing := 2;
153
154 goodbye := TXtructImpl.Create;
155 goodbye.String_thing := 'Goodbye4';
156 goodbye.Byte_thing := 4;
157 goodbye.I32_thing := 4;
158 goodbye.I64_thing := 4;
159
160 crazy := TInsanityImpl.Create;
161 crazy.UserMap := TThriftDictionaryImpl<TNumberz, Int64>.Create;
162 crazy.UserMap.AddOrSetValue( TNumberz.EIGHT, 8);
163 crazy.Xtructs := TThriftListImpl<IXtruct>.Create;
164 crazy.Xtructs.Add(goodbye);
165
166 looney := TInsanityImpl.Create;
167 crazy.UserMap.AddOrSetValue( TNumberz.FIVE, 5);
168 crazy.Xtructs.Add(hello);
169
170 first_map := TThriftDictionaryImpl<TNumberz, IInsanity>.Create;
171 second_map := TThriftDictionaryImpl<TNumberz, IInsanity>.Create;
172
173 first_map.AddOrSetValue( TNumberz.SIX, crazy);
174 first_map.AddOrSetValue( TNumberz.THREE, crazy);
175
176 second_map.AddOrSetValue( TNumberz.SIX, looney);
177
178 insane := TThriftDictionaryImpl<Int64, IThriftDictionary<TNumberz, IInsanity>>.Create;
179
180 insane.AddOrSetValue( 1, first_map);
181 insane.AddOrSetValue( 2, second_map);
182
183 Result := insane;
184end;
185
186function TTestServer.TTestHandlerImpl.testList(
187 thing: IThriftList<Integer>): IThriftList<Integer>;
188var
189 first : Boolean;
190 elem : Integer;
191begin
192 Console.Write('testList({');
193 first := True;
194 for elem in thing do
195 begin
196 if first then
197 begin
198 first := False;
199 end else
200 begin
201 Console.Write(', ');
202 end;
203 Console.Write( IntToStr( elem));
204 end;
205 Console.WriteLine('})');
206 Result := thing;
207end;
208
209function TTestServer.TTestHandlerImpl.testMap(
210 thing: IThriftDictionary<Integer, Integer>): IThriftDictionary<Integer, Integer>;
211var
212 first : Boolean;
213 key : Integer;
214begin
215 Console.Write('testMap({');
216 first := True;
217 for key in thing.Keys do
218 begin
219 if (first) then
220 begin
221 first := false;
222 end else
223 begin
224 Console.Write(', ');
225 end;
226 Console.Write(IntToStr(key) + ' => ' + IntToStr( thing[key]));
227 end;
228 Console.WriteLine('})');
229 Result := thing;
230end;
231
232function TTestServer.TTestHandlerImpl.TestMapMap(
233 hello: Integer): IThriftDictionary<Integer, IThriftDictionary<Integer, Integer>>;
234var
235 mapmap : IThriftDictionary<Integer, IThriftDictionary<Integer, Integer>>;
236 pos : IThriftDictionary<Integer, Integer>;
237 neg : IThriftDictionary<Integer, Integer>;
238 i : Integer;
239begin
240 Console.WriteLine('testMapMap(' + IntToStr( hello) + ')');
241 mapmap := TThriftDictionaryImpl<Integer, IThriftDictionary<Integer, Integer>>.Create;
242 pos := TThriftDictionaryImpl<Integer, Integer>.Create;
243 neg := TThriftDictionaryImpl<Integer, Integer>.Create;
244
245 for i := 1 to 4 do
246 begin
247 pos.AddOrSetValue( i, i);
248 neg.AddOrSetValue( -i, -i);
249 end;
250
251 mapmap.AddOrSetValue(4, pos);
252 mapmap.AddOrSetValue( -4, neg);
253
254 Result := mapmap;
255end;
256
257function TTestServer.TTestHandlerImpl.testMulti(arg0: ShortInt; arg1: Integer;
258 arg2: Int64; arg3: IThriftDictionary<SmallInt, string>; arg4: TNumberz;
259 arg5: Int64): IXtruct;
260var
261 hello : IXtruct;
262begin
263 Console.WriteLine('testMulti()');
264 hello := TXtructImpl.Create;
265 hello.String_thing := 'Hello2';
266 hello.Byte_thing := arg0;
267 hello.I32_thing := arg1;
268 hello.I64_thing := arg2;
269 Result := hello;
270end;
271
272function TTestServer.TTestHandlerImpl.testMultiException(arg0,
273 arg1: string): IXtruct;
274var
275 x : TXception;
276 x2 : TXception2;
277begin
278 Console.WriteLine('testMultiException(' + arg0 + ', ' + arg1 + ')');
279 if ( arg0 = 'Xception') then
280 begin
281 x := TXception.Create;
282 x.ErrorCode := 1001;
283 x.Message_ := 'This is an Xception';
Jake Farrellac102562011-11-23 14:30:41 +0000284 x.UpdateMessageProperty;
Jake Farrell27274222011-11-10 20:32:44 +0000285 raise x;
286 end else
287 if ( arg0 = 'Xception2') then
288 begin
289 x2 := TXception2.Create;
290 x2.ErrorCode := 2002;
291 x2.Struct_thing := TXtructImpl.Create;
292 x2.Struct_thing.String_thing := 'This is an Xception2';
Jake Farrellac102562011-11-23 14:30:41 +0000293 x2.UpdateMessageProperty;
Jake Farrell27274222011-11-10 20:32:44 +0000294 raise x2;
295 end;
296
297 Result := TXtructImpl.Create;
298 Result.String_thing := arg1;
299end;
300
301function TTestServer.TTestHandlerImpl.testNest(thing: IXtruct2): IXtruct2;
302var
303 temp : IXtruct;
304begin
305 temp := thing.Struct_thing;
306 Console.WriteLine('testNest({' +
307 IntToStr( thing.Byte_thing) + ', {' +
308 '"' + temp.String_thing + '", ' +
309 IntToStr( temp.Byte_thing) + ', ' +
310 IntToStr( temp.I32_thing) + ', ' +
311 IntToStr( temp.I64_thing) + '}, ' +
312 IntToStr( temp.I32_thing) + '})');
313 Result := thing;
314end;
315
316procedure TTestServer.TTestHandlerImpl.testOneway(secondsToSleep: Integer);
317begin
318 Console.WriteLine('testOneway(' + IntToStr( secondsToSleep )+ '), sleeping...');
319 Sleep(secondsToSleep * 1000);
320 Console.WriteLine('testOneway finished');
321end;
322
323function TTestServer.TTestHandlerImpl.testSet(
324 thing: IHashSet<Integer>):IHashSet<Integer>;
325var
326 first : Boolean;
327 elem : Integer;
328begin
329 Console.Write('testSet({');
330 first := True;
331
332 for elem in thing do
333 begin
334 if first then
335 begin
336 first := False;
337 end else
338 begin
339 Console.Write( ', ');
340 end;
341 Console.Write( IntToStr( elem));
342 end;
343 Console.WriteLine('})');
344 Result := thing;
345end;
346
347procedure TTestServer.TTestHandlerImpl.testStop;
348begin
349 if FServer <> nil then
350 begin
351 FServer.Stop;
352 end;
353end;
354
355function TTestServer.TTestHandlerImpl.testString(thing: string): string;
356begin
357 Console.WriteLine('teststring("' + thing + '")');
358 Result := thing;
359end;
360
361function TTestServer.TTestHandlerImpl.testStringMap(
362 thing: IThriftDictionary<string, string>): IThriftDictionary<string, string>;
363begin
364
365end;
366
367function TTestServer.TTestHandlerImpl.testTypedef(thing: Int64): Int64;
368begin
369 Console.WriteLine('testTypedef(' + IntToStr( thing) + ')');
370 Result := thing;
371end;
372
373procedure TTestServer.TTestHandlerImpl.TestVoid;
374begin
375 Console.WriteLine('testVoid()');
376end;
377
378function TTestServer.TTestHandlerImpl.testStruct(thing: IXtruct): IXtruct;
379begin
380 Console.WriteLine('testStruct({' +
381 '"' + thing.String_thing + '", ' +
382 IntToStr( thing.Byte_thing) + ', ' +
383 IntToStr( thing.I32_thing) + ', ' +
384 IntToStr( thing.I64_thing));
385 Result := thing;
386end;
387
388{ TTestServer }
389
390class procedure TTestServer.Execute(args: array of string);
391var
392 UseBufferedSockets : Boolean;
393 UseFramed : Boolean;
394 Port : Integer;
395 testHandler : ITestHandler;
396 testProcessor : IProcessor;
397 ServerSocket : IServerTransport;
398 ServerEngine : IServer;
399 TransportFactory : ITransportFactory;
400 ProtocolFactory : IProtocolFactory;
401 i : Integer;
402 s : string;
403 protType, p : TKnownProtocol;
404begin
405 try
406 UseBufferedSockets := False;
407 UseFramed := False;
408 protType := prot_Binary;
409 Port := 9090;
410
411 i := 0;
412 while ( i < Length(args) ) do begin
413 s := args[i];
414 Inc(i);
415
416 if StrToIntDef( s, -1) > 0 then
417 begin
418 Port := StrToIntDef( s, Port);
419 end else
420 if ( s = 'raw' ) then
421 begin
422 // as default
423 end else
424 if ( s = 'buffered' ) then
425 begin
426 UseBufferedSockets := True;
427 end else
428 if ( s = 'framed' ) then
429 begin
430 UseFramed := True;
431 end else
432 if (s = '-prot') then // -prot JSON|binary
433 begin
434 s := args[i];
435 Inc( i );
436 for p:= Low(TKnownProtocol) to High(TKnownProtocol) do begin
437 if SameText( s, KNOWN_PROTOCOLS[p]) then begin
438 protType := p;
439 Break;
440 end;
441 end;
442 end else
443 begin
444 // Fall back to the older boolean syntax
445 UseBufferedSockets := StrToBoolDef( args[1], UseBufferedSockets);
446 end
447 end;
448
449 // create protocol factory, default to BinaryProtocol
450 case protType of
451 prot_Binary: ProtocolFactory := TBinaryProtocolImpl.TFactory.Create;
452 prot_JSON : ProtocolFactory := TJSONProtocolImpl.TFactory.Create;
453 else
454 ASSERT( FALSE); // unhandled case!
455 ProtocolFactory := TBinaryProtocolImpl.TFactory.Create;
456 end;
457
458 testHandler := TTestHandlerImpl.Create;
459
460 testProcessor := TThriftTest.TProcessorImpl.Create( testHandler );
461 ServerSocket := TServerSocketImpl.Create( Port, 0, UseBufferedSockets );
462
463 if UseFramed
464 then TransportFactory := TFramedTransportImpl.TFactory.Create
465 else TransportFactory := TTransportFactoryImpl.Create;
466
467 ServerEngine := TSimpleServer.Create( testProcessor,
468 ServerSocket,
469 TransportFactory,
470 ProtocolFactory);
471
472 testHandler.SetServer( ServerEngine);
473
474 Console.WriteLine('Starting the server on port ' + IntToStr( Port) +
475 IfValue(UseBufferedSockets, ' with buffered socket', '') +
476 IfValue(useFramed, ' with framed transport', '') +
477 ' using '+KNOWN_PROTOCOLS[protType]+' protocol' +
478 '...');
479
480 serverEngine.Serve;
481 testHandler.SetServer( nil);
482
483 except
484 on E: Exception do
485 begin
486 Console.Write( E.Message);
487 end;
488 end;
489 Console.WriteLine( 'done.');
490end;
491
492end.