(* | |
* 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. |