Server builder plugin

pull/6373/head
Yuchen Zeng 9 years ago
parent f921f2bee1
commit a42ec21341
  1. 4
      BUILD
  2. 51
      Makefile
  3. 15
      build.yaml
  4. 8
      include/grpc++/impl/server_builder_option.h
  5. 79
      include/grpc++/impl/server_builder_plugin.h
  6. 70
      include/grpc++/impl/server_initializer.h
  7. 8
      include/grpc++/server.h
  8. 9
      include/grpc++/server_builder.h
  9. 19
      src/cpp/server/server.cc
  10. 16
      src/cpp/server/server_builder.cc
  11. 28
      test/cpp/end2end/async_end2end_test.cc
  12. 234
      test/cpp/end2end/server_builder_plugin_test.cc
  13. 2
      tools/doxygen/Doxyfile.c++
  14. 2
      tools/doxygen/Doxyfile.c++.internal
  15. 22
      tools/run_tests/sources_and_headers.json
  16. 21
      tools/run_tests/tests.json
  17. 2
      vsprojects/vcxproj/grpc++/grpc++.vcxproj
  18. 6
      vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
  19. 2
      vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
  20. 6
      vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
  21. 207
      vsprojects/vcxproj/test/server_builder_plugin_test/server_builder_plugin_test.vcxproj
  22. 21
      vsprojects/vcxproj/test/server_builder_plugin_test/server_builder_plugin_test.vcxproj.filters

