Merge branch 'handshaker_api' into http_connect

pull/7611/head
Mark D. Roth 8 years ago
commit 9dfd0b72b8
  1. 4
      BUILD
  2. 2
      CMakeLists.txt
  3. 112
      Makefile
  4. 27
      build.yaml
  5. 2
      doc/health-checking.md
  6. 2
      examples/php/route_guide/README.md
  7. 8
      include/grpc/grpc.h
  8. 3
      src/core/ext/lb_policy/grpclb/grpclb.c
  9. 16
      src/core/ext/transport/chttp2/transport/chttp2_transport.c
  10. 8
      src/core/lib/channel/channel_stack.h
  11. 8
      src/core/lib/channel/channel_stack_builder.h
  12. 11
      src/core/lib/channel/context.h
  13. 25
      src/core/lib/iomgr/tcp_server_posix.c
  14. 8
      src/core/lib/security/context/security_context.h
  15. 8
      src/core/lib/surface/channel.h
  16. 8
      src/core/lib/surface/channel_init.h
  17. 9
      src/core/lib/surface/server.c
  18. 6
      src/core/lib/transport/byte_stream.h
  19. 8
      src/core/lib/transport/metadata.h
  20. 3
      src/core/lib/transport/metadata_batch.c
  21. 12
      src/core/lib/transport/metadata_batch.h
  22. 10
      src/core/lib/transport/transport.h
  23. 112
      src/cpp/common/channel_filter.cc
  24. 386
      src/cpp/common/channel_filter.h
  25. 10
      src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py
  26. 6
      src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py
  27. 48
      src/python/grpcio_tests/tests/unit/_thread_pool.py
  28. 353
      test/cpp/end2end/filter_end2end_test.cc
  29. 23
      test/cpp/interop/interop_server.cc
  30. 54
      test/cpp/interop/interop_server_bootstrap.cc
  31. 6
      test/cpp/interop/server_helper.h
  32. 1
      tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh
  33. 2
      tools/doxygen/Doxyfile.c++.internal
  34. 2
      tools/run_tests/run_tests.py
  35. 39
      tools/run_tests/sources_and_headers.json
  36. 21
      tools/run_tests/tests.json
  37. 3
      vsprojects/vcxproj/grpc++/grpc++.vcxproj
  38. 6
      vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
  39. 3
      vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
  40. 6
      vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
  41. 212
      vsprojects/vcxproj/interop_server_lib/interop_server_lib.vcxproj
  42. 42
      vsprojects/vcxproj/interop_server_lib/interop_server_lib.vcxproj.filters
  43. 51
      vsprojects/vcxproj/interop_server_main/interop_server_main.vcxproj
  44. 23
      vsprojects/vcxproj/interop_server_main/interop_server_main.vcxproj.filters
  45. 207
      vsprojects/vcxproj/test/filter_end2end_test/filter_end2end_test.vcxproj
  46. 21
      vsprojects/vcxproj/test/filter_end2end_test/filter_end2end_test.vcxproj.filters

