From a23f17b1233453334ad137a3aeb338c801b5ada4 Mon Sep 17 00:00:00 2001
From: yang-g <yangg@google.com>
Date: Wed, 25 Nov 2015 10:21:05 -0800
Subject: [PATCH] add server_builder_option

---
 BUILD                                         |  2 +
 Makefile                                      |  2 +
 build.yaml                                    |  1 +
 include/grpc++/impl/server_builder_option.h   | 49 +++++++++++++++++++
 include/grpc++/server.h                       |  5 +-
 include/grpc++/server_builder.h               |  6 ++-
 src/cpp/server/server.cc                      | 25 ++--------
 src/cpp/server/server_builder.cc              | 18 +++++--
 tools/doxygen/Doxyfile.c++                    |  1 +
 tools/doxygen/Doxyfile.c++.internal           |  1 +
 tools/run_tests/sources_and_headers.json      |  4 ++
 .../grpc++_unsecure/grpc++_unsecure.vcxproj   |  1 +
 .../grpc++_unsecure.vcxproj.filters           |  3 ++
 vsprojects/vcxproj/grpc++/grpc++.vcxproj      |  1 +
 .../vcxproj/grpc++/grpc++.vcxproj.filters     |  3 ++
 .../grpc++_unsecure/grpc++_unsecure.vcxproj   |  1 +
 .../grpc++_unsecure.vcxproj.filters           |  3 ++
 17 files changed, 100 insertions(+), 26 deletions(-)
 create mode 100644 include/grpc++/impl/server_builder_option.h