@ -890,6 +890,8 @@ cc_library(
"include/grpc++/impl/rpc_service_method.h",
"include/grpc++/impl/serialization_traits.h",
"include/grpc++/impl/server_builder_option.h",
"include/grpc++/impl/server_builder_plugin.h",
"include/grpc++/impl/server_initializer.h",
"include/grpc++/impl/service_type.h",
"include/grpc++/impl/sync.h",
"include/grpc++/impl/sync_cxx11.h",
@ -1035,6 +1037,8 @@ cc_library(
"include/grpc++/impl/rpc_service_method.h",
"include/grpc++/impl/serialization_traits.h",
"include/grpc++/impl/server_builder_option.h",
"include/grpc++/impl/server_builder_plugin.h",
"include/grpc++/impl/server_initializer.h",
"include/grpc++/impl/service_type.h",
"include/grpc++/impl/sync.h",
"include/grpc++/impl/sync_cxx11.h",

@ -1035,6 +1035,7 @@ reconnect_interop_client: $(BINDIR)/$(CONFIG)/reconnect_interop_client
reconnect_interop_server: $(BINDIR)/$(CONFIG)/reconnect_interop_server
secure_auth_context_test: $(BINDIR)/$(CONFIG)/secure_auth_context_test
secure_sync_unary_ping_pong_test: $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test
server_builder_plugin_test: $(BINDIR)/$(CONFIG)/server_builder_plugin_test
server_crash_test: $(BINDIR)/$(CONFIG)/server_crash_test
server_crash_test_client: $(BINDIR)/$(CONFIG)/server_crash_test_client
shutdown_test: $(BINDIR)/$(CONFIG)/shutdown_test
@ -1401,6 +1402,7 @@ buildtests_cxx: buildtests_zookeeper privatelibs_cxx \
$(BINDIR)/$(CONFIG)/reconnect_interop_server \
$(BINDIR)/$(CONFIG)/secure_auth_context_test \
$(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test \
$(BINDIR)/$(CONFIG)/server_builder_plugin_test \
$(BINDIR)/$(CONFIG)/server_crash_test \
$(BINDIR)/$(CONFIG)/server_crash_test_client \
$(BINDIR)/$(CONFIG)/shutdown_test \
@ -1732,6 +1734,8 @@ test_cxx: test_zookeeper buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/secure_auth_context_test || ( echo test secure_auth_context_test failed ; exit 1 )
$(E) "[RUN] Testing secure_sync_unary_ping_pong_test"
$(Q) $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test || ( echo test secure_sync_unary_ping_pong_test failed ; exit 1 )
$(E) "[RUN] Testing server_builder_plugin_test"
$(Q) $(BINDIR)/$(CONFIG)/server_builder_plugin_test || ( echo test server_builder_plugin_test failed ; exit 1 )
$(E) "[RUN] Testing server_crash_test"
$(Q) $(BINDIR)/$(CONFIG)/server_crash_test || ( echo test server_crash_test failed ; exit 1 )
$(E) "[RUN] Testing shutdown_test"
@ -3200,6 +3204,8 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/impl/rpc_service_method.h \
include/grpc++/impl/serialization_traits.h \
include/grpc++/impl/server_builder_option.h \
include/grpc++/impl/server_builder_plugin.h \
include/grpc++/impl/server_initializer.h \
include/grpc++/impl/service_type.h \
include/grpc++/impl/sync.h \
include/grpc++/impl/sync_cxx11.h \
@ -3503,6 +3509,8 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/impl/rpc_service_method.h \
include/grpc++/impl/serialization_traits.h \
include/grpc++/impl/server_builder_option.h \
include/grpc++/impl/server_builder_plugin.h \
include/grpc++/impl/server_initializer.h \
include/grpc++/impl/service_type.h \
include/grpc++/impl/sync.h \
include/grpc++/impl/sync_cxx11.h \
@ -11479,6 +11487,49 @@ endif
endif
SERVER_BUILDER_PLUGIN_TEST_SRC = \
test/cpp/end2end/server_builder_plugin_test.cc \
SERVER_BUILDER_PLUGIN_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SERVER_BUILDER_PLUGIN_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/server_builder_plugin_test: openssl_dep_error
else
ifeq ($(NO_PROTOBUF),true)
# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
$(BINDIR)/$(CONFIG)/server_builder_plugin_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/server_builder_plugin_test: $(PROTOBUF_DEP) $(SERVER_BUILDER_PLUGIN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(SERVER_BUILDER_PLUGIN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_builder_plugin_test
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_builder_plugin_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_server_builder_plugin_test: $(SERVER_BUILDER_PLUGIN_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(SERVER_BUILDER_PLUGIN_TEST_OBJS:.o=.dep)
endif
endif
SERVER_CRASH_TEST_SRC = \
test/cpp/end2end/server_crash_test.cc \

@ -590,6 +590,8 @@ filegroups:
- include/grpc++/impl/rpc_service_method.h
- include/grpc++/impl/serialization_traits.h
- include/grpc++/impl/server_builder_option.h
- include/grpc++/impl/server_builder_plugin.h
- include/grpc++/impl/server_initializer.h
- include/grpc++/impl/service_type.h
- include/grpc++/impl/sync.h
- include/grpc++/impl/sync_cxx11.h
@ -2914,6 +2916,19 @@ targets:
- mac
- linux
- posix
- name: server_builder_plugin_test
gtest: true
build: test
language: c++
src:
- test/cpp/end2end/server_builder_plugin_test.cc
deps:
- grpc++_test_util
- grpc_test_util
- grpc++
- grpc
- gpr_test_util
- gpr
- name: server_crash_test
gtest: true
cpu_cost: 0.1

@ -34,6 +34,10 @@
#ifndef GRPCXX_IMPL_SERVER_BUILDER_OPTION_H
#define GRPCXX_IMPL_SERVER_BUILDER_OPTION_H
#include <map>
#include <memory>
#include <grpc++/impl/server_builder_plugin.h>
#include <grpc++/support/channel_arguments.h>
namespace grpc {
@ -44,6 +48,10 @@ class ServerBuilderOption {
virtual ~ServerBuilderOption() {}
/// Alter the \a ChannelArguments used to create the gRPC server.
virtual void UpdateArguments(ChannelArguments* args) = 0;
/// Alter the ServerBuilderPlugin map that will be added into ServerBuilder.
virtual void UpdatePlugins(
std::map<grpc::string, std::unique_ptr<ServerBuilderPlugin> >*
plugins) = 0;
};
} // namespace grpc

@ -0,0 +1,79 @@
/*
*
* Copyright 2016, 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_PLUGIN_H
#define GRPCXX_IMPL_SERVER_BUILDER_PLUGIN_H
#include <memory>
#include <grpc++/support/config.h>
namespace grpc {
class ServerInitializer;
class ServerBuilderPlugin {
public:
virtual ~ServerBuilderPlugin() {}
virtual grpc::string name() = 0;
// InitServer will be called in ServerBuilder::BuildAndStart(), after the
// Server instance is created.
virtual void InitServer(ServerInitializer* si) = 0;
// Finish will be called at the end of ServerBuilder::BuildAndStart().
virtual void Finish(ServerInitializer* si) = 0;
// ChangeArguments is an interface that can be used in
// ServerBuilderOption::UpdatePlugins
virtual void ChangeArguments(const grpc::string& name, void* value) = 0;
virtual bool has_sync_methods() const { return false; }
virtual bool has_async_methods() const { return false; }
};
} // namespace grpc
#define DECLARE_PLUGIN(plugin_name) \
namespace sBP##plugin_name { \
extern std::unique_ptr<ServerBuilderPlugin> Create##plugin_name(); \
}
#define INIT_PLUGIN(map, plugin_name) \
{ \
std::unique_ptr<ServerBuilderPlugin> plugin = \
sBP##plugin_name::Create##plugin_name(); \
map[plugin->name()] = std::move(plugin); \
}
#endif // GRPCXX_IMPL_SERVER_BUILDER_PLUGIN_H

@ -0,0 +1,70 @@
/*
*
* Copyright 2016, 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_INITIALIZER_H
#define GRPCXX_IMPL_SERVER_INITIALIZER_H
#include <memory>
#include <vector>
#include <grpc++/server.h>
namespace grpc {
class Server;
class Service;
class ServerInitializer {
public:
ServerInitializer(Server* server) : server_(server) {}
bool RegisterService(std::shared_ptr<Service> service) {
if (!server_->RegisterService(nullptr, service.get())) {
return false;
}
default_services_.push_back(service);
return true;
}
const std::vector<grpc::string>* GetServiceList() {
return &server_->services_;
}
private:
Server* server_;
std::vector<std::shared_ptr<Service> > default_services_;
};
} // namespace grpc
#endif // GRPCXX_IMPL_SERVER_INITIALIZER_H

@ -36,6 +36,7 @@
#include <list>
#include <memory>
#include <vector>
#include <grpc++/completion_queue.h>
#include <grpc++/impl/call.h>
@ -57,6 +58,7 @@ class GenericServerContext;
class AsyncGenericService;
class ServerAsyncStreamingInterface;
class ServerContext;
class ServerInitializer;
class ThreadPoolInterface;
/// Models a gRPC server.
@ -94,6 +96,7 @@ class Server GRPC_FINAL : public ServerInterface, private GrpcLibraryCodegen {
private:
friend class AsyncGenericService;
friend class ServerBuilder;
friend class ServerInitializer;
class SyncRequest;
class AsyncRequest;
@ -159,6 +162,8 @@ class Server GRPC_FINAL : public ServerInterface, private GrpcLibraryCodegen {
grpc_server* server() GRPC_OVERRIDE { return server_; };
ServerInitializer* initializer();
const int max_message_size_;
// Completion queue.
@ -175,6 +180,7 @@ class Server GRPC_FINAL : public ServerInterface, private GrpcLibraryCodegen {
std::shared_ptr<GlobalCallbacks> global_callbacks_;
std::list<SyncRequest>* sync_methods_;
std::vector<grpc::string> services_;
std::unique_ptr<RpcServiceMethod> unknown_method_;
bool has_generic_service_;
@ -184,6 +190,8 @@ class Server GRPC_FINAL : public ServerInterface, private GrpcLibraryCodegen {
ThreadPoolInterface* thread_pool_;
// Whether the thread pool is created and owned by the server.
bool thread_pool_owned_;
std::unique_ptr<ServerInitializer> server_initializer_;
};
} // namespace grpc

@ -34,10 +34,12 @@
#ifndef GRPCXX_SERVER_BUILDER_H
#define GRPCXX_SERVER_BUILDER_H
#include <map>
#include <memory>
#include <vector>
#include <grpc++/impl/server_builder_option.h>
#include <grpc++/impl/server_builder_plugin.h>
#include <grpc++/support/config.h>
#include <grpc/compression.h>
@ -51,6 +53,10 @@ class ServerCompletionQueue;
class ServerCredentials;
class Service;
namespace testing {
class ServerBuilderPluginTest;
} // namespace testing
/// A builder class for the creation and startup of \a grpc::Server instances.
class ServerBuilder {
public:
@ -108,6 +114,8 @@ class ServerBuilder {
std::unique_ptr<Server> BuildAndStart();
private:
friend class ::grpc::testing::ServerBuilderPluginTest;
struct Port {
grpc::string addr;
std::shared_ptr<ServerCredentials> creds;
@ -130,6 +138,7 @@ class ServerBuilder {
std::vector<Port> ports_;
std::vector<ServerCompletionQueue*> cqs_;
std::shared_ptr<ServerCredentials> creds_;
std::map<grpc::string, std::unique_ptr<ServerBuilderPlugin>> plugins_;
AsyncGenericService* generic_service_;
};

@ -33,6 +33,7 @@
#include <grpc++/server.h>
#include <sstream>
#include <utility>
#include <grpc++/completion_queue.h>
@ -41,6 +42,7 @@
#include <grpc++/impl/grpc_library.h>
#include <grpc++/impl/method_handler_impl.h>
#include <grpc++/impl/rpc_service_method.h>
#include <grpc++/impl/server_initializer.h>
#include <grpc++/impl/service_type.h>
#include <grpc++/security/server_credentials.h>
#include <grpc++/server_context.h>
@ -284,7 +286,8 @@ Server::Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned,
has_generic_service_(false),
server_(nullptr),
thread_pool_(thread_pool),
thread_pool_owned_(thread_pool_owned) {
thread_pool_owned_(thread_pool_owned),
server_initializer_(new ServerInitializer(this)) {
g_gli_initializer.summon();
gpr_once_init(&g_once_init_callbacks, InitGlobalCallbacks);
global_callbacks_ = g_callbacks;
@ -341,6 +344,7 @@ bool Server::RegisterService(const grpc::string* host, Service* service) {
"Can only register an asynchronous service against one server.");
service->server_ = this;
}
const char* method_name = nullptr;
for (auto it = service->methods_.begin(); it != service->methods_.end();
++it) {
if (it->get() == nullptr) { // Handled by generic service if any.
@ -360,6 +364,17 @@ bool Server::RegisterService(const grpc::string* host, Service* service) {
} else {
sync_methods_->emplace_back(method, tag);
}
method_name = method->name();
}
// Parse service name.
if (method_name != nullptr) {
std::stringstream ss(method_name);
grpc::string service_name;
if (std::getline(ss, service_name, '/') &&
std::getline(ss, service_name, '/')) {
services_.push_back(service_name);
}
}
return true;
}
@ -598,4 +613,6 @@ void Server::RunRpc() {
}
}
ServerInitializer* Server::initializer() { return server_initializer_.get(); }
} // namespace grpc

@ -96,6 +96,15 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
ChannelArguments args;
for (auto option = options_.begin(); option != options_.end(); ++option) {
(*option)->UpdateArguments(&args);
(*option)->UpdatePlugins(&plugins_);
}
if (thread_pool == nullptr) {
for (auto plugin = plugins_.begin(); plugin != plugins_.end(); plugin++) {
if ((*plugin).second->has_sync_methods()) {
thread_pool.reset(CreateDefaultThreadPool());
break;
}
}
}
if (max_message_size_ > 0) {
args.SetInt(GRPC_ARG_MAX_MESSAGE_LENGTH, max_message_size_);
@ -104,6 +113,7 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
compression_options_.enabled_algorithms_bitset);
std::unique_ptr<Server> server(
new Server(thread_pool.release(), true, max_message_size_, &args));
ServerInitializer* initializer = server->initializer();
for (auto cq = cqs_.begin(); cq != cqs_.end(); ++cq) {
grpc_server_register_completion_queue(server->server_, (*cq)->cq(),
nullptr);
@ -114,6 +124,9 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
return nullptr;
}
}
for (auto plugin = plugins_.begin(); plugin != plugins_.end(); plugin++) {
(*plugin).second->InitServer(initializer);
}
if (generic_service_) {
server->RegisterAsyncGenericService(generic_service_);
} else {
@ -137,6 +150,9 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
if (!server->Start(cqs_data, cqs_.size())) {
return nullptr;
}
for (auto plugin = plugins_.begin(); plugin != plugins_.end(); plugin++) {
(*plugin).second->Finish(initializer);
}
return server;
}

@ -197,6 +197,28 @@ class Verifier {
bool spin_;
};
// This class disables the server builder plugins that may add sync services to
// the server. If there are sync services, UnimplementedRpc test will triger
// the sync unkown rpc routine on the server side, rather than the async one
// that needs to be tested here.
class ServerBuilderSyncPluginDisabler : public ::grpc::ServerBuilderOption {
public:
void UpdateArguments(ChannelArguments* arg) GRPC_OVERRIDE {}
void UpdatePlugins(
std::map<grpc::string, std::unique_ptr<ServerBuilderPlugin>>* plugins)
GRPC_OVERRIDE {
auto plugin = plugins->begin();
while (plugin != plugins->end()) {
if ((*plugin).second->has_sync_methods()) {
plugins->erase(plugin++);
} else {
plugin++;
}
}
}
};
class AsyncEnd2endTest : public ::testing::TestWithParam<bool> {
protected:
AsyncEnd2endTest() {}
@ -213,6 +235,12 @@ class AsyncEnd2endTest : public ::testing::TestWithParam<bool> {
grpc::InsecureServerCredentials());
builder.RegisterService(&service_);
cq_ = builder.AddCompletionQueue();
// TODO(zyc): make a test option to choose wheather sync plugins should be
// deleted
std::unique_ptr<ServerBuilderOption> sync_plugin_disabler(
new ServerBuilderSyncPluginDisabler());
builder.SetOption(move(sync_plugin_disabler));
server_ = builder.BuildAndStart();
gpr_tls_set(&g_is_async_end2end_test, 1);

@ -0,0 +1,234 @@
/*
*
* Copyright 2016, 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.
*
*/
#include <grpc++/channel.h>
#include <grpc++/client_context.h>
#include <grpc++/create_channel.h>
#include <grpc++/impl/server_builder_option.h>
#include <grpc++/impl/server_builder_plugin.h>
#include <grpc++/impl/server_initializer.h>
#include <grpc++/security/credentials.h>
#include <grpc++/security/server_credentials.h>
#include <grpc++/server.h>
#include <grpc++/server_builder.h>
#include <grpc++/server_context.h>
#include <grpc/grpc.h>
#include <gtest/gtest.h>
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
#include "test/cpp/end2end/test_service_impl.h"
#define PLUGIN_NAME "TestServerBuilderPlugin"
namespace grpc {
namespace testing {
class TestServerBuilderPlugin : public ServerBuilderPlugin {
public:
TestServerBuilderPlugin() : service_(new TestServiceImpl()) {
init_server_is_called_ = false;
finish_is_called_ = false;
change_arguments_is_called_ = false;
}
grpc::string name() GRPC_OVERRIDE { return PLUGIN_NAME; }
void InitServer(ServerInitializer* si) GRPC_OVERRIDE {
init_server_is_called_ = true;
if (register_service_) {
si->RegisterService(service_);
}
}
void Finish(ServerInitializer* si) GRPC_OVERRIDE { finish_is_called_ = true; }
void ChangeArguments(const grpc::string& name, void* value) GRPC_OVERRIDE {
change_arguments_is_called_ = true;
}
bool has_async_methods() const GRPC_OVERRIDE { return register_service_; }
bool has_sync_methods() const GRPC_OVERRIDE { return register_service_; }
void SetRegisterService() { register_service_ = true; }
bool init_server_is_called() { return init_server_is_called_; }
bool finish_is_called() { return finish_is_called_; }
bool change_arguments_is_called() { return change_arguments_is_called_; }
private:
bool init_server_is_called_;
bool finish_is_called_;
bool change_arguments_is_called_;
bool register_service_;
std::shared_ptr<TestServiceImpl> service_;
};
class InsertPluginServerBuilderOption : public ServerBuilderOption {
public:
InsertPluginServerBuilderOption() { register_service_ = false; }
void UpdateArguments(ChannelArguments* arg) GRPC_OVERRIDE {}
void UpdatePlugins(
std::map<grpc::string, std::unique_ptr<ServerBuilderPlugin>>* plugins)
GRPC_OVERRIDE {
std::unique_ptr<TestServerBuilderPlugin> plugin(
new TestServerBuilderPlugin());
if (register_service_) plugin->SetRegisterService();
(*plugins)[plugin->name()] = std::move(plugin);
}
void SetRegisterService() { register_service_ = true; }
private:
bool register_service_;
};
namespace sBPTestServerBuilderPlugin {
std::unique_ptr<ServerBuilderPlugin> CreateTestServerBuilderPlugin() {
return std::unique_ptr<ServerBuilderPlugin>(new TestServerBuilderPlugin());
}
} // namespace sBPTestServerBuilderPlugin
class ServerBuilderPluginTest : public ::testing::TestWithParam<bool> {
public:
ServerBuilderPluginTest() {}
void SetUp() GRPC_OVERRIDE {
port_ = grpc_pick_unused_port_or_die();
builder_.reset(new ServerBuilder());
}
void InsertPlugin() {
if (GetParam()) {
// Add ServerBuilder plugin directly
INIT_PLUGIN(builder_->plugins_, TestServerBuilderPlugin);
EXPECT_TRUE(builder_->plugins_[PLUGIN_NAME] != nullptr);
} else {
// Add ServerBuilder plugin using ServerBuilder::SetOption()
builder_->SetOption(std::unique_ptr<ServerBuilderOption>(
new InsertPluginServerBuilderOption()));
}
}
void InsertPluginWithTestService() {
if (GetParam()) {
// Add ServerBuilder plugin directly
INIT_PLUGIN(builder_->plugins_, TestServerBuilderPlugin);
EXPECT_TRUE(builder_->plugins_[PLUGIN_NAME] != nullptr);
auto plugin = static_cast<TestServerBuilderPlugin*>(
builder_->plugins_[PLUGIN_NAME].get());
EXPECT_TRUE(plugin != nullptr);
plugin->SetRegisterService();
} else {
// Add ServerBuilder plugin using ServerBuilder::SetOption()
std::unique_ptr<InsertPluginServerBuilderOption> option(
new InsertPluginServerBuilderOption());
option->SetRegisterService();
builder_->SetOption(std::move(option));
}
}
void StartServer() {
grpc::string server_address = "localhost:" + to_string(port_);
builder_->AddListeningPort(server_address, InsecureServerCredentials());
server_ = builder_->BuildAndStart();
EXPECT_TRUE(builder_->plugins_[PLUGIN_NAME] != nullptr);
}
void ResetStub() {
string target = "dns:localhost:" + to_string(port_);
channel_ = CreateChannel(target, InsecureChannelCredentials());
stub_ = grpc::testing::EchoTestService::NewStub(channel_);
}
void TearDown() GRPC_OVERRIDE {
EXPECT_TRUE(builder_->plugins_[PLUGIN_NAME] != nullptr);
auto plugin = static_cast<TestServerBuilderPlugin*>(
builder_->plugins_[PLUGIN_NAME].get());
EXPECT_TRUE(plugin != nullptr);
EXPECT_TRUE(plugin->init_server_is_called());
EXPECT_TRUE(plugin->finish_is_called());
}
string to_string(const int number) {
std::stringstream strs;
strs << number;
return strs.str();
}
protected:
std::shared_ptr<Channel> channel_;
std::unique_ptr<ServerBuilder> builder_;
std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_;
std::unique_ptr<Server> server_;
TestServiceImpl service_;
int port_;
};
TEST_P(ServerBuilderPluginTest, PluginWithoutServiceTest) {
InsertPlugin();
StartServer();
}
TEST_P(ServerBuilderPluginTest, PluginWithServiceTest) {
InsertPluginWithTestService();
StartServer();
ResetStub();
EchoRequest request;
EchoResponse response;
request.set_message("Hello hello hello hello");
ClientContext context;
context.set_compression_algorithm(GRPC_COMPRESS_GZIP);
Status s = stub_->Echo(&context, request, &response);
EXPECT_EQ(response.message(), request.message());
EXPECT_TRUE(s.ok());
}
INSTANTIATE_TEST_CASE_P(ServerBuilderPluginTest, ServerBuilderPluginTest,
::testing::Values(false, true));
} // namespace testing
} // namespace grpc
int main(int argc, char** argv) {
grpc_test_init(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

@ -777,6 +777,8 @@ 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/server_builder_plugin.h \
include/grpc++/impl/server_initializer.h \
include/grpc++/impl/service_type.h \
include/grpc++/impl/sync.h \
include/grpc++/impl/sync_cxx11.h \

@ -777,6 +777,8 @@ 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/server_builder_plugin.h \
include/grpc++/impl/server_initializer.h \
include/grpc++/impl/service_type.h \
include/grpc++/impl/sync.h \
include/grpc++/impl/sync_cxx11.h \

@ -2588,6 +2588,24 @@
"third_party": false,
"type": "target"
},
{
"deps": [
"gpr",
"gpr_test_util",
"grpc",
"grpc++",
"grpc++_test_util",
"grpc_test_util"
],
"headers": [],
"language": "c++",
"name": "server_builder_plugin_test",
"src": [
"test/cpp/end2end/server_builder_plugin_test.cc"
],
"third_party": false,
"type": "target"
},
{
"deps": [
"gpr",
@ -6326,6 +6344,8 @@
"include/grpc++/impl/rpc_service_method.h",
"include/grpc++/impl/serialization_traits.h",
"include/grpc++/impl/server_builder_option.h",
"include/grpc++/impl/server_builder_plugin.h",
"include/grpc++/impl/server_initializer.h",
"include/grpc++/impl/service_type.h",
"include/grpc++/impl/sync.h",
"include/grpc++/impl/sync_cxx11.h",
@ -6376,6 +6396,8 @@
"include/grpc++/impl/rpc_service_method.h",
"include/grpc++/impl/serialization_traits.h",
"include/grpc++/impl/server_builder_option.h",
"include/grpc++/impl/server_builder_plugin.h",
"include/grpc++/impl/server_initializer.h",
"include/grpc++/impl/service_type.h",
"include/grpc++/impl/sync.h",
"include/grpc++/impl/sync_cxx11.h",

@ -2448,6 +2448,27 @@
"posix"
]
},
{
"args": [],
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"gtest": true,
"language": "c++",
"name": "server_builder_plugin_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
]
},
{
"args": [],
"ci_platforms": [

@ -275,6 +275,8 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\rpc_service_method.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\serialization_traits.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\server_builder_option.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\server_builder_plugin.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\server_initializer.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\service_type.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\sync.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\sync_cxx11.h" />

@ -147,6 +147,12 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\server_builder_option.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\server_builder_plugin.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\server_initializer.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\service_type.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>

@ -275,6 +275,8 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\rpc_service_method.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\serialization_traits.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\server_builder_option.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\server_builder_plugin.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\server_initializer.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\service_type.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\sync.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\sync_cxx11.h" />

@ -132,6 +132,12 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\server_builder_option.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\server_builder_plugin.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\server_initializer.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\service_type.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>

@ -0,0 +1,207 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\1.0.204.1.props')" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{86751DC8-C8D9-57B6-2C8A-BB33021C773C}</ProjectGuid>
<IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
<IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
<PlatformToolset>v100</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'" Label="Configuration">
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(SolutionDir)\..\vsprojects\cpptest.props" />
<Import Project="$(SolutionDir)\..\vsprojects\global.props" />
<Import Project="$(SolutionDir)\..\vsprojects\openssl.props" />
<Import Project="$(SolutionDir)\..\vsprojects\protobuf.props" />
<Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
<Import Project="$(SolutionDir)\..\vsprojects\zlib.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<TargetName>server_builder_plugin_test</TargetName>
<Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
<Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
<Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
<Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<TargetName>server_builder_plugin_test</TargetName>
<Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
<Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
<Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
<Configuration-grpc_dependencies_openssl>Release</Configuration-grpc_dependencies_openssl>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
<MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
<GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
<MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
<GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
<MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
<GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
<MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
<GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="$(SolutionDir)\..\test\cpp\end2end\server_builder_plugin_test.cc">
</ClCompile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++_test_util\grpc++_test_util.vcxproj">
<Project>{0BE77741-552A-929B-A497-4EF7ECE17A64}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
<Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++\grpc++.vcxproj">
<Project>{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
<Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
<Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
<Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
<Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
<Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
<Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" />
<Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" />
<Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" />
<Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" />
<Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" />
</Target>
</Project>

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="$(SolutionDir)\..\test\cpp\end2end\server_builder_plugin_test.cc">
<Filter>test\cpp\end2end</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="test">
<UniqueIdentifier>{37b2ebc1-b2f2-ecb9-37b7-f6d757bb99e3}</UniqueIdentifier>
</Filter>
<Filter Include="test\cpp">
<UniqueIdentifier>{39400fed-f7b7-0f44-0ef3-ba3693d42011}</UniqueIdentifier>
</Filter>
<Filter Include="test\cpp\end2end">
<UniqueIdentifier>{dab9dd19-3e5b-005e-4b5a-456de6111d71}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>
Loading…
Cancel
Save