blob: d4375276a0de3391b2c09965b4aedb61f98c3ef7 [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
123 Create(
124 AProcessor,
125 AServerTransport,
126 InputTransFactory,
127 OutputTransFactory,
128 InputFactory,
129 OutputFactory,
130 ALogDelegate
131 );
132end;
133
Roger Meier333bbf32012-01-08 21:51:08 +0000134constructor TServerImpl.Create(const AProcessor: IProcessor;
135 const AServerTransport: IServerTransport);
Jake Farrell27274222011-11-10 20:32:44 +0000136var
137 InputFactory, OutputFactory : IProtocolFactory;
138 InputTransFactory, OutputTransFactory : ITransportFactory;
139
140begin
141 InputFactory := TBinaryProtocolImpl.TFactory.Create;
142 OutputFactory := TBinaryProtocolImpl.TFactory.Create;
143 InputTransFactory := TTransportFactoryImpl.Create;
144 OutputTransFactory := TTransportFactoryImpl.Create;
145
146 Create(
147 AProcessor,
148 AServerTransport,
149 InputTransFactory,
150 OutputTransFactory,
151 InputFactory,
152 OutputFactory,
153 DefaultLogDelegate
154 );
155end;
156
Roger Meier333bbf32012-01-08 21:51:08 +0000157constructor TServerImpl.Create(const AProcessor: IProcessor;
158 const AServerTransport: IServerTransport; const ATransportFactory: ITransportFactory);
Jake Farrell27274222011-11-10 20:32:44 +0000159var
160 InputProtocolFactory : IProtocolFactory;
161 OutputProtocolFactory : IProtocolFactory;
162begin
163 InputProtocolFactory := TBinaryProtocolImpl.TFactory.Create;
164 OutputProtocolFactory := TBinaryProtocolImpl.TFactory.Create;
165
166 Create( AProcessor, AServerTransport, ATransportFactory, ATransportFactory,
167 InputProtocolFactory, OutputProtocolFactory, DefaultLogDelegate);
168end;
169
Roger Meier333bbf32012-01-08 21:51:08 +0000170constructor TServerImpl.Create(const AProcessor: IProcessor;
171 const AServerTransport: IServerTransport;
172 const AInputTransportFactory, AOutputTransportFactory: ITransportFactory;
173 const AInputProtocolFactory, AOutputProtocolFactory: IProtocolFactory;
174 const ALogDelegate : TLogDelegate);
Jake Farrell27274222011-11-10 20:32:44 +0000175begin
176 FProcessor := AProcessor;
177 FServerTransport := AServerTransport;
178 FInputTransportFactory := AInputTransportFactory;
179 FOutputTransportFactory := AOutputTransportFactory;
180 FInputProtocolFactory := AInputProtocolFactory;
181 FOutputProtocolFactory := AOutputProtocolFactory;
182 FLogDelegate := ALogDelegate;
183end;
184
Roger Meier333bbf32012-01-08 21:51:08 +0000185class procedure TServerImpl.DefaultLogDelegate( const str: string);
Jake Farrell27274222011-11-10 20:32:44 +0000186begin
187 Writeln( str );
188end;
189
Roger Meier333bbf32012-01-08 21:51:08 +0000190constructor TServerImpl.Create( const AProcessor: IProcessor;
191 const AServerTransport: IServerTransport; const ATransportFactory: ITransportFactory;
192 const AProtocolFactory: IProtocolFactory);
Jake Farrell806d2982011-10-26 02:33:31 +0000193begin
194 Create( AProcessor, AServerTransport,
195 ATransportFactory, ATransportFactory,
196 AProtocolFactory, AProtocolFactory,
197 DefaultLogDelegate);
198end;
199
200{ TSimpleServer }
Jake Farrell27274222011-11-10 20:32:44 +0000201
Roger Meier333bbf32012-01-08 21:51:08 +0000202constructor TSimpleServer.Create( const AProcessor: IProcessor;
203 const AServerTransport: IServerTransport);
Jake Farrell27274222011-11-10 20:32:44 +0000204var
205 InputProtocolFactory : IProtocolFactory;
206 OutputProtocolFactory : IProtocolFactory;
207 InputTransportFactory : ITransportFactory;
208 OutputTransportFactory : ITransportFactory;
209begin
210 InputProtocolFactory := TBinaryProtocolImpl.TFactory.Create;
211 OutputProtocolFactory := TBinaryProtocolImpl.TFactory.Create;
212 InputTransportFactory := TTransportFactoryImpl.Create;
213 OutputTransportFactory := TTransportFactoryImpl.Create;
214
215 inherited Create( AProcessor, AServerTransport, InputTransportFactory,
216 OutputTransportFactory, InputProtocolFactory, OutputProtocolFactory, DefaultLogDelegate);
217end;
218
Roger Meier333bbf32012-01-08 21:51:08 +0000219constructor TSimpleServer.Create( const AProcessor: IProcessor;
220 const AServerTransport: IServerTransport; ALogDel: TServerImpl.TLogDelegate);
Jake Farrell27274222011-11-10 20:32:44 +0000221var
222 InputProtocolFactory : IProtocolFactory;
223 OutputProtocolFactory : IProtocolFactory;
224 InputTransportFactory : ITransportFactory;
225 OutputTransportFactory : ITransportFactory;
226begin
227 InputProtocolFactory := TBinaryProtocolImpl.TFactory.Create;
228 OutputProtocolFactory := TBinaryProtocolImpl.TFactory.Create;
229 InputTransportFactory := TTransportFactoryImpl.Create;
230 OutputTransportFactory := TTransportFactoryImpl.Create;
231
232 inherited Create( AProcessor, AServerTransport, InputTransportFactory,
233 OutputTransportFactory, InputProtocolFactory, OutputProtocolFactory, ALogDel);
234end;
235
Roger Meier333bbf32012-01-08 21:51:08 +0000236constructor TSimpleServer.Create( const AProcessor: IProcessor;
237 const AServerTransport: IServerTransport; const ATransportFactory: ITransportFactory);
Jake Farrell27274222011-11-10 20:32:44 +0000238begin
239 inherited Create( AProcessor, AServerTransport, ATransportFactory,
240 ATransportFactory, TBinaryProtocolImpl.TFactory.Create, TBinaryProtocolImpl.TFactory.Create, DefaultLogDelegate);
241end;
242
Roger Meier333bbf32012-01-08 21:51:08 +0000243constructor TSimpleServer.Create( const AProcessor: IProcessor;
244 const AServerTransport: IServerTransport; const ATransportFactory: ITransportFactory;
245 const AProtocolFactory: IProtocolFactory);
Jake Farrell27274222011-11-10 20:32:44 +0000246begin
247 inherited Create( AProcessor, AServerTransport, ATransportFactory,
248 ATransportFactory, AProtocolFactory, AProtocolFactory, DefaultLogDelegate);
249end;
250
251procedure TSimpleServer.Serve;
252var
253 client : ITransport;
254 InputTransport : ITransport;
255 OutputTransport : ITransport;
256 InputProtocol : IProtocol;
257 OutputProtocol : IProtocol;
258begin
259 try
260 FServerTransport.Listen;
261 except
262 on E: Exception do
263 begin
264 FLogDelegate( E.ToString);
265 end;
266 end;
267
268 client := nil;
269 InputTransport := nil;
270 OutputTransport := nil;
271 InputProtocol := nil;
272 OutputProtocol := nil;
273
274 while (not FStop) do
275 begin
276 try
277 client := FServerTransport.Accept;
278 FLogDelegate( 'Client Connected!');
279 InputTransport := FInputTransportFactory.GetTransport( client );
280 OutputTransport := FOutputTransportFactory.GetTransport( client );
281 InputProtocol := FInputProtocolFactory.GetProtocol( InputTransport );
282 OutputProtocol := FOutputProtocolFactory.GetProtocol( OutputTransport );
283 while ( FProcessor.Process( InputProtocol, OutputProtocol )) do
284 begin
285 if FStop then Break;
286 end;
287 except
288 on E: TTransportException do
289 begin
290 if FStop then
291 begin
292 FLogDelegate('TSimpleServer was shutting down, caught ' + E.ClassName);
293 end;
294 end;
295 on E: Exception do
296 begin
297 FLogDelegate( E.ToString );
298 end;
299 end;
300 if InputTransport <> nil then
301 begin
302 InputTransport.Close;
303 end;
304 if OutputTransport <> nil then
305 begin
306 OutputTransport.Close;
307 end;
308 end;
309
310 if FStop then
311 begin
312 try
313 FServerTransport.Close;
314 except
315 on E: TTransportException do
316 begin
317 FLogDelegate('TServerTranport failed on close: ' + E.Message);
318 end;
319 end;
320 FStop := False;
321 end;
322end;
323
324procedure TSimpleServer.Stop;
325begin
326 FStop := True;
327 FServerTransport.Close;
328end;
329
330end.