1 /*
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 #ifndef _THRIFT_SERVER_TSERVER_H_
21 #define _THRIFT_SERVER_TSERVER_H_ 1
22 
23 #include <thrift/TProcessor.h>
24 #include <thrift/transport/TServerTransport.h>
25 #include <thrift/protocol/TBinaryProtocol.h>
26 #include <thrift/concurrency/Thread.h>
27 
28 #include <memory>
29 
30 namespace apache {
31 namespace thrift {
32 namespace server {
33 
34 using apache::thrift::TProcessor;
35 using apache::thrift::protocol::TBinaryProtocolFactory;
36 using apache::thrift::protocol::TProtocol;
37 using apache::thrift::protocol::TProtocolFactory;
38 using apache::thrift::transport::TServerTransport;
39 using apache::thrift::transport::TTransport;
40 using apache::thrift::transport::TTransportFactory;
41 
42 /**
43  * Virtual interface class that can handle events from the server core. To
44  * use this you should subclass it and implement the methods that you care
45  * about. Your subclass can also store local data that you may care about,
46  * such as additional "arguments" to these methods (stored in the object
47  * instance's state).
48  */
49 class TServerEventHandler {
50 public:
51   virtual ~TServerEventHandler() = default;
52 
53   /**
54    * Called before the server begins.
55    */
preServe()56   virtual void preServe() {}
57 
58   /**
59    * Called when a new client has connected and is about to being processing.
60    */
createContext(std::shared_ptr<TProtocol> input,std::shared_ptr<TProtocol> output)61   virtual void* createContext(std::shared_ptr<TProtocol> input,
62                               std::shared_ptr<TProtocol> output) {
63     (void)input;
64     (void)output;
65     return nullptr;
66   }
67 
68   /**
69    * Called when a client has finished request-handling to delete server
70    * context.
71    */
deleteContext(void * serverContext,std::shared_ptr<TProtocol> input,std::shared_ptr<TProtocol> output)72   virtual void deleteContext(void* serverContext,
73                              std::shared_ptr<TProtocol> input,
74                              std::shared_ptr<TProtocol> output) {
75     (void)serverContext;
76     (void)input;
77     (void)output;
78   }
79 
80   /**
81    * Called when a client is about to call the processor.
82    */
processContext(void * serverContext,std::shared_ptr<TTransport> transport)83   virtual void processContext(void* serverContext, std::shared_ptr<TTransport> transport) {
84     (void)serverContext;
85     (void)transport;
86   }
87 
88 protected:
89   /**
90    * Prevent direct instantiation.
91    */
92   TServerEventHandler() = default;
93 };
94 
95 /**
96  * Thrift server.
97  *
98  */
99 class TServer : public concurrency::Runnable {
100 public:
101   ~TServer() override = default;
102 
103   virtual void serve() = 0;
104 
stop()105   virtual void stop() {}
106 
107   // Allows running the server as a Runnable thread
run()108   void run() override { serve(); }
109 
getProcessorFactory()110   std::shared_ptr<TProcessorFactory> getProcessorFactory() { return processorFactory_; }
111 
getServerTransport()112   std::shared_ptr<TServerTransport> getServerTransport() { return serverTransport_; }
113 
getInputTransportFactory()114   std::shared_ptr<TTransportFactory> getInputTransportFactory() { return inputTransportFactory_; }
115 
getOutputTransportFactory()116   std::shared_ptr<TTransportFactory> getOutputTransportFactory() {
117     return outputTransportFactory_;
118   }
119 
getInputProtocolFactory()120   std::shared_ptr<TProtocolFactory> getInputProtocolFactory() { return inputProtocolFactory_; }
121 
getOutputProtocolFactory()122   std::shared_ptr<TProtocolFactory> getOutputProtocolFactory() { return outputProtocolFactory_; }
123 
getEventHandler()124   std::shared_ptr<TServerEventHandler> getEventHandler() { return eventHandler_; }
125 
126 protected:
TServer(const std::shared_ptr<TProcessorFactory> & processorFactory)127   TServer(const std::shared_ptr<TProcessorFactory>& processorFactory)
128     : processorFactory_(processorFactory) {
129     setInputTransportFactory(std::shared_ptr<TTransportFactory>(new TTransportFactory()));
130     setOutputTransportFactory(std::shared_ptr<TTransportFactory>(new TTransportFactory()));
131     setInputProtocolFactory(std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
132     setOutputProtocolFactory(std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
133   }
134 
TServer(const std::shared_ptr<TProcessor> & processor)135   TServer(const std::shared_ptr<TProcessor>& processor)
136     : processorFactory_(new TSingletonProcessorFactory(processor)) {
137     setInputTransportFactory(std::shared_ptr<TTransportFactory>(new TTransportFactory()));
138     setOutputTransportFactory(std::shared_ptr<TTransportFactory>(new TTransportFactory()));
139     setInputProtocolFactory(std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
140     setOutputProtocolFactory(std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
141   }
142 
TServer(const std::shared_ptr<TProcessorFactory> & processorFactory,const std::shared_ptr<TServerTransport> & serverTransport)143   TServer(const std::shared_ptr<TProcessorFactory>& processorFactory,
144           const std::shared_ptr<TServerTransport>& serverTransport)
145     : processorFactory_(processorFactory), serverTransport_(serverTransport) {
146     setInputTransportFactory(std::shared_ptr<TTransportFactory>(new TTransportFactory()));
147     setOutputTransportFactory(std::shared_ptr<TTransportFactory>(new TTransportFactory()));
148     setInputProtocolFactory(std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
149     setOutputProtocolFactory(std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
150   }
151 
TServer(const std::shared_ptr<TProcessor> & processor,const std::shared_ptr<TServerTransport> & serverTransport)152   TServer(const std::shared_ptr<TProcessor>& processor,
153           const std::shared_ptr<TServerTransport>& serverTransport)
154     : processorFactory_(new TSingletonProcessorFactory(processor)),
155       serverTransport_(serverTransport) {
156     setInputTransportFactory(std::shared_ptr<TTransportFactory>(new TTransportFactory()));
157     setOutputTransportFactory(std::shared_ptr<TTransportFactory>(new TTransportFactory()));
158     setInputProtocolFactory(std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
159     setOutputProtocolFactory(std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
160   }
161 
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)162   TServer(const std::shared_ptr<TProcessorFactory>& processorFactory,
163           const std::shared_ptr<TServerTransport>& serverTransport,
164           const std::shared_ptr<TTransportFactory>& transportFactory,
165           const std::shared_ptr<TProtocolFactory>& protocolFactory)
166     : processorFactory_(processorFactory),
167       serverTransport_(serverTransport),
168       inputTransportFactory_(transportFactory),
169       outputTransportFactory_(transportFactory),
170       inputProtocolFactory_(protocolFactory),
171       outputProtocolFactory_(protocolFactory) {}
172 
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)173   TServer(const std::shared_ptr<TProcessor>& processor,
174           const std::shared_ptr<TServerTransport>& serverTransport,
175           const std::shared_ptr<TTransportFactory>& transportFactory,
176           const std::shared_ptr<TProtocolFactory>& protocolFactory)
177     : processorFactory_(new TSingletonProcessorFactory(processor)),
178       serverTransport_(serverTransport),
179       inputTransportFactory_(transportFactory),
180       outputTransportFactory_(transportFactory),
181       inputProtocolFactory_(protocolFactory),
182       outputProtocolFactory_(protocolFactory) {}
183 
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)184   TServer(const std::shared_ptr<TProcessorFactory>& processorFactory,
185           const std::shared_ptr<TServerTransport>& serverTransport,
186           const std::shared_ptr<TTransportFactory>& inputTransportFactory,
187           const std::shared_ptr<TTransportFactory>& outputTransportFactory,
188           const std::shared_ptr<TProtocolFactory>& inputProtocolFactory,
189           const std::shared_ptr<TProtocolFactory>& outputProtocolFactory)
190     : processorFactory_(processorFactory),
191       serverTransport_(serverTransport),
192       inputTransportFactory_(inputTransportFactory),
193       outputTransportFactory_(outputTransportFactory),
194       inputProtocolFactory_(inputProtocolFactory),
195       outputProtocolFactory_(outputProtocolFactory) {}
196 
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)197   TServer(const std::shared_ptr<TProcessor>& processor,
198           const std::shared_ptr<TServerTransport>& serverTransport,
199           const std::shared_ptr<TTransportFactory>& inputTransportFactory,
200           const std::shared_ptr<TTransportFactory>& outputTransportFactory,
201           const std::shared_ptr<TProtocolFactory>& inputProtocolFactory,
202           const std::shared_ptr<TProtocolFactory>& outputProtocolFactory)
203     : processorFactory_(new TSingletonProcessorFactory(processor)),
204       serverTransport_(serverTransport),
205       inputTransportFactory_(inputTransportFactory),
206       outputTransportFactory_(outputTransportFactory),
207       inputProtocolFactory_(inputProtocolFactory),
208       outputProtocolFactory_(outputProtocolFactory) {}
209 
210   /**
211    * Get a TProcessor to handle calls on a particular connection.
212    *
213    * This method should only be called once per connection (never once per
214    * call).  This allows the TProcessorFactory to return a different processor
215    * for each connection if it desires.
216    */
getProcessor(std::shared_ptr<TProtocol> inputProtocol,std::shared_ptr<TProtocol> outputProtocol,std::shared_ptr<TTransport> transport)217   std::shared_ptr<TProcessor> getProcessor(std::shared_ptr<TProtocol> inputProtocol,
218                                              std::shared_ptr<TProtocol> outputProtocol,
219                                              std::shared_ptr<TTransport> transport) {
220     TConnectionInfo connInfo;
221     connInfo.input = inputProtocol;
222     connInfo.output = outputProtocol;
223     connInfo.transport = transport;
224     return processorFactory_->getProcessor(connInfo);
225   }
226 
227   // Class variables
228   std::shared_ptr<TProcessorFactory> processorFactory_;
229   std::shared_ptr<TServerTransport> serverTransport_;
230 
231   std::shared_ptr<TTransportFactory> inputTransportFactory_;
232   std::shared_ptr<TTransportFactory> outputTransportFactory_;
233 
234   std::shared_ptr<TProtocolFactory> inputProtocolFactory_;
235   std::shared_ptr<TProtocolFactory> outputProtocolFactory_;
236 
237   std::shared_ptr<TServerEventHandler> eventHandler_;
238 
239 public:
setInputTransportFactory(std::shared_ptr<TTransportFactory> inputTransportFactory)240   void setInputTransportFactory(std::shared_ptr<TTransportFactory> inputTransportFactory) {
241     inputTransportFactory_ = inputTransportFactory;
242   }
243 
setOutputTransportFactory(std::shared_ptr<TTransportFactory> outputTransportFactory)244   void setOutputTransportFactory(std::shared_ptr<TTransportFactory> outputTransportFactory) {
245     outputTransportFactory_ = outputTransportFactory;
246   }
247 
setInputProtocolFactory(std::shared_ptr<TProtocolFactory> inputProtocolFactory)248   void setInputProtocolFactory(std::shared_ptr<TProtocolFactory> inputProtocolFactory) {
249     inputProtocolFactory_ = inputProtocolFactory;
250   }
251 
setOutputProtocolFactory(std::shared_ptr<TProtocolFactory> outputProtocolFactory)252   void setOutputProtocolFactory(std::shared_ptr<TProtocolFactory> outputProtocolFactory) {
253     outputProtocolFactory_ = outputProtocolFactory;
254   }
255 
setServerEventHandler(std::shared_ptr<TServerEventHandler> eventHandler)256   void setServerEventHandler(std::shared_ptr<TServerEventHandler> eventHandler) {
257     eventHandler_ = eventHandler;
258   }
259 };
260 
261 /**
262  * Helper function to increase the max file descriptors limit
263  * for the current process and all of its children.
264  * By default, tries to increase it to as much as 2^24.
265  */
266 #ifdef HAVE_SYS_RESOURCE_H
267 int increase_max_fds(int max_fds = (1 << 24));
268 #endif
269 }
270 }
271 } // apache::thrift::server
272 
273 #endif // #ifndef _THRIFT_SERVER_TSERVER_H_
274