@ -1257,6 +1257,7 @@ cc_library(
"src/cpp/common/secure_auth_context.h",
"src/cpp/server/secure_server_credentials.h",
"src/cpp/client/create_channel_internal.h",
"src/cpp/common/channel_filter.h",
"src/cpp/server/dynamic_thread_pool.h",
"src/cpp/server/thread_pool_interface.h",
"src/cpp/client/secure_credentials.cc",
@ -1274,6 +1275,7 @@ cc_library(
"src/cpp/client/generic_stub.cc",
"src/cpp/client/insecure_credentials.cc",
"src/cpp/common/channel_arguments.cc",
"src/cpp/common/channel_filter.cc",
"src/cpp/common/completion_queue.cc",
"src/cpp/common/core_codegen.cc",
"src/cpp/common/rpc_method.cc",
@ -1488,6 +1490,7 @@ cc_library(
name = "grpc++_unsecure",
srcs = [
"src/cpp/client/create_channel_internal.h",
"src/cpp/common/channel_filter.h",
"src/cpp/server/dynamic_thread_pool.h",
"src/cpp/server/thread_pool_interface.h",
"src/cpp/common/insecure_create_auth_context.cc",
@ -1500,6 +1503,7 @@ cc_library(
"src/cpp/client/generic_stub.cc",
"src/cpp/client/insecure_credentials.cc",
"src/cpp/common/channel_arguments.cc",
"src/cpp/common/channel_filter.cc",
"src/cpp/common/completion_queue.cc",
"src/cpp/common/core_codegen.cc",
"src/cpp/common/rpc_method.cc",

@ -1003,6 +1003,7 @@ add_library(grpc++
src/cpp/client/generic_stub.cc
src/cpp/client/insecure_credentials.cc
src/cpp/common/channel_arguments.cc
src/cpp/common/channel_filter.cc
src/cpp/common/completion_queue.cc
src/cpp/common/core_codegen.cc
src/cpp/common/rpc_method.cc
@ -1258,6 +1259,7 @@ add_library(grpc++_unsecure
src/cpp/client/generic_stub.cc
src/cpp/client/insecure_credentials.cc
src/cpp/common/channel_arguments.cc
src/cpp/common/channel_filter.cc
src/cpp/common/completion_queue.cc
src/cpp/common/core_codegen.cc
src/cpp/common/rpc_method.cc

@ -1039,6 +1039,7 @@ cxx_slice_test: $(BINDIR)/$(CONFIG)/cxx_slice_test
cxx_string_ref_test: $(BINDIR)/$(CONFIG)/cxx_string_ref_test
cxx_time_test: $(BINDIR)/$(CONFIG)/cxx_time_test
end2end_test: $(BINDIR)/$(CONFIG)/end2end_test
filter_end2end_test: $(BINDIR)/$(CONFIG)/filter_end2end_test
generic_end2end_test: $(BINDIR)/$(CONFIG)/generic_end2end_test
golden_file_test: $(BINDIR)/$(CONFIG)/golden_file_test
grpc_cli: $(BINDIR)/$(CONFIG)/grpc_cli
@ -1220,9 +1221,9 @@ pc_cxx: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++.pc
pc_cxx_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++_unsecure.pc
ifeq ($(EMBED_OPENSSL),true)
privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_reflection_codegen.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a
privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_reflection_codegen.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a
else
privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_reflection_codegen.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a
privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_reflection_codegen.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a
endif
@ -1406,6 +1407,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/cxx_string_ref_test \
$(BINDIR)/$(CONFIG)/cxx_time_test \
$(BINDIR)/$(CONFIG)/end2end_test \
$(BINDIR)/$(CONFIG)/filter_end2end_test \
$(BINDIR)/$(CONFIG)/generic_end2end_test \
$(BINDIR)/$(CONFIG)/golden_file_test \
$(BINDIR)/$(CONFIG)/grpc_cli \
@ -1491,6 +1493,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/cxx_string_ref_test \
$(BINDIR)/$(CONFIG)/cxx_time_test \
$(BINDIR)/$(CONFIG)/end2end_test \
$(BINDIR)/$(CONFIG)/filter_end2end_test \
$(BINDIR)/$(CONFIG)/generic_end2end_test \
$(BINDIR)/$(CONFIG)/golden_file_test \
$(BINDIR)/$(CONFIG)/grpc_cli \
@ -1779,6 +1782,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/cxx_time_test || ( echo test cxx_time_test failed ; exit 1 )
$(E) "[RUN] Testing end2end_test"
$(Q) $(BINDIR)/$(CONFIG)/end2end_test || ( echo test end2end_test failed ; exit 1 )
$(E) "[RUN] Testing filter_end2end_test"
$(Q) $(BINDIR)/$(CONFIG)/filter_end2end_test || ( echo test filter_end2end_test failed ; exit 1 )
$(E) "[RUN] Testing generic_end2end_test"
$(Q) $(BINDIR)/$(CONFIG)/generic_end2end_test || ( echo test generic_end2end_test failed ; exit 1 )
$(E) "[RUN] Testing golden_file_test"
@ -3590,6 +3595,7 @@ LIBGRPC++_SRC = \
src/cpp/client/generic_stub.cc \
src/cpp/client/insecure_credentials.cc \
src/cpp/common/channel_arguments.cc \
src/cpp/common/channel_filter.cc \
src/cpp/common/completion_queue.cc \
src/cpp/common/core_codegen.cc \
src/cpp/common/rpc_method.cc \
@ -4126,6 +4132,7 @@ LIBGRPC++_UNSECURE_SRC = \
src/cpp/client/generic_stub.cc \
src/cpp/client/insecure_credentials.cc \
src/cpp/common/channel_arguments.cc \
src/cpp/common/channel_filter.cc \
src/cpp/common/completion_queue.cc \
src/cpp/common/core_codegen.cc \
src/cpp/common/rpc_method.cc \
@ -4542,7 +4549,7 @@ endif
endif
LIBINTEROP_SERVER_MAIN_SRC = \
LIBINTEROP_SERVER_LIB_SRC = \
$(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc \
@ -4550,6 +4557,56 @@ LIBINTEROP_SERVER_MAIN_SRC = \
PUBLIC_HEADERS_CXX += \
LIBINTEROP_SERVER_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBINTEROP_SERVER_LIB_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure libraries if you don't have OpenSSL.
$(LIBDIR)/$(CONFIG)/libinterop_server_lib.a: openssl_dep_error
else
ifeq ($(NO_PROTOBUF),true)
# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
$(LIBDIR)/$(CONFIG)/libinterop_server_lib.a: protobuf_dep_error
else
$(LIBDIR)/$(CONFIG)/libinterop_server_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBINTEROP_SERVER_LIB_OBJS)
$(E) "[AR] Creating $@"
$(Q) mkdir -p `dirname $@`
$(Q) rm -f $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a
$(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBINTEROP_SERVER_LIB_OBJS)
ifeq ($(SYSTEM),Darwin)
$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a
endif
endif
endif
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(LIBINTEROP_SERVER_LIB_OBJS:.o=.dep)
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/interop/interop_server.o: $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc
LIBINTEROP_SERVER_MAIN_SRC = \
test/cpp/interop/interop_server_bootstrap.cc \
PUBLIC_HEADERS_CXX += \
LIBINTEROP_SERVER_MAIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBINTEROP_SERVER_MAIN_SRC))))
@ -4592,7 +4649,6 @@ ifneq ($(NO_DEPS),true)
-include $(LIBINTEROP_SERVER_MAIN_OBJS:.o=.dep)
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/interop/interop_server.o: $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc
LIBQPS_SRC = \
@ -11128,6 +11184,49 @@ endif
endif
FILTER_END2END_TEST_SRC = \
test/cpp/end2end/filter_end2end_test.cc \
FILTER_END2END_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(FILTER_END2END_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/filter_end2end_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)/filter_end2end_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/filter_end2end_test: $(PROTOBUF_DEP) $(FILTER_END2END_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) $(FILTER_END2END_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)/filter_end2end_test
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/filter_end2end_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_filter_end2end_test: $(FILTER_END2END_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(FILTER_END2END_TEST_OBJS:.o=.dep)
endif
endif
GENERIC_END2END_TEST_SRC = \
test/cpp/end2end/generic_end2end_test.cc \
@ -11634,10 +11733,10 @@ $(BINDIR)/$(CONFIG)/interop_server: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/interop_server: $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
$(BINDIR)/$(CONFIG)/interop_server: $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/interop_server
$(Q) $(LDXX) $(LDFLAGS) $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/interop_server
endif
@ -15247,6 +15346,7 @@ test/cpp/interop/client.cc: $(OPENSSL_DEP)
test/cpp/interop/client_helper.cc: $(OPENSSL_DEP)
test/cpp/interop/interop_client.cc: $(OPENSSL_DEP)
test/cpp/interop/interop_server.cc: $(OPENSSL_DEP)
test/cpp/interop/interop_server_bootstrap.cc: $(OPENSSL_DEP)
test/cpp/interop/server_helper.cc: $(OPENSSL_DEP)
test/cpp/qps/client_async.cc: $(OPENSSL_DEP)
test/cpp/qps/client_sync.cc: $(OPENSSL_DEP)

@ -696,6 +696,7 @@ filegroups:
- include/grpc++/support/time.h
headers:
- src/cpp/client/create_channel_internal.h
- src/cpp/common/channel_filter.h
- src/cpp/server/dynamic_thread_pool.h
- src/cpp/server/thread_pool_interface.h
src:
@ -708,6 +709,7 @@ filegroups:
- src/cpp/client/generic_stub.cc
- src/cpp/client/insecure_credentials.cc
- src/cpp/common/channel_arguments.cc
- src/cpp/common/channel_filter.cc
- src/cpp/common/completion_queue.cc
- src/cpp/common/core_codegen.cc
- src/cpp/common/rpc_method.cc
@ -827,7 +829,6 @@ libs:
- grpc_lb_policy_grpclb
- grpc_lb_policy_pick_first
- grpc_lb_policy_round_robin
- grpc_lb_policy_grpclb
- grpc_resolver_dns_native
- grpc_resolver_sockaddr
- grpc_load_reporting
@ -926,7 +927,6 @@ libs:
- grpc_lb_policy_grpclb
- grpc_lb_policy_pick_first
- grpc_lb_policy_round_robin
- grpc_lb_policy_grpclb
- census
generate_plugin_registry: true
secure: false
@ -1144,7 +1144,7 @@ libs:
- grpc++
- grpc
- gpr
- name: interop_server_main
- name: interop_server_lib
build: private
language: c++
src:
@ -1161,6 +1161,13 @@ libs:
- gpr_test_util
- gpr
- grpc++_test_config
- name: interop_server_main
build: private
language: c++
src:
- test/cpp/interop/interop_server_bootstrap.cc
deps:
- interop_server_lib
- name: qps
build: private
language: c++
@ -2663,6 +2670,19 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: filter_end2end_test
gtest: true
build: test
language: c++
src:
- test/cpp/end2end/filter_end2end_test.cc
deps:
- grpc++_test_util
- grpc_test_util
- grpc++
- grpc
- gpr_test_util
- gpr
- name: generic_end2end_test
gtest: true
build: test
@ -2828,6 +2848,7 @@ targets:
deps:
- interop_server_main
- interop_server_helper
- interop_server_lib
- grpc++_test_util
- grpc_test_util
- grpc++

@ -58,7 +58,7 @@ a response must be sent back with an `OK` status and the status field should be
set to `SERVING` or `NOT_SERVING` accordingly. If the service name is not
registered, the server returns a `NOT_FOUND` GRPC status.
The server should use an empty string as the key for servers
The server should use an empty string as the key for server's
overall health status, so that a client not interested in a specific service can
query the server's status with an empty request. The server can just do exact
matching of the service name without support of any kind of wildcard matching.

@ -1,6 +1,6 @@
#gRPC Basics: PHP sample code
The files in this folder are the samples used in [gRPC Basics: PHP][],
a detailed tutorial for using gRPC in Ruby.
a detailed tutorial for using gRPC in PHP.
[gRPC Basics: PHP]:http://www.grpc.io/docs/tutorials/basic/php.html

@ -170,8 +170,9 @@ GRPCAPI void grpc_channel_watch_connectivity_state(
completions are sent to 'completion_queue'. 'method' and 'host' need only
live through the invocation of this function.
If parent_call is non-NULL, it must be a server-side call. It will be used
to propagate properties from the server call to this new client call.
*/
to propagate properties from the server call to this new client call,
depending on the value of \a propagation_mask (see propagation_bits.h for
possible values). */
GRPCAPI grpc_call *grpc_channel_create_call(
grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
grpc_completion_queue *completion_queue, const char *method,
@ -187,7 +188,8 @@ GRPCAPI void *grpc_channel_register_call(grpc_channel *channel,
const char *method, const char *host,
void *reserved);
/** Create a call given a handle returned from grpc_channel_register_call */
/** Create a call given a handle returned from grpc_channel_register_call.
\sa grpc_channel_create_call. */
GRPCAPI grpc_call *grpc_channel_create_registered_call(
grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
grpc_completion_queue *completion_queue, void *registered_call_handle,

@ -767,6 +767,9 @@ static lb_client_data *lb_client_data_create(glb_lb_policy *glb_policy) {
lb_client->deadline = gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
gpr_time_from_seconds(3, GPR_TIMESPAN));
/* Note the following LB call progresses every time there's activity in \a
* glb_policy->base.interested_parties, which is comprised of the polling
* entities passed to glb_pick(). */
lb_client->lb_call = grpc_channel_create_pollset_set_call(
glb_policy->lb_channel, NULL, GRPC_PROPAGATE_DEFAULTS,
glb_policy->base.interested_parties, "/BalanceLoad",

@ -94,7 +94,8 @@ static void initiate_writing(grpc_exec_ctx *exec_ctx, void *t,
static void start_writing(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t);
static void end_waiting_for_write(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport *t, grpc_error *error);
grpc_chttp2_transport *t, grpc_error *error,
const char *reason);
/** Set a transport level setting, and push it to our peer */
static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
@ -876,7 +877,7 @@ static void start_writing(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) {
set_write_state(t, GRPC_CHTTP2_WRITING_INACTIVE,
"start_writing:nothing_to_write");
}
end_waiting_for_write(exec_ctx, t, GRPC_ERROR_CREATE("Nothing to write"));
end_waiting_for_write(exec_ctx, t, GRPC_ERROR_NONE, "Nothing to write");
if (t->ep && !t->endpoint_reading) {
destroy_endpoint(exec_ctx, t);
}
@ -925,11 +926,18 @@ static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
}
}
/* error may be GRPC_ERROR_NONE if there is no error allocated yet.
In that case, use "reason" as the text for a new error. */
static void end_waiting_for_write(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport *t, grpc_error *error) {
grpc_chttp2_transport *t, grpc_error *error,
const char *reason) {
grpc_chttp2_stream_global *stream_global;
while (grpc_chttp2_list_pop_closed_waiting_for_writing(&t->global,
&stream_global)) {
if (error == GRPC_ERROR_NONE && reason != NULL) {
/* create error object. */
error = GRPC_ERROR_CREATE(reason);
}
fail_pending_writes(exec_ctx, &t->global, stream_global,
GRPC_ERROR_REF(error));
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "finish_writes");
@ -951,7 +959,7 @@ static void terminate_writing_with_lock(grpc_exec_ctx *exec_ctx,
grpc_chttp2_cleanup_writing(exec_ctx, &t->global, &t->writing);
end_waiting_for_write(exec_ctx, t, error);
end_waiting_for_write(exec_ctx, t, error, NULL);
switch (t->executor.write_state) {
case GRPC_CHTTP2_WRITING_INACTIVE:

@ -51,6 +51,10 @@
#include "src/core/lib/iomgr/polling_entity.h"
#include "src/core/lib/transport/transport.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct grpc_channel_element grpc_channel_element;
typedef struct grpc_call_element grpc_call_element;
@ -291,4 +295,8 @@ extern int grpc_trace_channel;
#define GRPC_CALL_LOG_OP(sev, elem, op) \
if (grpc_trace_channel) grpc_call_log_op(sev, elem, op)
#ifdef __cplusplus
}
#endif
#endif /* GRPC_CORE_LIB_CHANNEL_CHANNEL_STACK_H */

@ -39,6 +39,10 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_stack.h"
#ifdef __cplusplus
extern "C" {
#endif
/// grpc_channel_stack_builder offers a programmatic interface to selected
/// and order channel filters
typedef struct grpc_channel_stack_builder grpc_channel_stack_builder;
@ -158,4 +162,8 @@ void grpc_channel_stack_builder_destroy(grpc_channel_stack_builder *builder);
extern int grpc_trace_channel_stack_builder;
#ifdef __cplusplus
}
#endif
#endif /* GRPC_CORE_LIB_CHANNEL_CHANNEL_STACK_BUILDER_H */

@ -34,10 +34,19 @@
#ifndef GRPC_CORE_LIB_CHANNEL_CONTEXT_H
#define GRPC_CORE_LIB_CHANNEL_CONTEXT_H
/* Call object context pointers */
/// Call object context pointers.
/// Call context is represented as an array of \a grpc_call_context_elements.
/// This enum represents the indexes into the array, where each index
/// contains a different type of value.
typedef enum {
/// Value is either a \a grpc_client_security_context or a
/// \a grpc_server_security_context.
GRPC_CONTEXT_SECURITY = 0,
/// Value is a \a census_context.
GRPC_CONTEXT_TRACING,
GRPC_CONTEXT_COUNT
} grpc_context_index;

@ -90,10 +90,12 @@ struct grpc_tcp_listener {
grpc_closure read_closure;
grpc_closure destroyed_closure;
struct grpc_tcp_listener *next;
/* When we add a listener, more than one can be created, mainly because of
IPv6. A sibling will still be in the normal list, but will be flagged
as such. Any action, such as ref or unref, will affect all of the
siblings in the list. */
/* sibling is a linked list of all listeners for a given port. add_port and
clone_port place all new listeners in the same sibling list. A member of
the 'sibling' list is also a member of the 'next' list. The head of each
sibling list has is_sibling==0, and subsequent members of sibling lists
have is_sibling==1. is_sibling allows separate sibling lists to be
identified while iterating through 'next'. */
struct grpc_tcp_listener *sibling;
int is_sibling;
};
@ -306,7 +308,7 @@ static grpc_error *prepare_socket(int fd, const struct sockaddr *addr,
GPR_ASSERT(fd >= 0);
if (so_reuseport) {
if (so_reuseport && !grpc_is_unix_socket(addr)) {
err = grpc_set_socket_reuse_port(fd, 1);
if (err != GRPC_ERROR_NONE) goto error;
}
@ -480,6 +482,9 @@ static grpc_error *add_socket_to_server(grpc_tcp_server *s, int fd,
return err;
}
/* Insert count new listeners after listener. Every new listener will have the
same listen address as listener (SO_REUSEPORT must be enabled). Every new
listener is a sibling of listener. */
static grpc_error *clone_port(grpc_tcp_listener *listener, unsigned count) {
grpc_tcp_listener *sp = NULL;
char *addr_str;
@ -506,6 +511,11 @@ static grpc_error *clone_port(grpc_tcp_listener *listener, unsigned count) {
sp = gpr_malloc(sizeof(grpc_tcp_listener));
sp->next = listener->next;
listener->next = sp;
/* sp (the new listener) is a sibling of 'listener' (the original
listener). */
sp->is_sibling = 1;
sp->sibling = listener->sibling;
listener->sibling = sp;
sp->server = listener->server;
sp->fd = fd;
sp->emfd = grpc_fd_create(fd, name);
@ -514,8 +524,6 @@ static grpc_error *clone_port(grpc_tcp_listener *listener, unsigned count) {
sp->port = port;
sp->port_index = listener->port_index;
sp->fd_index = listener->fd_index + count - i;
sp->is_sibling = 1;
sp->sibling = listener->is_sibling ? listener->sibling : listener;
GPR_ASSERT(sp->emfd);
while (listener->server->tail->next != NULL) {
listener->server->tail = listener->server->tail->next;
@ -685,7 +693,8 @@ void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s,
s->pollset_count = pollset_count;
sp = s->head;
while (sp != NULL) {
if (s->so_reuseport && pollset_count > 1) {
if (s->so_reuseport && !grpc_is_unix_socket(&sp->addr.sockaddr) &&
pollset_count > 1) {
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"clone_port", clone_port(sp, (unsigned)(pollset_count - 1))));
for (i = 0; i < pollset_count; i++) {

@ -37,6 +37,10 @@
#include "src/core/lib/iomgr/pollset.h"
#include "src/core/lib/security/credentials/credentials.h"
#ifdef __cplusplus
extern "C" {
#endif
/* --- grpc_auth_context ---
High level authentication context object. Can optionally be chained. */
@ -111,4 +115,8 @@ grpc_auth_context *grpc_auth_context_from_arg(const grpc_arg *arg);
grpc_auth_context *grpc_find_auth_context_in_args(
const grpc_channel_args *args);
#ifdef __cplusplus
}
#endif
#endif /* GRPC_CORE_LIB_SECURITY_CONTEXT_SECURITY_CONTEXT_H */

@ -42,6 +42,14 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
grpc_channel_stack_type channel_stack_type,
grpc_transport *optional_transport);
/** Create a call given a grpc_channel, in order to call \a method.
Progress is tied to activity on \a pollset_set. The returned call object is
meant to be used with \a grpc_call_start_batch_and_execute, which relies on
callbacks to signal completions. \a method and \a host need
only live through the invocation of this function. If \a parent_call is
non-NULL, it must be a server-side call. It will be used to propagate
properties from the server call to this new client call, depending on the
value of \a propagation_mask (see propagation_bits.h for possible values) */
grpc_call *grpc_channel_create_pollset_set_call(
grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
grpc_pollset_set *pollset_set, const char *method, const char *host,

@ -40,6 +40,10 @@
#define GRPC_CHANNEL_INIT_BUILTIN_PRIORITY 10000
#ifdef __cplusplus
extern "C" {
#endif
/// This module provides a way for plugins (and the grpc core library itself)
/// to register mutators for channel stacks.
/// It also provides a universal entry path to run those mutators to build
@ -84,4 +88,8 @@ bool grpc_channel_init_create_stack(grpc_exec_ctx *exec_ctx,
grpc_channel_stack_builder *builder,
grpc_channel_stack_type type);
#ifdef __cplusplus
}
#endif
#endif /* GRPC_CORE_LIB_SURFACE_CHANNEL_INIT_H */

@ -272,7 +272,7 @@ static void shutdown_cleanup(grpc_exec_ctx *exec_ctx, void *arg,
}
static void send_shutdown(grpc_exec_ctx *exec_ctx, grpc_channel *channel,
int send_goaway, grpc_error *send_disconnect) {
bool send_goaway, grpc_error *send_disconnect) {
grpc_transport_op op;
struct shutdown_cleanup_args *sc;
grpc_channel_element *elem;
@ -293,7 +293,7 @@ static void send_shutdown(grpc_exec_ctx *exec_ctx, grpc_channel *channel,
static void channel_broadcaster_shutdown(grpc_exec_ctx *exec_ctx,
channel_broadcaster *cb,
int send_goaway,
bool send_goaway,
grpc_error *force_disconnect) {
size_t i;
@ -1252,7 +1252,8 @@ void grpc_server_shutdown_and_notify(grpc_server *server,
l->destroy(&exec_ctx, server, l->arg, &l->destroy_done);
}
channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 1, 0);
channel_broadcaster_shutdown(&exec_ctx, &broadcaster, true /* send_goaway */,
GRPC_ERROR_NONE);
done:
grpc_exec_ctx_finish(&exec_ctx);
@ -1268,7 +1269,7 @@ void grpc_server_cancel_all_calls(grpc_server *server) {
channel_broadcaster_init(server, &broadcaster);
gpr_mu_unlock(&server->mu_global);
channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 0,
channel_broadcaster_shutdown(&exec_ctx, &broadcaster, false /* send_goaway */,
GRPC_ERROR_CREATE("Cancelling all calls"));
grpc_exec_ctx_finish(&exec_ctx);
}

@ -59,13 +59,9 @@ struct grpc_byte_stream {
* on_complete will not be called), 0 if the bytes will be available
* asynchronously.
*
* on entry, *remaining can be set as a hint as to the maximum number
* max_size_hint can be set as a hint as to the maximum number
* of bytes that would be acceptable to read.
*
* fills *buffer, *length, *remaining with the bytes, length of bytes
* and length of data remaining to be read before either returning 1
* or calling on_complete.
*
* once a slice is returned into *slice, it is owned by the caller.
*/
int grpc_byte_stream_next(grpc_exec_ctx *exec_ctx,

@ -37,6 +37,10 @@
#include <grpc/support/slice.h>
#include <grpc/support/useful.h>
#ifdef __cplusplus
extern "C" {
#endif
/* This file provides a mechanism for tracking metadata through the grpc stack.
It's not intended for consumption outside of the library.
@ -164,4 +168,8 @@ void grpc_mdctx_global_shutdown(void);
extern gpr_slice (*grpc_chttp2_base64_encode_and_huffman_compress)(
gpr_slice input);
#ifdef __cplusplus
}
#endif
#endif /* GRPC_CORE_LIB_TRANSPORT_METADATA_H */

@ -33,6 +33,7 @@
#include "src/core/lib/transport/metadata_batch.h"
#include <stdbool.h>
#include <string.h>
#include <grpc/support/alloc.h>
@ -187,7 +188,7 @@ void grpc_metadata_batch_clear(grpc_metadata_batch *batch) {
grpc_metadata_batch_filter(batch, no_metadata_for_you, NULL);
}
int grpc_metadata_batch_is_empty(grpc_metadata_batch *batch) {
bool grpc_metadata_batch_is_empty(grpc_metadata_batch *batch) {
return batch->list.head == NULL &&
gpr_time_cmp(gpr_inf_future(batch->deadline.clock_type),
batch->deadline) == 0;

@ -34,12 +34,18 @@
#ifndef GRPC_CORE_LIB_TRANSPORT_METADATA_BATCH_H
#define GRPC_CORE_LIB_TRANSPORT_METADATA_BATCH_H
#include <stdbool.h>
#include <grpc/grpc.h>
#include <grpc/support/port_platform.h>
#include <grpc/support/slice.h>
#include <grpc/support/time.h>
#include "src/core/lib/transport/metadata.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct grpc_linked_mdelem {
grpc_mdelem *md;
struct grpc_linked_mdelem *next;
@ -64,7 +70,7 @@ typedef struct grpc_metadata_batch {
void grpc_metadata_batch_init(grpc_metadata_batch *batch);
void grpc_metadata_batch_destroy(grpc_metadata_batch *batch);
void grpc_metadata_batch_clear(grpc_metadata_batch *batch);
int grpc_metadata_batch_is_empty(grpc_metadata_batch *batch);
bool grpc_metadata_batch_is_empty(grpc_metadata_batch *batch);
/* Returns the transport size of the batch. */
size_t grpc_metadata_batch_size(grpc_metadata_batch *batch);
@ -125,4 +131,8 @@ void grpc_metadata_batch_assert_ok(grpc_metadata_batch *comd);
} while (0)
#endif
#ifdef __cplusplus
}
#endif
#endif /* GRPC_CORE_LIB_TRANSPORT_METADATA_BATCH_H */

@ -43,6 +43,10 @@
#include "src/core/lib/transport/byte_stream.h"
#include "src/core/lib/transport/metadata_batch.h"
#ifdef __cplusplus
extern "C" {
#endif
/* forward declarations */
typedef struct grpc_transport grpc_transport;
@ -158,7 +162,7 @@ typedef struct grpc_transport_op {
/** should we send a goaway?
after a goaway is sent, once there are no more active calls on
the transport, the transport should disconnect */
int send_goaway;
bool send_goaway;
/** what should the goaway contain? */
grpc_status_code goaway_status;
gpr_slice *goaway_message;
@ -268,4 +272,8 @@ void grpc_transport_destroy(grpc_exec_ctx *exec_ctx, grpc_transport *transport);
char *grpc_transport_get_peer(grpc_exec_ctx *exec_ctx,
grpc_transport *transport);
#ifdef __cplusplus
}
#endif
#endif /* GRPC_CORE_LIB_TRANSPORT_TRANSPORT_H */

@ -0,0 +1,112 @@
/*
*
* 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 <string.h>
#include "src/core/lib/channel/channel_stack.h"
#include "src/cpp/common/channel_filter.h"
namespace grpc {
// MetadataBatch
grpc_linked_mdelem *MetadataBatch::AddMetadata(const string &key,
const string &value) {
grpc_linked_mdelem *storage = new grpc_linked_mdelem;
memset(storage, 0, sizeof(grpc_linked_mdelem));
storage->md = grpc_mdelem_from_strings(key.c_str(), value.c_str());
grpc_metadata_batch_link_head(batch_, storage);
return storage;
}
// ChannelData
void ChannelData::StartTransportOp(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem,
TransportOp *op) {
grpc_channel_next_op(exec_ctx, elem, op->op());
}
// CallData
void CallData::StartTransportStreamOp(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem,
TransportStreamOp *op) {
grpc_call_next_op(exec_ctx, elem, op->op());
}
void CallData::SetPollsetOrPollsetSet(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem,
grpc_polling_entity *pollent) {
grpc_call_stack_ignore_set_pollset_or_pollset_set(exec_ctx, elem, pollent);
}
char *CallData::GetPeer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
return grpc_call_next_get_peer(exec_ctx, elem);
}
// internal code used by RegisterChannelFilter()
namespace internal {
// Note: Implicitly initialized to nullptr due to static lifetime.
std::vector<FilterRecord> *channel_filters;
namespace {
bool MaybeAddFilter(grpc_channel_stack_builder *builder, void *arg) {
const FilterRecord &filter = *(FilterRecord *)arg;
if (filter.include_filter) {
const grpc_channel_args *args =
grpc_channel_stack_builder_get_channel_arguments(builder);
if (!filter.include_filter(*args)) return true;
}
return grpc_channel_stack_builder_prepend_filter(builder, &filter.filter,
nullptr, nullptr);
}
} // namespace
void ChannelFilterPluginInit() {
for (size_t i = 0; i < channel_filters->size(); ++i) {
FilterRecord &filter = (*channel_filters)[i];
grpc_channel_init_register_stage(filter.stack_type, filter.priority,
MaybeAddFilter, (void *)&filter);
}
}
void ChannelFilterPluginShutdown() {}
} // namespace internal
} // namespace grpc

@ -0,0 +1,386 @@
/*
*
* 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_CHANNEL_FILTER_H
#define GRPCXX_CHANNEL_FILTER_H
#include <grpc++/impl/codegen/config.h>
#include <grpc/census.h>
#include <grpc/grpc.h>
#include <grpc/impl/codegen/alloc.h>
#include <functional>
#include <vector>
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/surface/channel_init.h"
#include "src/core/lib/transport/metadata_batch.h"
/// An interface to define filters.
///
/// To define a filter, implement a subclass of each of \c CallData and
/// \c ChannelData. Then register the filter using something like this:
/// \code{.cpp}
/// RegisterChannelFilter<MyChannelDataSubclass, MyCallDataSubclass>(
/// "name-of-filter", GRPC_SERVER_CHANNEL, INT_MAX, nullptr);
/// \endcode
namespace grpc {
/// A C++ wrapper for the \c grpc_metadata_batch struct.
class MetadataBatch {
public:
/// Borrows a pointer to \a batch, but does NOT take ownership.
/// The caller must ensure that \a batch continues to exist for as
/// long as the MetadataBatch object does.
explicit MetadataBatch(grpc_metadata_batch *batch) : batch_(batch) {}
grpc_metadata_batch *batch() const { return batch_; }
/// Adds metadata and returns the newly allocated storage.
/// The caller takes ownership of the result, which must exist for the
/// lifetime of the gRPC call.
grpc_linked_mdelem *AddMetadata(const string &key, const string &value);
class const_iterator : public std::iterator<std::bidirectional_iterator_tag,
const grpc_mdelem> {
public:
const grpc_mdelem &operator*() const { return *elem_->md; }
const grpc_mdelem *operator->() const { return elem_->md; }
const_iterator &operator++() {
elem_ = elem_->next;
return *this;
}
const_iterator operator++(int) {
const_iterator tmp(*this);
operator++();
return tmp;
}
const_iterator &operator--() {
elem_ = elem_->prev;
return *this;
}
const_iterator operator--(int) {
const_iterator tmp(*this);
operator--();
return tmp;
}
bool operator==(const const_iterator &other) const {
return elem_ == other.elem_;
}
bool operator!=(const const_iterator &other) const {
return elem_ != other.elem_;
}
private:
friend class MetadataBatch;
explicit const_iterator(grpc_linked_mdelem *elem) : elem_(elem) {}
grpc_linked_mdelem *elem_;
};
const_iterator begin() const { return const_iterator(batch_->list.head); }
const_iterator end() const { return const_iterator(nullptr); }
private:
grpc_metadata_batch *batch_; // Not owned.
};
/// A C++ wrapper for the \c grpc_transport_op struct.
class TransportOp {
public:
/// Borrows a pointer to \a op, but does NOT take ownership.
/// The caller must ensure that \a op continues to exist for as
/// long as the TransportOp object does.
explicit TransportOp(grpc_transport_op *op) : op_(op) {}
grpc_transport_op *op() const { return op_; }
// TODO(roth): Add a C++ wrapper for grpc_error?
grpc_error *disconnect_with_error() const {
return op_->disconnect_with_error;
}
bool send_goaway() const { return op_->send_goaway; }
// TODO(roth): Add methods for additional fields as needed.
private:
grpc_transport_op *op_; // Not owned.
};
/// A C++ wrapper for the \c grpc_transport_stream_op struct.
class TransportStreamOp {
public:
/// Borrows a pointer to \a op, but does NOT take ownership.
/// The caller must ensure that \a op continues to exist for as
/// long as the TransportStreamOp object does.
explicit TransportStreamOp(grpc_transport_stream_op *op)
: op_(op),
send_initial_metadata_(op->send_initial_metadata),
send_trailing_metadata_(op->send_trailing_metadata),
recv_initial_metadata_(op->recv_initial_metadata),
recv_trailing_metadata_(op->recv_trailing_metadata) {}
grpc_transport_stream_op *op() const { return op_; }
grpc_closure *on_complete() const { return op_->on_complete; }
void set_on_complete(grpc_closure *closure) { op_->on_complete = closure; }
MetadataBatch *send_initial_metadata() {
return op_->send_initial_metadata == nullptr ? nullptr
: &send_initial_metadata_;
}
MetadataBatch *send_trailing_metadata() {
return op_->send_trailing_metadata == nullptr ? nullptr
: &send_trailing_metadata_;
}
MetadataBatch *recv_initial_metadata() {
return op_->recv_initial_metadata == nullptr ? nullptr
: &recv_initial_metadata_;
}
MetadataBatch *recv_trailing_metadata() {
return op_->recv_trailing_metadata == nullptr ? nullptr
: &recv_trailing_metadata_;
}
uint32_t *send_initial_metadata_flags() const {
return &op_->send_initial_metadata_flags;
}
grpc_closure *recv_initial_metadata_ready() const {
return op_->recv_initial_metadata_ready;
}
void set_recv_initial_metadata_ready(grpc_closure *closure) {
op_->recv_initial_metadata_ready = closure;
}
grpc_byte_stream *send_message() const { return op_->send_message; }
void set_send_message(grpc_byte_stream *send_message) {
op_->send_message = send_message;
}
/// To be called only on clients and servers, respectively.
grpc_client_security_context *client_security_context() const {
return (grpc_client_security_context *)op_->context[GRPC_CONTEXT_SECURITY]
.value;
}
grpc_server_security_context *server_security_context() const {
return (grpc_server_security_context *)op_->context[GRPC_CONTEXT_SECURITY]
.value;
}
census_context *get_census_context() const {
return (census_context *)op_->context[GRPC_CONTEXT_TRACING].value;
}
private:
grpc_transport_stream_op *op_; // Not owned.
MetadataBatch send_initial_metadata_;
MetadataBatch send_trailing_metadata_;
MetadataBatch recv_initial_metadata_;
MetadataBatch recv_trailing_metadata_;
};
/// Represents channel data.
class ChannelData {
public:
virtual ~ChannelData() {
if (peer_) gpr_free((void *)peer_);
}
/// Caller does NOT take ownership of result.
const char *peer() const { return peer_; }
// TODO(roth): Find a way to avoid passing elem into these methods.
virtual void StartTransportOp(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem, TransportOp *op);
protected:
/// Takes ownership of \a peer.
ChannelData(const grpc_channel_args &args, const char *peer) : peer_(peer) {}
private:
const char *peer_;
};
/// Represents call data.
class CallData {
public:
virtual ~CallData() {}
/// Initializes the call data.
virtual grpc_error *Init() { return GRPC_ERROR_NONE; }
// TODO(roth): Find a way to avoid passing elem into these methods.
/// Starts a new stream operation.
virtual void StartTransportStreamOp(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem,
TransportStreamOp *op);
/// Sets a pollset or pollset set.
virtual void SetPollsetOrPollsetSet(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem,
grpc_polling_entity *pollent);
/// Gets the peer name.
virtual char *GetPeer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem);
protected:
explicit CallData(const ChannelData &) {}
};
namespace internal {
// Defines static members for passing to C core.
// Members of this class correspond to the members of the C
// grpc_channel_filter struct.
template <typename ChannelDataType, typename CallDataType>
class ChannelFilter GRPC_FINAL {
public:
static const size_t channel_data_size = sizeof(ChannelDataType);
static void InitChannelElement(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem,
grpc_channel_element_args *args) {
const char *peer =
args->optional_transport
? grpc_transport_get_peer(exec_ctx, args->optional_transport)
: nullptr;
// Construct the object in the already-allocated memory.
new (elem->channel_data) ChannelDataType(*args->channel_args, peer);
}
static void DestroyChannelElement(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem) {
reinterpret_cast<ChannelDataType *>(elem->channel_data)->~ChannelDataType();
}
static void StartTransportOp(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem,
grpc_transport_op *op) {
ChannelDataType *channel_data = (ChannelDataType *)elem->channel_data;
TransportOp op_wrapper(op);
channel_data->StartTransportOp(exec_ctx, elem, &op_wrapper);
}
static const size_t call_data_size = sizeof(CallDataType);
static grpc_error *InitCallElement(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem,
grpc_call_element_args *args) {
const ChannelDataType &channel_data =
*(ChannelDataType *)elem->channel_data;
// Construct the object in the already-allocated memory.
CallDataType *call_data = new (elem->call_data) CallDataType(channel_data);
return call_data->Init();
}
static void DestroyCallElement(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem,
const grpc_call_final_info *final_info,
void *and_free_memory) {
reinterpret_cast<CallDataType *>(elem->call_data)->~CallDataType();
}
static void StartTransportStreamOp(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem,
grpc_transport_stream_op *op) {
CallDataType *call_data = (CallDataType *)elem->call_data;
TransportStreamOp op_wrapper(op);
call_data->StartTransportStreamOp(exec_ctx, elem, &op_wrapper);
}
static void SetPollsetOrPollsetSet(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem,
grpc_polling_entity *pollent) {
CallDataType *call_data = (CallDataType *)elem->call_data;
call_data->SetPollsetOrPollsetSet(exec_ctx, elem, pollent);
}
static char *GetPeer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
CallDataType *call_data = (CallDataType *)elem->call_data;
return call_data->GetPeer(exec_ctx, elem);
}
};
struct FilterRecord {
grpc_channel_stack_type stack_type;
int priority;
std::function<bool(const grpc_channel_args &)> include_filter;
grpc_channel_filter filter;
};
extern std::vector<FilterRecord> *channel_filters;
void ChannelFilterPluginInit();
void ChannelFilterPluginShutdown();
} // namespace internal
/// Registers a new filter.
/// Must be called by only one thread at a time.
/// The \a include_filter argument specifies a function that will be called
/// to determine at run-time whether or not to add the filter. If the
/// value is nullptr, the filter will be added unconditionally.
template <typename ChannelDataType, typename CallDataType>
void RegisterChannelFilter(
const char *name, grpc_channel_stack_type stack_type, int priority,
std::function<bool(const grpc_channel_args &)> include_filter) {
// If we haven't been called before, initialize channel_filters and
// call grpc_register_plugin().
if (internal::channel_filters == nullptr) {
grpc_register_plugin(internal::ChannelFilterPluginInit,
internal::ChannelFilterPluginShutdown);
internal::channel_filters = new std::vector<internal::FilterRecord>();
}
// Add an entry to channel_filters. The filter will be added when the
// C-core initialization code calls ChannelFilterPluginInit().
typedef internal::ChannelFilter<ChannelDataType, CallDataType> FilterType;
internal::FilterRecord filter_record = {
stack_type,
priority,
include_filter,
{FilterType::StartTransportStreamOp, FilterType::StartTransportOp,
FilterType::call_data_size, FilterType::InitCallElement,
FilterType::SetPollsetOrPollsetSet, FilterType::DestroyCallElement,
FilterType::channel_data_size, FilterType::InitChannelElement,
FilterType::DestroyChannelElement, FilterType::GetPeer, name}};
internal::channel_filters->push_back(filter_record);
}
} // namespace grpc
#endif // GRPCXX_CHANNEL_FILTER_H

@ -32,12 +32,12 @@
import threading
import time
import unittest
from concurrent import futures
import grpc
from grpc import _channel
from grpc import _server
from tests.unit.framework.common import test_constants
from tests.unit import _thread_pool
def _ready_in_connectivities(connectivities):
@ -104,7 +104,8 @@ class ChannelConnectivityTest(unittest.TestCase):
grpc.ChannelConnectivity.READY, fifth_connectivities)
def test_immediately_connectable_channel_connectivity(self):
server = _server.Server(futures.ThreadPoolExecutor(max_workers=0), ())
thread_pool = _thread_pool.RecordingThreadPool(max_workers=None)
server = _server.Server(thread_pool, ())
port = server.add_insecure_port('[::]:0')
server.start()
first_callback = _Callback()
@ -141,9 +142,11 @@ class ChannelConnectivityTest(unittest.TestCase):
fourth_connectivities)
self.assertNotIn(
grpc.ChannelConnectivity.SHUTDOWN, fourth_connectivities)
self.assertFalse(thread_pool.was_used())
def test_reachable_then_unreachable_channel_connectivity(self):
server = _server.Server(futures.ThreadPoolExecutor(max_workers=0), ())
thread_pool = _thread_pool.RecordingThreadPool(max_workers=None)
server = _server.Server(thread_pool, ())
port = server.add_insecure_port('[::]:0')
server.start()
callback = _Callback()
@ -155,6 +158,7 @@ class ChannelConnectivityTest(unittest.TestCase):
server.stop(None)
callback.block_until_connectivities_satisfy(_last_connectivity_is_not_ready)
channel.unsubscribe(callback.update)
self.assertFalse(thread_pool.was_used())
if __name__ == '__main__':

@ -31,12 +31,12 @@
import threading
import unittest
from concurrent import futures
import grpc
from grpc import _channel
from grpc import _server
from tests.unit.framework.common import test_constants
from tests.unit import _thread_pool
class _Callback(object):
@ -78,7 +78,8 @@ class ChannelReadyFutureTest(unittest.TestCase):
self.assertFalse(ready_future.running())
def test_immediately_connectable_channel_connectivity(self):
server = _server.Server(futures.ThreadPoolExecutor(max_workers=0), ())
thread_pool = _thread_pool.RecordingThreadPool(max_workers=None)
server = _server.Server(thread_pool, ())
port = server.add_insecure_port('[::]:0')
server.start()
channel = grpc.insecure_channel('localhost:{}'.format(port))
@ -97,6 +98,7 @@ class ChannelReadyFutureTest(unittest.TestCase):
self.assertFalse(ready_future.cancelled())
self.assertTrue(ready_future.done())
self.assertFalse(ready_future.running())
self.assertFalse(thread_pool.was_used())
if __name__ == '__main__':

@ -0,0 +1,48 @@
# 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.
import threading
from concurrent import futures
class RecordingThreadPool(futures.Executor):
"""A thread pool that records if used."""
def __init__(self, max_workers):
self._tp_executor = futures.ThreadPoolExecutor(max_workers=max_workers)
self._lock = threading.Lock()
self._was_used = False
def submit(self, fn, *args, **kwargs):
with self._lock:
self._was_used = True
self._tp_executor.submit(fn, *args, **kwargs)
def was_used(self):
with self._lock:
return self._was_used

@ -0,0 +1,353 @@
/*
*
* 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 <memory>
#include <mutex>
#include <grpc++/channel.h>
#include <grpc++/client_context.h>
#include <grpc++/create_channel.h>
#include <grpc++/generic/async_generic_service.h>
#include <grpc++/generic/generic_stub.h>
#include <grpc++/impl/codegen/proto_utils.h>
#include <grpc++/server.h>
#include <grpc++/server_builder.h>
#include <grpc++/server_context.h>
#include <grpc++/support/config.h>
#include <grpc++/support/slice.h>
#include <grpc/grpc.h>
#include <grpc/support/thd.h>
#include <grpc/support/time.h>
#include <gtest/gtest.h>
#include "src/cpp/common/channel_filter.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/util/byte_buffer_proto_helper.h"
using grpc::testing::EchoRequest;
using grpc::testing::EchoResponse;
using std::chrono::system_clock;
namespace grpc {
namespace testing {
namespace {
void* tag(int i) { return (void*)(intptr_t)i; }
void verify_ok(CompletionQueue* cq, int i, bool expect_ok) {
bool ok;
void* got_tag;
EXPECT_TRUE(cq->Next(&got_tag, &ok));
EXPECT_EQ(expect_ok, ok);
EXPECT_EQ(tag(i), got_tag);
}
namespace {
int global_num_connections = 0;
int global_num_calls = 0;
mutex global_mu;
void IncrementConnectionCounter() {
unique_lock<mutex> lock(global_mu);
++global_num_connections;
}
void ResetConnectionCounter() {
unique_lock<mutex> lock(global_mu);
global_num_connections = 0;
}
int GetConnectionCounterValue() {
unique_lock<mutex> lock(global_mu);
return global_num_connections;
}
void IncrementCallCounter() {
unique_lock<mutex> lock(global_mu);
++global_num_calls;
}
void ResetCallCounter() {
unique_lock<mutex> lock(global_mu);
global_num_calls = 0;
}
int GetCallCounterValue() {
unique_lock<mutex> lock(global_mu);
return global_num_calls;
}
} // namespace
class ChannelDataImpl : public ChannelData {
public:
ChannelDataImpl(const grpc_channel_args& args, const char* peer)
: ChannelData(args, peer) {
IncrementConnectionCounter();
}
};
class CallDataImpl : public CallData {
public:
explicit CallDataImpl(const ChannelDataImpl& channel_data)
: CallData(channel_data) {}
void StartTransportStreamOp(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
TransportStreamOp* op) GRPC_OVERRIDE {
// Incrementing the counter could be done from the ctor, but we want
// to test that the individual methods are actually called correctly.
if (op->recv_initial_metadata() != nullptr) IncrementCallCounter();
grpc_call_next_op(exec_ctx, elem, op->op());
}
};
class FilterEnd2endTest : public ::testing::Test {
protected:
FilterEnd2endTest() : server_host_("localhost") {}
void SetUp() GRPC_OVERRIDE {
int port = grpc_pick_unused_port_or_die();
server_address_ << server_host_ << ":" << port;
// Setup server
ServerBuilder builder;
builder.AddListeningPort(server_address_.str(),
InsecureServerCredentials());
builder.RegisterAsyncGenericService(&generic_service_);
srv_cq_ = builder.AddCompletionQueue();
server_ = builder.BuildAndStart();
}
void TearDown() GRPC_OVERRIDE {
server_->Shutdown();
void* ignored_tag;
bool ignored_ok;
cli_cq_.Shutdown();
srv_cq_->Shutdown();
while (cli_cq_.Next(&ignored_tag, &ignored_ok))
;
while (srv_cq_->Next(&ignored_tag, &ignored_ok))
;
}
void ResetStub() {
std::shared_ptr<Channel> channel =
CreateChannel(server_address_.str(), InsecureChannelCredentials());
generic_stub_.reset(new GenericStub(channel));
ResetConnectionCounter();
ResetCallCounter();
}
void server_ok(int i) { verify_ok(srv_cq_.get(), i, true); }
void client_ok(int i) { verify_ok(&cli_cq_, i, true); }
void server_fail(int i) { verify_ok(srv_cq_.get(), i, false); }
void client_fail(int i) { verify_ok(&cli_cq_, i, false); }
void SendRpc(int num_rpcs) {
const grpc::string kMethodName("/grpc.cpp.test.util.EchoTestService/Echo");
for (int i = 0; i < num_rpcs; i++) {
EchoRequest send_request;
EchoRequest recv_request;
EchoResponse send_response;
EchoResponse recv_response;
Status recv_status;
ClientContext cli_ctx;
GenericServerContext srv_ctx;
GenericServerAsyncReaderWriter stream(&srv_ctx);
// The string needs to be long enough to test heap-based slice.
send_request.set_message("Hello world. Hello world. Hello world.");
std::unique_ptr<GenericClientAsyncReaderWriter> call =
generic_stub_->Call(&cli_ctx, kMethodName, &cli_cq_, tag(1));
client_ok(1);
std::unique_ptr<ByteBuffer> send_buffer =
SerializeToByteBuffer(&send_request);
call->Write(*send_buffer, tag(2));
// Send ByteBuffer can be destroyed after calling Write.
send_buffer.reset();
client_ok(2);
call->WritesDone(tag(3));
client_ok(3);
generic_service_.RequestCall(&srv_ctx, &stream, srv_cq_.get(),
srv_cq_.get(), tag(4));
verify_ok(srv_cq_.get(), 4, true);
EXPECT_EQ(server_host_, srv_ctx.host().substr(0, server_host_.length()));
EXPECT_EQ(kMethodName, srv_ctx.method());
ByteBuffer recv_buffer;
stream.Read(&recv_buffer, tag(5));
server_ok(5);
EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_request));
EXPECT_EQ(send_request.message(), recv_request.message());
send_response.set_message(recv_request.message());
send_buffer = SerializeToByteBuffer(&send_response);
stream.Write(*send_buffer, tag(6));
send_buffer.reset();
server_ok(6);
stream.Finish(Status::OK, tag(7));
server_ok(7);
recv_buffer.Clear();
call->Read(&recv_buffer, tag(8));
client_ok(8);
EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_response));
call->Finish(&recv_status, tag(9));
client_ok(9);
EXPECT_EQ(send_response.message(), recv_response.message());
EXPECT_TRUE(recv_status.ok());
}
}
CompletionQueue cli_cq_;
std::unique_ptr<ServerCompletionQueue> srv_cq_;
std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_;
std::unique_ptr<grpc::GenericStub> generic_stub_;
std::unique_ptr<Server> server_;
AsyncGenericService generic_service_;
const grpc::string server_host_;
std::ostringstream server_address_;
};
TEST_F(FilterEnd2endTest, SimpleRpc) {
ResetStub();
EXPECT_EQ(0, GetConnectionCounterValue());
EXPECT_EQ(0, GetCallCounterValue());
SendRpc(1);
EXPECT_EQ(1, GetConnectionCounterValue());
EXPECT_EQ(1, GetCallCounterValue());
}
TEST_F(FilterEnd2endTest, SequentialRpcs) {
ResetStub();
EXPECT_EQ(0, GetConnectionCounterValue());
EXPECT_EQ(0, GetCallCounterValue());
SendRpc(10);
EXPECT_EQ(1, GetConnectionCounterValue());
EXPECT_EQ(10, GetCallCounterValue());
}
// One ping, one pong.
TEST_F(FilterEnd2endTest, SimpleBidiStreaming) {
ResetStub();
EXPECT_EQ(0, GetConnectionCounterValue());
EXPECT_EQ(0, GetCallCounterValue());
const grpc::string kMethodName(
"/grpc.cpp.test.util.EchoTestService/BidiStream");
EchoRequest send_request;
EchoRequest recv_request;
EchoResponse send_response;
EchoResponse recv_response;
Status recv_status;
ClientContext cli_ctx;
GenericServerContext srv_ctx;
GenericServerAsyncReaderWriter srv_stream(&srv_ctx);
cli_ctx.set_compression_algorithm(GRPC_COMPRESS_GZIP);
send_request.set_message("Hello");
std::unique_ptr<GenericClientAsyncReaderWriter> cli_stream =
generic_stub_->Call(&cli_ctx, kMethodName, &cli_cq_, tag(1));
client_ok(1);
generic_service_.RequestCall(&srv_ctx, &srv_stream, srv_cq_.get(),
srv_cq_.get(), tag(2));
verify_ok(srv_cq_.get(), 2, true);
EXPECT_EQ(server_host_, srv_ctx.host().substr(0, server_host_.length()));
EXPECT_EQ(kMethodName, srv_ctx.method());
std::unique_ptr<ByteBuffer> send_buffer =
SerializeToByteBuffer(&send_request);
cli_stream->Write(*send_buffer, tag(3));
send_buffer.reset();
client_ok(3);
ByteBuffer recv_buffer;
srv_stream.Read(&recv_buffer, tag(4));
server_ok(4);
EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_request));
EXPECT_EQ(send_request.message(), recv_request.message());
send_response.set_message(recv_request.message());
send_buffer = SerializeToByteBuffer(&send_response);
srv_stream.Write(*send_buffer, tag(5));
send_buffer.reset();
server_ok(5);
cli_stream->Read(&recv_buffer, tag(6));
client_ok(6);
EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_response));
EXPECT_EQ(send_response.message(), recv_response.message());
cli_stream->WritesDone(tag(7));
client_ok(7);
srv_stream.Read(&recv_buffer, tag(8));
server_fail(8);
srv_stream.Finish(Status::OK, tag(9));
server_ok(9);
cli_stream->Finish(&recv_status, tag(10));
client_ok(10);
EXPECT_EQ(send_response.message(), recv_response.message());
EXPECT_TRUE(recv_status.ok());
EXPECT_EQ(1, GetCallCounterValue());
EXPECT_EQ(1, GetConnectionCounterValue());
}
void RegisterFilter() {
grpc::RegisterChannelFilter<ChannelDataImpl, CallDataImpl>(
"test-filter", GRPC_SERVER_CHANNEL, INT_MAX, nullptr);
}
} // namespace
} // namespace testing
} // namespace grpc
int main(int argc, char** argv) {
grpc_test_init(argc, argv);
::testing::InitGoogleTest(&argc, argv);
grpc::testing::RegisterFilter();
return RUN_ALL_TESTS();
}

@ -31,7 +31,6 @@
*
*/
#include <signal.h>
#include <unistd.h>
#include <fstream>
@ -78,8 +77,6 @@ using grpc::testing::StreamingOutputCallResponse;
using grpc::testing::TestService;
using grpc::Status;
static bool got_sigint = false;
const char kEchoInitialMetadataKey[] = "x-grpc-test-echo-initial";
const char kEchoTrailingBinMetadataKey[] = "x-grpc-test-echo-trailing-bin";
const char kEchoUserAgentKey[] = "x-grpc-test-echo-useragent";
@ -311,7 +308,9 @@ class TestServiceImpl : public TestService::Service {
}
};
void RunServer() {
void grpc::testing::interop::RunServer(
std::shared_ptr<ServerCredentials> creds) {
GPR_ASSERT(FLAGS_port != 0);
std::ostringstream server_address;
server_address << "0.0.0.0:" << FLAGS_port;
TestServiceImpl service;
@ -321,24 +320,10 @@ void RunServer() {
ServerBuilder builder;
builder.RegisterService(&service);
std::shared_ptr<ServerCredentials> creds =
grpc::testing::CreateInteropServerCredentials();
builder.AddListeningPort(server_address.str(), creds);
std::unique_ptr<Server> server(builder.BuildAndStart());
gpr_log(GPR_INFO, "Server listening on %s", server_address.str().c_str());
while (!got_sigint) {
while (!g_got_sigint) {
sleep(5);
}
}
static void sigint_handler(int x) { got_sigint = true; }
int main(int argc, char** argv) {
grpc::testing::InitTest(&argc, &argv, true);
signal(SIGINT, sigint_handler);
GPR_ASSERT(FLAGS_port != 0);
RunServer();
return 0;
}

@ -0,0 +1,54 @@
/*
*
* 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 <signal.h>
#include <unistd.h>
#include "test/cpp/interop/server_helper.h"
#include "test/cpp/util/test_config.h"
bool grpc::testing::interop::g_got_sigint = false;
static void sigint_handler(int x) {
grpc::testing::interop::g_got_sigint = true;
}
int main(int argc, char** argv) {
grpc::testing::InitTest(&argc, &argv, true);
signal(SIGINT, sigint_handler);
grpc::testing::interop::RunServer(
grpc::testing::CreateInteropServerCredentials());
return 0;
}

@ -60,6 +60,12 @@ class InteropServerContextInspector {
const ::grpc::ServerContext& context_;
};
namespace interop {
extern bool g_got_sigint;
void RunServer(std::shared_ptr<ServerCredentials> creds);
} // namespace interop
} // namespace testing
} // namespace grpc

@ -46,6 +46,7 @@ go get github.com/golang/protobuf/proto
go get golang.org/x/net/context
go get golang.org/x/net/trace
go get golang.org/x/oauth2
go get golang.org/x/oauth2/google
go get google.golang.org/cloud
# Build the interop client and server

@ -863,6 +863,7 @@ src/cpp/client/secure_credentials.h \
src/cpp/common/secure_auth_context.h \
src/cpp/server/secure_server_credentials.h \
src/cpp/client/create_channel_internal.h \
src/cpp/common/channel_filter.h \
src/cpp/server/dynamic_thread_pool.h \
src/cpp/server/thread_pool_interface.h \
src/cpp/client/secure_credentials.cc \
@ -880,6 +881,7 @@ src/cpp/client/credentials.cc \
src/cpp/client/generic_stub.cc \
src/cpp/client/insecure_credentials.cc \
src/cpp/common/channel_arguments.cc \
src/cpp/common/channel_filter.cc \
src/cpp/common/completion_queue.cc \
src/cpp/common/core_codegen.cc \
src/cpp/common/rpc_method.cc \

@ -706,7 +706,7 @@ class ObjCLanguage(object):
shortname='objc-tests',
environ=_FORCE_ENVIRON_FOR_WRAPPERS),
self.config.job_spec(['src/objective-c/tests/build_example_test.sh'],
timeout_seconds=15*60,
timeout_seconds=30*60,
shortname='objc-examples-build',
environ=_FORCE_ENVIRON_FOR_WRAPPERS)]

@ -2107,6 +2107,24 @@
"third_party": false,
"type": "target"
},
{
"deps": [
"gpr",
"gpr_test_util",
"grpc",
"grpc++",
"grpc++_test_util",
"grpc_test_util"
],
"headers": [],
"language": "c++",
"name": "filter_end2end_test",
"src": [
"test/cpp/end2end/filter_end2end_test.cc"
],
"third_party": false,
"type": "target"
},
{
"deps": [
"gpr",
@ -2329,6 +2347,7 @@
"grpc++_test_util",
"grpc_test_util",
"interop_server_helper",
"interop_server_lib",
"interop_server_main"
],
"headers": [],
@ -4248,7 +4267,6 @@
"gpr",
"grpc_base",
"grpc_lb_policy_grpclb",
"grpc_lb_policy_grpclb",
"grpc_lb_policy_pick_first",
"grpc_lb_policy_round_robin",
"grpc_load_reporting",
@ -4344,7 +4362,6 @@
"gpr",
"grpc_base",
"grpc_lb_policy_grpclb",
"grpc_lb_policy_grpclb",
"grpc_lb_policy_pick_first",
"grpc_lb_policy_round_robin",
"grpc_load_reporting",
@ -4702,13 +4719,26 @@
"src/proto/grpc/testing/test.pb.h"
],
"language": "c++",
"name": "interop_server_main",
"name": "interop_server_lib",
"src": [
"test/cpp/interop/interop_server.cc"
],
"third_party": false,
"type": "lib"
},
{
"deps": [
"interop_server_lib"
],
"headers": [],
"language": "c++",
"name": "interop_server_main",
"src": [
"test/cpp/interop/interop_server_bootstrap.cc"
],
"third_party": false,
"type": "lib"
},
{
"deps": [
"grpc++",
@ -6658,6 +6688,7 @@
"include/grpc++/support/sync_stream.h",
"include/grpc++/support/time.h",
"src/cpp/client/create_channel_internal.h",
"src/cpp/common/channel_filter.h",
"src/cpp/server/dynamic_thread_pool.h",
"src/cpp/server/thread_pool_interface.h"
],
@ -6721,6 +6752,8 @@
"src/cpp/client/generic_stub.cc",
"src/cpp/client/insecure_credentials.cc",
"src/cpp/common/channel_arguments.cc",
"src/cpp/common/channel_filter.cc",
"src/cpp/common/channel_filter.h",
"src/cpp/common/completion_queue.cc",
"src/cpp/common/core_codegen.cc",
"src/cpp/common/rpc_method.cc",

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

@ -363,6 +363,7 @@
<ClInclude Include="$(SolutionDir)\..\src\cpp\common\secure_auth_context.h" />
<ClInclude Include="$(SolutionDir)\..\src\cpp\server\secure_server_credentials.h" />
<ClInclude Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.h" />
<ClInclude Include="$(SolutionDir)\..\src\cpp\common\channel_filter.h" />
<ClInclude Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.h" />
<ClInclude Include="$(SolutionDir)\..\src\cpp\server\thread_pool_interface.h" />
</ItemGroup>
@ -397,6 +398,8 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\cpp\common\channel_arguments.cc">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\cpp\common\channel_filter.cc">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\cpp\common\completion_queue.cc">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\cpp\common\core_codegen.cc">

@ -46,6 +46,9 @@
<ClCompile Include="$(SolutionDir)\..\src\cpp\common\channel_arguments.cc">
<Filter>src\cpp\common</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\cpp\common\channel_filter.cc">
<Filter>src\cpp\common</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\cpp\common\completion_queue.cc">
<Filter>src\cpp\common</Filter>
</ClCompile>
@ -413,6 +416,9 @@
<ClInclude Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.h">
<Filter>src\cpp\client</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\cpp\common\channel_filter.h">
<Filter>src\cpp\common</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.h">
<Filter>src\cpp\server</Filter>
</ClInclude>

@ -359,6 +359,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.h" />
<ClInclude Include="$(SolutionDir)\..\src\cpp\common\channel_filter.h" />
<ClInclude Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.h" />
<ClInclude Include="$(SolutionDir)\..\src\cpp\server\thread_pool_interface.h" />
</ItemGroup>
@ -383,6 +384,8 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\cpp\common\channel_arguments.cc">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\cpp\common\channel_filter.cc">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\cpp\common\completion_queue.cc">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\cpp\common\core_codegen.cc">

@ -31,6 +31,9 @@
<ClCompile Include="$(SolutionDir)\..\src\cpp\common\channel_arguments.cc">
<Filter>src\cpp\common</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\cpp\common\channel_filter.cc">
<Filter>src\cpp\common</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\cpp\common\completion_queue.cc">
<Filter>src\cpp\common</Filter>
</ClCompile>
@ -386,6 +389,9 @@
<ClInclude Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.h">
<Filter>src\cpp\client</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\cpp\common\channel_filter.h">
<Filter>src\cpp\common</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.h">
<Filter>src\cpp\server</Filter>
</ClInclude>

@ -0,0 +1,212 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<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>{458DCA09-83B9-5E68-D7E9-118864ECBD94}</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>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<ConfigurationType>StaticLibrary</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\global.props" />
<Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<TargetName>interop_server_lib</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<TargetName>interop_server_lib</TargetName>
</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>Windows</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>Windows</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>Windows</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>Windows</SubSystem>
<GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
<GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\empty.pb.cc">
</ClCompile>
<ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\empty.pb.h">
</ClInclude>
<ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\empty.grpc.pb.cc">
</ClCompile>
<ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\empty.grpc.pb.h">
</ClInclude>
<ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\messages.pb.cc">
</ClCompile>
<ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\messages.pb.h">
</ClInclude>
<ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\messages.grpc.pb.cc">
</ClCompile>
<ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\messages.grpc.pb.h">
</ClInclude>
<ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\test.pb.cc">
</ClCompile>
<ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\test.pb.h">
</ClInclude>
<ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\test.grpc.pb.cc">
</ClCompile>
<ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\test.grpc.pb.h">
</ClInclude>
<ClCompile Include="$(SolutionDir)\..\test\cpp\interop\interop_server.cc">
</ClCompile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\interop_server_helper\interop_server_helper.vcxproj">
<Project>{F55BEA2C-B61D-AAFE-CA15-223B8AC0DE5A}</Project>
</ProjectReference>
<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>
<ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++_test_config\grpc++_test_config.vcxproj">
<Project>{3F7D093D-11F9-C4BC-BEB7-18EB28E3F290}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</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>
</Target>
</Project>

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\empty.proto">
<Filter>src\proto\grpc\testing</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\messages.proto">
<Filter>src\proto\grpc\testing</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\test.proto">
<Filter>src\proto\grpc\testing</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\cpp\interop\interop_server.cc">
<Filter>test\cpp\interop</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="src">
<UniqueIdentifier>{356c90d7-2dcd-5f6a-d3ca-6461f2597581}</UniqueIdentifier>
</Filter>
<Filter Include="src\proto">
<UniqueIdentifier>{70740334-0cbf-ab29-0e1c-f0ffa390d77f}</UniqueIdentifier>
</Filter>
<Filter Include="src\proto\grpc">
<UniqueIdentifier>{d581eb6c-94b6-eb79-6b76-d122c13cff3c}</UniqueIdentifier>
</Filter>
<Filter Include="src\proto\grpc\testing">
<UniqueIdentifier>{27f43e87-cfd9-68cc-179a-fc44046797c4}</UniqueIdentifier>
</Filter>
<Filter Include="test">
<UniqueIdentifier>{3402c01e-a9f6-2dd8-6963-03a5774d37f2}</UniqueIdentifier>
</Filter>
<Filter Include="test\cpp">
<UniqueIdentifier>{656eed4b-782e-224c-6101-8a61c2daa94e}</UniqueIdentifier>
</Filter>
<Filter Include="test\cpp\interop">
<UniqueIdentifier>{61c0dab5-5c69-82b0-2961-4104445f2e06}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>

@ -147,57 +147,12 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\empty.pb.cc">
</ClCompile>
<ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\empty.pb.h">
</ClInclude>
<ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\empty.grpc.pb.cc">
</ClCompile>
<ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\empty.grpc.pb.h">
</ClInclude>
<ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\messages.pb.cc">
</ClCompile>
<ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\messages.pb.h">
</ClInclude>
<ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\messages.grpc.pb.cc">
</ClCompile>
<ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\messages.grpc.pb.h">
</ClInclude>
<ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\test.pb.cc">
</ClCompile>
<ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\test.pb.h">
</ClInclude>
<ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\test.grpc.pb.cc">
</ClCompile>
<ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\test.grpc.pb.h">
</ClInclude>
<ClCompile Include="$(SolutionDir)\..\test\cpp\interop\interop_server.cc">
<ClCompile Include="$(SolutionDir)\..\test\cpp\interop\interop_server_bootstrap.cc">
</ClCompile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\interop_server_helper\interop_server_helper.vcxproj">
<Project>{F55BEA2C-B61D-AAFE-CA15-223B8AC0DE5A}</Project>
</ProjectReference>
<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>
<ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++_test_config\grpc++_test_config.vcxproj">
<Project>{3F7D093D-11F9-C4BC-BEB7-18EB28E3F290}</Project>
<ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\interop_server_lib\interop_server_lib.vcxproj">
<Project>{458DCA09-83B9-5E68-D7E9-118864ECBD94}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

@ -1,33 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\empty.proto">
<Filter>src\proto\grpc\testing</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\messages.proto">
<Filter>src\proto\grpc\testing</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\test.proto">
<Filter>src\proto\grpc\testing</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\cpp\interop\interop_server.cc">
<ClCompile Include="$(SolutionDir)\..\test\cpp\interop\interop_server_bootstrap.cc">
<Filter>test\cpp\interop</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="src">
<UniqueIdentifier>{9dfb04b3-9e58-7efb-70a2-b02ec8c5e83e}</UniqueIdentifier>
</Filter>
<Filter Include="src\proto">
<UniqueIdentifier>{ebd8177f-6130-a4fb-1c41-d894f801e3b9}</UniqueIdentifier>
</Filter>
<Filter Include="src\proto\grpc">
<UniqueIdentifier>{1df1acf2-4654-4530-10af-912381c69012}</UniqueIdentifier>
</Filter>
<Filter Include="src\proto\grpc\testing">
<UniqueIdentifier>{ba56d830-1546-c07f-f5ee-03164e41914e}</UniqueIdentifier>
</Filter>
<Filter Include="test">
<UniqueIdentifier>{02523054-816a-75a0-b24b-f527e99c7142}</UniqueIdentifier>
</Filter>

@ -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>{1D42975A-18A5-09D0-30B1-2AE6A97FB9DE}</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>filter_end2end_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>filter_end2end_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\filter_end2end_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\filter_end2end_test.cc">
<Filter>test\cpp\end2end</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="test">
<UniqueIdentifier>{f7581160-220d-1118-f29e-6b37e45671c9}</UniqueIdentifier>
</Filter>
<Filter Include="test\cpp">
<UniqueIdentifier>{63784d35-03cc-1a7e-0c95-a9451bc1daf4}</UniqueIdentifier>
</Filter>
<Filter Include="test\cpp\end2end">
<UniqueIdentifier>{d2a01682-970e-d23d-1eb8-ef020e3a1ca3}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>
Loading…
Cancel
Save