blob: ecaf80d60b5379c1a8d5d4acd618ecf5f16e8673 [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';
118 raise x;
119 end;
120end;
121
122function TTestServer.TTestHandlerImpl.testI32(thing: Integer): Integer;
123begin
124 Console.WriteLine('testI32("' + IntToStr( thing) + '")');
125 Result := thing;
126end;
127
128function TTestServer.TTestHandlerImpl.testI64(thing: Int64): Int64;
129begin
130 Console.WriteLine('testI64("' + IntToStr( thing) + '")');
131 Result := thing;
132end;
133
134function TTestServer.TTestHandlerImpl.testInsanity(
135 argument: IInsanity): IThriftDictionary<Int64, IThriftDictionary<TNumberz, IInsanity>>;
136var
137 hello, goodbye : IXtruct;
138 crazy : IInsanity;
139 looney : IInsanity;
140 first_map : IThriftDictionary<TNumberz, IInsanity>;
141 second_map : IThriftDictionary<TNumberz, IInsanity>;
142 insane : IThriftDictionary<Int64, IThriftDictionary<TNumberz, IInsanity>>;
143
144begin
145
146 Console.WriteLine('testInsanity()');
147 hello := TXtructImpl.Create;
148 hello.String_thing := 'hello';
149 hello.Byte_thing := 2;
150 hello.I32_thing := 2;
151 hello.I64_thing := 2;
152
153 goodbye := TXtructImpl.Create;
154 goodbye.String_thing := 'Goodbye4';
155 goodbye.Byte_thing := 4;
156 goodbye.I32_thing := 4;
157 goodbye.I64_thing := 4;
158
159 crazy := TInsanityImpl.Create;
160 crazy.UserMap := TThriftDictionaryImpl<TNumberz, Int64>.Create;
161 crazy.UserMap.AddOrSetValue( TNumberz.EIGHT, 8);
162 crazy.Xtructs := TThriftListImpl<IXtruct>.Create;
163 crazy.Xtructs.Add(goodbye);
164
165 looney := TInsanityImpl.Create;
166 crazy.UserMap.AddOrSetValue( TNumberz.FIVE, 5);
167 crazy.Xtructs.Add(hello);
168
169 first_map := TThriftDictionaryImpl<TNumberz, IInsanity>.Create;
170 second_map := TThriftDictionaryImpl<TNumberz, IInsanity>.Create;
171
172 first_map.AddOrSetValue( TNumberz.SIX, crazy);
173 first_map.AddOrSetValue( TNumberz.THREE, crazy);
174
175 second_map.AddOrSetValue( TNumberz.SIX, looney);
176
177 insane := TThriftDictionaryImpl<Int64, IThriftDictionary<TNumberz, IInsanity>>.Create;
178
179 insane.AddOrSetValue( 1, first_map);
180 insane.AddOrSetValue( 2, second_map);
181
182 Result := insane;
183end;
184
185function TTestServer.TTestHandlerImpl.testList(
186 thing: IThriftList<Integer>): IThriftList<Integer>;
187var
188 first : Boolean;
189 elem : Integer;
190begin
191 Console.Write('testList({');
192 first := True;
193 for elem in thing do
194 begin
195 if first then
196 begin
197 first := False;
198 end else
199 begin
200 Console.Write(', ');
201 end;
202 Console.Write( IntToStr( elem));
203 end;
204 Console.WriteLine('})');
205 Result := thing;
206end;
207
208function TTestServer.TTestHandlerImpl.testMap(
209 thing: IThriftDictionary<Integer, Integer>): IThriftDictionary<Integer, Integer>;
210var
211 first : Boolean;
212 key : Integer;
213begin
214 Console.Write('testMap({');
215 first := True;
216 for key in thing.Keys do
217 begin
218 if (first) then
219 begin
220 first := false;
221 end else
222 begin
223 Console.Write(', ');
224 end;
225 Console.Write(IntToStr(key) + ' => ' + IntToStr( thing[key]));
226 end;
227 Console.WriteLine('})');
228 Result := thing;
229end;
230
231function TTestServer.TTestHandlerImpl.TestMapMap(
232 hello: Integer): IThriftDictionary<Integer, IThriftDictionary<Integer, Integer>>;
233var
234 mapmap : IThriftDictionary<Integer, IThriftDictionary<Integer, Integer>>;
235 pos : IThriftDictionary<Integer, Integer>;
236 neg : IThriftDictionary<Integer, Integer>;
237 i : Integer;
238begin
239 Console.WriteLine('testMapMap(' + IntToStr( hello) + ')');
240 mapmap := TThriftDictionaryImpl<Integer, IThriftDictionary<Integer, Integer>>.Create;
241 pos := TThriftDictionaryImpl<Integer, Integer>.Create;
242 neg := TThriftDictionaryImpl<Integer, Integer>.Create;
243
244 for i := 1 to 4 do
245 begin
246 pos.AddOrSetValue( i, i);
247 neg.AddOrSetValue( -i, -i);
248 end;
249
250 mapmap.AddOrSetValue(4, pos);
251 mapmap.AddOrSetValue( -4, neg);
252
253 Result := mapmap;
254end;
255
256function TTestServer.TTestHandlerImpl.testMulti(arg0: ShortInt; arg1: Integer;
257 arg2: Int64; arg3: IThriftDictionary<SmallInt, string>; arg4: TNumberz;
258 arg5: Int64): IXtruct;
259var
260 hello : IXtruct;
261begin
262 Console.WriteLine('testMulti()');
263 hello := TXtructImpl.Create;
264 hello.String_thing := 'Hello2';
265 hello.Byte_thing := arg0;
266 hello.I32_thing := arg1;
267 hello.I64_thing := arg2;
268 Result := hello;
269end;
270
271function TTestServer.TTestHandlerImpl.testMultiException(arg0,
272 arg1: string): IXtruct;
273var
274 x : TXception;
275 x2 : TXception2;
276begin
277 Console.WriteLine('testMultiException(' + arg0 + ', ' + arg1 + ')');
278 if ( arg0 = 'Xception') then
279 begin
280 x := TXception.Create;
281 x.ErrorCode := 1001;
282 x.Message_ := 'This is an Xception';
283 raise x;
284 end else
285 if ( arg0 = 'Xception2') then
286 begin
287 x2 := TXception2.Create;
288 x2.ErrorCode := 2002;
289 x2.Struct_thing := TXtructImpl.Create;
290 x2.Struct_thing.String_thing := 'This is an Xception2';
291 raise x2;
292 end;
293
294 Result := TXtructImpl.Create;
295 Result.String_thing := arg1;
296end;
297
298function TTestServer.TTestHandlerImpl.testNest(thing: IXtruct2): IXtruct2;
299var
300 temp : IXtruct;
301begin
302 temp := thing.Struct_thing;
303 Console.WriteLine('testNest({' +
304 IntToStr( thing.Byte_thing) + ', {' +
305 '"' + temp.String_thing + '", ' +
306 IntToStr( temp.Byte_thing) + ', ' +
307 IntToStr( temp.I32_thing) + ', ' +
308 IntToStr( temp.I64_thing) + '}, ' +
309 IntToStr( temp.I32_thing) + '})');
310 Result := thing;
311end;
312
313procedure TTestServer.TTestHandlerImpl.testOneway(secondsToSleep: Integer);
314begin
315 Console.WriteLine('testOneway(' + IntToStr( secondsToSleep )+ '), sleeping...');
316 Sleep(secondsToSleep * 1000);
317 Console.WriteLine('testOneway finished');
318end;
319
320function TTestServer.TTestHandlerImpl.testSet(
321 thing: IHashSet<Integer>):IHashSet<Integer>;
322var
323 first : Boolean;
324 elem : Integer;
325begin
326 Console.Write('testSet({');
327 first := True;
328
329 for elem in thing do
330 begin
331 if first then
332 begin
333 first := False;
334 end else
335 begin
336 Console.Write( ', ');
337 end;
338 Console.Write( IntToStr( elem));
339 end;
340 Console.WriteLine('})');
341 Result := thing;
342end;
343
344procedure TTestServer.TTestHandlerImpl.testStop;
345begin
346 if FServer <> nil then
347 begin
348 FServer.Stop;
349 end;
350end;
351
352function TTestServer.TTestHandlerImpl.testString(thing: string): string;
353begin
354 Console.WriteLine('teststring("' + thing + '")');
355 Result := thing;
356end;
357
358function TTestServer.TTestHandlerImpl.testStringMap(
359 thing: IThriftDictionary<string, string>): IThriftDictionary<string, string>;
360begin
361
362end;
363
364function TTestServer.TTestHandlerImpl.testTypedef(thing: Int64): Int64;
365begin
366 Console.WriteLine('testTypedef(' + IntToStr( thing) + ')');
367 Result := thing;
368end;
369
370procedure TTestServer.TTestHandlerImpl.TestVoid;
371begin
372 Console.WriteLine('testVoid()');
373end;
374
375function TTestServer.TTestHandlerImpl.testStruct(thing: IXtruct): IXtruct;
376begin
377 Console.WriteLine('testStruct({' +
378 '"' + thing.String_thing + '", ' +
379 IntToStr( thing.Byte_thing) + ', ' +
380 IntToStr( thing.I32_thing) + ', ' +
381 IntToStr( thing.I64_thing));
382 Result := thing;
383end;
384
385{ TTestServer }
386
387class procedure TTestServer.Execute(args: array of string);
388var
389 UseBufferedSockets : Boolean;
390 UseFramed : Boolean;
391 Port : Integer;
392 testHandler : ITestHandler;
393 testProcessor : IProcessor;
394 ServerSocket : IServerTransport;
395 ServerEngine : IServer;
396 TransportFactory : ITransportFactory;
397 ProtocolFactory : IProtocolFactory;
398 i : Integer;
399 s : string;
400 protType, p : TKnownProtocol;
401begin
402 try
403 UseBufferedSockets := False;
404 UseFramed := False;
405 protType := prot_Binary;
406 Port := 9090;
407
408 i := 0;
409 while ( i < Length(args) ) do begin
410 s := args[i];
411 Inc(i);
412
413 if StrToIntDef( s, -1) > 0 then
414 begin
415 Port := StrToIntDef( s, Port);
416 end else
417 if ( s = 'raw' ) then
418 begin
419 // as default
420 end else
421 if ( s = 'buffered' ) then
422 begin
423 UseBufferedSockets := True;
424 end else
425 if ( s = 'framed' ) then
426 begin
427 UseFramed := True;
428 end else
429 if (s = '-prot') then // -prot JSON|binary
430 begin
431 s := args[i];
432 Inc( i );
433 for p:= Low(TKnownProtocol) to High(TKnownProtocol) do begin
434 if SameText( s, KNOWN_PROTOCOLS[p]) then begin
435 protType := p;
436 Break;
437 end;
438 end;
439 end else
440 begin
441 // Fall back to the older boolean syntax
442 UseBufferedSockets := StrToBoolDef( args[1], UseBufferedSockets);
443 end
444 end;
445
446 // create protocol factory, default to BinaryProtocol
447 case protType of
448 prot_Binary: ProtocolFactory := TBinaryProtocolImpl.TFactory.Create;
449 prot_JSON : ProtocolFactory := TJSONProtocolImpl.TFactory.Create;
450 else
451 ASSERT( FALSE); // unhandled case!
452 ProtocolFactory := TBinaryProtocolImpl.TFactory.Create;
453 end;
454
455 testHandler := TTestHandlerImpl.Create;
456
457 testProcessor := TThriftTest.TProcessorImpl.Create( testHandler );
458 ServerSocket := TServerSocketImpl.Create( Port, 0, UseBufferedSockets );
459
460 if UseFramed
461 then TransportFactory := TFramedTransportImpl.TFactory.Create
462 else TransportFactory := TTransportFactoryImpl.Create;
463
464 ServerEngine := TSimpleServer.Create( testProcessor,
465 ServerSocket,
466 TransportFactory,
467 ProtocolFactory);
468
469 testHandler.SetServer( ServerEngine);
470
471 Console.WriteLine('Starting the server on port ' + IntToStr( Port) +
472 IfValue(UseBufferedSockets, ' with buffered socket', '') +
473 IfValue(useFramed, ' with framed transport', '') +
474 ' using '+KNOWN_PROTOCOLS[protType]+' protocol' +
475 '...');
476
477 serverEngine.Serve;
478 testHandler.SetServer( nil);
479
480 except
481 on E: Exception do
482 begin
483 Console.Write( E.Message);
484 end;
485 end;
486 Console.WriteLine( 'done.');
487end;
488
489end.