1 /*
2  * Copyright (c) 2006- Facebook
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 /*
7  * Licensed to the Apache Software Foundation (ASF) under one
8  * or more contributor license agreements. See the NOTICE file
9  * distributed with this work for additional information
10  * regarding copyright ownership. The ASF licenses this file
11  * to you under the Apache License, Version 2.0 (the
12  * "License"); you may not use this file except in compliance
13  * with the License. You may obtain a copy of the License at
14  *
15  *   http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing,
18  * software distributed under the License is distributed on an
19  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20  * KIND, either express or implied. See the License for the
21  * specific language governing permissions and limitations
22  * under the License.
23  */
24 
25 #ifndef _THRIFT_SERVER_TSERVER_H_
26 #define _THRIFT_SERVER_TSERVER_H_ 1
27 
28 #include <thrift/TProcessor.h>
29 #include <thrift/protocol/TBinaryProtocol.h>
30 #include <thrift/transport/TServerTransport.h>
31 
32 #include <memory>
33 
34 namespace apache
35 {
36 namespace thrift
37 {
38 namespace server
39 {
40 
41 using apache::thrift::TProcessor;
42 using apache::thrift::protocol::TBinaryProtocolFactory;
43 using apache::thrift::protocol::TProtocol;
44 using apache::thrift::protocol::TProtocolFactory;
45 using apache::thrift::transport::TServerTransport;
46 using apache::thrift::transport::TTransport;
47 using apache::thrift::transport::TTransportFactory;
48 
49 /**
50  * Virtual interface class that can handle events from the server core. To
51  * use this you should subclass it and implement the methods that you care
52  * about. Your subclass can also store local data that you may care about,
53  * such as additional "arguments" to these methods (stored in the object
54  * instance's state).
55  */
56 class TServerEventHandler
57 {
58 public:
59 	virtual ~TServerEventHandler() = default;
60 
61 	/**
62 	 * Called before the server begins.
63 	 */
preServe()64 	virtual void preServe()
65 	{
66 	}
67 
68 	/**
69 	 * Called when a new client has connected and is about to being processing.
70 	 */
createContext(std::shared_ptr<TProtocol> input,std::shared_ptr<TProtocol> output)71 	virtual void *createContext(std::shared_ptr<TProtocol> input,
72 				    std::shared_ptr<TProtocol> output)
73 	{
74 		(void)input;
75 		(void)output;
76 		return nullptr;
77 	}
78 
79 	/**
80 	 * Called when a client has finished request-handling to delete server
81 	 * context.
82 	 */
deleteContext(void * serverContext,std::shared_ptr<TProtocol> input,std::shared_ptr<TProtocol> output)83 	virtual void deleteContext(void *serverContext, std::shared_ptr<TProtocol> input,
84 				   std::shared_ptr<TProtocol> output)
85 	{
86 		(void)serverContext;
87 		(void)input;
88 		(void)output;
89 	}
90 
91 	/**
92 	 * Called when a client is about to call the processor.
93 	 */
processContext(void * serverContext,std::shared_ptr<TTransport> transport)94 	virtual void processContext(void *serverContext, std::shared_ptr<TTransport> transport)
95 	{
96 		(void)serverContext;
97 		(void)transport;
98 	}
99 
100 protected:
101 	/**
102 	 * Prevent direct instantiation.
103 	 */
104 	TServerEventHandler() = default;
105 };
106 
107 /**
108  * Thrift server.
109  *
110  */
111 class TServer
112 {
113 public:
114 	~TServer() = default;
115 
116 	virtual void serve() = 0;
117 
stop()118 	virtual void stop()
119 	{
120 	}
121 
122 	// Allows running the server as a Runnable thread
run()123 	void run()
124 	{
125 		serve();
126 	}
127 
getProcessorFactory()128 	std::shared_ptr<TProcessorFactory> getProcessorFactory()
129 	{
130 		return processorFactory_;
131 	}
132 
getServerTransport()133 	std::shared_ptr<TServerTransport> getServerTransport()
134 	{
135 		return serverTransport_;
136 	}
137 
getInputTransportFactory()138 	std::shared_ptr<TTransportFactory> getInputTransportFactory()
139 	{
140 		return inputTransportFactory_;
141 	}
142 
getOutputTransportFactory()143 	std::shared_ptr<TTransportFactory> getOutputTransportFactory()
144 	{
145 		return outputTransportFactory_;
146 	}
147 
getInputProtocolFactory()148 	std::shared_ptr<TProtocolFactory> getInputProtocolFactory()
149 	{
150 		return inputProtocolFactory_;
151 	}
152 
getOutputProtocolFactory()153 	std::shared_ptr<TProtocolFactory> getOutputProtocolFactory()
154 	{
155 		return outputProtocolFactory_;
156 	}
157 
getEventHandler()158 	std::shared_ptr<TServerEventHandler> getEventHandler()
159 	{
160 		return eventHandler_;
161 	}
162 
163 protected:
TServer(const std::shared_ptr<TProcessorFactory> & processorFactory)164 	TServer(const std::shared_ptr<TProcessorFactory> &processorFactory)
165 		: processorFactory_(processorFactory)
166 	{
167 		setInputTransportFactory(
168 			std::shared_ptr<TTransportFactory>(new TTransportFactory()));
169 		setOutputTransportFactory(
170 			std::shared_ptr<TTransportFactory>(new TTransportFactory()));
171 		setInputProtocolFactory(
172 			std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
173 		setOutputProtocolFactory(
174 			std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
175 	}
176 
TServer(const std::shared_ptr<TProcessor> & processor)177 	TServer(const std::shared_ptr<TProcessor> &processor)
178 		: processorFactory_(new TSingletonProcessorFactory(processor))
179 	{
180 		setInputTransportFactory(
181 			std::shared_ptr<TTransportFactory>(new TTransportFactory()));
182 		setOutputTransportFactory(
183 			std::shared_ptr<TTransportFactory>(new TTransportFactory()));
184 		setInputProtocolFactory(
185 			std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
186 		setOutputProtocolFactory(
187 			std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
188 	}
189 
TServer(const std::shared_ptr<TProcessorFactory> & processorFactory,const std::shared_ptr<TServerTransport> & serverTransport)190 	TServer(const std::shared_ptr<TProcessorFactory> &processorFactory,
191 		const std::shared_ptr<TServerTransport> &serverTransport)
192 		: processorFactory_(processorFactory), serverTransport_(serverTransport)
193 	{
194 		setInputTransportFactory(
195 			std::shared_ptr<TTransportFactory>(new TTransportFactory()));
196 		setOutputTransportFactory(
197 			std::shared_ptr<TTransportFactory>(new TTransportFactory()));
198 		setInputProtocolFactory(
199 			std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
200 		setOutputProtocolFactory(
201 			std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
202 	}
203 
TServer(const std::shared_ptr<TProcessor> & processor,const std::shared_ptr<TServerTransport> & serverTransport)204 	TServer(const std::shared_ptr<TProcessor> &processor,
205 		const std::shared_ptr<TServerTransport> &serverTransport)
206 		: processorFactory_(new TSingletonProcessorFactory(processor)),
207 		  serverTransport_(serverTransport)
208 	{
209 		setInputTransportFactory(
210 			std::shared_ptr<TTransportFactory>(new TTransportFactory()));
211 		setOutputTransportFactory(
212 			std::shared_ptr<TTransportFactory>(new TTransportFactory()));
213 		setInputProtocolFactory(
214 			std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
215 		setOutputProtocolFactory(
216 			std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
217 	}
218 
TServer(const std::shared_ptr<TProcessorFactory> & processorFactory,const std::shared_ptr<TServerTransport> & serverTransport,const std::shared_ptr<TTransportFactory> & transportFactory,const std::shared_ptr<TProtocolFactory> & protocolFactory)219 	TServer(const std::shared_ptr<TProcessorFactory> &processorFactory,
220 		const std::shared_ptr<TServerTransport> &serverTransport,
221 		const std::shared_ptr<TTransportFactory> &transportFactory,
222 		const std::shared_ptr<TProtocolFactory> &protocolFactory)
223 		: processorFactory_(processorFactory), serverTransport_(serverTransport),
224 		  inputTransportFactory_(transportFactory),
225 		  outputTransportFactory_(transportFactory), inputProtocolFactory_(protocolFactory),
226 		  outputProtocolFactory_(protocolFactory)
227 	{
228 	}
229 
TServer(const std::shared_ptr<TProcessor> & processor,const std::shared_ptr<TServerTransport> & serverTransport,const std::shared_ptr<TTransportFactory> & transportFactory,const std::shared_ptr<TProtocolFactory> & protocolFactory)230 	TServer(const std::shared_ptr<TProcessor> &processor,
231 		const std::shared_ptr<TServerTransport> &serverTransport,
232 		const std::shared_ptr<TTransportFactory> &transportFactory,
233 		const std::shared_ptr<TProtocolFactory> &protocolFactory)
234 		: processorFactory_(new TSingletonProcessorFactory(processor)),
235 		  serverTransport_(serverTransport), inputTransportFactory_(transportFactory),
236 		  outputTransportFactory_(transportFactory), inputProtocolFactory_(protocolFactory),
237 		  outputProtocolFactory_(protocolFactory)
238 	{
239 	}
240 
TServer(const std::shared_ptr<TProcessorFactory> & processorFactory,const std::shared_ptr<TServerTransport> & serverTransport,const std::shared_ptr<TTransportFactory> & inputTransportFactory,const std::shared_ptr<TTransportFactory> & outputTransportFactory,const std::shared_ptr<TProtocolFactory> & inputProtocolFactory,const std::shared_ptr<TProtocolFactory> & outputProtocolFactory)241 	TServer(const std::shared_ptr<TProcessorFactory> &processorFactory,
242 		const std::shared_ptr<TServerTransport> &serverTransport,
243 		const std::shared_ptr<TTransportFactory> &inputTransportFactory,
244 		const std::shared_ptr<TTransportFactory> &outputTransportFactory,
245 		const std::shared_ptr<TProtocolFactory> &inputProtocolFactory,
246 		const std::shared_ptr<TProtocolFactory> &outputProtocolFactory)
247 		: processorFactory_(processorFactory), serverTransport_(serverTransport),
248 		  inputTransportFactory_(inputTransportFactory),
249 		  outputTransportFactory_(outputTransportFactory),
250 		  inputProtocolFactory_(inputProtocolFactory),
251 		  outputProtocolFactory_(outputProtocolFactory)
252 	{
253 	}
254 
TServer(const std::shared_ptr<TProcessor> & processor,const std::shared_ptr<TServerTransport> & serverTransport,const std::shared_ptr<TTransportFactory> & inputTransportFactory,const std::shared_ptr<TTransportFactory> & outputTransportFactory,const std::shared_ptr<TProtocolFactory> & inputProtocolFactory,const std::shared_ptr<TProtocolFactory> & outputProtocolFactory)255 	TServer(const std::shared_ptr<TProcessor> &processor,
256 		const std::shared_ptr<TServerTransport> &serverTransport,
257 		const std::shared_ptr<TTransportFactory> &inputTransportFactory,
258 		const std::shared_ptr<TTransportFactory> &outputTransportFactory,
259 		const std::shared_ptr<TProtocolFactory> &inputProtocolFactory,
260 		const std::shared_ptr<TProtocolFactory> &outputProtocolFactory)
261 		: processorFactory_(new TSingletonProcessorFactory(processor)),
262 		  serverTransport_(serverTransport), inputTransportFactory_(inputTransportFactory),
263 		  outputTransportFactory_(outputTransportFactory),
264 		  inputProtocolFactory_(inputProtocolFactory),
265 		  outputProtocolFactory_(outputProtocolFactory)
266 	{
267 	}
268 
269 	/**
270 	 * Get a TProcessor to handle calls on a particular connection.
271 	 *
272 	 * This method should only be called once per connection (never once per
273 	 * call).  This allows the TProcessorFactory to return a different processor
274 	 * for each connection if it desires.
275 	 */
getProcessor(std::shared_ptr<TProtocol> inputProtocol,std::shared_ptr<TProtocol> outputProtocol,std::shared_ptr<TTransport> transport)276 	std::shared_ptr<TProcessor> getProcessor(std::shared_ptr<TProtocol> inputProtocol,
277 						 std::shared_ptr<TProtocol> outputProtocol,
278 						 std::shared_ptr<TTransport> transport)
279 	{
280 		TConnectionInfo connInfo;
281 		connInfo.input = inputProtocol;
282 		connInfo.output = outputProtocol;
283 		connInfo.transport = transport;
284 		return processorFactory_->getProcessor(connInfo);
285 	}
286 
287 	// Class variables
288 	std::shared_ptr<TProcessorFactory> processorFactory_;
289 	std::shared_ptr<TServerTransport> serverTransport_;
290 
291 	std::shared_ptr<TTransportFactory> inputTransportFactory_;
292 	std::shared_ptr<TTransportFactory> outputTransportFactory_;
293 
294 	std::shared_ptr<TProtocolFactory> inputProtocolFactory_;
295 	std::shared_ptr<TProtocolFactory> outputProtocolFactory_;
296 
297 	std::shared_ptr<TServerEventHandler> eventHandler_;
298 
299 public:
setInputTransportFactory(std::shared_ptr<TTransportFactory> inputTransportFactory)300 	void setInputTransportFactory(std::shared_ptr<TTransportFactory> inputTransportFactory)
301 	{
302 		inputTransportFactory_ = inputTransportFactory;
303 	}
304 
setOutputTransportFactory(std::shared_ptr<TTransportFactory> outputTransportFactory)305 	void setOutputTransportFactory(std::shared_ptr<TTransportFactory> outputTransportFactory)
306 	{
307 		outputTransportFactory_ = outputTransportFactory;
308 	}
309 
setInputProtocolFactory(std::shared_ptr<TProtocolFactory> inputProtocolFactory)310 	void setInputProtocolFactory(std::shared_ptr<TProtocolFactory> inputProtocolFactory)
311 	{
312 		inputProtocolFactory_ = inputProtocolFactory;
313 	}
314 
setOutputProtocolFactory(std::shared_ptr<TProtocolFactory> outputProtocolFactory)315 	void setOutputProtocolFactory(std::shared_ptr<TProtocolFactory> outputProtocolFactory)
316 	{
317 		outputProtocolFactory_ = outputProtocolFactory;
318 	}
319 
setServerEventHandler(std::shared_ptr<TServerEventHandler> eventHandler)320 	void setServerEventHandler(std::shared_ptr<TServerEventHandler> eventHandler)
321 	{
322 		eventHandler_ = eventHandler;
323 	}
324 };
325 
326 /**
327  * Helper function to increase the max file descriptors limit
328  * for the current process and all of its children.
329  * By default, tries to increase it to as much as 2^24.
330  */
331 #ifdef HAVE_SYS_RESOURCE_H
332 int increase_max_fds(int max_fds = (1 << 24));
333 #endif
334 } // namespace server
335 } // namespace thrift
336 } // namespace apache
337 
338 #endif // #ifndef _THRIFT_SERVER_TSERVER_H_
339