1 // 2 // 3 // Copyright 2015-2016 gRPC authors. 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 // 17 // 18 19 #ifndef GRPCPP_SERVER_BUILDER_H 20 #define GRPCPP_SERVER_BUILDER_H 21 22 #include <grpc/compression.h> 23 #include <grpc/event_engine/event_engine.h> 24 #include <grpc/passive_listener.h> 25 #include <grpc/support/cpu.h> 26 #include <grpc/support/port_platform.h> 27 #include <grpc/support/workaround_list.h> 28 #include <grpcpp/impl/channel_argument_option.h> 29 #include <grpcpp/impl/server_builder_option.h> 30 #include <grpcpp/impl/server_builder_plugin.h> 31 #include <grpcpp/passive_listener.h> 32 #include <grpcpp/security/authorization_policy_provider.h> 33 #include <grpcpp/security/server_credentials.h> 34 #include <grpcpp/server.h> 35 #include <grpcpp/support/config.h> 36 #include <grpcpp/support/server_interceptor.h> 37 38 #include <climits> 39 #include <map> 40 #include <memory> 41 #include <vector> 42 43 struct grpc_resource_quota; 44 45 namespace grpc { 46 47 class CompletionQueue; 48 class Server; 49 class ServerCompletionQueue; 50 class AsyncGenericService; 51 class ResourceQuota; 52 class ServerCredentials; 53 class Service; 54 namespace testing { 55 class ServerBuilderPluginTest; 56 } // namespace testing 57 58 namespace internal { 59 class ExternalConnectionAcceptorImpl; 60 } // namespace internal 61 62 class CallbackGenericService; 63 64 namespace experimental { 65 // EXPERIMENTAL API: 66 // Interface for a grpc server to build transports with connections created out 67 // of band. 68 // See ServerBuilder's AddExternalConnectionAcceptor API. 69 class ExternalConnectionAcceptor { 70 public: 71 struct NewConnectionParameters { 72 int listener_fd = -1; 73 int fd = -1; 74 ByteBuffer read_buffer; // data intended for the grpc server 75 }; ~ExternalConnectionAcceptor()76 virtual ~ExternalConnectionAcceptor() {} 77 // If called before grpc::Server is started or after it is shut down, the new 78 // connection will be closed. 79 virtual void HandleNewConnection(NewConnectionParameters* p) = 0; 80 }; 81 82 } // namespace experimental 83 } // namespace grpc 84 85 namespace grpc { 86 87 /// A builder class for the creation and startup of \a grpc::Server instances. 88 class ServerBuilder { 89 public: 90 ServerBuilder(); 91 virtual ~ServerBuilder(); 92 93 ////////////////////////////////////////////////////////////////////////////// 94 // Primary API's 95 96 /// Return a running server which is ready for processing calls. 97 /// Before calling, one typically needs to ensure that: 98 /// 1. a service is registered - so that the server knows what to serve 99 /// (via RegisterService, or RegisterAsyncGenericService) 100 /// 2. a listening port has been added - so the server knows where to receive 101 /// traffic (via AddListeningPort) 102 /// 3. [for async api only] completion queues have been added via 103 /// AddCompletionQueue 104 /// 105 /// Will return a nullptr on errors. 106 virtual std::unique_ptr<grpc::Server> BuildAndStart(); 107 108 /// Register a service. This call does not take ownership of the service. 109 /// The service must exist for the lifetime of the \a Server instance returned 110 /// by \a BuildAndStart(). 111 /// Matches requests with any :authority 112 ServerBuilder& RegisterService(grpc::Service* service); 113 114 /// Enlists an endpoint \a addr (port with an optional IP address) to 115 /// bind the \a grpc::Server object to be created to. 116 /// 117 /// It can be invoked multiple times. 118 /// 119 /// \param addr_uri The address to try to bind to the server in URI form. If 120 /// the scheme name is omitted, "dns:///" is assumed. To bind to any address, 121 /// please use IPv6 any, i.e., [::]:<port>, which also accepts IPv4 122 /// connections. Valid values include dns:///localhost:1234, 123 /// 192.168.1.1:31416, dns:///[::1]:27182, etc. 124 /// \param creds The credentials associated with the server. 125 /// \param[out] selected_port If not `nullptr`, gets populated with the port 126 /// number bound to the \a grpc::Server for the corresponding endpoint after 127 /// it is successfully bound by BuildAndStart(), 0 otherwise. AddListeningPort 128 /// does not modify this pointer. 129 ServerBuilder& AddListeningPort( 130 const std::string& addr_uri, 131 std::shared_ptr<grpc::ServerCredentials> creds, 132 int* selected_port = nullptr); 133 134 /// Add a completion queue for handling asynchronous services. 135 /// 136 /// Best performance is typically obtained by using one thread per polling 137 /// completion queue. 138 /// 139 /// Caller is required to shutdown the server prior to shutting down the 140 /// returned completion queue. Caller is also required to drain the 141 /// completion queue after shutting it down. A typical usage scenario: 142 /// 143 /// // While building the server: 144 /// ServerBuilder builder; 145 /// ... 146 /// cq_ = builder.AddCompletionQueue(); 147 /// server_ = builder.BuildAndStart(); 148 /// 149 /// // While shutting down the server; 150 /// server_->Shutdown(); 151 /// cq_->Shutdown(); // Always *after* the associated server's Shutdown()! 152 /// // Drain the cq_ that was created 153 /// void* ignored_tag; 154 /// bool ignored_ok; 155 /// while (cq_->Next(&ignored_tag, &ignored_ok)) { } 156 /// 157 /// \param is_frequently_polled This is an optional parameter to inform gRPC 158 /// library about whether this completion queue would be frequently polled 159 /// (i.e. by calling \a Next() or \a AsyncNext()). The default value is 160 /// 'true' and is the recommended setting. Setting this to 'false' (i.e. 161 /// not polling the completion queue frequently) will have a significantly 162 /// negative performance impact and hence should not be used in production 163 /// use cases. 164 std::unique_ptr<grpc::ServerCompletionQueue> AddCompletionQueue( 165 bool is_frequently_polled = true); 166 167 ////////////////////////////////////////////////////////////////////////////// 168 // Less commonly used RegisterService variants 169 170 /// Register a service. This call does not take ownership of the service. 171 /// The service must exist for the lifetime of the \a Server instance 172 /// returned by \a BuildAndStart(). Only matches requests with :authority \a 173 /// host 174 ServerBuilder& RegisterService(const std::string& host, 175 grpc::Service* service); 176 177 /// Register a generic service. 178 /// Matches requests with any :authority 179 /// This is mostly useful for writing generic gRPC Proxies where the exact 180 /// serialization format is unknown 181 ServerBuilder& RegisterAsyncGenericService( 182 grpc::AsyncGenericService* service); 183 184 ////////////////////////////////////////////////////////////////////////////// 185 // Fine control knobs 186 187 /// Set max receive message size in bytes. 188 /// The default is GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH. SetMaxReceiveMessageSize(int max_receive_message_size)189 ServerBuilder& SetMaxReceiveMessageSize(int max_receive_message_size) { 190 max_receive_message_size_ = max_receive_message_size; 191 return *this; 192 } 193 194 /// Set max send message size in bytes. 195 /// The default is GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH. SetMaxSendMessageSize(int max_send_message_size)196 ServerBuilder& SetMaxSendMessageSize(int max_send_message_size) { 197 max_send_message_size_ = max_send_message_size; 198 return *this; 199 } 200 201 /// \deprecated For backward compatibility. SetMaxMessageSize(int max_message_size)202 ServerBuilder& SetMaxMessageSize(int max_message_size) { 203 return SetMaxReceiveMessageSize(max_message_size); 204 } 205 206 /// Set the support status for compression algorithms. All algorithms are 207 /// enabled by default. 208 /// 209 /// Incoming calls compressed with an unsupported algorithm will fail with 210 /// \a GRPC_STATUS_UNIMPLEMENTED. 211 ServerBuilder& SetCompressionAlgorithmSupportStatus( 212 grpc_compression_algorithm algorithm, bool enabled); 213 214 /// The default compression level to use for all channel calls in the 215 /// absence of a call-specific level. 216 ServerBuilder& SetDefaultCompressionLevel(grpc_compression_level level); 217 218 /// The default compression algorithm to use for all channel calls in the 219 /// absence of a call-specific level. Note that it overrides any compression 220 /// level set by \a SetDefaultCompressionLevel. 221 ServerBuilder& SetDefaultCompressionAlgorithm( 222 grpc_compression_algorithm algorithm); 223 224 /// Set the attached buffer pool for this server 225 ServerBuilder& SetResourceQuota(const grpc::ResourceQuota& resource_quota); 226 227 ServerBuilder& SetOption(std::unique_ptr<grpc::ServerBuilderOption> option); 228 229 /// Options for synchronous servers. 230 enum SyncServerOption { 231 NUM_CQS, ///< Number of completion queues. 232 MIN_POLLERS, ///< Minimum number of polling threads. 233 MAX_POLLERS, ///< Maximum number of polling threads. 234 CQ_TIMEOUT_MSEC ///< Completion queue timeout in milliseconds. 235 }; 236 237 /// Only useful if this is a Synchronous server. 238 ServerBuilder& SetSyncServerOption(SyncServerOption option, int value); 239 240 /// Add a channel argument (an escape hatch to tuning core library parameters 241 /// directly) 242 template <class T> AddChannelArgument(const std::string & arg,const T & value)243 ServerBuilder& AddChannelArgument(const std::string& arg, const T& value) { 244 return SetOption(grpc::MakeChannelArgumentOption(arg, value)); 245 } 246 247 /// For internal use only: Register a ServerBuilderPlugin factory function. 248 static void InternalAddPluginFactory( 249 std::unique_ptr<grpc::ServerBuilderPlugin> (*CreatePlugin)()); 250 251 /// Enable a server workaround. Do not use unless you know what the workaround 252 /// does. For explanation and detailed descriptions of workarounds, see 253 /// doc/workarounds.md. 254 ServerBuilder& EnableWorkaround(grpc_workaround_list id); 255 256 /// NOTE: class experimental_type is not part of the public API of this class. 257 /// TODO(yashykt): Integrate into public API when this is no longer 258 /// experimental. 259 class experimental_type { 260 public: experimental_type(ServerBuilder * builder)261 explicit experimental_type(ServerBuilder* builder) : builder_(builder) {} 262 SetInterceptorCreators(std::vector<std::unique_ptr<grpc::experimental::ServerInterceptorFactoryInterface>> interceptor_creators)263 void SetInterceptorCreators( 264 std::vector<std::unique_ptr< 265 grpc::experimental::ServerInterceptorFactoryInterface>> 266 interceptor_creators) { 267 builder_->interceptor_creators_ = std::move(interceptor_creators); 268 } 269 270 enum class ExternalConnectionType { 271 FROM_FD = 0 // in the form of a file descriptor 272 }; 273 274 /// Register an acceptor to handle the externally accepted connection in 275 /// grpc server. The returned acceptor can be used to pass the connection 276 /// to grpc server, where a channel will be created with the provided 277 /// server credentials. 278 std::unique_ptr<grpc::experimental::ExternalConnectionAcceptor> 279 AddExternalConnectionAcceptor(ExternalConnectionType type, 280 std::shared_ptr<ServerCredentials> creds); 281 282 /// Sets server authorization policy provider in 283 /// GRPC_ARG_AUTHORIZATION_POLICY_PROVIDER channel argument. 284 void SetAuthorizationPolicyProvider( 285 std::shared_ptr<experimental::AuthorizationPolicyProviderInterface> 286 provider); 287 288 /// Enables per-call load reporting. The server will automatically send the 289 /// load metrics after each RPC. The caller can report load metrics for the 290 /// current call to what ServerContext::ExperimentalGetCallMetricRecorder() 291 /// returns. The server merges metrics from the optional 292 /// server_metric_recorder when provided where the call metric recorder take 293 /// a higher precedence. The caller owns and must ensure the server metric 294 /// recorder outlives the server. 295 void EnableCallMetricRecording( 296 experimental::ServerMetricRecorder* server_metric_recorder = nullptr); 297 298 // Creates a passive listener for Server Endpoint injection. 299 /// 300 /// \a PassiveListener lets applications provide pre-established connections 301 /// to gRPC Servers. The server will behave as if it accepted the connection 302 /// itself on its own listening addresses. 303 /// 304 /// This can be called multiple times to create passive listeners with 305 /// different server credentials. 306 ServerBuilder& AddPassiveListener( 307 std::shared_ptr<grpc::ServerCredentials> creds, 308 std::unique_ptr<grpc::experimental::PassiveListener>& passive_listener); 309 310 private: 311 ServerBuilder* builder_; 312 }; 313 314 /// Set the allocator for creating and releasing callback server context. 315 /// Takes the owndership of the allocator. 316 ServerBuilder& SetContextAllocator( 317 std::unique_ptr<grpc::ContextAllocator> context_allocator); 318 319 /// Register a generic service that uses the callback API. 320 /// Matches requests with any :authority 321 /// This is mostly useful for writing generic gRPC Proxies where the exact 322 /// serialization format is unknown 323 ServerBuilder& RegisterCallbackGenericService( 324 grpc::CallbackGenericService* service); 325 326 /// NOTE: The function experimental() is not stable public API. It is a view 327 /// to the experimental components of this class. It may be changed or removed 328 /// at any time. experimental()329 experimental_type experimental() { return experimental_type(this); } 330 331 protected: 332 /// Experimental, to be deprecated 333 struct Port { 334 std::string addr; 335 std::shared_ptr<ServerCredentials> creds; 336 int* selected_port; 337 }; 338 339 /// Experimental, to be deprecated 340 typedef std::unique_ptr<std::string> HostString; 341 struct NamedService { NamedServiceNamedService342 explicit NamedService(grpc::Service* s) : service(s) {} NamedServiceNamedService343 NamedService(const std::string& h, grpc::Service* s) 344 : host(new std::string(h)), service(s) {} 345 HostString host; 346 grpc::Service* service; 347 }; 348 349 /// Experimental, to be deprecated ports()350 std::vector<Port> ports() { return ports_; } 351 352 /// Experimental, to be deprecated services()353 std::vector<NamedService*> services() { 354 std::vector<NamedService*> service_refs; 355 service_refs.reserve(services_.size()); 356 for (auto& ptr : services_) { 357 service_refs.push_back(ptr.get()); 358 } 359 return service_refs; 360 } 361 362 /// Experimental, to be deprecated options()363 std::vector<grpc::ServerBuilderOption*> options() { 364 std::vector<grpc::ServerBuilderOption*> option_refs; 365 option_refs.reserve(options_.size()); 366 for (auto& ptr : options_) { 367 option_refs.push_back(ptr.get()); 368 } 369 return option_refs; 370 } 371 372 /// Experimental API, subject to change. set_fetcher(grpc_server_config_fetcher * server_config_fetcher)373 void set_fetcher(grpc_server_config_fetcher* server_config_fetcher) { 374 server_config_fetcher_ = server_config_fetcher; 375 } 376 377 /// Experimental API, subject to change. 378 virtual ChannelArguments BuildChannelArgs(); 379 380 private: 381 friend class grpc::testing::ServerBuilderPluginTest; 382 383 struct UnstartedPassiveListener { 384 std::weak_ptr<grpc_core::experimental::PassiveListenerImpl> 385 passive_listener; 386 std::shared_ptr<grpc::ServerCredentials> credentials; UnstartedPassiveListenerUnstartedPassiveListener387 UnstartedPassiveListener( 388 std::weak_ptr<grpc_core::experimental::PassiveListenerImpl> listener, 389 std::shared_ptr<grpc::ServerCredentials> creds) 390 : passive_listener(std::move(listener)), 391 credentials(std::move(creds)) {} 392 }; 393 394 struct SyncServerSettings { SyncServerSettingsSyncServerSettings395 SyncServerSettings() 396 : num_cqs(1), min_pollers(1), max_pollers(2), cq_timeout_msec(10000) {} 397 398 /// Number of server completion queues to create to listen to incoming RPCs. 399 int num_cqs; 400 401 /// Minimum number of threads per completion queue that should be listening 402 /// to incoming RPCs. 403 int min_pollers; 404 405 /// Maximum number of threads per completion queue that can be listening to 406 /// incoming RPCs. 407 int max_pollers; 408 409 /// The timeout for server completion queue's AsyncNext call. 410 int cq_timeout_msec; 411 }; 412 413 int max_receive_message_size_; 414 int max_send_message_size_; 415 std::vector<std::unique_ptr<grpc::ServerBuilderOption>> options_; 416 std::vector<std::unique_ptr<NamedService>> services_; 417 std::vector<Port> ports_; 418 std::vector<UnstartedPassiveListener> unstarted_passive_listeners_; 419 420 SyncServerSettings sync_server_settings_; 421 422 /// List of completion queues added via \a AddCompletionQueue method. 423 std::vector<grpc::ServerCompletionQueue*> cqs_; 424 425 std::shared_ptr<grpc::ServerCredentials> creds_; 426 std::vector<std::unique_ptr<grpc::ServerBuilderPlugin>> plugins_; 427 grpc_resource_quota* resource_quota_; 428 grpc::AsyncGenericService* generic_service_{nullptr}; 429 std::unique_ptr<ContextAllocator> context_allocator_; 430 grpc::CallbackGenericService* callback_generic_service_{nullptr}; 431 432 struct { 433 bool is_set; 434 grpc_compression_level level; 435 } maybe_default_compression_level_; 436 struct { 437 bool is_set; 438 grpc_compression_algorithm algorithm; 439 } maybe_default_compression_algorithm_; 440 uint32_t enabled_compression_algorithms_bitset_; 441 std::vector< 442 std::unique_ptr<grpc::experimental::ServerInterceptorFactoryInterface>> 443 interceptor_creators_; 444 std::vector<std::shared_ptr<grpc::internal::ExternalConnectionAcceptorImpl>> 445 acceptors_; 446 grpc_server_config_fetcher* server_config_fetcher_ = nullptr; 447 std::shared_ptr<experimental::AuthorizationPolicyProviderInterface> 448 authorization_provider_; 449 experimental::ServerMetricRecorder* server_metric_recorder_ = nullptr; 450 }; 451 452 } // namespace grpc 453 454 #endif // GRPCPP_SERVER_BUILDER_H 455