blob: 7d39f6bd313550b4ec7479f2e37de9bd94fb14c4 [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
20 unit Thrift.Server;
21
22interface
23
24uses
25 SysUtils,
26 Thrift,
27 Thrift.Protocol,
28 Thrift.Transport;
29
30type
31 IServer = interface
32 ['{CF9F56C6-BB39-4C7D-877B-43B416572CE6}']
33 procedure Serve;
34 procedure Stop;
35 end;
36
37 TServerImpl = class abstract( TInterfacedObject, IServer )
38 public
39 type
Roger Meier333bbf32012-01-08 21:51:08 +000040 TLogDelegate = reference to procedure( const str: string);
Jake Farrell27274222011-11-10 20:32:44 +000041 protected
42 FProcessor : IProcessor;
43 FServerTransport : IServerTransport;
44 FInputTransportFactory : ITransportFactory;
45 FOutputTransportFactory : ITransportFactory;
46 FInputProtocolFactory : IProtocolFactory;
47 FOutputProtocolFactory : IProtocolFactory;
48 FLogDelegate : TLogDelegate;
49
Roger Meier333bbf32012-01-08 21:51:08 +000050 class procedure DefaultLogDelegate( const str: string);
Jake Farrell27274222011-11-10 20:32:44 +000051
52 procedure Serve; virtual; abstract;
53 procedure Stop; virtual; abstract;
54 public
55 constructor Create(
Roger Meier333bbf32012-01-08 21:51:08 +000056 const AProcessor :IProcessor;
57 const AServerTransport: IServerTransport;
58 const AInputTransportFactory : ITransportFactory;
59 const AOutputTransportFactory : ITransportFactory;
60 const AInputProtocolFactory : IProtocolFactory;
61 const AOutputProtocolFactory : IProtocolFactory;
62 const ALogDelegate : TLogDelegate
Jake Farrell27274222011-11-10 20:32:44 +000063 ); overload;
64
Roger Meier333bbf32012-01-08 21:51:08 +000065 constructor Create(
66 const AProcessor :IProcessor;
67 const AServerTransport: IServerTransport
68 ); overload;
Jake Farrell27274222011-11-10 20:32:44 +000069
70 constructor Create(
Roger Meier333bbf32012-01-08 21:51:08 +000071 const AProcessor :IProcessor;
72 const AServerTransport: IServerTransport;
73 const ALogDelegate: TLogDelegate
Jake Farrell27274222011-11-10 20:32:44 +000074 ); overload;
75
76 constructor Create(
Roger Meier333bbf32012-01-08 21:51:08 +000077 const AProcessor :IProcessor;
78 const AServerTransport: IServerTransport;
79 const ATransportFactory : ITransportFactory
Jake Farrell27274222011-11-10 20:32:44 +000080 ); overload;
81
82 constructor Create(
Roger Meier333bbf32012-01-08 21:51:08 +000083 const AProcessor :IProcessor;
84 const AServerTransport: IServerTransport;
85 const ATransportFactory : ITransportFactory;
86 const AProtocolFactory : IProtocolFactory
Jake Farrell27274222011-11-10 20:32:44 +000087 ); overload;
88 end;
89
90 TSimpleServer = class( TServerImpl)
91 private
92 FStop : Boolean;
93 public
Roger Meier333bbf32012-01-08 21:51:08 +000094 constructor Create( const AProcessor: IProcessor; const AServerTransport: IServerTransport); overload;
95 constructor Create( const AProcessor: IProcessor; const AServerTransport: IServerTransport;
Jake Farrell27274222011-11-10 20:32:44 +000096 ALogDel: TServerImpl.TLogDelegate); overload;
Roger Meier333bbf32012-01-08 21:51:08 +000097 constructor Create( const AProcessor: IProcessor; const AServerTransport: IServerTransport;
98 const ATransportFactory: ITransportFactory); overload;
99 constructor Create( const AProcessor: IProcessor; const AServerTransport: IServerTransport;
100 const ATransportFactory: ITransportFactory; const AProtocolFactory: IProtocolFactory); overload;
Jake Farrell27274222011-11-10 20:32:44 +0000101
102 procedure Serve; override;
103 procedure Stop; override;
104 end;
105
106
107implementation
108
109{ TServerImpl }
110
Roger Meier333bbf32012-01-08 21:51:08 +0000111constructor TServerImpl.Create( const AProcessor: IProcessor;
112 const AServerTransport: IServerTransport; const ALogDelegate: TLogDelegate);
Jake Farrell27274222011-11-10 20:32:44 +0000113var
114 InputFactory, OutputFactory : IProtocolFactory;
115 InputTransFactory, OutputTransFactory : ITransportFactory;
116
117begin
118 InputFactory := TBinaryProtocolImpl.TFactory.Create;
119 OutputFactory := TBinaryProtocolImpl.TFactory.Create;
120 InputTransFactory := TTransportFactoryImpl.Create;
121 OutputTransFactory := TTransportFactoryImpl.Create;
122
Jens Geyer718f6ee2013-09-06 21:02:34 +0200123 //no inherited;
Jake Farrell27274222011-11-10 20:32:44 +0000124 Create(
125 AProcessor,
126 AServerTransport,
127 InputTransFactory,
128 OutputTransFactory,
129 InputFactory,
130 OutputFactory,
131 ALogDelegate
132 );
133end;
134
Roger Meier333bbf32012-01-08 21:51:08 +0000135constructor TServerImpl.Create(const AProcessor: IProcessor;
136 const AServerTransport: IServerTransport);
Jake Farrell27274222011-11-10 20:32:44 +0000137var
138 InputFactory, OutputFactory : IProtocolFactory;
139 InputTransFactory, OutputTransFactory : ITransportFactory;
140
141begin
142 InputFactory := TBinaryProtocolImpl.TFactory.Create;
143 OutputFactory := TBinaryProtocolImpl.TFactory.Create;
144 InputTransFactory := TTransportFactoryImpl.Create;
145 OutputTransFactory := TTransportFactoryImpl.Create;
146
Jens Geyer718f6ee2013-09-06 21:02:34 +0200147 //no inherited;
Jake Farrell27274222011-11-10 20:32:44 +0000148 Create(
149 AProcessor,
150 AServerTransport,
151 InputTransFactory,
152 OutputTransFactory,
153 InputFactory,
154 OutputFactory,
155 DefaultLogDelegate
156 );
157end;
158
Roger Meier333bbf32012-01-08 21:51:08 +0000159constructor TServerImpl.Create(const AProcessor: IProcessor;
160 const AServerTransport: IServerTransport; const ATransportFactory: ITransportFactory);
Jake Farrell27274222011-11-10 20:32:44 +0000161var
162 InputProtocolFactory : IProtocolFactory;
163 OutputProtocolFactory : IProtocolFactory;
164begin
165 InputProtocolFactory := TBinaryProtocolImpl.TFactory.Create;
166 OutputProtocolFactory := TBinaryProtocolImpl.TFactory.Create;
167
Jens Geyer718f6ee2013-09-06 21:02:34 +0200168 //no inherited;
Jake Farrell27274222011-11-10 20:32:44 +0000169 Create( AProcessor, AServerTransport, ATransportFactory, ATransportFactory,
170 InputProtocolFactory, OutputProtocolFactory, DefaultLogDelegate);
171end;
172
Roger Meier333bbf32012-01-08 21:51:08 +0000173constructor TServerImpl.Create(const AProcessor: IProcessor;
174 const AServerTransport: IServerTransport;
175 const AInputTransportFactory, AOutputTransportFactory: ITransportFactory;
176 const AInputProtocolFactory, AOutputProtocolFactory: IProtocolFactory;
177 const ALogDelegate : TLogDelegate);
Jake Farrell27274222011-11-10 20:32:44 +0000178begin
Jens Geyer718f6ee2013-09-06 21:02:34 +0200179 inherited Create;
Jake Farrell27274222011-11-10 20:32:44 +0000180 FProcessor := AProcessor;
181 FServerTransport := AServerTransport;
182 FInputTransportFactory := AInputTransportFactory;
183 FOutputTransportFactory := AOutputTransportFactory;
184 FInputProtocolFactory := AInputProtocolFactory;
185 FOutputProtocolFactory := AOutputProtocolFactory;
186 FLogDelegate := ALogDelegate;
187end;
188
Roger Meier333bbf32012-01-08 21:51:08 +0000189class procedure TServerImpl.DefaultLogDelegate( const str: string);
Jake Farrell27274222011-11-10 20:32:44 +0000190begin
191 Writeln( str );
192end;
193
Roger Meier333bbf32012-01-08 21:51:08 +0000194constructor TServerImpl.Create( const AProcessor: IProcessor;
195 const AServerTransport: IServerTransport; const ATransportFactory: ITransportFactory;
196 const AProtocolFactory: IProtocolFactory);
Jake Farrell806d2982011-10-26 02:33:31 +0000197begin
Jens Geyer718f6ee2013-09-06 21:02:34 +0200198 //no inherited;
Jake Farrell806d2982011-10-26 02:33:31 +0000199 Create( AProcessor, AServerTransport,
200 ATransportFactory, ATransportFactory,
201 AProtocolFactory, AProtocolFactory,
202 DefaultLogDelegate);
203end;
204
205{ TSimpleServer }
Jake Farrell27274222011-11-10 20:32:44 +0000206
Roger Meier333bbf32012-01-08 21:51:08 +0000207constructor TSimpleServer.Create( const AProcessor: IProcessor;
208 const AServerTransport: IServerTransport);
Jake Farrell27274222011-11-10 20:32:44 +0000209var
210 InputProtocolFactory : IProtocolFactory;
211 OutputProtocolFactory : IProtocolFactory;
212 InputTransportFactory : ITransportFactory;
213 OutputTransportFactory : ITransportFactory;
214begin
215 InputProtocolFactory := TBinaryProtocolImpl.TFactory.Create;
216 OutputProtocolFactory := TBinaryProtocolImpl.TFactory.Create;
217 InputTransportFactory := TTransportFactoryImpl.Create;
218 OutputTransportFactory := TTransportFactoryImpl.Create;
219
220 inherited Create( AProcessor, AServerTransport, InputTransportFactory,
221 OutputTransportFactory, InputProtocolFactory, OutputProtocolFactory, DefaultLogDelegate);
222end;
223
Roger Meier333bbf32012-01-08 21:51:08 +0000224constructor TSimpleServer.Create( const AProcessor: IProcessor;
225 const AServerTransport: IServerTransport; ALogDel: TServerImpl.TLogDelegate);
Jake Farrell27274222011-11-10 20:32:44 +0000226var
227 InputProtocolFactory : IProtocolFactory;
228 OutputProtocolFactory : IProtocolFactory;
229 InputTransportFactory : ITransportFactory;
230 OutputTransportFactory : ITransportFactory;
231begin
232 InputProtocolFactory := TBinaryProtocolImpl.TFactory.Create;
233 OutputProtocolFactory := TBinaryProtocolImpl.TFactory.Create;
234 InputTransportFactory := TTransportFactoryImpl.Create;
235 OutputTransportFactory := TTransportFactoryImpl.Create;
236
237 inherited Create( AProcessor, AServerTransport, InputTransportFactory,
238 OutputTransportFactory, InputProtocolFactory, OutputProtocolFactory, ALogDel);
239end;
240
Roger Meier333bbf32012-01-08 21:51:08 +0000241constructor TSimpleServer.Create( const AProcessor: IProcessor;
242 const AServerTransport: IServerTransport; const ATransportFactory: ITransportFactory);
Jake Farrell27274222011-11-10 20:32:44 +0000243begin
244 inherited Create( AProcessor, AServerTransport, ATransportFactory,
245 ATransportFactory, TBinaryProtocolImpl.TFactory.Create, TBinaryProtocolImpl.TFactory.Create, DefaultLogDelegate);
246end;
247
Roger Meier333bbf32012-01-08 21:51:08 +0000248constructor TSimpleServer.Create( const AProcessor: IProcessor;
249 const AServerTransport: IServerTransport; const ATransportFactory: ITransportFactory;
250 const AProtocolFactory: IProtocolFactory);
Jake Farrell27274222011-11-10 20:32:44 +0000251begin
252 inherited Create( AProcessor, AServerTransport, ATransportFactory,
253 ATransportFactory, AProtocolFactory, AProtocolFactory, DefaultLogDelegate);
254end;
255
256procedure TSimpleServer.Serve;
257var
258 client : ITransport;
259 InputTransport : ITransport;
260 OutputTransport : ITransport;
261 InputProtocol : IProtocol;
262 OutputProtocol : IProtocol;
263begin
264 try
265 FServerTransport.Listen;
266 except
267 on E: Exception do
268 begin
269 FLogDelegate( E.ToString);
270 end;
271 end;
272
273 client := nil;
Jake Farrell27274222011-11-10 20:32:44 +0000274 while (not FStop) do
275 begin
276 try
Jens Geyer06045cf2013-03-27 20:26:25 +0200277 // clean up any old instances before waiting for clients
278 InputTransport := nil;
279 OutputTransport := nil;
280 InputProtocol := nil;
281 OutputProtocol := nil;
282
Jake Farrell27274222011-11-10 20:32:44 +0000283 client := FServerTransport.Accept;
284 FLogDelegate( 'Client Connected!');
Jens Geyer06045cf2013-03-27 20:26:25 +0200285
Jake Farrell27274222011-11-10 20:32:44 +0000286 InputTransport := FInputTransportFactory.GetTransport( client );
287 OutputTransport := FOutputTransportFactory.GetTransport( client );
288 InputProtocol := FInputProtocolFactory.GetProtocol( InputTransport );
289 OutputProtocol := FOutputProtocolFactory.GetProtocol( OutputTransport );
290 while ( FProcessor.Process( InputProtocol, OutputProtocol )) do
291 begin
292 if FStop then Break;
293 end;
Jens Geyer06045cf2013-03-27 20:26:25 +0200294
Jake Farrell27274222011-11-10 20:32:44 +0000295 except
296 on E: TTransportException do
297 begin
Roger Meier79655fb2012-10-20 20:59:41 +0000298 if FStop
299 then FLogDelegate('TSimpleServer was shutting down, caught ' + E.ToString)
300 else FLogDelegate( E.ToString);
Jake Farrell27274222011-11-10 20:32:44 +0000301 end;
302 on E: Exception do
303 begin
Roger Meier79655fb2012-10-20 20:59:41 +0000304 FLogDelegate( E.ToString);
Jake Farrell27274222011-11-10 20:32:44 +0000305 end;
306 end;
307 if InputTransport <> nil then
308 begin
309 InputTransport.Close;
310 end;
311 if OutputTransport <> nil then
312 begin
313 OutputTransport.Close;
314 end;
315 end;
316
317 if FStop then
318 begin
319 try
320 FServerTransport.Close;
321 except
322 on E: TTransportException do
323 begin
324 FLogDelegate('TServerTranport failed on close: ' + E.Message);
325 end;
326 end;
327 FStop := False;
328 end;
329end;
330
331procedure TSimpleServer.Stop;
332begin
333 FStop := True;
334 FServerTransport.Close;
335end;
336
337end.