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