diff --git a/BUILD b/BUILD
index 67365dcd0f..5ae3b37b29 100644
--- a/BUILD
+++ b/BUILD
@@ -784,6 +784,7 @@ cc_library(
     "include/grpc++/impl/rpc_method.h",
     "include/grpc++/impl/rpc_service_method.h",
     "include/grpc++/impl/serialization_traits.h",
+    "include/grpc++/impl/server_builder_option.h",
     "include/grpc++/impl/service_type.h",
     "include/grpc++/impl/sync.h",
     "include/grpc++/impl/sync_cxx11.h",
@@ -876,6 +877,7 @@ cc_library(
     "include/grpc++/impl/rpc_method.h",
     "include/grpc++/impl/rpc_service_method.h",
     "include/grpc++/impl/serialization_traits.h",
+    "include/grpc++/impl/server_builder_option.h",
     "include/grpc++/impl/service_type.h",
     "include/grpc++/impl/sync.h",
     "include/grpc++/impl/sync_cxx11.h",
diff --git a/Makefile b/Makefile
index 960fd77141..e239aab999 100644
--- a/Makefile
+++ b/Makefile
@@ -5101,6 +5101,7 @@ PUBLIC_HEADERS_CXX += \
     include/grpc++/impl/rpc_method.h \
     include/grpc++/impl/rpc_service_method.h \
     include/grpc++/impl/serialization_traits.h \
+    include/grpc++/impl/server_builder_option.h \
     include/grpc++/impl/service_type.h \
     include/grpc++/impl/sync.h \
     include/grpc++/impl/sync_cxx11.h \
@@ -5347,6 +5348,7 @@ PUBLIC_HEADERS_CXX += \
     include/grpc++/impl/rpc_method.h \
     include/grpc++/impl/rpc_service_method.h \
     include/grpc++/impl/serialization_traits.h \
+    include/grpc++/impl/server_builder_option.h \
     include/grpc++/impl/service_type.h \
     include/grpc++/impl/sync.h \
     include/grpc++/impl/sync_cxx11.h \
diff --git a/build.yaml b/build.yaml
index cc8a942e91..612983596b 100644
--- a/build.yaml
+++ b/build.yaml
@@ -37,6 +37,7 @@ filegroups:
   - include/grpc++/impl/rpc_method.h
   - include/grpc++/impl/rpc_service_method.h
   - include/grpc++/impl/serialization_traits.h
+  - include/grpc++/impl/server_builder_option.h
   - include/grpc++/impl/service_type.h
   - include/grpc++/impl/sync.h
   - include/grpc++/impl/sync_cxx11.h
diff --git a/include/grpc++/impl/server_builder_option.h b/include/grpc++/impl/server_builder_option.h
new file mode 100644
index 0000000000..cf5c1d93e4
--- /dev/null
+++ b/include/grpc++/impl/server_builder_option.h
@@ -0,0 +1,49 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPCXX_IMPL_SERVER_BUILDER_OPTION_H
+#define GRPCXX_IMPL_SERVER_BUILDER_OPTION_H
+
+#include <grpc++/support/channel_arguments.h>
+
+namespace grpc {
+
+class ServerBuilderOption {
+ public:
+  virtual ~ServerBuilderOption() {}
+  virtual void UpdateArguments(ChannelArguments* args) = 0;
+};
+
+}  // namespace grpc
+
+#endif  // GRPCXX_IMPL_SERVER_BUILDER_OPTION_H
diff --git a/include/grpc++/server.h b/include/grpc++/server.h
index 1a62df5698..3161526aa9 100644
--- a/include/grpc++/server.h
+++ b/include/grpc++/server.h
@@ -37,14 +37,15 @@
 #include <list>
 #include <memory>
 
-#include <grpc/compression.h>
 #include <grpc++/completion_queue.h>
 #include <grpc++/impl/call.h>
 #include <grpc++/impl/grpc_library.h>
 #include <grpc++/impl/sync.h>
 #include <grpc++/security/server_credentials.h>
+#include <grpc++/support/channel_arguments.h>
 #include <grpc++/support/config.h>
 #include <grpc++/support/status.h>
+#include <grpc/compression.h>
 
 struct grpc_server;
 
@@ -100,7 +101,7 @@ class Server GRPC_FINAL : public GrpcLibrary, private CallHook {
   /// \param max_message_size Maximum message length that the channel can
   /// receive.
   Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned,
-         int max_message_size, grpc_compression_options compression_options);
+         int max_message_size, const ChannelArguments& args);
 
   /// Register a service. This call does not take ownership of the service.
   /// The service must exist for the lifetime of the Server instance.
diff --git a/include/grpc++/server_builder.h b/include/grpc++/server_builder.h
index 05937f150b..b324deb9e0 100644
--- a/include/grpc++/server_builder.h
+++ b/include/grpc++/server_builder.h
@@ -37,8 +37,9 @@
 #include <memory>
 #include <vector>
 
-#include <grpc/compression.h>
+#include <grpc++/impl/server_builder_option.h>
 #include <grpc++/support/config.h>
+#include <grpc/compression.h>
 
 namespace grpc {
 
@@ -98,6 +99,8 @@ class ServerBuilder {
     compression_options_ = options;
   }
 
+  void SetOption(std::unique_ptr<ServerBuilderOption> option);
+
   /// Tries to bind \a server to the given \a addr.
   ///
   /// It can be invoked multiple times.
@@ -140,6 +143,7 @@ class ServerBuilder {
 
   int max_message_size_;
   grpc_compression_options compression_options_;
+  std::vector<std::unique_ptr<ServerBuilderOption>> options_;
   std::vector<std::unique_ptr<NamedService<RpcService>>> services_;
   std::vector<std::unique_ptr<NamedService<AsynchronousService>>>
       async_services_;
diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc
index 695e811654..f1c8c11c4e 100644
--- a/src/cpp/server/server.cc
+++ b/src/cpp/server/server.cc
@@ -251,36 +251,21 @@ class Server::SyncRequest GRPC_FINAL : public CompletionQueueTag {
   grpc_completion_queue* cq_;
 };
 
-static grpc_server* CreateServer(
-    int max_message_size, const grpc_compression_options& compression_options) {
-  grpc_arg args[2];
-  size_t args_idx = 0;
-  if (max_message_size > 0) {
-    args[args_idx].type = GRPC_ARG_INTEGER;
-    args[args_idx].key = const_cast<char*>(GRPC_ARG_MAX_MESSAGE_LENGTH);
-    args[args_idx].value.integer = max_message_size;
-    args_idx++;
-  }
-
-  args[args_idx].type = GRPC_ARG_INTEGER;
-  args[args_idx].key = const_cast<char*>(GRPC_COMPRESSION_ALGORITHM_STATE_ARG);
-  args[args_idx].value.integer = compression_options.enabled_algorithms_bitset;
-  args_idx++;
-
-  grpc_channel_args channel_args = {args_idx, args};
+static grpc_server* CreateServer(const ChannelArguments& args) {
+  grpc_channel_args channel_args;
+  args.SetChannelArgs(&channel_args);
   return grpc_server_create(&channel_args, nullptr);
 }
 
 Server::Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned,
-               int max_message_size,
-               grpc_compression_options compression_options)
+               int max_message_size, const ChannelArguments& args)
     : max_message_size_(max_message_size),
       started_(false),
       shutdown_(false),
       num_running_cb_(0),
       sync_methods_(new std::list<SyncRequest>),
       has_generic_service_(false),
-      server_(CreateServer(max_message_size, compression_options)),
+      server_(CreateServer(args)),
       thread_pool_(thread_pool),
       thread_pool_owned_(thread_pool_owned) {
   grpc_server_register_completion_queue(server_, cq_.cq(), nullptr);
diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc
index b8094aa8f6..26c0724a30 100644
--- a/src/cpp/server/server_builder.cc
+++ b/src/cpp/server/server_builder.cc
@@ -84,6 +84,10 @@ void ServerBuilder::RegisterAsyncGenericService(AsyncGenericService* service) {
   generic_service_ = service;
 }
 
+void ServerBuilder::SetOption(std::unique_ptr<ServerBuilderOption> option) {
+  options_.push_back(std::move(option));
+}
+
 void ServerBuilder::AddListeningPort(const grpc::string& addr,
                                      std::shared_ptr<ServerCredentials> creds,
                                      int* selected_port) {
@@ -101,9 +105,17 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
     thread_pool_ = CreateDefaultThreadPool();
     thread_pool_owned = true;
   }
-  std::unique_ptr<Server> server(new Server(thread_pool_, thread_pool_owned,
-                                            max_message_size_,
-                                            compression_options_));
+  ChannelArguments args;
+  for (auto option = options_.begin(); option != options_.end(); ++option) {
+    (*option)->UpdateArguments(&args);
+  }
+  if (max_message_size_ > 0) {
+    args.SetInt(GRPC_ARG_MAX_MESSAGE_LENGTH, max_message_size_);
+  }
+  args.SetInt(GRPC_COMPRESSION_ALGORITHM_STATE_ARG,
+              compression_options_.enabled_algorithms_bitset);
+  std::unique_ptr<Server> server(
+      new Server(thread_pool_, thread_pool_owned, max_message_size_, args));
   for (auto cq = cqs_.begin(); cq != cqs_.end(); ++cq) {
     grpc_server_register_completion_queue(server->server_, (*cq)->cq(),
                                           nullptr);
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index f07718515a..500d110ad0 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -774,6 +774,7 @@ include/grpc++/impl/proto_utils.h \
 include/grpc++/impl/rpc_method.h \
 include/grpc++/impl/rpc_service_method.h \
 include/grpc++/impl/serialization_traits.h \
+include/grpc++/impl/server_builder_option.h \
 include/grpc++/impl/service_type.h \
 include/grpc++/impl/sync.h \
 include/grpc++/impl/sync_cxx11.h \
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 11aaa379ce..26e808c799 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -774,6 +774,7 @@ include/grpc++/impl/proto_utils.h \
 include/grpc++/impl/rpc_method.h \
 include/grpc++/impl/rpc_service_method.h \
 include/grpc++/impl/serialization_traits.h \
+include/grpc++/impl/server_builder_option.h \
 include/grpc++/impl/service_type.h \
 include/grpc++/impl/sync.h \
 include/grpc++/impl/sync_cxx11.h \
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index 66ca0dc2e3..33b6ccf1f1 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -15270,6 +15270,7 @@
       "include/grpc++/impl/rpc_method.h", 
       "include/grpc++/impl/rpc_service_method.h", 
       "include/grpc++/impl/serialization_traits.h", 
+      "include/grpc++/impl/server_builder_option.h", 
       "include/grpc++/impl/service_type.h", 
       "include/grpc++/impl/sync.h", 
       "include/grpc++/impl/sync_cxx11.h", 
@@ -15323,6 +15324,7 @@
       "include/grpc++/impl/rpc_method.h", 
       "include/grpc++/impl/rpc_service_method.h", 
       "include/grpc++/impl/serialization_traits.h", 
+      "include/grpc++/impl/server_builder_option.h", 
       "include/grpc++/impl/service_type.h", 
       "include/grpc++/impl/sync.h", 
       "include/grpc++/impl/sync_cxx11.h", 
@@ -15454,6 +15456,7 @@
       "include/grpc++/impl/rpc_method.h", 
       "include/grpc++/impl/rpc_service_method.h", 
       "include/grpc++/impl/serialization_traits.h", 
+      "include/grpc++/impl/server_builder_option.h", 
       "include/grpc++/impl/service_type.h", 
       "include/grpc++/impl/sync.h", 
       "include/grpc++/impl/sync_cxx11.h", 
@@ -15504,6 +15507,7 @@
       "include/grpc++/impl/rpc_method.h", 
       "include/grpc++/impl/rpc_service_method.h", 
       "include/grpc++/impl/serialization_traits.h", 
+      "include/grpc++/impl/server_builder_option.h", 
       "include/grpc++/impl/service_type.h", 
       "include/grpc++/impl/sync.h", 
       "include/grpc++/impl/sync_cxx11.h", 
diff --git a/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj
index 74b0fbf2be..defd102577 100644
--- a/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj
+++ b/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj
@@ -251,6 +251,7 @@
     <ClInclude Include="..\..\..\include\grpc++\impl\rpc_method.h" />
     <ClInclude Include="..\..\..\include\grpc++\impl\rpc_service_method.h" />
     <ClInclude Include="..\..\..\include\grpc++\impl\serialization_traits.h" />
+    <ClInclude Include="..\..\..\include\grpc++\impl\server_builder_option.h" />
     <ClInclude Include="..\..\..\include\grpc++\impl\service_type.h" />
     <ClInclude Include="..\..\..\include\grpc++\impl\sync.h" />
     <ClInclude Include="..\..\..\include\grpc++\impl\sync_cxx11.h" />
diff --git a/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
index 96effe2961..97c484fcfc 100644
--- a/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
+++ b/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
@@ -126,6 +126,9 @@
     <ClInclude Include="..\..\..\include\grpc++\impl\serialization_traits.h">
       <Filter>include\grpc++\impl</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\..\include\grpc++\impl\server_builder_option.h">
+      <Filter>include\grpc++\impl</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\..\include\grpc++\impl\service_type.h">
       <Filter>include\grpc++\impl</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
index 9f88c728c6..d2345cfd0d 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
@@ -251,6 +251,7 @@
     <ClInclude Include="..\..\..\include\grpc++\impl\rpc_method.h" />
     <ClInclude Include="..\..\..\include\grpc++\impl\rpc_service_method.h" />
     <ClInclude Include="..\..\..\include\grpc++\impl\serialization_traits.h" />
+    <ClInclude Include="..\..\..\include\grpc++\impl\server_builder_option.h" />
     <ClInclude Include="..\..\..\include\grpc++\impl\service_type.h" />
     <ClInclude Include="..\..\..\include\grpc++\impl\sync.h" />
     <ClInclude Include="..\..\..\include\grpc++\impl\sync_cxx11.h" />
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
index 7d9cd4769d..8c042215dc 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
@@ -141,6 +141,9 @@
     <ClInclude Include="..\..\..\include\grpc++\impl\serialization_traits.h">
       <Filter>include\grpc++\impl</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\..\include\grpc++\impl\server_builder_option.h">
+      <Filter>include\grpc++\impl</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\..\include\grpc++\impl\service_type.h">
       <Filter>include\grpc++\impl</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
index 74b0fbf2be..defd102577 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
@@ -251,6 +251,7 @@
     <ClInclude Include="..\..\..\include\grpc++\impl\rpc_method.h" />
     <ClInclude Include="..\..\..\include\grpc++\impl\rpc_service_method.h" />
     <ClInclude Include="..\..\..\include\grpc++\impl\serialization_traits.h" />
+    <ClInclude Include="..\..\..\include\grpc++\impl\server_builder_option.h" />
     <ClInclude Include="..\..\..\include\grpc++\impl\service_type.h" />
     <ClInclude Include="..\..\..\include\grpc++\impl\sync.h" />
     <ClInclude Include="..\..\..\include\grpc++\impl\sync_cxx11.h" />
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
index 96effe2961..97c484fcfc 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
@@ -126,6 +126,9 @@
     <ClInclude Include="..\..\..\include\grpc++\impl\serialization_traits.h">
       <Filter>include\grpc++\impl</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\..\include\grpc++\impl\server_builder_option.h">
+      <Filter>include\grpc++\impl</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\..\include\grpc++\impl\service_type.h">
       <Filter>include\grpc++\impl</Filter>
     </ClInclude>
-- 
GitLab