| (* | |
| * Licensed to the Apache Software Foundation (ASF) under one | |
| * or more contributor license agreements. See the NOTICE file | |
| * distributed with this work for additional information | |
| * regarding copyright ownership. The ASF licenses this file | |
| * to you under the Apache License, Version 2.0 (the | |
| * "License"); you may not use this file except in compliance | |
| * with the License. You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, | |
| * software distributed under the License is distributed on an | |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| * KIND, either express or implied. See the License for the | |
| * specific language governing permissions and limitations | |
| * under the License. | |
| *) | |
| unit TestServer; | |
| interface | |
| uses | |
| SysUtils, | |
| Generics.Collections, | |
| Thrift.Console, | |
| Thrift.Server, | |
| Thrift.Transport, | |
| Thrift.Collections, | |
| Thrift.Utils, | |
| Thrift.Test, | |
| Thrift, | |
| Contnrs; | |
| type | |
| TTestServer = class | |
| public | |
| type | |
| ITestHandler = interface( TThriftTest.Iface ) | |
| procedure SetServer( AServer : IServer ); | |
| end; | |
| TTestHandlerImpl = class( TInterfacedObject, ITestHandler ) | |
| private | |
| FServer : IServer; | |
| protected | |
| procedure testVoid(); | |
| function testString(thing: string): string; | |
| function testByte(thing: ShortInt): ShortInt; | |
| function testI32(thing: Integer): Integer; | |
| function testI64(thing: Int64): Int64; | |
| function testDouble(thing: Double): Double; | |
| function testStruct(thing: IXtruct): IXtruct; | |
| function testNest(thing: IXtruct2): IXtruct2; | |
| function testMap(thing: IThriftDictionary<Integer, Integer>): IThriftDictionary<Integer, Integer>; | |
| function testStringMap(thing: IThriftDictionary<string, string>): IThriftDictionary<string, string>; | |
| function testSet(thing: IHashSet<Integer>): IHashSet<Integer>; | |
| function testList(thing: IThriftList<Integer>): IThriftList<Integer>; | |
| function testEnum(thing: TNumberz): TNumberz; | |
| function testTypedef(thing: Int64): Int64; | |
| function testMapMap(hello: Integer): IThriftDictionary<Integer, IThriftDictionary<Integer, Integer>>; | |
| function testInsanity(argument: IInsanity): IThriftDictionary<Int64, IThriftDictionary<TNumberz, IInsanity>>; | |
| function testMulti(arg0: ShortInt; arg1: Integer; arg2: Int64; arg3: IThriftDictionary<SmallInt, string>; arg4: TNumberz; arg5: Int64): IXtruct; | |
| procedure testException(arg: string); | |
| function testMultiException(arg0: string; arg1: string): IXtruct; | |
| procedure testOneway(secondsToSleep: Integer); | |
| procedure testStop; | |
| procedure SetServer( AServer : IServer ); | |
| end; | |
| class procedure Execute( args: array of string); | |
| end; | |
| implementation | |
| { TTestServer.TTestHandlerImpl } | |
| procedure TTestServer.TTestHandlerImpl.SetServer(AServer: IServer); | |
| begin | |
| FServer := AServer; | |
| end; | |
| function TTestServer.TTestHandlerImpl.testByte(thing: ShortInt): ShortInt; | |
| begin | |
| Console.WriteLine('testByte("' + IntToStr( thing) + '")'); | |
| Result := thing; | |
| end; | |
| function TTestServer.TTestHandlerImpl.testDouble(thing: Double): Double; | |
| begin | |
| Console.WriteLine('testDouble("' + FloatToStr( thing ) + '")'); | |
| Result := thing; | |
| end; | |
| function TTestServer.TTestHandlerImpl.testEnum(thing: TNumberz): TNumberz; | |
| begin | |
| Console.WriteLine('testEnum(' + IntToStr( Integer( thing)) + ')'); | |
| Result := thing; | |
| end; | |
| procedure TTestServer.TTestHandlerImpl.testException(arg: string); | |
| var | |
| x : TXception; | |
| begin | |
| Console.WriteLine('testException(' + arg + ')'); | |
| if ( arg = 'Xception') then | |
| begin | |
| x := TXception.Create; | |
| x.ErrorCode := 1001; | |
| x.Message_ := 'This is an Xception'; | |
| raise x; | |
| end; | |
| end; | |
| function TTestServer.TTestHandlerImpl.testI32(thing: Integer): Integer; | |
| begin | |
| Console.WriteLine('testI32("' + IntToStr( thing) + '")'); | |
| Result := thing; | |
| end; | |
| function TTestServer.TTestHandlerImpl.testI64(thing: Int64): Int64; | |
| begin | |
| Console.WriteLine('testI64("' + IntToStr( thing) + '")'); | |
| Result := thing; | |
| end; | |
| function TTestServer.TTestHandlerImpl.testInsanity( | |
| argument: IInsanity): IThriftDictionary<Int64, IThriftDictionary<TNumberz, IInsanity>>; | |
| var | |
| hello, goodbye : IXtruct; | |
| crazy : IInsanity; | |
| looney : IInsanity; | |
| first_map : IThriftDictionary<TNumberz, IInsanity>; | |
| second_map : IThriftDictionary<TNumberz, IInsanity>; | |
| insane : IThriftDictionary<Int64, IThriftDictionary<TNumberz, IInsanity>>; | |
| begin | |
| Console.WriteLine('testInsanity()'); | |
| hello := TXtructImpl.Create; | |
| hello.String_thing := 'hello'; | |
| hello.Byte_thing := 2; | |
| hello.I32_thing := 2; | |
| hello.I64_thing := 2; | |
| goodbye := TXtructImpl.Create; | |
| goodbye.String_thing := 'Goodbye4'; | |
| goodbye.Byte_thing := 4; | |
| goodbye.I32_thing := 4; | |
| goodbye.I64_thing := 4; | |
| crazy := TInsanityImpl.Create; | |
| crazy.UserMap := TThriftDictionaryImpl<TNumberz, Int64>.Create; | |
| crazy.UserMap.AddOrSetValue( TNumberz.EIGHT, 8); | |
| crazy.Xtructs := TThriftListImpl<IXtruct>.Create; | |
| crazy.Xtructs.Add(goodbye); | |
| looney := TInsanityImpl.Create; | |
| crazy.UserMap.AddOrSetValue( TNumberz.FIVE, 5); | |
| crazy.Xtructs.Add(hello); | |
| first_map := TThriftDictionaryImpl<TNumberz, IInsanity>.Create; | |
| second_map := TThriftDictionaryImpl<TNumberz, IInsanity>.Create; | |
| first_map.AddOrSetValue( TNumberz.SIX, crazy); | |
| first_map.AddOrSetValue( TNumberz.THREE, crazy); | |
| second_map.AddOrSetValue( TNumberz.SIX, looney); | |
| insane := TThriftDictionaryImpl<Int64, IThriftDictionary<TNumberz, IInsanity>>.Create; | |
| insane.AddOrSetValue( 1, first_map); | |
| insane.AddOrSetValue( 2, second_map); | |
| Result := insane; | |
| end; | |
| function TTestServer.TTestHandlerImpl.testList( | |
| thing: IThriftList<Integer>): IThriftList<Integer>; | |
| var | |
| first : Boolean; | |
| elem : Integer; | |
| begin | |
| Console.Write('testList({'); | |
| first := True; | |
| for elem in thing do | |
| begin | |
| if first then | |
| begin | |
| first := False; | |
| end else | |
| begin | |
| Console.Write(', '); | |
| end; | |
| Console.Write( IntToStr( elem)); | |
| end; | |
| Console.WriteLine('})'); | |
| Result := thing; | |
| end; | |
| function TTestServer.TTestHandlerImpl.testMap( | |
| thing: IThriftDictionary<Integer, Integer>): IThriftDictionary<Integer, Integer>; | |
| var | |
| first : Boolean; | |
| key : Integer; | |
| begin | |
| Console.Write('testMap({'); | |
| first := True; | |
| for key in thing.Keys do | |
| begin | |
| if (first) then | |
| begin | |
| first := false; | |
| end else | |
| begin | |
| Console.Write(', '); | |
| end; | |
| Console.Write(IntToStr(key) + ' => ' + IntToStr( thing[key])); | |
| end; | |
| Console.WriteLine('})'); | |
| Result := thing; | |
| end; | |
| function TTestServer.TTestHandlerImpl.TestMapMap( | |
| hello: Integer): IThriftDictionary<Integer, IThriftDictionary<Integer, Integer>>; | |
| var | |
| mapmap : IThriftDictionary<Integer, IThriftDictionary<Integer, Integer>>; | |
| pos : IThriftDictionary<Integer, Integer>; | |
| neg : IThriftDictionary<Integer, Integer>; | |
| i : Integer; | |
| begin | |
| Console.WriteLine('testMapMap(' + IntToStr( hello) + ')'); | |
| mapmap := TThriftDictionaryImpl<Integer, IThriftDictionary<Integer, Integer>>.Create; | |
| pos := TThriftDictionaryImpl<Integer, Integer>.Create; | |
| neg := TThriftDictionaryImpl<Integer, Integer>.Create; | |
| for i := 1 to 4 do | |
| begin | |
| pos.AddOrSetValue( i, i); | |
| neg.AddOrSetValue( -i, -i); | |
| end; | |
| mapmap.AddOrSetValue(4, pos); | |
| mapmap.AddOrSetValue( -4, neg); | |
| Result := mapmap; | |
| end; | |
| function TTestServer.TTestHandlerImpl.testMulti(arg0: ShortInt; arg1: Integer; | |
| arg2: Int64; arg3: IThriftDictionary<SmallInt, string>; arg4: TNumberz; | |
| arg5: Int64): IXtruct; | |
| var | |
| hello : IXtruct; | |
| begin | |
| Console.WriteLine('testMulti()'); | |
| hello := TXtructImpl.Create; | |
| hello.String_thing := 'Hello2'; | |
| hello.Byte_thing := arg0; | |
| hello.I32_thing := arg1; | |
| hello.I64_thing := arg2; | |
| Result := hello; | |
| end; | |
| function TTestServer.TTestHandlerImpl.testMultiException(arg0, | |
| arg1: string): IXtruct; | |
| var | |
| x : TXception; | |
| x2 : TXception2; | |
| begin | |
| Console.WriteLine('testMultiException(' + arg0 + ', ' + arg1 + ')'); | |
| if ( arg0 = 'Xception') then | |
| begin | |
| x := TXception.Create; | |
| x.ErrorCode := 1001; | |
| x.Message_ := 'This is an Xception'; | |
| raise x; | |
| end else | |
| if ( arg0 = 'Xception2') then | |
| begin | |
| x2 := TXception2.Create; | |
| x2.ErrorCode := 2002; | |
| x2.Struct_thing := TXtructImpl.Create; | |
| x2.Struct_thing.String_thing := 'This is an Xception2'; | |
| raise x2; | |
| end; | |
| Result := TXtructImpl.Create; | |
| Result.String_thing := arg1; | |
| end; | |
| function TTestServer.TTestHandlerImpl.testNest(thing: IXtruct2): IXtruct2; | |
| var | |
| temp : IXtruct; | |
| begin | |
| temp := thing.Struct_thing; | |
| Console.WriteLine('testNest({' + | |
| IntToStr( thing.Byte_thing) + ', {' + | |
| '"' + temp.String_thing + '", ' + | |
| IntToStr( temp.Byte_thing) + ', ' + | |
| IntToStr( temp.I32_thing) + ', ' + | |
| IntToStr( temp.I64_thing) + '}, ' + | |
| IntToStr( temp.I32_thing) + '})'); | |
| Result := thing; | |
| end; | |
| procedure TTestServer.TTestHandlerImpl.testOneway(secondsToSleep: Integer); | |
| begin | |
| Console.WriteLine('testOneway(' + IntToStr( secondsToSleep )+ '), sleeping...'); | |
| Sleep(secondsToSleep * 1000); | |
| Console.WriteLine('testOneway finished'); | |
| end; | |
| function TTestServer.TTestHandlerImpl.testSet( | |
| thing: IHashSet<Integer>):IHashSet<Integer>; | |
| var | |
| first : Boolean; | |
| elem : Integer; | |
| begin | |
| Console.Write('testSet({'); | |
| first := True; | |
| for elem in thing do | |
| begin | |
| if first then | |
| begin | |
| first := False; | |
| end else | |
| begin | |
| Console.Write( ', '); | |
| end; | |
| Console.Write( IntToStr( elem)); | |
| end; | |
| Console.WriteLine('})'); | |
| Result := thing; | |
| end; | |
| procedure TTestServer.TTestHandlerImpl.testStop; | |
| begin | |
| if FServer <> nil then | |
| begin | |
| FServer.Stop; | |
| end; | |
| end; | |
| function TTestServer.TTestHandlerImpl.testString(thing: string): string; | |
| begin | |
| Console.WriteLine('teststring("' + thing + '")'); | |
| Result := thing; | |
| end; | |
| function TTestServer.TTestHandlerImpl.testStringMap( | |
| thing: IThriftDictionary<string, string>): IThriftDictionary<string, string>; | |
| begin | |
| end; | |
| function TTestServer.TTestHandlerImpl.testTypedef(thing: Int64): Int64; | |
| begin | |
| Console.WriteLine('testTypedef(' + IntToStr( thing) + ')'); | |
| Result := thing; | |
| end; | |
| procedure TTestServer.TTestHandlerImpl.TestVoid; | |
| begin | |
| Console.WriteLine('testVoid()'); | |
| end; | |
| function TTestServer.TTestHandlerImpl.testStruct(thing: IXtruct): IXtruct; | |
| begin | |
| Console.WriteLine('testStruct({' + | |
| '"' + thing.String_thing + '", ' + | |
| IntToStr( thing.Byte_thing) + ', ' + | |
| IntToStr( thing.I32_thing) + ', ' + | |
| IntToStr( thing.I64_thing)); | |
| Result := thing; | |
| end; | |
| { TTestServer } | |
| class procedure TTestServer.Execute(args: array of string); | |
| var | |
| UseBufferedSockets : Boolean; | |
| UseFramed : Boolean; | |
| Port : Integer; | |
| testHandler : ITestHandler; | |
| testProcessor : IProcessor; | |
| ServerSocket : IServerTransport; | |
| ServerEngine : IServer; | |
| TransportFactroy : ITransportFactory; | |
| begin | |
| try | |
| UseBufferedSockets := False; | |
| UseFramed := False; | |
| Port := 9090; | |
| if ( Length( args) > 0) then | |
| begin | |
| Port := StrToIntDef( args[0], Port); | |
| if ( Length( args) > 0) then | |
| begin | |
| if ( args[0] = 'raw' ) then | |
| begin | |
| // as default | |
| end else | |
| if ( args[0] = 'buffered' ) then | |
| begin | |
| UseBufferedSockets := True; | |
| end else | |
| if ( args[0] = 'framed' ) then | |
| begin | |
| UseFramed := True; | |
| end else | |
| begin | |
| // Fall back to the older boolean syntax | |
| UseBufferedSockets := StrToBoolDef( args[1], UseBufferedSockets); | |
| end | |
| end | |
| end; | |
| testHandler := TTestHandlerImpl.Create; | |
| testProcessor := TThriftTest.TProcessorImpl.Create( testHandler ); | |
| ServerSocket := TServerSocketImpl.Create( Port, 0, UseBufferedSockets ); | |
| if UseFramed then | |
| begin | |
| TransportFactroy := TFramedTransportImpl.TFactory.Create; | |
| ServerEngine := TSimpleServer.Create( testProcessor, ServerSocket, | |
| TransportFactroy); | |
| end else | |
| begin | |
| ServerEngine := TSimpleServer.Create( testProcessor, ServerSocket); | |
| end; | |
| testHandler.SetServer( ServerEngine); | |
| Console.WriteLine('Starting the server on port ' + IntToStr( Port) + | |
| IfValue(UseBufferedSockets, ' with buffered socket', '') + | |
| IfValue(useFramed, ' with framed transport', '') + | |
| '...'); | |
| serverEngine.Serve; | |
| testHandler.SetServer( nil); | |
| except | |
| on E: Exception do | |
| begin | |
| Console.Write( E.Message); | |
| end; | |
| end; | |
| Console.WriteLine( 'done.'); | |
| end; | |
| end. |