Merge branch 'master' of github.com:google/grpc into add_timed_out_tests_back

pull/972/head
Donna Dionne 10 years ago
commit 7167f895f9
  1. 184
      Makefile
  2. 139
      build.json
  3. 3
      examples/pubsub/main.cc
  4. 6
      examples/pubsub/publisher_test.cc
  5. 6
      examples/pubsub/subscriber_test.cc
  6. 2
      include/grpc++/async_unary_call.h
  7. 6
      include/grpc++/channel_arguments.h
  8. 5
      include/grpc++/create_channel.h
  9. 115
      include/grpc++/credentials.h
  10. 13
      include/grpc++/server.h
  11. 16
      include/grpc++/server_builder.h
  12. 29
      include/grpc++/server_credentials.h
  13. 3
      include/grpc/grpc.h
  14. 9
      include/grpc/grpc_security.h
  15. 2
      src/core/iomgr/pollset_posix.c
  16. 2
      src/core/iomgr/resolve_address_posix.c
  17. 12
      src/core/security/credentials.c
  18. 30
      src/core/security/factories.c
  19. 4
      src/core/security/google_default_credentials.c
  20. 2
      src/core/security/json_token.c
  21. 5
      src/core/security/security_context.c
  22. 42
      src/core/security/server_secure_chttp2.c
  23. 2
      src/core/surface/lame_client.c
  24. 4
      src/core/tsi/fake_transport_security.c
  25. 5
      src/core/tsi/ssl_transport_security.c
  26. 2
      src/core/tsi/transport_security.c
  27. 40
      src/cpp/client/channel.cc
  28. 7
      src/cpp/client/channel.h
  29. 8
      src/cpp/client/create_channel.cc
  30. 90
      src/cpp/client/credentials.cc
  31. 44
      src/cpp/client/insecure_credentials.cc
  32. 131
      src/cpp/client/secure_credentials.cc
  33. 22
      src/cpp/server/insecure_server_credentials.cc
  34. 71
      src/cpp/server/secure_server_credentials.cc
  35. 27
      src/cpp/server/server.cc
  36. 23
      src/cpp/server/server_builder.cc
  37. 22
      src/cpp/server/server_credentials.cc
  38. 32
      src/node/ext/server.cc
  39. 10
      src/node/interop/interop_server.js
  40. 19
      src/node/src/server.js
  41. 42
      src/php/ext/grpc/server.c
  42. 6
      src/php/tests/unit_tests/SecureEndToEndTest.php
  43. 2
      src/python/README.md
  44. 56
      src/python/interop/interop/_insecure_interop_test.py
  45. 55
      src/python/interop/interop/_interop_test_case.py
  46. 63
      src/python/interop/interop/_secure_interop_test.py
  47. 15
      src/python/interop/interop/client.py
  48. 35
      src/python/interop/interop/methods.py
  49. 9
      src/python/src/grpc/_adapter/_c_test.py
  50. 28
      src/python/src/grpc/_adapter/_channel.c
  51. 30
      src/python/src/grpc/_adapter/_face_test_case.py
  52. 4
      src/python/src/grpc/_adapter/_low_test.py
  53. 43
      src/python/src/grpc/_adapter/_server.c
  54. 7
      src/python/src/grpc/_adapter/fore.py
  55. 23
      src/python/src/grpc/_adapter/rear.py
  56. 41
      src/python/src/grpc/early_adopter/_face_utilities.py
  57. 47
      src/python/src/grpc/early_adopter/_reexport.py
  58. 18
      src/python/src/grpc/early_adopter/implementations.py
  59. 111
      src/python/src/grpc/framework/assembly/implementations.py
  60. 28
      src/python/src/grpc/framework/assembly/implementations_test.py
  61. 56
      src/python/src/grpc/framework/assembly/interfaces.py
  62. 179
      src/python/src/grpc/framework/assembly/utilities.py
  63. 18
      src/python/src/grpc/framework/face/_service.py
  64. 30
      src/python/src/grpc/framework/face/_test_case.py
  65. 268
      src/python/src/grpc/framework/face/implementations.py
  66. 462
      src/python/src/grpc/framework/face/interfaces.py
  67. 16
      src/python/src/grpc/framework/face/testing/blocking_invocation_inline_service_test_case.py
  68. 122
      src/python/src/grpc/framework/face/testing/digest.py
  69. 9
      src/python/src/grpc/framework/face/testing/event_invocation_synchronous_event_service_test_case.py
  70. 17
      src/python/src/grpc/framework/face/testing/future_invocation_asynchronous_event_service_test_case.py
  71. 38
      src/python/src/grpc/framework/face/testing/service.py
  72. 8
      src/python/src/grpc/framework/face/testing/stock_service.py
  73. 53
      src/python/src/grpc/framework/face/testing/test_case.py
  74. 174
      src/python/src/grpc/framework/face/utilities.py
  75. 5
      src/ruby/bin/interop/interop_server.rb
  76. 5
      src/ruby/bin/math_server.rb
  77. 5
      src/ruby/bin/noproto_server.rb
  78. 41
      src/ruby/ext/grpc/rb_server.c
  79. 4
      src/ruby/grpc.gemspec
  80. 61
      src/ruby/lib/grpc/generic/client_stub.rb
  81. 9
      src/ruby/lib/grpc/generic/rpc_server.rb
  82. 18
      src/ruby/spec/client_server_spec.rb
  83. 13
      src/ruby/spec/generic/rpc_server_spec.rb
  84. 15
      src/ruby/spec/server_spec.rb
  85. 38
      templates/Makefile.template
  86. 4
      test/core/echo/server.c
  87. 4
      test/core/end2end/fixtures/chttp2_fake_security.c
  88. 4
      test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c
  89. 4
      test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c
  90. 4
      test/core/end2end/gen_build_json.py
  91. 4
      test/core/fling/server.c
  92. 2
      test/core/network_benchmarks/low_level_ping_pong.c
  93. 18
      test/core/security/base64_test.c
  94. 99
      test/core/security/credentials_test.c
  95. 38
      test/core/security/json_token_test.c
  96. 2
      test/core/support/env_test.c
  97. 2
      test/core/surface/lame_client_test.c
  98. 3
      test/cpp/client/credentials_test.cc
  99. 7
      test/cpp/end2end/async_end2end_test.cc
  100. 14
      test/cpp/end2end/end2end_test.cc
  101. Some files were not shown because too many files have changed in this diff Show More

@ -942,13 +942,13 @@ static: static_c static_cxx
static_c: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a static_c: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a
static_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++.a static_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
shared: shared_c shared_cxx shared: shared_c shared_cxx
shared_c: $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT) shared_c: $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT)
shared_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) shared_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT)
shared_csharp: shared_c $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) shared_csharp: shared_c $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT)
grpc_csharp_ext: shared_csharp grpc_csharp_ext: shared_csharp
@ -1844,6 +1844,8 @@ strip-static_cxx: static_cxx
ifeq ($(CONFIG),opt) ifeq ($(CONFIG),opt)
$(E) "[STRIP] Stripping libgrpc++.a" $(E) "[STRIP] Stripping libgrpc++.a"
$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++.a
$(E) "[STRIP] Stripping libgrpc++_unsecure.a"
$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
endif endif
strip-shared_c: shared_c strip-shared_c: shared_c
@ -1860,6 +1862,8 @@ strip-shared_cxx: shared_cxx
ifeq ($(CONFIG),opt) ifeq ($(CONFIG),opt)
$(E) "[STRIP] Stripping libgrpc++.so" $(E) "[STRIP] Stripping libgrpc++.so"
$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT)
$(E) "[STRIP] Stripping libgrpc++_unsecure.so"
$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT)
endif endif
strip-shared_csharp: shared_csharp strip-shared_csharp: shared_csharp
@ -2019,6 +2023,9 @@ install-static_cxx: static_cxx strip-static_cxx
$(E) "[INSTALL] Installing libgrpc++.a" $(E) "[INSTALL] Installing libgrpc++.a"
$(Q) $(INSTALL) -d $(prefix)/lib $(Q) $(INSTALL) -d $(prefix)/lib
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(prefix)/lib/libgrpc++.a $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(prefix)/lib/libgrpc++.a
$(E) "[INSTALL] Installing libgrpc++_unsecure.a"
$(Q) $(INSTALL) -d $(prefix)/lib
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(prefix)/lib/libgrpc++_unsecure.a
@ -2083,6 +2090,19 @@ ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf libgrpc++.$(SHARED_EXT) $(prefix)/lib/libgrpc++.so $(Q) ln -sf libgrpc++.$(SHARED_EXT) $(prefix)/lib/libgrpc++.so
endif endif
endif endif
ifeq ($(SYSTEM),MINGW32)
$(E) "[INSTALL] Installing grpc++_unsecure.$(SHARED_EXT)"
$(Q) $(INSTALL) -d $(prefix)/lib
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/grpc++_unsecure.$(SHARED_EXT)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure-imp.a $(prefix)/lib/libgrpc++_unsecure-imp.a
else
$(E) "[INSTALL] Installing libgrpc++_unsecure.$(SHARED_EXT)"
$(Q) $(INSTALL) -d $(prefix)/lib
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc++_unsecure.$(SHARED_EXT)
ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf libgrpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc++_unsecure.so
endif
endif
ifneq ($(SYSTEM),MINGW32) ifneq ($(SYSTEM),MINGW32)
ifneq ($(SYSTEM),Darwin) ifneq ($(SYSTEM),Darwin)
$(Q) ldconfig || true $(Q) ldconfig || true
@ -2350,7 +2370,6 @@ LIBGRPC_SRC = \
src/core/security/server_secure_chttp2.c \ src/core/security/server_secure_chttp2.c \
src/core/surface/init_secure.c \ src/core/surface/init_secure.c \
src/core/surface/secure_channel_create.c \ src/core/surface/secure_channel_create.c \
src/core/surface/secure_server_create.c \
src/core/tsi/fake_transport_security.c \ src/core/tsi/fake_transport_security.c \
src/core/tsi/ssl_transport_security.c \ src/core/tsi/ssl_transport_security.c \
src/core/tsi/transport_security.c \ src/core/tsi/transport_security.c \
@ -2496,7 +2515,6 @@ src/core/security/security_context.c: $(OPENSSL_DEP)
src/core/security/server_secure_chttp2.c: $(OPENSSL_DEP) src/core/security/server_secure_chttp2.c: $(OPENSSL_DEP)
src/core/surface/init_secure.c: $(OPENSSL_DEP) src/core/surface/init_secure.c: $(OPENSSL_DEP)
src/core/surface/secure_channel_create.c: $(OPENSSL_DEP) src/core/surface/secure_channel_create.c: $(OPENSSL_DEP)
src/core/surface/secure_server_create.c: $(OPENSSL_DEP)
src/core/tsi/fake_transport_security.c: $(OPENSSL_DEP) src/core/tsi/fake_transport_security.c: $(OPENSSL_DEP)
src/core/tsi/ssl_transport_security.c: $(OPENSSL_DEP) src/core/tsi/ssl_transport_security.c: $(OPENSSL_DEP)
src/core/tsi/transport_security.c: $(OPENSSL_DEP) src/core/tsi/transport_security.c: $(OPENSSL_DEP)
@ -2602,13 +2620,13 @@ $(LIBDIR)/$(CONFIG)/libgrpc.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBGRPC_OBJS)
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc.a $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc.a
$(Q) $(AR) rcs $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBGRPC_OBJS) $(Q) $(AR) rcs $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBGRPC_OBJS)
$(Q) rm -rf tmp-merge $(Q) rm -rf tmp-merge-grpc
$(Q) mkdir tmp-merge $(Q) mkdir tmp-merge-grpc
$(Q) ( cd tmp-merge ; $(AR) x ../$(LIBDIR)/$(CONFIG)/libgrpc.a ) $(Q) ( cd tmp-merge-grpc ; $(AR) x ../$(LIBDIR)/$(CONFIG)/libgrpc.a )
$(Q) for l in $(OPENSSL_MERGE_LIBS) ; do ( cd tmp-merge ; ar x ../$${l} ) ; done $(Q) for l in $(OPENSSL_MERGE_LIBS) ; do ( cd tmp-merge-grpc ; ar x ../$${l} ) ; done
$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc.a tmp-merge/__.SYMDEF* $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc.a tmp-merge-grpc/__.SYMDEF*
$(Q) ar rcs $(LIBDIR)/$(CONFIG)/libgrpc.a tmp-merge/* $(Q) ar rcs $(LIBDIR)/$(CONFIG)/libgrpc.a tmp-merge-grpc/*
$(Q) rm -rf tmp-merge $(Q) rm -rf tmp-merge-grpc
ifeq ($(SYSTEM),Darwin) ifeq ($(SYSTEM),Darwin)
$(Q) ranlib $(LIBDIR)/$(CONFIG)/libgrpc.a $(Q) ranlib $(LIBDIR)/$(CONFIG)/libgrpc.a
endif endif
@ -2659,7 +2677,6 @@ $(OBJDIR)/$(CONFIG)/src/core/security/security_context.o:
$(OBJDIR)/$(CONFIG)/src/core/security/server_secure_chttp2.o: $(OBJDIR)/$(CONFIG)/src/core/security/server_secure_chttp2.o:
$(OBJDIR)/$(CONFIG)/src/core/surface/init_secure.o: $(OBJDIR)/$(CONFIG)/src/core/surface/init_secure.o:
$(OBJDIR)/$(CONFIG)/src/core/surface/secure_channel_create.o: $(OBJDIR)/$(CONFIG)/src/core/surface/secure_channel_create.o:
$(OBJDIR)/$(CONFIG)/src/core/surface/secure_server_create.o:
$(OBJDIR)/$(CONFIG)/src/core/tsi/fake_transport_security.o: $(OBJDIR)/$(CONFIG)/src/core/tsi/fake_transport_security.o:
$(OBJDIR)/$(CONFIG)/src/core/tsi/ssl_transport_security.o: $(OBJDIR)/$(CONFIG)/src/core/tsi/ssl_transport_security.o:
$(OBJDIR)/$(CONFIG)/src/core/tsi/transport_security.o: $(OBJDIR)/$(CONFIG)/src/core/tsi/transport_security.o:
@ -3074,17 +3091,21 @@ $(OBJDIR)/$(CONFIG)/src/core/transport/transport.o:
LIBGRPC++_SRC = \ LIBGRPC++_SRC = \
src/cpp/client/secure_credentials.cc \
src/cpp/server/secure_server_credentials.cc \
src/cpp/client/channel.cc \ src/cpp/client/channel.cc \
src/cpp/client/channel_arguments.cc \ src/cpp/client/channel_arguments.cc \
src/cpp/client/client_context.cc \ src/cpp/client/client_context.cc \
src/cpp/client/client_unary_call.cc \ src/cpp/client/client_unary_call.cc \
src/cpp/client/create_channel.cc \ src/cpp/client/create_channel.cc \
src/cpp/client/credentials.cc \ src/cpp/client/credentials.cc \
src/cpp/client/insecure_credentials.cc \
src/cpp/client/internal_stub.cc \ src/cpp/client/internal_stub.cc \
src/cpp/common/call.cc \ src/cpp/common/call.cc \
src/cpp/common/completion_queue.cc \ src/cpp/common/completion_queue.cc \
src/cpp/common/rpc_method.cc \ src/cpp/common/rpc_method.cc \
src/cpp/proto/proto_utils.cc \ src/cpp/proto/proto_utils.cc \
src/cpp/server/insecure_server_credentials.cc \
src/cpp/server/server.cc \ src/cpp/server/server.cc \
src/cpp/server/server_builder.cc \ src/cpp/server/server_builder.cc \
src/cpp/server/server_context.cc \ src/cpp/server/server_context.cc \
@ -3151,17 +3172,21 @@ ifneq ($(OPENSSL_DEP),)
# This is to ensure the embedded OpenSSL is built beforehand, properly # This is to ensure the embedded OpenSSL is built beforehand, properly
# installing headers to their final destination on the drive. We need this # installing headers to their final destination on the drive. We need this
# otherwise parallel compilation will fail if a source is compiled first. # otherwise parallel compilation will fail if a source is compiled first.
src/cpp/client/secure_credentials.cc: $(OPENSSL_DEP)
src/cpp/server/secure_server_credentials.cc: $(OPENSSL_DEP)
src/cpp/client/channel.cc: $(OPENSSL_DEP) src/cpp/client/channel.cc: $(OPENSSL_DEP)
src/cpp/client/channel_arguments.cc: $(OPENSSL_DEP) src/cpp/client/channel_arguments.cc: $(OPENSSL_DEP)
src/cpp/client/client_context.cc: $(OPENSSL_DEP) src/cpp/client/client_context.cc: $(OPENSSL_DEP)
src/cpp/client/client_unary_call.cc: $(OPENSSL_DEP) src/cpp/client/client_unary_call.cc: $(OPENSSL_DEP)
src/cpp/client/create_channel.cc: $(OPENSSL_DEP) src/cpp/client/create_channel.cc: $(OPENSSL_DEP)
src/cpp/client/credentials.cc: $(OPENSSL_DEP) src/cpp/client/credentials.cc: $(OPENSSL_DEP)
src/cpp/client/insecure_credentials.cc: $(OPENSSL_DEP)
src/cpp/client/internal_stub.cc: $(OPENSSL_DEP) src/cpp/client/internal_stub.cc: $(OPENSSL_DEP)
src/cpp/common/call.cc: $(OPENSSL_DEP) src/cpp/common/call.cc: $(OPENSSL_DEP)
src/cpp/common/completion_queue.cc: $(OPENSSL_DEP) src/cpp/common/completion_queue.cc: $(OPENSSL_DEP)
src/cpp/common/rpc_method.cc: $(OPENSSL_DEP) src/cpp/common/rpc_method.cc: $(OPENSSL_DEP)
src/cpp/proto/proto_utils.cc: $(OPENSSL_DEP) src/cpp/proto/proto_utils.cc: $(OPENSSL_DEP)
src/cpp/server/insecure_server_credentials.cc: $(OPENSSL_DEP)
src/cpp/server/server.cc: $(OPENSSL_DEP) src/cpp/server/server.cc: $(OPENSSL_DEP)
src/cpp/server/server_builder.cc: $(OPENSSL_DEP) src/cpp/server/server_builder.cc: $(OPENSSL_DEP)
src/cpp/server/server_context.cc: $(OPENSSL_DEP) src/cpp/server/server_context.cc: $(OPENSSL_DEP)
@ -3186,15 +3211,15 @@ ifeq ($(SYSTEM),MINGW32)
$(LIBDIR)/$(CONFIG)/grpc++.$(SHARED_EXT): $(LIBGRPC++_OBJS) $(ZLIB_DEP)$(LIBDIR)/$(CONFIG)/gpr.$(SHARED_EXT)$(LIBDIR)/$(CONFIG)/grpc.$(SHARED_EXT) $(OPENSSL_DEP) $(LIBDIR)/$(CONFIG)/grpc++.$(SHARED_EXT): $(LIBGRPC++_OBJS) $(ZLIB_DEP)$(LIBDIR)/$(CONFIG)/gpr.$(SHARED_EXT)$(LIBDIR)/$(CONFIG)/grpc.$(SHARED_EXT) $(OPENSSL_DEP)
$(E) "[LD] Linking $@" $(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++.def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++-imp.a -o $(LIBDIR)/$(CONFIG)/grpc++.$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr-imp -lgrpc-imp $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++.def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++-imp.a -o $(LIBDIR)/$(CONFIG)/grpc++.$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr-imp -lgrpc-imp
else else
$(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT): $(LIBGRPC++_OBJS) $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(OPENSSL_DEP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT): $(LIBGRPC++_OBJS) $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(OPENSSL_DEP)
$(E) "[LD] Linking $@" $(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
ifeq ($(SYSTEM),Darwin) ifeq ($(SYSTEM),Darwin)
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc
else else
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc
$(Q) ln -sf libgrpc++.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++.so.0 $(Q) ln -sf libgrpc++.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++.so.0
$(Q) ln -sf libgrpc++.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++.so $(Q) ln -sf libgrpc++.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++.so
endif endif
@ -3210,17 +3235,21 @@ ifneq ($(NO_DEPS),true)
endif endif
endif endif
$(OBJDIR)/$(CONFIG)/src/cpp/client/secure_credentials.o:
$(OBJDIR)/$(CONFIG)/src/cpp/server/secure_server_credentials.o:
$(OBJDIR)/$(CONFIG)/src/cpp/client/channel.o: $(OBJDIR)/$(CONFIG)/src/cpp/client/channel.o:
$(OBJDIR)/$(CONFIG)/src/cpp/client/channel_arguments.o: $(OBJDIR)/$(CONFIG)/src/cpp/client/channel_arguments.o:
$(OBJDIR)/$(CONFIG)/src/cpp/client/client_context.o: $(OBJDIR)/$(CONFIG)/src/cpp/client/client_context.o:
$(OBJDIR)/$(CONFIG)/src/cpp/client/client_unary_call.o: $(OBJDIR)/$(CONFIG)/src/cpp/client/client_unary_call.o:
$(OBJDIR)/$(CONFIG)/src/cpp/client/create_channel.o: $(OBJDIR)/$(CONFIG)/src/cpp/client/create_channel.o:
$(OBJDIR)/$(CONFIG)/src/cpp/client/credentials.o: $(OBJDIR)/$(CONFIG)/src/cpp/client/credentials.o:
$(OBJDIR)/$(CONFIG)/src/cpp/client/insecure_credentials.o:
$(OBJDIR)/$(CONFIG)/src/cpp/client/internal_stub.o: $(OBJDIR)/$(CONFIG)/src/cpp/client/internal_stub.o:
$(OBJDIR)/$(CONFIG)/src/cpp/common/call.o: $(OBJDIR)/$(CONFIG)/src/cpp/common/call.o:
$(OBJDIR)/$(CONFIG)/src/cpp/common/completion_queue.o: $(OBJDIR)/$(CONFIG)/src/cpp/common/completion_queue.o:
$(OBJDIR)/$(CONFIG)/src/cpp/common/rpc_method.o: $(OBJDIR)/$(CONFIG)/src/cpp/common/rpc_method.o:
$(OBJDIR)/$(CONFIG)/src/cpp/proto/proto_utils.o: $(OBJDIR)/$(CONFIG)/src/cpp/proto/proto_utils.o:
$(OBJDIR)/$(CONFIG)/src/cpp/server/insecure_server_credentials.o:
$(OBJDIR)/$(CONFIG)/src/cpp/server/server.o: $(OBJDIR)/$(CONFIG)/src/cpp/server/server.o:
$(OBJDIR)/$(CONFIG)/src/cpp/server/server_builder.o: $(OBJDIR)/$(CONFIG)/src/cpp/server/server_builder.o:
$(OBJDIR)/$(CONFIG)/src/cpp/server/server_context.o: $(OBJDIR)/$(CONFIG)/src/cpp/server/server_context.o:
@ -3295,6 +3324,125 @@ endif
$(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o: $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc $(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o: $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc
LIBGRPC++_UNSECURE_SRC = \
src/cpp/client/channel.cc \
src/cpp/client/channel_arguments.cc \
src/cpp/client/client_context.cc \
src/cpp/client/client_unary_call.cc \
src/cpp/client/create_channel.cc \
src/cpp/client/credentials.cc \
src/cpp/client/insecure_credentials.cc \
src/cpp/client/internal_stub.cc \
src/cpp/common/call.cc \
src/cpp/common/completion_queue.cc \
src/cpp/common/rpc_method.cc \
src/cpp/proto/proto_utils.cc \
src/cpp/server/insecure_server_credentials.cc \
src/cpp/server/server.cc \
src/cpp/server/server_builder.cc \
src/cpp/server/server_context.cc \
src/cpp/server/server_credentials.cc \
src/cpp/server/thread_pool.cc \
src/cpp/util/status.cc \
src/cpp/util/time.cc \
PUBLIC_HEADERS_CXX += \
include/grpc++/async_unary_call.h \
include/grpc++/channel_arguments.h \
include/grpc++/channel_interface.h \
include/grpc++/client_context.h \
include/grpc++/completion_queue.h \
include/grpc++/config.h \
include/grpc++/create_channel.h \
include/grpc++/credentials.h \
include/grpc++/impl/call.h \
include/grpc++/impl/client_unary_call.h \
include/grpc++/impl/internal_stub.h \
include/grpc++/impl/rpc_method.h \
include/grpc++/impl/rpc_service_method.h \
include/grpc++/impl/service_type.h \
include/grpc++/server.h \
include/grpc++/server_builder.h \
include/grpc++/server_context.h \
include/grpc++/server_credentials.h \
include/grpc++/status.h \
include/grpc++/status_code_enum.h \
include/grpc++/stream.h \
include/grpc++/thread_pool_interface.h \
LIBGRPC++_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_UNSECURE_SRC))))
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)/libgrpc++_unsecure.a: protobuf_dep_error
ifeq ($(SYSTEM),MINGW32)
$(LIBDIR)/$(CONFIG)/grpc++_unsecure.$(SHARED_EXT): protobuf_dep_error
else
$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT): protobuf_dep_error
endif
else
$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_UNSECURE_OBJS)
$(E) "[AR] Creating $@"
$(Q) mkdir -p `dirname $@`
$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
$(Q) $(AR) rcs $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBGRPC++_UNSECURE_OBJS)
ifeq ($(SYSTEM),Darwin)
$(Q) ranlib $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
endif
ifeq ($(SYSTEM),MINGW32)
$(LIBDIR)/$(CONFIG)/grpc++_unsecure.$(SHARED_EXT): $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_DEP)$(LIBDIR)/$(CONFIG)/gpr.$(SHARED_EXT)$(LIBDIR)/$(CONFIG)/grpc_unsecure.$(SHARED_EXT)
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_unsecure.def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure-imp.a -o $(LIBDIR)/$(CONFIG)/grpc++_unsecure.$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr-imp -lgrpc_unsecure-imp
else
$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT): $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT)
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
ifeq ($(SYSTEM),Darwin)
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure
else
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_unsecure.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure
$(Q) ln -sf libgrpc++_unsecure.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.so.0
$(Q) ln -sf libgrpc++_unsecure.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.so
endif
endif
endif
ifneq ($(NO_DEPS),true)
-include $(LIBGRPC++_UNSECURE_OBJS:.o=.dep)
endif
$(OBJDIR)/$(CONFIG)/src/cpp/client/channel.o:
$(OBJDIR)/$(CONFIG)/src/cpp/client/channel_arguments.o:
$(OBJDIR)/$(CONFIG)/src/cpp/client/client_context.o:
$(OBJDIR)/$(CONFIG)/src/cpp/client/client_unary_call.o:
$(OBJDIR)/$(CONFIG)/src/cpp/client/create_channel.o:
$(OBJDIR)/$(CONFIG)/src/cpp/client/credentials.o:
$(OBJDIR)/$(CONFIG)/src/cpp/client/insecure_credentials.o:
$(OBJDIR)/$(CONFIG)/src/cpp/client/internal_stub.o:
$(OBJDIR)/$(CONFIG)/src/cpp/common/call.o:
$(OBJDIR)/$(CONFIG)/src/cpp/common/completion_queue.o:
$(OBJDIR)/$(CONFIG)/src/cpp/common/rpc_method.o:
$(OBJDIR)/$(CONFIG)/src/cpp/proto/proto_utils.o:
$(OBJDIR)/$(CONFIG)/src/cpp/server/insecure_server_credentials.o:
$(OBJDIR)/$(CONFIG)/src/cpp/server/server.o:
$(OBJDIR)/$(CONFIG)/src/cpp/server/server_builder.o:
$(OBJDIR)/$(CONFIG)/src/cpp/server/server_context.o:
$(OBJDIR)/$(CONFIG)/src/cpp/server/server_credentials.o:
$(OBJDIR)/$(CONFIG)/src/cpp/server/thread_pool.o:
$(OBJDIR)/$(CONFIG)/src/cpp/util/status.o:
$(OBJDIR)/$(CONFIG)/src/cpp/util/time.o:
LIBPUBSUB_CLIENT_LIB_SRC = \ LIBPUBSUB_CLIENT_LIB_SRC = \
$(GENDIR)/examples/pubsub/label.pb.cc \ $(GENDIR)/examples/pubsub/label.pb.cc \
$(GENDIR)/examples/pubsub/empty.pb.cc \ $(GENDIR)/examples/pubsub/empty.pb.cc \
@ -3468,15 +3616,15 @@ ifeq ($(SYSTEM),MINGW32)
$(LIBDIR)/$(CONFIG)/grpc_csharp_ext.$(SHARED_EXT): $(LIBGRPC_CSHARP_EXT_OBJS) $(ZLIB_DEP)$(LIBDIR)/$(CONFIG)/gpr.$(SHARED_EXT)$(LIBDIR)/$(CONFIG)/grpc.$(SHARED_EXT) $(OPENSSL_DEP) $(LIBDIR)/$(CONFIG)/grpc_csharp_ext.$(SHARED_EXT): $(LIBGRPC_CSHARP_EXT_OBJS) $(ZLIB_DEP)$(LIBDIR)/$(CONFIG)/gpr.$(SHARED_EXT)$(LIBDIR)/$(CONFIG)/grpc.$(SHARED_EXT) $(OPENSSL_DEP)
$(E) "[LD] Linking $@" $(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_csharp_ext.def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext-imp.a -o $(LIBDIR)/$(CONFIG)/grpc_csharp_ext.$(SHARED_EXT) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS) -lgpr-imp -lgrpc-imp $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_csharp_ext.def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext-imp.a -o $(LIBDIR)/$(CONFIG)/grpc_csharp_ext.$(SHARED_EXT) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) -lgpr-imp -lgrpc-imp
else else
$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT): $(LIBGRPC_CSHARP_EXT_OBJS) $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(OPENSSL_DEP) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT): $(LIBGRPC_CSHARP_EXT_OBJS) $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(OPENSSL_DEP)
$(E) "[LD] Linking $@" $(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
ifeq ($(SYSTEM),Darwin) ifeq ($(SYSTEM),Darwin)
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS) -lgpr -lgrpc $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) -lgpr -lgrpc
else else
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_csharp_ext.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS) -lgpr -lgrpc $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_csharp_ext.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) -lgpr -lgrpc
$(Q) ln -sf libgrpc_csharp_ext.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.so.0 $(Q) ln -sf libgrpc_csharp_ext.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.so.0
$(Q) ln -sf libgrpc_csharp_ext.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.so $(Q) ln -sf libgrpc_csharp_ext.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.so
endif endif

@ -9,6 +9,61 @@
} }
}, },
"filegroups": [ "filegroups": [
{
"name": "grpc++_base",
"public_headers": [
"include/grpc++/async_unary_call.h",
"include/grpc++/channel_arguments.h",
"include/grpc++/channel_interface.h",
"include/grpc++/client_context.h",
"include/grpc++/completion_queue.h",
"include/grpc++/config.h",
"include/grpc++/create_channel.h",
"include/grpc++/credentials.h",
"include/grpc++/impl/call.h",
"include/grpc++/impl/client_unary_call.h",
"include/grpc++/impl/internal_stub.h",
"include/grpc++/impl/rpc_method.h",
"include/grpc++/impl/rpc_service_method.h",
"include/grpc++/impl/service_type.h",
"include/grpc++/server.h",
"include/grpc++/server_builder.h",
"include/grpc++/server_context.h",
"include/grpc++/server_credentials.h",
"include/grpc++/status.h",
"include/grpc++/status_code_enum.h",
"include/grpc++/stream.h",
"include/grpc++/thread_pool_interface.h"
],
"headers": [
"src/cpp/client/channel.h",
"src/cpp/proto/proto_utils.h",
"src/cpp/server/thread_pool.h",
"src/cpp/util/time.h"
],
"src": [
"src/cpp/client/channel.cc",
"src/cpp/client/channel_arguments.cc",
"src/cpp/client/client_context.cc",
"src/cpp/client/client_unary_call.cc",
"src/cpp/client/create_channel.cc",
"src/cpp/client/credentials.cc",
"src/cpp/client/insecure_credentials.cc",
"src/cpp/client/internal_stub.cc",
"src/cpp/common/call.cc",
"src/cpp/common/completion_queue.cc",
"src/cpp/common/rpc_method.cc",
"src/cpp/proto/proto_utils.cc",
"src/cpp/server/insecure_server_credentials.cc",
"src/cpp/server/server.cc",
"src/cpp/server/server_builder.cc",
"src/cpp/server/server_context.cc",
"src/cpp/server/server_credentials.cc",
"src/cpp/server/thread_pool.cc",
"src/cpp/util/status.cc",
"src/cpp/util/time.cc"
]
},
{ {
"name": "grpc_base", "name": "grpc_base",
"public_headers": [ "public_headers": [
@ -80,7 +135,6 @@
"src/core/surface/completion_queue.h", "src/core/surface/completion_queue.h",
"src/core/surface/event_string.h", "src/core/surface/event_string.h",
"src/core/surface/init.h", "src/core/surface/init.h",
"src/core/surface/lame_client.h",
"src/core/surface/server.h", "src/core/surface/server.h",
"src/core/surface/surface_trace.h", "src/core/surface/surface_trace.h",
"src/core/transport/chttp2/bin_encoder.h", "src/core/transport/chttp2/bin_encoder.h",
@ -276,7 +330,7 @@
"src/core/support/time_posix.c", "src/core/support/time_posix.c",
"src/core/support/time_win32.c" "src/core/support/time_win32.c"
], ],
"secure": false, "secure": "no",
"vs_project_guid": "{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}" "vs_project_guid": "{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}"
}, },
{ {
@ -333,7 +387,6 @@
"src/core/security/server_secure_chttp2.c", "src/core/security/server_secure_chttp2.c",
"src/core/surface/init_secure.c", "src/core/surface/init_secure.c",
"src/core/surface/secure_channel_create.c", "src/core/surface/secure_channel_create.c",
"src/core/surface/secure_server_create.c",
"src/core/tsi/fake_transport_security.c", "src/core/tsi/fake_transport_security.c",
"src/core/tsi/ssl_transport_security.c", "src/core/tsi/ssl_transport_security.c",
"src/core/tsi/transport_security.c" "src/core/tsi/transport_security.c"
@ -345,7 +398,7 @@
"filegroups": [ "filegroups": [
"grpc_base" "grpc_base"
], ],
"secure": true, "secure": "yes",
"vs_project_guid": "{29D16885-7228-4C31-81ED-5F9187C7F2A9}" "vs_project_guid": "{29D16885-7228-4C31-81ED-5F9187C7F2A9}"
}, },
{ {
@ -385,68 +438,26 @@
"filegroups": [ "filegroups": [
"grpc_base" "grpc_base"
], ],
"secure": false, "secure": "no",
"vs_project_guid": "{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}" "vs_project_guid": "{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}"
}, },
{ {
"name": "grpc++", "name": "grpc++",
"build": "all", "build": "all",
"language": "c++", "language": "c++",
"public_headers": [
"include/grpc++/async_unary_call.h",
"include/grpc++/channel_arguments.h",
"include/grpc++/channel_interface.h",
"include/grpc++/client_context.h",
"include/grpc++/completion_queue.h",
"include/grpc++/config.h",
"include/grpc++/create_channel.h",
"include/grpc++/credentials.h",
"include/grpc++/impl/call.h",
"include/grpc++/impl/client_unary_call.h",
"include/grpc++/impl/internal_stub.h",
"include/grpc++/impl/rpc_method.h",
"include/grpc++/impl/rpc_service_method.h",
"include/grpc++/impl/service_type.h",
"include/grpc++/server.h",
"include/grpc++/server_builder.h",
"include/grpc++/server_context.h",
"include/grpc++/server_credentials.h",
"include/grpc++/status.h",
"include/grpc++/status_code_enum.h",
"include/grpc++/stream.h",
"include/grpc++/thread_pool_interface.h"
],
"headers": [
"src/cpp/client/channel.h",
"src/cpp/proto/proto_utils.h",
"src/cpp/server/thread_pool.h",
"src/cpp/util/time.h"
],
"src": [ "src": [
"src/cpp/client/channel.cc", "src/cpp/client/secure_credentials.cc",
"src/cpp/client/channel_arguments.cc", "src/cpp/server/secure_server_credentials.cc"
"src/cpp/client/client_context.cc",
"src/cpp/client/client_unary_call.cc",
"src/cpp/client/create_channel.cc",
"src/cpp/client/credentials.cc",
"src/cpp/client/internal_stub.cc",
"src/cpp/common/call.cc",
"src/cpp/common/completion_queue.cc",
"src/cpp/common/rpc_method.cc",
"src/cpp/proto/proto_utils.cc",
"src/cpp/server/server.cc",
"src/cpp/server/server_builder.cc",
"src/cpp/server/server_context.cc",
"src/cpp/server/server_credentials.cc",
"src/cpp/server/thread_pool.cc",
"src/cpp/util/status.cc",
"src/cpp/util/time.cc"
], ],
"deps": [ "deps": [
"gpr", "gpr",
"grpc" "grpc"
], ],
"secure": true, "baselib": true,
"filegroups": [
"grpc++_base"
],
"secure": "check",
"vs_project_guid": "{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}" "vs_project_guid": "{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}"
}, },
{ {
@ -460,6 +471,20 @@
"test/cpp/util/create_test_channel.cc" "test/cpp/util/create_test_channel.cc"
] ]
}, },
{
"name": "grpc++_unsecure",
"build": "all",
"language": "c++",
"deps": [
"gpr",
"grpc_unsecure"
],
"baselib": true,
"filegroups": [
"grpc++_base"
],
"secure": "no"
},
{ {
"name": "pubsub_client_lib", "name": "pubsub_client_lib",
"build": "private", "build": "private",
@ -1686,7 +1711,7 @@
"src/compiler/cpp_plugin.cc" "src/compiler/cpp_plugin.cc"
], ],
"deps": [], "deps": [],
"secure": false "secure": "no"
}, },
{ {
"name": "grpc_python_plugin", "name": "grpc_python_plugin",
@ -1700,7 +1725,7 @@
"src/compiler/python_plugin.cc" "src/compiler/python_plugin.cc"
], ],
"deps": [], "deps": [],
"secure": false "secure": "no"
}, },
{ {
"name": "grpc_ruby_plugin", "name": "grpc_ruby_plugin",
@ -1711,7 +1736,7 @@
"src/compiler/ruby_plugin.cc" "src/compiler/ruby_plugin.cc"
], ],
"deps": [], "deps": [],
"secure": false "secure": "no"
}, },
{ {
"name": "interop_client", "name": "interop_client",

@ -79,8 +79,7 @@ int main(int argc, char** argv) {
ss << FLAGS_server_host << ":" << FLAGS_server_port; ss << FLAGS_server_host << ":" << FLAGS_server_port;
std::unique_ptr<grpc::Credentials> creds = std::unique_ptr<grpc::Credentials> creds = grpc::GoogleDefaultCredentials();
grpc::CredentialsFactory::GoogleDefaultCredentials();
std::shared_ptr<grpc::ChannelInterface> channel = std::shared_ptr<grpc::ChannelInterface> channel =
grpc::CreateChannel(ss.str(), creds, grpc::ChannelArguments()); grpc::CreateChannel(ss.str(), creds, grpc::ChannelArguments());

@ -40,6 +40,7 @@
#include <grpc++/server.h> #include <grpc++/server.h>
#include <grpc++/server_builder.h> #include <grpc++/server_builder.h>
#include <grpc++/server_context.h> #include <grpc++/server_context.h>
#include <grpc++/server_credentials.h>
#include <grpc++/status.h> #include <grpc++/status.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
@ -106,12 +107,11 @@ class PublisherTest : public ::testing::Test {
int port = grpc_pick_unused_port_or_die(); int port = grpc_pick_unused_port_or_die();
server_address_ << "localhost:" << port; server_address_ << "localhost:" << port;
ServerBuilder builder; ServerBuilder builder;
builder.AddPort(server_address_.str()); builder.AddPort(server_address_.str(), grpc::InsecureServerCredentials());
builder.RegisterService(&service_); builder.RegisterService(&service_);
server_ = builder.BuildAndStart(); server_ = builder.BuildAndStart();
channel_ = channel_ = CreateChannel(server_address_.str(), grpc::InsecureCredentials(), ChannelArguments());
CreateChannelDeprecated(server_address_.str(), ChannelArguments());
publisher_.reset(new grpc::examples::pubsub::Publisher(channel_)); publisher_.reset(new grpc::examples::pubsub::Publisher(channel_));
} }

@ -40,6 +40,7 @@
#include <grpc++/server.h> #include <grpc++/server.h>
#include <grpc++/server_builder.h> #include <grpc++/server_builder.h>
#include <grpc++/server_context.h> #include <grpc++/server_context.h>
#include <grpc++/server_credentials.h>
#include <grpc++/status.h> #include <grpc++/status.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
@ -104,12 +105,11 @@ class SubscriberTest : public ::testing::Test {
int port = grpc_pick_unused_port_or_die(); int port = grpc_pick_unused_port_or_die();
server_address_ << "localhost:" << port; server_address_ << "localhost:" << port;
ServerBuilder builder; ServerBuilder builder;
builder.AddPort(server_address_.str()); builder.AddPort(server_address_.str(), grpc::InsecureServerCredentials());
builder.RegisterService(&service_); builder.RegisterService(&service_);
server_ = builder.BuildAndStart(); server_ = builder.BuildAndStart();
channel_ = channel_ = CreateChannel(server_address_.str(), grpc::InsecureCredentials(), ChannelArguments());
CreateChannelDeprecated(server_address_.str(), ChannelArguments());
subscriber_.reset(new grpc::examples::pubsub::Subscriber(channel_)); subscriber_.reset(new grpc::examples::pubsub::Subscriber(channel_));
} }

@ -92,7 +92,7 @@ class ServerAsyncResponseWriter GRPC_FINAL
explicit ServerAsyncResponseWriter(ServerContext* ctx) explicit ServerAsyncResponseWriter(ServerContext* ctx)
: call_(nullptr, nullptr, nullptr), ctx_(ctx) {} : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
void SendInitialMetadata(void* tag) { void SendInitialMetadata(void* tag) GRPC_OVERRIDE {
GPR_ASSERT(!ctx_->sent_initial_metadata_); GPR_ASSERT(!ctx_->sent_initial_metadata_);
meta_buf_.Reset(tag); meta_buf_.Reset(tag);

@ -62,6 +62,9 @@ class ChannelArguments {
void SetInt(const grpc::string& key, int value); void SetInt(const grpc::string& key, int value);
void SetString(const grpc::string& key, const grpc::string& value); void SetString(const grpc::string& key, const grpc::string& value);
// Populates given channel_args with args_, does not take ownership.
void SetChannelArgs(grpc_channel_args* channel_args) const;
private: private:
friend class Channel; friend class Channel;
friend class testing::ChannelArgumentsTest; friend class testing::ChannelArgumentsTest;
@ -73,9 +76,6 @@ class ChannelArguments {
// Returns empty string when it is not set. // Returns empty string when it is not set.
grpc::string GetSslTargetNameOverride() const; grpc::string GetSslTargetNameOverride() const;
// Populates given channel_args with args_, does not take ownership.
void SetChannelArgs(grpc_channel_args* channel_args) const;
std::vector<grpc_arg> args_; std::vector<grpc_arg> args_;
std::list<grpc::string> strings_; std::list<grpc::string> strings_;
}; };

@ -43,11 +43,6 @@ namespace grpc {
class ChannelArguments; class ChannelArguments;
class ChannelInterface; class ChannelInterface;
// Deprecation warning: This function will soon be deleted
// (See pull request #711)
std::shared_ptr<ChannelInterface> CreateChannelDeprecated(
const grpc::string& target, const ChannelArguments& args);
// If creds does not hold an object or is invalid, a lame channel is returned. // If creds does not hold an object or is invalid, a lame channel is returned.
std::shared_ptr<ChannelInterface> CreateChannel( std::shared_ptr<ChannelInterface> CreateChannel(
const grpc::string& target, const std::unique_ptr<Credentials>& creds, const grpc::string& target, const std::unique_ptr<Credentials>& creds,

@ -39,29 +39,29 @@
#include <grpc++/config.h> #include <grpc++/config.h>
struct grpc_credentials;
namespace grpc { namespace grpc {
class ChannelArguments;
class ChannelInterface;
class SecureCredentials;
// grpc_credentials wrapper class. Typical use in C++ applications is limited class Credentials {
// to creating an instance using CredentialsFactory, and passing it down
// during channel construction.
class Credentials GRPC_FINAL {
public: public:
~Credentials(); virtual ~Credentials();
// TODO(abhikumar): Specify a plugin API here to be implemented by protected:
// credentials that do not have a corresponding implementation in C. friend std::unique_ptr<Credentials> CompositeCredentials(
const std::unique_ptr<Credentials>& creds1,
const std::unique_ptr<Credentials>& creds2);
private: virtual SecureCredentials* AsSecureCredentials() = 0;
explicit Credentials(grpc_credentials*);
grpc_credentials* GetRawCreds();
friend class Channel; private:
friend class CredentialsFactory; friend std::shared_ptr<ChannelInterface> CreateChannel(
const grpc::string& target, const std::unique_ptr<Credentials>& creds,
const ChannelArguments& args);
grpc_credentials* creds_; virtual std::shared_ptr<ChannelInterface> CreateChannel(
const grpc::string& target, const ChannelArguments& args) = 0;
}; };
// Options used to build SslCredentials // Options used to build SslCredentials
@ -79,57 +79,44 @@ struct SslCredentialsOptions {
grpc::string pem_cert_chain; grpc::string pem_cert_chain;
}; };
// Factory for building different types of Credentials // Factories for building different types of Credentials
// The methods may return empty unique_ptr when credentials cannot be created. // The functions may return empty unique_ptr when credentials cannot be created.
// If a Credentials pointer is returned, it can still be invalid when used to // If a Credentials pointer is returned, it can still be invalid when used to
// create a channel. A lame channel will be created then and all rpcs will // create a channel. A lame channel will be created then and all rpcs will
// fail on it. // fail on it.
class CredentialsFactory {
public: // Builds credentials with reasonable defaults.
// Builds google credentials with reasonable defaults. std::unique_ptr<Credentials> GoogleDefaultCredentials();
// WARNING: Do NOT use this credentials to connect to a non-google service as
// this could result in an oauth2 token leak. // Builds SSL Credentials given SSL specific options
static std::unique_ptr<Credentials> GoogleDefaultCredentials(); std::unique_ptr<Credentials> SslCredentials(
const SslCredentialsOptions& options);
// Builds SSL Credentials given SSL specific options
static std::unique_ptr<Credentials> SslCredentials( // Builds credentials for use when running in GCE
const SslCredentialsOptions& options); std::unique_ptr<Credentials> ComputeEngineCredentials();
// Builds credentials for use when running in GCE // Builds service account credentials.
// WARNING: Do NOT use this credentials to connect to a non-google service as // json_key is the JSON key string containing the client's private key.
// this could result in an oauth2 token leak. // scope is a space-delimited list of the requested permissions.
static std::unique_ptr<Credentials> ComputeEngineCredentials(); // token_lifetime is the lifetime of each token acquired through this service
// account credentials. It should be positive and should not exceed
// Builds service account credentials. // grpc_max_auth_token_lifetime or will be cropped to this value.
// WARNING: Do NOT use this credentials to connect to a non-google service as std::unique_ptr<Credentials> ServiceAccountCredentials(
// this could result in an oauth2 token leak. const grpc::string& json_key, const grpc::string& scope,
// json_key is the JSON key string containing the client's private key. std::chrono::seconds token_lifetime);
// scope is a space-delimited list of the requested permissions.
// token_lifetime is the lifetime of each token acquired through this service // Builds IAM credentials.
// account credentials. It should be positive and should not exceed std::unique_ptr<Credentials> IAMCredentials(
// grpc_max_auth_token_lifetime or will be cropped to this value. const grpc::string& authorization_token,
static std::unique_ptr<Credentials> ServiceAccountCredentials( const grpc::string& authority_selector);
const grpc::string& json_key, const grpc::string& scope,
std::chrono::seconds token_lifetime); // Combines two credentials objects into a composite credentials
std::unique_ptr<Credentials> CompositeCredentials(
// Builds JWT credentials. const std::unique_ptr<Credentials>& creds1,
// json_key is the JSON key string containing the client's private key. const std::unique_ptr<Credentials>& creds2);
// token_lifetime is the lifetime of each Json Web Token (JWT) created with
// this credentials. It should not exceed grpc_max_auth_token_lifetime or // Credentials for an unencrypted, unauthenticated channel
// will be cropped to this value. std::unique_ptr<Credentials> InsecureCredentials();
static std::unique_ptr<Credentials> JWTCredentials(
const grpc::string& json_key, std::chrono::seconds token_lifetime);
// Builds IAM credentials.
static std::unique_ptr<Credentials> IAMCredentials(
const grpc::string& authorization_token,
const grpc::string& authority_selector);
// Combines two credentials objects into a composite credentials
static std::unique_ptr<Credentials> CompositeCredentials(
const std::unique_ptr<Credentials>& creds1,
const std::unique_ptr<Credentials>& creds2);
};
} // namespace grpc } // namespace grpc

@ -75,15 +75,14 @@ class Server GRPC_FINAL : private CallHook,
class AsyncRequest; class AsyncRequest;
// ServerBuilder use only // ServerBuilder use only
Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned, Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned);
ServerCredentials* creds); Server() = delete;
Server();
// Register a service. This call does not take ownership of the service. // Register a service. This call does not take ownership of the service.
// The service must exist for the lifetime of the Server instance. // The service must exist for the lifetime of the Server instance.
bool RegisterService(RpcService* service); bool RegisterService(RpcService* service);
bool RegisterAsyncService(AsynchronousService* service); bool RegisterAsyncService(AsynchronousService* service);
// Add a listening port. Can be called multiple times. // Add a listening port. Can be called multiple times.
int AddPort(const grpc::string& addr); int AddPort(const grpc::string& addr, ServerCredentials* creds);
// Start the server. // Start the server.
bool Start(); bool Start();
@ -97,7 +96,7 @@ class Server GRPC_FINAL : private CallHook,
void RequestAsyncCall(void* registered_method, ServerContext* context, void RequestAsyncCall(void* registered_method, ServerContext* context,
grpc::protobuf::Message* request, grpc::protobuf::Message* request,
ServerAsyncStreamingInterface* stream, ServerAsyncStreamingInterface* stream,
CompletionQueue* cq, void* tag); CompletionQueue* cq, void* tag) GRPC_OVERRIDE;
// Completion queue. // Completion queue.
CompletionQueue cq_; CompletionQueue cq_;
@ -113,13 +112,11 @@ class Server GRPC_FINAL : private CallHook,
std::list<SyncRequest> sync_methods_; std::list<SyncRequest> sync_methods_;
// Pointer to the c grpc server. // Pointer to the c grpc server.
grpc_server* server_; grpc_server* const server_;
ThreadPoolInterface* thread_pool_; ThreadPoolInterface* thread_pool_;
// Whether the thread pool is created and owned by the server. // Whether the thread pool is created and owned by the server.
bool thread_pool_owned_; bool thread_pool_owned_;
// Whether the server is created with credentials.
bool secure_;
}; };
} // namespace grpc } // namespace grpc

@ -65,11 +65,9 @@ class ServerBuilder {
void RegisterAsyncService(AsynchronousService* service); void RegisterAsyncService(AsynchronousService* service);
// Add a listening port. Can be called multiple times. // Add a listening port. Can be called multiple times.
void AddPort(const grpc::string& addr); void AddPort(const grpc::string& addr,
std::shared_ptr<ServerCredentials> creds,
// Set a ServerCredentials. Can only be called once. int* selected_port = nullptr);
// TODO(yangg) move this to be part of AddPort
void SetCredentials(const std::shared_ptr<ServerCredentials>& creds);
// Set the thread pool used for running appliation rpc handlers. // Set the thread pool used for running appliation rpc handlers.
// Does not take ownership. // Does not take ownership.
@ -79,9 +77,15 @@ class ServerBuilder {
std::unique_ptr<Server> BuildAndStart(); std::unique_ptr<Server> BuildAndStart();
private: private:
struct Port {
grpc::string addr;
std::shared_ptr<ServerCredentials> creds;
int* selected_port;
};
std::vector<RpcService*> services_; std::vector<RpcService*> services_;
std::vector<AsynchronousService*> async_services_; std::vector<AsynchronousService*> async_services_;
std::vector<grpc::string> ports_; std::vector<Port> ports_;
std::shared_ptr<ServerCredentials> creds_; std::shared_ptr<ServerCredentials> creds_;
ThreadPoolInterface* thread_pool_; ThreadPoolInterface* thread_pool_;
}; };

@ -39,24 +39,21 @@
#include <grpc++/config.h> #include <grpc++/config.h>
struct grpc_server_credentials; struct grpc_server;
namespace grpc { namespace grpc {
class Server;
// grpc_server_credentials wrapper class. // grpc_server_credentials wrapper class.
class ServerCredentials GRPC_FINAL { class ServerCredentials {
public: public:
~ServerCredentials(); virtual ~ServerCredentials();
private: private:
explicit ServerCredentials(grpc_server_credentials* c_creds); friend class ::grpc::Server;
grpc_server_credentials* GetRawCreds(); virtual int AddPortToServer(const grpc::string& addr,
grpc_server* server) = 0;
friend class ServerCredentialsFactory;
friend class Server;
grpc_server_credentials* creds_;
}; };
// Options to create ServerCredentials with SSL // Options to create ServerCredentials with SSL
@ -69,13 +66,11 @@ struct SslServerCredentialsOptions {
std::vector<PemKeyCertPair> pem_key_cert_pairs; std::vector<PemKeyCertPair> pem_key_cert_pairs;
}; };
// Factory for building different types of ServerCredentials // Builds SSL ServerCredentials given SSL specific options
class ServerCredentialsFactory { std::shared_ptr<ServerCredentials> SslServerCredentials(
public: const SslServerCredentialsOptions& options);
// Builds SSL ServerCredentials given SSL specific options
static std::shared_ptr<ServerCredentials> SslCredentials( std::shared_ptr<ServerCredentials> InsecureServerCredentials();
const SslServerCredentialsOptions& options);
};
} // namespace grpc } // namespace grpc

@ -436,6 +436,9 @@ grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
grpc_channel *grpc_channel_create(const char *target, grpc_channel *grpc_channel_create(const char *target,
const grpc_channel_args *args); const grpc_channel_args *args);
/* Create a lame client: this client fails every operation attempted on it. */
grpc_channel *grpc_lame_client_channel_create(void);
/* Close and destroy a grpc channel */ /* Close and destroy a grpc channel */
void grpc_channel_destroy(grpc_channel *channel); void grpc_channel_destroy(grpc_channel *channel);

@ -169,17 +169,12 @@ grpc_server_credentials *grpc_fake_transport_security_server_credentials_create(
/* --- Secure server creation. --- */ /* --- Secure server creation. --- */
/* Creates a secure server using the passed-in server credentials. */
grpc_server *grpc_secure_server_create(grpc_server_credentials *creds,
grpc_completion_queue *cq,
const grpc_channel_args *args);
/* Add a HTTP2 over an encrypted link over tcp listener. /* Add a HTTP2 over an encrypted link over tcp listener.
Server must have been created with grpc_secure_server_create. Server must have been created with grpc_secure_server_create.
Returns bound port number on success, 0 on failure. Returns bound port number on success, 0 on failure.
REQUIRES: server not started */ REQUIRES: server not started */
int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr); int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
grpc_server_credentials *creds);
#ifdef __cplusplus #ifdef __cplusplus
} }

@ -66,7 +66,7 @@ static void backup_poller(void *p) {
gpr_timespec next_poll = gpr_time_add(last_poll, delta); gpr_timespec next_poll = gpr_time_add(last_poll, delta);
grpc_pollset_work(&g_backup_pollset, gpr_time_add(gpr_now(), gpr_time_from_seconds(1))); grpc_pollset_work(&g_backup_pollset, gpr_time_add(gpr_now(), gpr_time_from_seconds(1)));
gpr_mu_unlock(&g_backup_pollset.mu); gpr_mu_unlock(&g_backup_pollset.mu);
/*gpr_sleep_until(next_poll);*/ gpr_sleep_until(next_poll);
gpr_mu_lock(&g_backup_pollset.mu); gpr_mu_lock(&g_backup_pollset.mu);
last_poll = next_poll; last_poll = next_poll;
} }

@ -109,7 +109,7 @@ grpc_resolved_addresses *grpc_blocking_resolve_address(
}; };
int i; int i;
for (i = 0; i < (int)(sizeof(svc) / sizeof(svc[0])); i++) { for (i = 0; i < (int)(sizeof(svc) / sizeof(svc[0])); i++) {
if (!strcmp(port, svc[i][0])) { if (strcmp(port, svc[i][0]) == 0) {
s = getaddrinfo(host, svc[i][1], &hints, &result); s = getaddrinfo(host, svc[i][1], &hints, &result);
break; break;
} }

@ -348,7 +348,7 @@ static void jwt_get_request_metadata(grpc_credentials *creds,
{ {
gpr_mu_lock(&c->cache_mu); gpr_mu_lock(&c->cache_mu);
if (c->cached.service_url != NULL && if (c->cached.service_url != NULL &&
!strcmp(c->cached.service_url, service_url) && strcmp(c->cached.service_url, service_url) == 0 &&
c->cached.jwt_md != NULL && c->cached.jwt_md != NULL &&
(gpr_time_cmp(gpr_time_sub(c->cached.jwt_expiration, gpr_now()), (gpr_time_cmp(gpr_time_sub(c->cached.jwt_expiration, gpr_now()),
refresh_threshold) > 0)) { refresh_threshold) > 0)) {
@ -957,7 +957,7 @@ static grpc_credentials_array get_creds_array(grpc_credentials **creds_addr) {
grpc_credentials *creds = *creds_addr; grpc_credentials *creds = *creds_addr;
result.creds_array = creds_addr; result.creds_array = creds_addr;
result.num_creds = 1; result.num_creds = 1;
if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE)) { if (strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE) == 0) {
result = *grpc_composite_credentials_get_credentials(creds); result = *grpc_composite_credentials_get_credentials(creds);
} }
return result; return result;
@ -995,7 +995,7 @@ const grpc_credentials_array *grpc_composite_credentials_get_credentials(
grpc_credentials *creds) { grpc_credentials *creds) {
const grpc_composite_credentials *c = const grpc_composite_credentials *c =
(const grpc_composite_credentials *)creds; (const grpc_composite_credentials *)creds;
GPR_ASSERT(!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE)); GPR_ASSERT(strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE) == 0);
return &c->inner; return &c->inner;
} }
@ -1003,14 +1003,14 @@ grpc_credentials *grpc_credentials_contains_type(
grpc_credentials *creds, const char *type, grpc_credentials *creds, const char *type,
grpc_credentials **composite_creds) { grpc_credentials **composite_creds) {
size_t i; size_t i;
if (!strcmp(creds->type, type)) { if (strcmp(creds->type, type) == 0) {
if (composite_creds != NULL) *composite_creds = NULL; if (composite_creds != NULL) *composite_creds = NULL;
return creds; return creds;
} else if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE)) { } else if (strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE) == 0) {
const grpc_credentials_array *inner_creds_array = const grpc_credentials_array *inner_creds_array =
grpc_composite_credentials_get_credentials(creds); grpc_composite_credentials_get_credentials(creds);
for (i = 0; i < inner_creds_array->num_creds; i++) { for (i = 0; i < inner_creds_array->num_creds; i++) {
if (!strcmp(type, inner_creds_array->creds_array[i]->type)) { if (strcmp(type, inner_creds_array->creds_array[i]->type) == 0) {
if (composite_creds != NULL) *composite_creds = creds; if (composite_creds != NULL) *composite_creds = creds;
return inner_creds_array->creds_array[i]; return inner_creds_array->creds_array[i];
} }

@ -33,9 +33,9 @@
#include <string.h> #include <string.h>
#include <grpc/grpc.h>
#include "src/core/security/credentials.h" #include "src/core/security/credentials.h"
#include "src/core/security/security_context.h" #include "src/core/security/security_context.h"
#include "src/core/surface/lame_client.h"
#include <grpc/support/alloc.h> #include <grpc/support/alloc.h>
#include <grpc/support/log.h> #include <grpc/support/log.h>
#include <grpc/support/useful.h> #include <grpc/support/useful.h>
@ -50,31 +50,3 @@ grpc_channel *grpc_secure_channel_create(grpc_credentials *creds,
return grpc_secure_channel_create_with_factories( return grpc_secure_channel_create_with_factories(
factories, GPR_ARRAY_SIZE(factories), creds, target, args); factories, GPR_ARRAY_SIZE(factories), creds, target, args);
} }
grpc_server *grpc_secure_server_create(grpc_server_credentials *creds,
grpc_completion_queue *cq,
const grpc_channel_args *args) {
grpc_security_status status = GRPC_SECURITY_ERROR;
grpc_security_context *ctx = NULL;
grpc_server *server = NULL;
if (creds == NULL) return NULL; /* TODO(ctiller): Return lame server. */
if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_SSL)) {
status = grpc_ssl_server_security_context_create(
grpc_ssl_server_credentials_get_config(creds), &ctx);
} else if (!strcmp(creds->type,
GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY)) {
ctx = grpc_fake_server_security_context_create();
status = GRPC_SECURITY_OK;
}
if (status != GRPC_SECURITY_OK) {
gpr_log(GPR_ERROR,
"Unable to create secure server with credentials of type %s.",
creds->type);
return NULL; /* TODO(ctiller): Return lame server. */
}
server = grpc_secure_server_create_internal(cq, args, ctx);
grpc_security_context_unref(ctx);
return server;
}

@ -75,8 +75,8 @@ static void on_compute_engine_detection_http_response(
size_t i; size_t i;
for (i = 0; i < response->hdr_count; i++) { for (i = 0; i < response->hdr_count; i++) {
grpc_httpcli_header *header = &response->hdrs[i]; grpc_httpcli_header *header = &response->hdrs[i];
if (!strcmp(header->key, "Metadata-Flavor") && if (strcmp(header->key, "Metadata-Flavor") == 0 &&
!strcmp(header->value, "Google")) { strcmp(header->value, "Google") == 0) {
detector->success = 1; detector->success = 1;
break; break;
} }

@ -257,7 +257,7 @@ static char *dot_concat_and_free_strings(char *str1, char *str2) {
} }
const EVP_MD *openssl_digest_from_algorithm(const char *algorithm) { const EVP_MD *openssl_digest_from_algorithm(const char *algorithm) {
if (!strcmp(algorithm, GRPC_JWT_RSA_SHA256_ALGORITHM)) { if (strcmp(algorithm, GRPC_JWT_RSA_SHA256_ALGORITHM) == 0) {
return EVP_sha256(); return EVP_sha256();
} else { } else {
gpr_log(GPR_ERROR, "Unknown algorithm %s.", algorithm); gpr_log(GPR_ERROR, "Unknown algorithm %s.", algorithm);

@ -42,7 +42,6 @@
#include "src/core/support/env.h" #include "src/core/support/env.h"
#include "src/core/support/file.h" #include "src/core/support/file.h"
#include "src/core/support/string.h" #include "src/core/support/string.h"
#include "src/core/surface/lame_client.h"
#include "src/core/transport/chttp2/alpn.h" #include "src/core/transport/chttp2/alpn.h"
#include <grpc/support/alloc.h> #include <grpc/support/alloc.h>
@ -422,7 +421,7 @@ static grpc_security_status ssl_channel_check_call_host(
/* If the target name was overridden, then the original target_name was /* If the target name was overridden, then the original target_name was
'checked' transitively during the previous peer check at the end of the 'checked' transitively during the previous peer check at the end of the
handshake. */ handshake. */
if (c->overridden_target_name != NULL && !strcmp(host, c->target_name)) { if (c->overridden_target_name != NULL && strcmp(host, c->target_name) == 0) {
return GRPC_SECURITY_OK; return GRPC_SECURITY_OK;
} else { } else {
return GRPC_SECURITY_ERROR; return GRPC_SECURITY_ERROR;
@ -611,7 +610,7 @@ grpc_channel *grpc_ssl_channel_create(grpc_credentials *ssl_creds,
for (i = 0; args && i < args->num_args; i++) { for (i = 0; args && i < args->num_args; i++) {
grpc_arg *arg = &args->args[i]; grpc_arg *arg = &args->args[i];
if (!strcmp(arg->key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG) && if (strcmp(arg->key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG) == 0 &&
arg->type == GRPC_ARG_STRING) { arg->type == GRPC_ARG_STRING) {
overridden_target_name = arg->value.string; overridden_target_name = arg->value.string;
break; break;

@ -33,6 +33,8 @@
#include <grpc/grpc.h> #include <grpc/grpc.h>
#include <string.h>
#include "src/core/channel/http_filter.h" #include "src/core/channel/http_filter.h"
#include "src/core/channel/http_server_filter.h" #include "src/core/channel/http_server_filter.h"
#include "src/core/iomgr/endpoint.h" #include "src/core/iomgr/endpoint.h"
@ -50,6 +52,7 @@
typedef struct grpc_server_secure_state { typedef struct grpc_server_secure_state {
grpc_server *server; grpc_server *server;
grpc_tcp_server *tcp; grpc_tcp_server *tcp;
grpc_security_context *ctx;
int is_shutdown; int is_shutdown;
gpr_mu mu; gpr_mu mu;
gpr_refcount refcount; gpr_refcount refcount;
@ -61,6 +64,7 @@ static void state_ref(grpc_server_secure_state *state) {
static void state_unref(grpc_server_secure_state *state) { static void state_unref(grpc_server_secure_state *state) {
if (gpr_unref(&state->refcount)) { if (gpr_unref(&state->refcount)) {
grpc_security_context_unref(state->ctx);
gpr_free(state); gpr_free(state);
} }
} }
@ -99,15 +103,10 @@ static void on_secure_transport_setup_done(void *statep,
static void on_accept(void *statep, grpc_endpoint *tcp) { static void on_accept(void *statep, grpc_endpoint *tcp) {
grpc_server_secure_state *state = statep; grpc_server_secure_state *state = statep;
const grpc_channel_args *args = grpc_server_get_channel_args(state->server);
grpc_security_context *ctx = grpc_find_security_context_in_args(args);
GPR_ASSERT(ctx);
state_ref(state); state_ref(state);
grpc_setup_secure_transport(ctx, tcp, on_secure_transport_setup_done, state); grpc_setup_secure_transport(state->ctx, tcp, on_secure_transport_setup_done, state);
} }
/* Note: the following code is the same with server_chttp2.c */
/* Server callback: start listening on our ports */ /* Server callback: start listening on our ports */
static void start(grpc_server *server, void *statep, grpc_pollset **pollsets, static void start(grpc_server *server, void *statep, grpc_pollset **pollsets,
size_t pollset_count) { size_t pollset_count) {
@ -126,7 +125,7 @@ static void destroy(grpc_server *server, void *statep) {
state_unref(state); state_unref(state);
} }
int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr) { int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr, grpc_server_credentials *creds) {
grpc_resolved_addresses *resolved = NULL; grpc_resolved_addresses *resolved = NULL;
grpc_tcp_server *tcp = NULL; grpc_tcp_server *tcp = NULL;
grpc_server_secure_state *state = NULL; grpc_server_secure_state *state = NULL;
@ -134,7 +133,29 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr) {
unsigned count = 0; unsigned count = 0;
int port_num = -1; int port_num = -1;
int port_temp; int port_temp;
grpc_security_status status = GRPC_SECURITY_ERROR;
grpc_security_context *ctx = NULL;
/* create security context */
if (creds == NULL) goto error;
if (strcmp(creds->type, GRPC_CREDENTIALS_TYPE_SSL) == 0) {
status = grpc_ssl_server_security_context_create(
grpc_ssl_server_credentials_get_config(creds), &ctx);
} else if (strcmp(creds->type,
GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY) == 0) {
ctx = grpc_fake_server_security_context_create();
status = GRPC_SECURITY_OK;
}
if (status != GRPC_SECURITY_OK) {
gpr_log(GPR_ERROR,
"Unable to create secure server with credentials of type %s.",
creds->type);
goto error;
}
/* resolve address */
resolved = grpc_blocking_resolve_address(addr, "https"); resolved = grpc_blocking_resolve_address(addr, "https");
if (!resolved) { if (!resolved) {
goto error; goto error;
@ -173,6 +194,7 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr) {
state = gpr_malloc(sizeof(*state)); state = gpr_malloc(sizeof(*state));
state->server = server; state->server = server;
state->tcp = tcp; state->tcp = tcp;
state->ctx = ctx;
state->is_shutdown = 0; state->is_shutdown = 0;
gpr_mu_init(&state->mu); gpr_mu_init(&state->mu);
gpr_ref_init(&state->refcount, 1); gpr_ref_init(&state->refcount, 1);
@ -184,11 +206,17 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr) {
/* Error path: cleanup and return */ /* Error path: cleanup and return */
error: error:
if (ctx) {
grpc_security_context_unref(ctx);
}
if (resolved) { if (resolved) {
grpc_resolved_addresses_destroy(resolved); grpc_resolved_addresses_destroy(resolved);
} }
if (tcp) { if (tcp) {
grpc_tcp_server_destroy(tcp); grpc_tcp_server_destroy(tcp);
} }
if (state) {
gpr_free(state);
}
return 0; return 0;
} }

@ -31,7 +31,7 @@
* *
*/ */
#include "src/core/surface/lame_client.h" #include <grpc/grpc.h>
#include <string.h> #include <string.h>

@ -102,8 +102,8 @@ static tsi_result tsi_fake_handshake_message_from_string(
const char* msg_string, tsi_fake_handshake_message* msg) { const char* msg_string, tsi_fake_handshake_message* msg) {
int i; int i;
for (i = 0; i < TSI_FAKE_HANDSHAKE_MESSAGE_MAX; i++) { for (i = 0; i < TSI_FAKE_HANDSHAKE_MESSAGE_MAX; i++) {
if (!strncmp(msg_string, tsi_fake_handshake_message_strings[i], if (strncmp(msg_string, tsi_fake_handshake_message_strings[i],
strlen(tsi_fake_handshake_message_strings[i]))) { strlen(tsi_fake_handshake_message_strings[i])) == 0) {
*msg = i; *msg = i;
return TSI_OK; return TSI_OK;
} }

@ -1083,7 +1083,8 @@ static int does_entry_match_name(const char* entry, size_t entry_length,
if (entry_length == 0) return 0; if (entry_length == 0) return 0;
} }
if ((name_length == entry_length) && !strncmp(name, entry, entry_length)) { if ((name_length == entry_length) &&
strncmp(name, entry, entry_length) == 0) {
return 1; /* Perfect match. */ return 1; /* Perfect match. */
} }
if (entry[0] != '*') return 0; if (entry[0] != '*') return 0;
@ -1110,7 +1111,7 @@ static int does_entry_match_name(const char* entry, size_t entry_length,
name_subdomain_length--; name_subdomain_length--;
} }
return ((entry_length > 0) && (name_subdomain_length == entry_length) && return ((entry_length > 0) && (name_subdomain_length == entry_length) &&
!strncmp(entry, name_subdomain, entry_length)); strncmp(entry, name_subdomain, entry_length) == 0);
} }
static int ssl_server_handshaker_factory_servername_callback(SSL* ssl, int* ap, static int ssl_server_handshaker_factory_servername_callback(SSL* ssl, int* ap,

@ -208,7 +208,7 @@ const tsi_peer_property* tsi_peer_get_property_by_name(const tsi_peer* self,
return property; return property;
} }
if (name != NULL && property->name != NULL && if (name != NULL && property->name != NULL &&
!strcmp(property->name, name)) { strcmp(property->name, name) == 0) {
return property; return property;
} }
} }

@ -53,43 +53,23 @@
namespace grpc { namespace grpc {
Channel::Channel(const grpc::string &target, const ChannelArguments &args) Channel::Channel(const grpc::string& target, grpc_channel* channel)
: target_(target) { : target_(target), c_channel_(channel) {}
grpc_channel_args channel_args;
args.SetChannelArgs(&channel_args);
c_channel_ = grpc_channel_create(
target_.c_str(), channel_args.num_args > 0 ? &channel_args : nullptr);
}
Channel::Channel(const grpc::string &target,
const std::unique_ptr<Credentials> &creds,
const ChannelArguments &args)
: target_(args.GetSslTargetNameOverride().empty()
? target
: args.GetSslTargetNameOverride()) {
grpc_channel_args channel_args;
args.SetChannelArgs(&channel_args);
grpc_credentials *c_creds = creds ? creds->GetRawCreds() : nullptr;
c_channel_ = grpc_secure_channel_create(
c_creds, target.c_str(),
channel_args.num_args > 0 ? &channel_args : nullptr);
}
Channel::~Channel() { grpc_channel_destroy(c_channel_); } Channel::~Channel() { grpc_channel_destroy(c_channel_); }
Call Channel::CreateCall(const RpcMethod &method, ClientContext *context, Call Channel::CreateCall(const RpcMethod& method, ClientContext* context,
CompletionQueue *cq) { CompletionQueue* cq) {
auto c_call = auto c_call = grpc_channel_create_call(c_channel_, cq->cq(), method.name(),
grpc_channel_create_call( context->authority().empty()
c_channel_, cq->cq(), method.name(), ? target_.c_str()
context->authority().empty() ? target_.c_str() : context->authority().c_str(),
: context->authority().c_str(), context->RawDeadline());
context->RawDeadline());
context->set_call(c_call); context->set_call(c_call);
return Call(c_call, this, cq); return Call(c_call, this, cq);
} }
void Channel::PerformOpsOnCall(CallOpBuffer *buf, Call *call) { void Channel::PerformOpsOnCall(CallOpBuffer* buf, Call* call) {
static const size_t MAX_OPS = 8; static const size_t MAX_OPS = 8;
size_t nops = MAX_OPS; size_t nops = MAX_OPS;
grpc_op ops[MAX_OPS]; grpc_op ops[MAX_OPS];

@ -51,10 +51,7 @@ class StreamContextInterface;
class Channel GRPC_FINAL : public ChannelInterface { class Channel GRPC_FINAL : public ChannelInterface {
public: public:
Channel(const grpc::string &target, const ChannelArguments &args); Channel(const grpc::string &target, grpc_channel *c_channel);
Channel(const grpc::string &target, const std::unique_ptr<Credentials> &creds,
const ChannelArguments &args);
~Channel() GRPC_OVERRIDE; ~Channel() GRPC_OVERRIDE;
virtual Call CreateCall(const RpcMethod &method, ClientContext *context, virtual Call CreateCall(const RpcMethod &method, ClientContext *context,
@ -63,7 +60,7 @@ class Channel GRPC_FINAL : public ChannelInterface {
private: private:
const grpc::string target_; const grpc::string target_;
grpc_channel *c_channel_; // owned grpc_channel *const c_channel_; // owned
}; };
} // namespace grpc } // namespace grpc

@ -40,14 +40,10 @@
namespace grpc { namespace grpc {
class ChannelArguments; class ChannelArguments;
std::shared_ptr<ChannelInterface> CreateChannelDeprecated(
const grpc::string &target, const ChannelArguments &args) {
return std::shared_ptr<ChannelInterface>(new Channel(target, args));
}
std::shared_ptr<ChannelInterface> CreateChannel( std::shared_ptr<ChannelInterface> CreateChannel(
const grpc::string &target, const std::unique_ptr<Credentials> &creds, const grpc::string &target, const std::unique_ptr<Credentials> &creds,
const ChannelArguments &args) { const ChannelArguments &args) {
return std::shared_ptr<ChannelInterface>(new Channel(target, creds, args)); return creds ? creds->CreateChannel(target, args) :
std::shared_ptr<ChannelInterface>(new Channel(target, grpc_lame_client_channel_create()));
} }
} // namespace grpc } // namespace grpc

@ -31,98 +31,10 @@
* *
*/ */
#include <string>
#include <grpc/grpc_security.h>
#include <grpc/support/log.h>
#include <grpc++/credentials.h> #include <grpc++/credentials.h>
namespace grpc { namespace grpc {
Credentials::Credentials(grpc_credentials *c_creds) : creds_(c_creds) {} Credentials::~Credentials() {}
Credentials::~Credentials() { grpc_credentials_release(creds_); }
grpc_credentials *Credentials::GetRawCreds() { return creds_; }
std::unique_ptr<Credentials> CredentialsFactory::GoogleDefaultCredentials() {
grpc_credentials *c_creds = grpc_google_default_credentials_create();
std::unique_ptr<Credentials> cpp_creds(
c_creds == nullptr ? nullptr : new Credentials(c_creds));
return cpp_creds;
}
// Builds SSL Credentials given SSL specific options
std::unique_ptr<Credentials> CredentialsFactory::SslCredentials(
const SslCredentialsOptions &options) {
grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {
options.pem_private_key.c_str(), options.pem_cert_chain.c_str()};
grpc_credentials *c_creds = grpc_ssl_credentials_create(
options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(),
options.pem_private_key.empty() ? nullptr : &pem_key_cert_pair);
std::unique_ptr<Credentials> cpp_creds(
c_creds == nullptr ? nullptr : new Credentials(c_creds));
return cpp_creds;
}
// Builds credentials for use when running in GCE
std::unique_ptr<Credentials> CredentialsFactory::ComputeEngineCredentials() {
grpc_credentials *c_creds = grpc_compute_engine_credentials_create();
std::unique_ptr<Credentials> cpp_creds(
c_creds == nullptr ? nullptr : new Credentials(c_creds));
return cpp_creds;
}
// Builds service account credentials.
std::unique_ptr<Credentials> CredentialsFactory::ServiceAccountCredentials(
const grpc::string &json_key, const grpc::string &scope,
std::chrono::seconds token_lifetime) {
gpr_timespec lifetime = gpr_time_from_seconds(
token_lifetime.count() > 0 ? token_lifetime.count() : 0);
grpc_credentials *c_creds = grpc_service_account_credentials_create(
json_key.c_str(), scope.c_str(), lifetime);
std::unique_ptr<Credentials> cpp_creds(
c_creds == nullptr ? nullptr : new Credentials(c_creds));
return cpp_creds;
}
// Builds JWT credentials.
std::unique_ptr<Credentials> CredentialsFactory::JWTCredentials(
const grpc::string &json_key, std::chrono::seconds token_lifetime) {
gpr_timespec lifetime = gpr_time_from_seconds(
token_lifetime.count() > 0 ? token_lifetime.count() : 0);
grpc_credentials *c_creds =
grpc_jwt_credentials_create(json_key.c_str(), lifetime);
std::unique_ptr<Credentials> cpp_creds(
c_creds == nullptr ? nullptr : new Credentials(c_creds));
return cpp_creds;
}
// Builds IAM credentials.
std::unique_ptr<Credentials> CredentialsFactory::IAMCredentials(
const grpc::string &authorization_token,
const grpc::string &authority_selector) {
grpc_credentials *c_creds = grpc_iam_credentials_create(
authorization_token.c_str(), authority_selector.c_str());
std::unique_ptr<Credentials> cpp_creds(
c_creds == nullptr ? nullptr : new Credentials(c_creds));
return cpp_creds;
}
// Combines two credentials objects into a composite credentials.
std::unique_ptr<Credentials> CredentialsFactory::CompositeCredentials(
const std::unique_ptr<Credentials> &creds1,
const std::unique_ptr<Credentials> &creds2) {
// Note that we are not saving unique_ptrs to the two credentials
// passed in here. This is OK because the underlying C objects (i.e.,
// creds1 and creds2) into grpc_composite_credentials_create will see their
// refcounts incremented.
grpc_credentials *c_creds = grpc_composite_credentials_create(
creds1->GetRawCreds(), creds2->GetRawCreds());
std::unique_ptr<Credentials> cpp_creds(
c_creds == nullptr ? nullptr : new Credentials(c_creds));
return cpp_creds;
}
} // namespace grpc } // namespace grpc

@ -31,27 +31,35 @@
* *
*/ */
#include <grpc/grpc.h> #include <string>
#include "src/core/channel/channel_args.h" #include <grpc/grpc.h>
#include "src/core/security/security_context.h"
#include "src/core/surface/completion_queue.h"
#include "src/core/surface/server.h"
#include <grpc/support/log.h> #include <grpc/support/log.h>
grpc_server *grpc_secure_server_create_internal( #include <grpc++/channel_arguments.h>
grpc_completion_queue *cq, const grpc_channel_args *args, #include <grpc++/config.h>
grpc_security_context *context) { #include <grpc++/credentials.h>
grpc_arg context_arg; #include "src/cpp/client/channel.h"
grpc_channel_args *args_copy;
grpc_server *server; namespace grpc {
if (grpc_find_security_context_in_args(args) != NULL) {
gpr_log(GPR_ERROR, "Cannot set security context in channel args."); namespace {
class InsecureCredentialsImpl GRPC_FINAL : public Credentials {
public:
std::shared_ptr<grpc::ChannelInterface> CreateChannel(
const string& target, const grpc::ChannelArguments& args) GRPC_OVERRIDE {
grpc_channel_args channel_args;
args.SetChannelArgs(&channel_args);
return std::shared_ptr<ChannelInterface>(new Channel(
target, grpc_channel_create(target.c_str(), &channel_args)));
} }
context_arg = grpc_security_context_to_arg(context); SecureCredentials* AsSecureCredentials() { return nullptr; }
args_copy = grpc_channel_args_copy_and_add(args, &context_arg); };
server = grpc_server_create_from_filters(cq, NULL, 0, args_copy); } // namespace
grpc_channel_args_destroy(args_copy);
return server; std::unique_ptr<Credentials> InsecureCredentials() {
return std::unique_ptr<Credentials>(new InsecureCredentialsImpl());
} }
} // namespace grpc

@ -0,0 +1,131 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <string>
#include <grpc/grpc_security.h>
#include <grpc/support/log.h>
#include <grpc++/channel_arguments.h>
#include <grpc++/config.h>
#include <grpc++/credentials.h>
#include "src/cpp/client/channel.h"
namespace grpc {
class SecureCredentials GRPC_FINAL : public Credentials {
public:
explicit SecureCredentials(grpc_credentials* c_creds) : c_creds_(c_creds) {}
~SecureCredentials() GRPC_OVERRIDE { grpc_credentials_release(c_creds_); }
grpc_credentials* GetRawCreds() { return c_creds_; }
std::shared_ptr<grpc::ChannelInterface> CreateChannel(
const string& target, const grpc::ChannelArguments& args) GRPC_OVERRIDE {
grpc_channel_args channel_args;
args.SetChannelArgs(&channel_args);
return std::shared_ptr<ChannelInterface>(new Channel(
target,
grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args)));
}
SecureCredentials* AsSecureCredentials() { return this; }
private:
grpc_credentials* const c_creds_;
};
namespace {
std::unique_ptr<Credentials> WrapCredentials(grpc_credentials* creds) {
return creds == nullptr
? nullptr
: std::unique_ptr<Credentials>(new SecureCredentials(creds));
}
} // namespace
std::unique_ptr<Credentials> GoogleDefaultCredentials() {
return WrapCredentials(grpc_google_default_credentials_create());
}
// Builds SSL Credentials given SSL specific options
std::unique_ptr<Credentials> SslCredentials(
const SslCredentialsOptions& options) {
grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {
options.pem_private_key.c_str(), options.pem_cert_chain.c_str()};
grpc_credentials* c_creds = grpc_ssl_credentials_create(
options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(),
options.pem_private_key.empty() ? nullptr : &pem_key_cert_pair);
return WrapCredentials(c_creds);
}
// Builds credentials for use when running in GCE
std::unique_ptr<Credentials> ComputeEngineCredentials() {
return WrapCredentials(grpc_compute_engine_credentials_create());
}
// Builds service account credentials.
std::unique_ptr<Credentials> ServiceAccountCredentials(
const grpc::string& json_key, const grpc::string& scope,
std::chrono::seconds token_lifetime) {
gpr_timespec lifetime = gpr_time_from_seconds(
token_lifetime.count() > 0 ? token_lifetime.count() : 0);
return WrapCredentials(grpc_service_account_credentials_create(
json_key.c_str(), scope.c_str(), lifetime));
}
// Builds IAM credentials.
std::unique_ptr<Credentials> IAMCredentials(
const grpc::string& authorization_token,
const grpc::string& authority_selector) {
return WrapCredentials(grpc_iam_credentials_create(
authorization_token.c_str(), authority_selector.c_str()));
}
// Combines two credentials objects into a composite credentials.
std::unique_ptr<Credentials> CompositeCredentials(
const std::unique_ptr<Credentials>& creds1,
const std::unique_ptr<Credentials>& creds2) {
// Note that we are not saving unique_ptrs to the two credentials
// passed in here. This is OK because the underlying C objects (i.e.,
// creds1 and creds2) into grpc_composite_credentials_create will see their
// refcounts incremented.
SecureCredentials* s1 = creds1->AsSecureCredentials();
SecureCredentials* s2 = creds2->AsSecureCredentials();
if (s1 && s2) {
return WrapCredentials(grpc_composite_credentials_create(
s1->GetRawCreds(), s2->GetRawCreds()));
}
return nullptr;
}
} // namespace grpc

@ -31,12 +31,22 @@
* *
*/ */
#ifndef GRPC_INTERNAL_CORE_SURFACE_LAME_CLIENT_H #include <grpc/grpc_security.h>
#define GRPC_INTERNAL_CORE_SURFACE_LAME_CLIENT_H #include <grpc++/server_credentials.h>
#include <grpc/grpc.h> namespace grpc {
namespace {
class InsecureServerCredentialsImpl GRPC_FINAL : public ServerCredentials {
public:
int AddPortToServer(const grpc::string& addr,
grpc_server* server) GRPC_OVERRIDE {
return grpc_server_add_http2_port(server, addr.c_str());
}
};
} // namespace
/* Create a lame client: this client fails every operation attempted on it. */ std::shared_ptr<ServerCredentials> InsecureServerCredentials() {
grpc_channel *grpc_lame_client_channel_create(void); return std::shared_ptr<ServerCredentials>(new InsecureServerCredentialsImpl());
}
#endif /* GRPC_INTERNAL_CORE_SURFACE_LAME_CLIENT_H */ } // namespace grpc

@ -0,0 +1,71 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <grpc/grpc_security.h>
#include <grpc++/server_credentials.h>
namespace grpc {
namespace {
class SecureServerCredentials GRPC_FINAL : public ServerCredentials {
public:
explicit SecureServerCredentials(grpc_server_credentials* creds) : creds_(creds) {}
~SecureServerCredentials() GRPC_OVERRIDE {
grpc_server_credentials_release(creds_);
}
int AddPortToServer(const grpc::string& addr,
grpc_server* server) GRPC_OVERRIDE {
return grpc_server_add_secure_http2_port(server, addr.c_str(), creds_);
}
private:
grpc_server_credentials* const creds_;
};
} // namespace
std::shared_ptr<ServerCredentials> SslServerCredentials(
const SslServerCredentialsOptions &options) {
std::vector<grpc_ssl_pem_key_cert_pair> pem_key_cert_pairs;
for (const auto &key_cert_pair : options.pem_key_cert_pairs) {
pem_key_cert_pairs.push_back(
{key_cert_pair.private_key.c_str(), key_cert_pair.cert_chain.c_str()});
}
grpc_server_credentials *c_creds = grpc_ssl_server_credentials_create(
options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(),
&pem_key_cert_pairs[0], pem_key_cert_pairs.size());
return std::shared_ptr<ServerCredentials>(new SecureServerCredentials(c_creds));
}
} // namespace grpc

@ -170,26 +170,13 @@ class Server::SyncRequest GRPC_FINAL : public CompletionQueueTag {
grpc_completion_queue* cq_; grpc_completion_queue* cq_;
}; };
Server::Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned, Server::Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned)
ServerCredentials* creds)
: started_(false), : started_(false),
shutdown_(false), shutdown_(false),
num_running_cb_(0), num_running_cb_(0),
server_(grpc_server_create(cq_.cq(), nullptr)),
thread_pool_(thread_pool), thread_pool_(thread_pool),
thread_pool_owned_(thread_pool_owned), thread_pool_owned_(thread_pool_owned) {}
secure_(creds != nullptr) {
if (creds) {
server_ =
grpc_secure_server_create(creds->GetRawCreds(), cq_.cq(), nullptr);
} else {
server_ = grpc_server_create(cq_.cq(), nullptr);
}
}
Server::Server() {
// Should not be called.
GPR_ASSERT(false);
}
Server::~Server() { Server::~Server() {
std::unique_lock<std::mutex> lock(mu_); std::unique_lock<std::mutex> lock(mu_);
@ -239,13 +226,9 @@ bool Server::RegisterAsyncService(AsynchronousService* service) {
return true; return true;
} }
int Server::AddPort(const grpc::string& addr) { int Server::AddPort(const grpc::string& addr, ServerCredentials* creds) {
GPR_ASSERT(!started_); GPR_ASSERT(!started_);
if (secure_) { return creds->AddPortToServer(addr, server_);
return grpc_server_add_secure_http2_port(server_, addr.c_str());
} else {
return grpc_server_add_http2_port(server_, addr.c_str());
}
} }
bool Server::Start() { bool Server::Start() {

@ -51,14 +51,10 @@ void ServerBuilder::RegisterAsyncService(AsynchronousService* service) {
async_services_.push_back(service); async_services_.push_back(service);
} }
void ServerBuilder::AddPort(const grpc::string& addr) { void ServerBuilder::AddPort(const grpc::string& addr,
ports_.push_back(addr); std::shared_ptr<ServerCredentials> creds,
} int* selected_port) {
ports_.push_back(Port{addr, creds, selected_port});
void ServerBuilder::SetCredentials(
const std::shared_ptr<ServerCredentials>& creds) {
GPR_ASSERT(!creds_);
creds_ = creds;
} }
void ServerBuilder::SetThreadPool(ThreadPoolInterface* thread_pool) { void ServerBuilder::SetThreadPool(ThreadPoolInterface* thread_pool) {
@ -71,14 +67,13 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
gpr_log(GPR_ERROR, "Mixing async and sync services is unsupported for now"); gpr_log(GPR_ERROR, "Mixing async and sync services is unsupported for now");
return nullptr; return nullptr;
} }
if (!thread_pool_ && services_.size()) { if (!thread_pool_ && !services_.empty()) {
int cores = gpr_cpu_num_cores(); int cores = gpr_cpu_num_cores();
if (!cores) cores = 4; if (!cores) cores = 4;
thread_pool_ = new ThreadPool(cores); thread_pool_ = new ThreadPool(cores);
thread_pool_owned = true; thread_pool_owned = true;
} }
std::unique_ptr<Server> server( std::unique_ptr<Server> server(new Server(thread_pool_, thread_pool_owned));
new Server(thread_pool_, thread_pool_owned, creds_.get()));
for (auto* service : services_) { for (auto* service : services_) {
if (!server->RegisterService(service)) { if (!server->RegisterService(service)) {
return nullptr; return nullptr;
@ -90,8 +85,10 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
} }
} }
for (auto& port : ports_) { for (auto& port : ports_) {
if (!server->AddPort(port)) { int r = server->AddPort(port.addr, port.creds.get());
return nullptr; if (!r) return nullptr;
if (port.selected_port != nullptr) {
*port.selected_port = r;
} }
} }
if (!server->Start()) { if (!server->Start()) {

@ -37,26 +37,6 @@
namespace grpc { namespace grpc {
ServerCredentials::ServerCredentials(grpc_server_credentials *c_creds) ServerCredentials::~ServerCredentials() {}
: creds_(c_creds) {}
ServerCredentials::~ServerCredentials() {
grpc_server_credentials_release(creds_);
}
grpc_server_credentials *ServerCredentials::GetRawCreds() { return creds_; }
std::shared_ptr<ServerCredentials> ServerCredentialsFactory::SslCredentials(
const SslServerCredentialsOptions &options) {
std::vector<grpc_ssl_pem_key_cert_pair> pem_key_cert_pairs;
for (const auto &key_cert_pair : options.pem_key_cert_pairs) {
pem_key_cert_pairs.push_back(
{key_cert_pair.private_key.c_str(), key_cert_pair.cert_chain.c_str()});
}
grpc_server_credentials *c_creds = grpc_ssl_server_credentials_create(
options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(),
&pem_key_cert_pairs[0], pem_key_cert_pairs.size());
return std::shared_ptr<ServerCredentials>(new ServerCredentials(c_creds));
}
} // namespace grpc } // namespace grpc

@ -165,19 +165,7 @@ NAN_METHOD(Server::New) {
if (args[0]->IsUndefined()) { if (args[0]->IsUndefined()) {
wrapped_server = grpc_server_create(queue, NULL); wrapped_server = grpc_server_create(queue, NULL);
} else if (args[0]->IsObject()) { } else if (args[0]->IsObject()) {
grpc_server_credentials *creds = NULL; Handle<Object> args_hash(args[0]->ToObject());
Handle<Object> args_hash(args[0]->ToObject()->Clone());
if (args_hash->HasOwnProperty(NanNew("credentials"))) {
Handle<Value> creds_value = args_hash->Get(NanNew("credentials"));
if (!ServerCredentials::HasInstance(creds_value)) {
return NanThrowTypeError(
"credentials arg must be a ServerCredentials object");
}
ServerCredentials *creds_object =
ObjectWrap::Unwrap<ServerCredentials>(creds_value->ToObject());
creds = creds_object->GetWrappedServerCredentials();
args_hash->Delete(NanNew("credentials"));
}
Handle<Array> keys(args_hash->GetOwnPropertyNames()); Handle<Array> keys(args_hash->GetOwnPropertyNames());
grpc_channel_args channel_args; grpc_channel_args channel_args;
channel_args.num_args = keys->Length(); channel_args.num_args = keys->Length();
@ -204,11 +192,7 @@ NAN_METHOD(Server::New) {
return NanThrowTypeError("Arg values must be strings"); return NanThrowTypeError("Arg values must be strings");
} }
} }
if (creds == NULL) { wrapped_server = grpc_server_create(queue, &channel_args);
wrapped_server = grpc_server_create(queue, &channel_args);
} else {
wrapped_server = grpc_secure_server_create(creds, queue, &channel_args);
}
free(channel_args.args); free(channel_args.args);
} else { } else {
return NanThrowTypeError("Server expects an object"); return NanThrowTypeError("Server expects an object");
@ -259,11 +243,19 @@ NAN_METHOD(Server::AddSecureHttp2Port) {
"addSecureHttp2Port can only be called on a Server"); "addSecureHttp2Port can only be called on a Server");
} }
if (!args[0]->IsString()) { if (!args[0]->IsString()) {
return NanThrowTypeError("addSecureHttp2Port's argument must be a String"); return NanThrowTypeError(
"addSecureHttp2Port's first argument must be a String");
}
if (!ServerCredentials::HasInstance(args[1])) {
return NanThrowTypeError(
"addSecureHttp2Port's second argument must be ServerCredentials");
} }
Server *server = ObjectWrap::Unwrap<Server>(args.This()); Server *server = ObjectWrap::Unwrap<Server>(args.This());
ServerCredentials *creds = ObjectWrap::Unwrap<ServerCredentials>(
args[1]->ToObject());
NanReturnValue(NanNew<Number>(grpc_server_add_secure_http2_port( NanReturnValue(NanNew<Number>(grpc_server_add_secure_http2_port(
server->wrapped_server, *NanUtf8String(args[0])))); server->wrapped_server, *NanUtf8String(args[0]),
creds->GetWrappedServerCredentials())));
} }
NAN_METHOD(Server::Start) { NAN_METHOD(Server::Start) {

@ -165,16 +165,16 @@ function handleHalfDuplex(call) {
function getServer(port, tls) { function getServer(port, tls) {
// TODO(mlumish): enable TLS functionality // TODO(mlumish): enable TLS functionality
var options = {}; var options = {};
var server_creds = null;
if (tls) { if (tls) {
var key_path = path.join(__dirname, '../test/data/server1.key'); var key_path = path.join(__dirname, '../test/data/server1.key');
var pem_path = path.join(__dirname, '../test/data/server1.pem'); var pem_path = path.join(__dirname, '../test/data/server1.pem');
var key_data = fs.readFileSync(key_path); var key_data = fs.readFileSync(key_path);
var pem_data = fs.readFileSync(pem_path); var pem_data = fs.readFileSync(pem_path);
var server_creds = grpc.ServerCredentials.createSsl(null, server_creds = grpc.ServerCredentials.createSsl(null,
key_data, key_data,
pem_data); pem_data);
options.credentials = server_creds;
} }
var server = new Server({ var server = new Server({
'grpc.testing.TestService' : { 'grpc.testing.TestService' : {
@ -186,7 +186,7 @@ function getServer(port, tls) {
halfDuplexCall: handleHalfDuplex halfDuplexCall: handleHalfDuplex
} }
}, null, options); }, null, options);
var port_num = server.bind('0.0.0.0:' + port, tls); var port_num = server.bind('0.0.0.0:' + port, server_creds);
return {server: server, port: port_num}; return {server: server, port: port_num};
} }

@ -517,14 +517,15 @@ Server.prototype.register = function(name, handler, serialize, deserialize,
}; };
/** /**
* Binds the server to the given port, with SSL enabled if secure is specified * Binds the server to the given port, with SSL enabled if creds is given
* @param {string} port The port that the server should bind on, in the format * @param {string} port The port that the server should bind on, in the format
* "address:port" * "address:port"
* @param {boolean=} secure Whether the server should open a secure port * @param {boolean=} creds Server credential object to be used for SSL. Pass
* nothing for an insecure port
*/ */
Server.prototype.bind = function(port, secure) { Server.prototype.bind = function(port, creds) {
if (secure) { if (creds) {
return this._server.addSecureHttp2Port(port); return this._server.addSecureHttp2Port(port, creds);
} else { } else {
return this._server.addHttp2Port(port); return this._server.addHttp2Port(port);
} }
@ -604,14 +605,14 @@ function makeServerConstructor(services) {
} }
/** /**
* Binds the server to the given port, with SSL enabled if secure is specified * Binds the server to the given port, with SSL enabled if creds is supplied
* @param {string} port The port that the server should bind on, in the format * @param {string} port The port that the server should bind on, in the format
* "address:port" * "address:port"
* @param {boolean=} secure Whether the server should open a secure port * @param {boolean=} creds Credentials to use for SSL
* @return {SurfaceServer} this * @return {SurfaceServer} this
*/ */
SurfaceServer.prototype.bind = function(port, secure) { SurfaceServer.prototype.bind = function(port, creds) {
return this.inner_server.bind(port, secure); return this.inner_server.bind(port, creds);
}; };
/** /**

@ -96,9 +96,6 @@ PHP_METHOD(Server, __construct) {
zval *queue_obj; zval *queue_obj;
zval *args_array = NULL; zval *args_array = NULL;
grpc_channel_args args; grpc_channel_args args;
HashTable *array_hash;
zval **creds_obj = NULL;
wrapped_grpc_server_credentials *creds = NULL;
/* "O|a" == 1 Object, 1 optional array */ /* "O|a" == 1 Object, 1 optional array */
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|a", &queue_obj, if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|a", &queue_obj,
grpc_ce_completion_queue, &args_array) == FAILURE) { grpc_ce_completion_queue, &args_array) == FAILURE) {
@ -114,28 +111,8 @@ PHP_METHOD(Server, __construct) {
if (args_array == NULL) { if (args_array == NULL) {
server->wrapped = grpc_server_create(queue->wrapped, NULL); server->wrapped = grpc_server_create(queue->wrapped, NULL);
} else { } else {
array_hash = Z_ARRVAL_P(args_array);
if (zend_hash_find(array_hash, "credentials", sizeof("credentials"),
(void **)&creds_obj) == SUCCESS) {
if (zend_get_class_entry(*creds_obj TSRMLS_CC) !=
grpc_ce_server_credentials) {
zend_throw_exception(spl_ce_InvalidArgumentException,
"credentials must be a ServerCredentials object",
1 TSRMLS_CC);
return;
}
creds = (wrapped_grpc_server_credentials *)zend_object_store_get_object(
*creds_obj TSRMLS_CC);
zend_hash_del(array_hash, "credentials", sizeof("credentials"));
}
php_grpc_read_args_array(args_array, &args); php_grpc_read_args_array(args_array, &args);
if (creds == NULL) { server->wrapped = grpc_server_create(queue->wrapped, &args);
server->wrapped = grpc_server_create(queue->wrapped, &args);
} else {
gpr_log(GPR_DEBUG, "Initialized secure server");
server->wrapped =
grpc_secure_server_create(creds->wrapped, queue->wrapped, &args);
}
efree(args.args); efree(args.args);
} }
} }
@ -187,14 +164,21 @@ PHP_METHOD(Server, add_secure_http2_port) {
(wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC); (wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC);
const char *addr; const char *addr;
int addr_len; int addr_len;
/* "s" == 1 string */ zval *creds_obj;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &addr, &addr_len) == /* "sO" == 1 string, 1 object */
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &addr, &addr_len,
&creds_obj, grpc_ce_server_credentials) ==
FAILURE) { FAILURE) {
zend_throw_exception(spl_ce_InvalidArgumentException, zend_throw_exception(
"add_http2_port expects a string", 1 TSRMLS_CC); spl_ce_InvalidArgumentException,
"add_http2_port expects a string and a ServerCredentials", 1 TSRMLS_CC);
return; return;
} }
RETURN_LONG(grpc_server_add_secure_http2_port(server->wrapped, addr)); wrapped_grpc_server_credentials *creds =
(wrapped_grpc_server_credentials *)zend_object_store_get_object(
creds_obj TSRMLS_CC);
RETURN_LONG(grpc_server_add_secure_http2_port(server->wrapped, addr,
creds->wrapped));
} }
/** /**

@ -41,9 +41,9 @@ class SecureEndToEndTest extends PHPUnit_Framework_TestCase{
null, null,
file_get_contents(dirname(__FILE__) . '/../data/server1.key'), file_get_contents(dirname(__FILE__) . '/../data/server1.key'),
file_get_contents(dirname(__FILE__) . '/../data/server1.pem')); file_get_contents(dirname(__FILE__) . '/../data/server1.pem'));
$this->server = new Grpc\Server($this->server_queue, $this->server = new Grpc\Server($this->server_queue);
['credentials' => $server_credentials]); $port = $this->server->add_secure_http2_port('0.0.0.0:0',
$port = $this->server->add_secure_http2_port('0.0.0.0:0'); $server_credentials);
$this->channel = new Grpc\Channel( $this->channel = new Grpc\Channel(
'localhost:' . $port, 'localhost:' . $port,
[ [

@ -46,7 +46,7 @@ Installing
- Install gRPC Python's dependencies - Install gRPC Python's dependencies
``` ```
$ pip install -r requirements.txt $ pip install -r src/python/requirements.txt
``` ```
- Install gRPC Python - Install gRPC Python

@ -0,0 +1,56 @@
# Copyright 2015, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Insecure client-server interoperability as a unit test."""
import unittest
from grpc.early_adopter import implementations
from interop import _interop_test_case
from interop import methods
class InsecureInteropTest(
_interop_test_case.InteropTestCase,
unittest.TestCase):
def setUp(self):
self.server = implementations.insecure_server(methods.SERVER_METHODS, 0)
self.server.start()
port = self.server.port()
self.stub = implementations.insecure_stub(
methods.CLIENT_METHODS, 'localhost', port)
def tearDown(self):
self.server.stop()
if __name__ == '__main__':
unittest.main()

@ -0,0 +1,55 @@
# Copyright 2015, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Common code for unit tests of the interoperability test code."""
from interop import methods
class InteropTestCase(object):
"""Unit test methods.
This class must be mixed in with unittest.TestCase and a class that defines
setUp and tearDown methods that manage a stub attribute.
"""
def testEmptyUnary(self):
methods.TestCase.EMPTY_UNARY.test_interoperability(self.stub)
def testLargeUnary(self):
methods.TestCase.LARGE_UNARY.test_interoperability(self.stub)
def testServerStreaming(self):
methods.TestCase.SERVER_STREAMING.test_interoperability(self.stub)
def testClientStreaming(self):
methods.TestCase.CLIENT_STREAMING.test_interoperability(self.stub)
def testPingPong(self):
methods.TestCase.PING_PONG.test_interoperability(self.stub)

@ -0,0 +1,63 @@
# Copyright 2015, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Secure client-server interoperability as a unit test."""
import unittest
from grpc.early_adopter import implementations
from interop import _interop_test_case
from interop import methods
from interop import resources
_SERVER_HOST_OVERRIDE = 'foo.test.google.fr'
class SecureInteropTest(
_interop_test_case.InteropTestCase,
unittest.TestCase):
def setUp(self):
self.server = implementations.secure_server(
methods.SERVER_METHODS, 0, resources.private_key(),
resources.certificate_chain())
self.server.start()
port = self.server.port()
self.stub = implementations.secure_stub(
methods.CLIENT_METHODS, 'localhost', port,
resources.test_root_certificates(), None, None,
server_host_override=_SERVER_HOST_OVERRIDE)
def tearDown(self):
self.server.stop()
if __name__ == '__main__':
unittest.main()

@ -65,21 +65,30 @@ def _stub(args):
root_certificates = resources.test_root_certificates() root_certificates = resources.test_root_certificates()
else: else:
root_certificates = resources.prod_root_certificates() root_certificates = resources.prod_root_certificates()
# TODO(nathaniel): server host override.
stub = implementations.secure_stub( stub = implementations.secure_stub(
methods.CLIENT_METHODS, args.server_host, args.server_port, methods.CLIENT_METHODS, args.server_host, args.server_port,
root_certificates, None, None) root_certificates, None, None,
server_host_override=args.server_host_override)
else: else:
stub = implementations.insecure_stub( stub = implementations.insecure_stub(
methods.CLIENT_METHODS, args.server_host, args.server_port) methods.CLIENT_METHODS, args.server_host, args.server_port)
return stub return stub
def _test_case_from_arg(test_case_arg):
for test_case in methods.TestCase:
if test_case_arg == test_case.value:
return test_case
else:
raise ValueError('No test case "%s"!' % test_case_arg)
def _test_interoperability(): def _test_interoperability():
args = _args() args = _args()
stub = _stub(args) stub = _stub(args)
methods.test_interoperability(args.test_case, stub) test_case = _test_case_from_arg(args.test_case)
test_case.test_interoperability(stub)
if __name__ == '__main__': if __name__ == '__main__':

@ -29,6 +29,7 @@
"""Implementations of interoperability test methods.""" """Implementations of interoperability test methods."""
import enum
import threading import threading
from grpc.early_adopter import utilities from grpc.early_adopter import utilities
@ -265,16 +266,24 @@ def _ping_pong(stub):
pipe.close() pipe.close()
def test_interoperability(test_case, stub): @enum.unique
if test_case == 'empty_unary': class TestCase(enum.Enum):
_empty_unary(stub) EMPTY_UNARY = 'empty_unary'
elif test_case == 'large_unary': LARGE_UNARY = 'large_unary'
_large_unary(stub) SERVER_STREAMING = 'server_streaming'
elif test_case == 'server_streaming': CLIENT_STREAMING = 'client_streaming'
_server_streaming(stub) PING_PONG = 'ping_pong'
elif test_case == 'client_streaming':
_client_streaming(stub) def test_interoperability(self, stub):
elif test_case == 'ping_pong': if self is TestCase.EMPTY_UNARY:
_ping_pong(stub) _empty_unary(stub)
else: elif self is TestCase.LARGE_UNARY:
raise NotImplementedError('Test case "%s" not implemented!') _large_unary(stub)
elif self is TestCase.SERVER_STREAMING:
_server_streaming(stub)
elif self is TestCase.CLIENT_STREAMING:
_client_streaming(stub)
elif self is TestCase.PING_PONG:
_ping_pong(stub)
else:
raise NotImplementedError('Test case "%s" not implemented!' % self.name)

@ -70,7 +70,8 @@ class _CTest(unittest.TestCase):
def testChannel(self): def testChannel(self):
_c.init() _c.init()
channel = _c.Channel('test host:12345', None) channel = _c.Channel(
'test host:12345', None, server_host_override='ignored')
del channel del channel
_c.shut_down() _c.shut_down()
@ -92,7 +93,7 @@ class _CTest(unittest.TestCase):
_c.init() _c.init()
completion_queue = _c.CompletionQueue() completion_queue = _c.CompletionQueue()
server = _c.Server(completion_queue, None) server = _c.Server(completion_queue)
server.add_http2_addr('[::]:0') server.add_http2_addr('[::]:0')
server.start() server.start()
server.stop() server.stop()
@ -102,7 +103,7 @@ class _CTest(unittest.TestCase):
service_tag = object() service_tag = object()
completion_queue = _c.CompletionQueue() completion_queue = _c.CompletionQueue()
server = _c.Server(completion_queue, None) server = _c.Server(completion_queue)
server.add_http2_addr('[::]:0') server.add_http2_addr('[::]:0')
server.start() server.start()
server.service(service_tag) server.service(service_tag)
@ -119,7 +120,7 @@ class _CTest(unittest.TestCase):
del completion_queue del completion_queue
completion_queue = _c.CompletionQueue() completion_queue = _c.CompletionQueue()
server = _c.Server(completion_queue, None) server = _c.Server(completion_queue)
server.add_http2_addr('[::]:0') server.add_http2_addr('[::]:0')
server.start() server.start()
thread = threading.Thread(target=completion_queue.get, args=(_FUTURE,)) thread = threading.Thread(target=completion_queue.get, args=(_FUTURE,))

@ -42,19 +42,35 @@
static int pygrpc_channel_init(Channel *self, PyObject *args, PyObject *kwds) { static int pygrpc_channel_init(Channel *self, PyObject *args, PyObject *kwds) {
const char *hostport; const char *hostport;
PyObject *client_credentials; PyObject *client_credentials;
static char *kwlist[] = {"hostport", "client_credentials", NULL}; char *server_host_override = NULL;
static char *kwlist[] = {"hostport", "client_credentials",
"server_host_override", NULL};
grpc_arg server_host_override_arg;
grpc_channel_args channel_args;
if (!(PyArg_ParseTupleAndKeywords(args, kwds, "sO:Channel", kwlist, if (!(PyArg_ParseTupleAndKeywords(args, kwds, "sO|z:Channel", kwlist,
&hostport, &client_credentials))) { &hostport, &client_credentials,
&server_host_override))) {
return -1; return -1;
} }
if (client_credentials == Py_None) { if (client_credentials == Py_None) {
self->c_channel = grpc_channel_create(hostport, NULL); self->c_channel = grpc_channel_create(hostport, NULL);
return 0; return 0;
} else { } else {
self->c_channel = grpc_secure_channel_create( if (server_host_override == NULL) {
((ClientCredentials *)client_credentials)->c_client_credentials, self->c_channel = grpc_secure_channel_create(
hostport, NULL); ((ClientCredentials *)client_credentials)->c_client_credentials,
hostport, NULL);
} else {
server_host_override_arg.type = GRPC_ARG_STRING;
server_host_override_arg.key = GRPC_SSL_TARGET_NAME_OVERRIDE_ARG;
server_host_override_arg.value.string = server_host_override;
channel_args.num_args = 1;
channel_args.args = &server_host_override_arg;
self->c_channel = grpc_secure_channel_create(
((ClientCredentials *)client_credentials)->c_client_credentials,
hostport, &channel_args);
}
return 0; return 0;
} }
} }

@ -50,31 +50,12 @@ class FaceTestCase(test_case.FaceTestCase, coverage.BlockingCoverage):
"""Provides abstract Face-layer tests a GRPC-backed implementation.""" """Provides abstract Face-layer tests a GRPC-backed implementation."""
def set_up_implementation( def set_up_implementation(
self, self, name, methods, method_implementations,
name, multi_method_implementation):
methods,
inline_value_in_value_out_methods,
inline_value_in_stream_out_methods,
inline_stream_in_value_out_methods,
inline_stream_in_stream_out_methods,
event_value_in_value_out_methods,
event_value_in_stream_out_methods,
event_stream_in_value_out_methods,
event_stream_in_stream_out_methods,
multi_method):
pool = logging_pool.pool(_MAXIMUM_POOL_SIZE) pool = logging_pool.pool(_MAXIMUM_POOL_SIZE)
servicer = face_implementations.servicer( servicer = face_implementations.servicer(
pool, pool, method_implementations, multi_method_implementation)
inline_value_in_value_out_methods=inline_value_in_value_out_methods,
inline_value_in_stream_out_methods=inline_value_in_stream_out_methods,
inline_stream_in_value_out_methods=inline_stream_in_value_out_methods,
inline_stream_in_stream_out_methods=inline_stream_in_stream_out_methods,
event_value_in_value_out_methods=event_value_in_value_out_methods,
event_value_in_stream_out_methods=event_value_in_stream_out_methods,
event_stream_in_value_out_methods=event_stream_in_value_out_methods,
event_stream_in_stream_out_methods=event_stream_in_stream_out_methods,
multi_method=multi_method)
serialization = serial.serialization(methods) serialization = serial.serialization(methods)
@ -96,9 +77,8 @@ class FaceTestCase(test_case.FaceTestCase, coverage.BlockingCoverage):
rear_link.join_fore_link(front) rear_link.join_fore_link(front)
front.join_rear_link(rear_link) front.join_rear_link(rear_link)
server = face_implementations.server() stub = face_implementations.generic_stub(front, pool)
stub = face_implementations.stub(front, pool) return stub, (rear_link, fore_link, front, back)
return server, stub, (rear_link, fore_link, front, back)
def tear_down_implementation(self, memo): def tear_down_implementation(self, memo):
rear_link, fore_link, front, back = memo rear_link, fore_link, front, back = memo

@ -82,7 +82,7 @@ class EchoTest(unittest.TestCase):
self.host = 'localhost' self.host = 'localhost'
self.server_completion_queue = _low.CompletionQueue() self.server_completion_queue = _low.CompletionQueue()
self.server = _low.Server(self.server_completion_queue, None) self.server = _low.Server(self.server_completion_queue)
port = self.server.add_http2_addr('[::]:0') port = self.server.add_http2_addr('[::]:0')
self.server.start() self.server.start()
@ -260,7 +260,7 @@ class CancellationTest(unittest.TestCase):
self.host = 'localhost' self.host = 'localhost'
self.server_completion_queue = _low.CompletionQueue() self.server_completion_queue = _low.CompletionQueue()
self.server = _low.Server(self.server_completion_queue, None) self.server = _low.Server(self.server_completion_queue)
port = self.server.add_http2_addr('[::]:0') port = self.server.add_http2_addr('[::]:0')
self.server.start() self.server.start()

@ -42,30 +42,16 @@
static int pygrpc_server_init(Server *self, PyObject *args, PyObject *kwds) { static int pygrpc_server_init(Server *self, PyObject *args, PyObject *kwds) {
const PyObject *completion_queue; const PyObject *completion_queue;
PyObject *server_credentials; static char *kwlist[] = {"completion_queue", NULL};
static char *kwlist[] = {"completion_queue", "server_credentials", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O:Server", kwlist, if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!:Server", kwlist,
&pygrpc_CompletionQueueType, &pygrpc_CompletionQueueType,
&completion_queue, &server_credentials)) { &completion_queue)) {
return -1;
}
if (server_credentials == Py_None) {
self->c_server = grpc_server_create(
((CompletionQueue *)completion_queue)->c_completion_queue, NULL);
return 0;
} else if (PyObject_TypeCheck(server_credentials,
&pygrpc_ServerCredentialsType)) {
self->c_server = grpc_secure_server_create(
((ServerCredentials *)server_credentials)->c_server_credentials,
((CompletionQueue *)completion_queue)->c_completion_queue, NULL);
return 0;
} else {
PyErr_Format(PyExc_TypeError,
"server_credentials must be _grpc.ServerCredentials, not %s",
Py_TYPE(server_credentials)->tp_name);
return -1; return -1;
} }
self->c_server = grpc_server_create(
((CompletionQueue *)completion_queue)->c_completion_queue, NULL);
return 0;
} }
static void pygrpc_server_dealloc(Server *self) { static void pygrpc_server_dealloc(Server *self) {
@ -92,13 +78,21 @@ static PyObject *pygrpc_server_add_http2_addr(Server *self, PyObject *args) {
} }
static PyObject *pygrpc_server_add_secure_http2_addr(Server *self, static PyObject *pygrpc_server_add_secure_http2_addr(Server *self,
PyObject *args) { PyObject *args,
PyObject *kwargs) {
const char *addr; const char *addr;
PyObject *server_credentials;
static char *kwlist[] = {"addr", "server_credentials", NULL};
int port; int port;
if (!PyArg_ParseTuple(args, "s:add_secure_http2_addr", &addr)) {
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO!:add_secure_http2_addr",
kwlist, &addr, &pygrpc_ServerCredentialsType,
&server_credentials)) {
return NULL; return NULL;
} }
port = grpc_server_add_secure_http2_port(self->c_server, addr); port = grpc_server_add_secure_http2_port(
self->c_server, addr,
((ServerCredentials *)server_credentials)->c_server_credentials);
if (port == 0) { if (port == 0) {
PyErr_SetString(PyExc_RuntimeError, "Couldn't add port to server!"); PyErr_SetString(PyExc_RuntimeError, "Couldn't add port to server!");
return NULL; return NULL;
@ -138,8 +132,7 @@ static PyMethodDef methods[] = {
METH_VARARGS, "Add a secure HTTP2 address."}, METH_VARARGS, "Add a secure HTTP2 address."},
{"start", (PyCFunction)pygrpc_server_start, METH_NOARGS, {"start", (PyCFunction)pygrpc_server_start, METH_NOARGS,
"Starts the server."}, "Starts the server."},
{"service", (PyCFunction)pygrpc_server_service, METH_O, {"service", (PyCFunction)pygrpc_server_service, METH_O, "Services a call."},
"Services a call."},
{"stop", (PyCFunction)pygrpc_server_stop, METH_NOARGS, "Stops the server."}, {"stop", (PyCFunction)pygrpc_server_stop, METH_NOARGS, "Stops the server."},
{NULL}}; {NULL}};

@ -280,13 +280,14 @@ class ForeLink(ticket_interfaces.ForeLink, activated.Activated):
0 if self._requested_port is None else self._requested_port) 0 if self._requested_port is None else self._requested_port)
self._completion_queue = _low.CompletionQueue() self._completion_queue = _low.CompletionQueue()
if self._root_certificates is None and not self._key_chain_pairs: if self._root_certificates is None and not self._key_chain_pairs:
self._server = _low.Server(self._completion_queue, None) self._server = _low.Server(self._completion_queue)
self._port = self._server.add_http2_addr(address) self._port = self._server.add_http2_addr(address)
else: else:
server_credentials = _low.ServerCredentials( server_credentials = _low.ServerCredentials(
self._root_certificates, self._key_chain_pairs) self._root_certificates, self._key_chain_pairs)
self._server = _low.Server(self._completion_queue, server_credentials) self._server = _low.Server(self._completion_queue)
self._port = self._server.add_secure_http2_addr(address) self._port = self._server.add_secure_http2_addr(
address, server_credentials)
self._server.start() self._server.start()
self._server.service(None) self._server.service(None)

@ -93,7 +93,8 @@ class RearLink(ticket_interfaces.RearLink, activated.Activated):
def __init__( def __init__(
self, host, port, pool, request_serializers, response_deserializers, self, host, port, pool, request_serializers, response_deserializers,
secure, root_certificates, private_key, certificate_chain): secure, root_certificates, private_key, certificate_chain,
server_host_override=None):
"""Constructor. """Constructor.
Args: Args:
@ -111,6 +112,8 @@ class RearLink(ticket_interfaces.RearLink, activated.Activated):
key should be used. key should be used.
certificate_chain: The PEM-encoded certificate chain to use or None if certificate_chain: The PEM-encoded certificate chain to use or None if
no certificate chain should be used. no certificate chain should be used.
server_host_override: (For testing only) the target name used for SSL
host name checking.
""" """
self._condition = threading.Condition() self._condition = threading.Condition()
self._host = host self._host = host
@ -132,6 +135,7 @@ class RearLink(ticket_interfaces.RearLink, activated.Activated):
self._root_certificates = root_certificates self._root_certificates = root_certificates
self._private_key = private_key self._private_key = private_key
self._certificate_chain = certificate_chain self._certificate_chain = certificate_chain
self._server_host_override = server_host_override
def _on_write_event(self, operation_id, event, rpc_state): def _on_write_event(self, operation_id, event, rpc_state):
if event.write_accepted: if event.write_accepted:
@ -327,7 +331,8 @@ class RearLink(ticket_interfaces.RearLink, activated.Activated):
with self._condition: with self._condition:
self._completion_queue = _low.CompletionQueue() self._completion_queue = _low.CompletionQueue()
self._channel = _low.Channel( self._channel = _low.Channel(
'%s:%d' % (self._host, self._port), self._client_credentials) '%s:%d' % (self._host, self._port), self._client_credentials,
server_host_override=self._server_host_override)
return self return self
def _stop(self): def _stop(self):
@ -388,7 +393,8 @@ class _ActivatedRearLink(ticket_interfaces.RearLink, activated.Activated):
def __init__( def __init__(
self, host, port, request_serializers, response_deserializers, secure, self, host, port, request_serializers, response_deserializers, secure,
root_certificates, private_key, certificate_chain): root_certificates, private_key, certificate_chain,
server_host_override=None):
self._host = host self._host = host
self._port = port self._port = port
self._request_serializers = request_serializers self._request_serializers = request_serializers
@ -397,6 +403,7 @@ class _ActivatedRearLink(ticket_interfaces.RearLink, activated.Activated):
self._root_certificates = root_certificates self._root_certificates = root_certificates
self._private_key = private_key self._private_key = private_key
self._certificate_chain = certificate_chain self._certificate_chain = certificate_chain
self._server_host_override = server_host_override
self._lock = threading.Lock() self._lock = threading.Lock()
self._pool = None self._pool = None
@ -415,7 +422,8 @@ class _ActivatedRearLink(ticket_interfaces.RearLink, activated.Activated):
self._rear_link = RearLink( self._rear_link = RearLink(
self._host, self._port, self._pool, self._request_serializers, self._host, self._port, self._pool, self._request_serializers,
self._response_deserializers, self._secure, self._root_certificates, self._response_deserializers, self._secure, self._root_certificates,
self._private_key, self._certificate_chain) self._private_key, self._certificate_chain,
server_host_override=self._server_host_override)
self._rear_link.join_fore_link(self._fore_link) self._rear_link.join_fore_link(self._fore_link)
self._rear_link.start() self._rear_link.start()
return self return self
@ -477,7 +485,7 @@ def activated_rear_link(
def secure_activated_rear_link( def secure_activated_rear_link(
host, port, request_serializers, response_deserializers, root_certificates, host, port, request_serializers, response_deserializers, root_certificates,
private_key, certificate_chain): private_key, certificate_chain, server_host_override=None):
"""Creates a RearLink that is also an activated.Activated. """Creates a RearLink that is also an activated.Activated.
The returned object is only valid for use between calls to its start and stop The returned object is only valid for use between calls to its start and stop
@ -496,7 +504,10 @@ def secure_activated_rear_link(
should be used. should be used.
certificate_chain: The PEM-encoded certificate chain to use or None if no certificate_chain: The PEM-encoded certificate chain to use or None if no
certificate chain should be used. certificate chain should be used.
server_host_override: (For testing only) the target name used for SSL
host name checking.
""" """
return _ActivatedRearLink( return _ActivatedRearLink(
host, port, request_serializers, response_deserializers, True, host, port, request_serializers, response_deserializers, True,
root_certificates, private_key, certificate_chain) root_certificates, private_key, certificate_chain,
server_host_override=server_host_override)

@ -30,23 +30,20 @@
import abc import abc
import collections import collections
# assembly_interfaces is referenced from specification in this module. # face_interfaces is referenced from specification in this module.
from grpc.framework.assembly import interfaces as assembly_interfaces # pylint: disable=unused-import from grpc.framework.common import cardinality
from grpc.framework.assembly import utilities as assembly_utilities from grpc.framework.face import interfaces as face_interfaces # pylint: disable=unused-import
from grpc.framework.face import utilities as face_utilities
from grpc.early_adopter import _reexport from grpc.early_adopter import _reexport
from grpc.early_adopter import interfaces from grpc.early_adopter import interfaces
# TODO(issue 726): Kill the "implementations" attribute of this in favor
# of the same-information-less-bogusly-represented "cardinalities".
class InvocationBreakdown(object): class InvocationBreakdown(object):
"""An intermediate representation of invocation-side views of RPC methods. """An intermediate representation of invocation-side views of RPC methods.
Attributes: Attributes:
cardinalities: A dictionary from RPC method name to interfaces.Cardinality cardinalities: A dictionary from RPC method name to interfaces.Cardinality
value. value.
implementations: A dictionary from RPC method name to
assembly_interfaces.MethodImplementation describing the method.
request_serializers: A dictionary from RPC method name to callable request_serializers: A dictionary from RPC method name to callable
behavior to be used serializing request values for the RPC. behavior to be used serializing request values for the RPC.
response_deserializers: A dictionary from RPC method name to callable response_deserializers: A dictionary from RPC method name to callable
@ -59,8 +56,7 @@ class _EasyInvocationBreakdown(
InvocationBreakdown, InvocationBreakdown,
collections.namedtuple( collections.namedtuple(
'_EasyInvocationBreakdown', '_EasyInvocationBreakdown',
('cardinalities', 'implementations', 'request_serializers', ('cardinalities', 'request_serializers', 'response_deserializers'))):
'response_deserializers'))):
pass pass
@ -68,8 +64,8 @@ class ServiceBreakdown(object):
"""An intermediate representation of service-side views of RPC methods. """An intermediate representation of service-side views of RPC methods.
Attributes: Attributes:
implementations: A dictionary from RPC method name implementations: A dictionary from RPC method name to
assembly_interfaces.MethodImplementation implementing the RPC method. face_interfaces.MethodImplementation implementing the RPC method.
request_deserializers: A dictionary from RPC method name to callable request_deserializers: A dictionary from RPC method name to callable
behavior to be used deserializing request values for the RPC. behavior to be used deserializing request values for the RPC.
response_serializers: A dictionary from RPC method name to callable response_serializers: A dictionary from RPC method name to callable
@ -97,25 +93,14 @@ def break_down_invocation(method_descriptions):
An InvocationBreakdown corresponding to the given method descriptions. An InvocationBreakdown corresponding to the given method descriptions.
""" """
cardinalities = {} cardinalities = {}
implementations = {}
request_serializers = {} request_serializers = {}
response_deserializers = {} response_deserializers = {}
for name, method_description in method_descriptions.iteritems(): for name, method_description in method_descriptions.iteritems():
cardinality = method_description.cardinality() cardinalities[name] = method_description.cardinality()
cardinalities[name] = cardinality
if cardinality is interfaces.Cardinality.UNARY_UNARY:
implementations[name] = assembly_utilities.unary_unary_inline(None)
elif cardinality is interfaces.Cardinality.UNARY_STREAM:
implementations[name] = assembly_utilities.unary_stream_inline(None)
elif cardinality is interfaces.Cardinality.STREAM_UNARY:
implementations[name] = assembly_utilities.stream_unary_inline(None)
elif cardinality is interfaces.Cardinality.STREAM_STREAM:
implementations[name] = assembly_utilities.stream_stream_inline(None)
request_serializers[name] = method_description.serialize_request request_serializers[name] = method_description.serialize_request
response_deserializers[name] = method_description.deserialize_response response_deserializers[name] = method_description.deserialize_response
return _EasyInvocationBreakdown( return _EasyInvocationBreakdown(
cardinalities, implementations, request_serializers, cardinalities, request_serializers, response_deserializers)
response_deserializers)
def break_down_service(method_descriptions): def break_down_service(method_descriptions):
@ -139,28 +124,28 @@ def break_down_service(method_descriptions):
service_behavior=method_description.service_unary_unary): service_behavior=method_description.service_unary_unary):
return service_behavior( return service_behavior(
request, _reexport.rpc_context(face_rpc_context)) request, _reexport.rpc_context(face_rpc_context))
implementations[name] = assembly_utilities.unary_unary_inline(service) implementations[name] = face_utilities.unary_unary_inline(service)
elif cardinality is interfaces.Cardinality.UNARY_STREAM: elif cardinality is interfaces.Cardinality.UNARY_STREAM:
def service( def service(
request, face_rpc_context, request, face_rpc_context,
service_behavior=method_description.service_unary_stream): service_behavior=method_description.service_unary_stream):
return service_behavior( return service_behavior(
request, _reexport.rpc_context(face_rpc_context)) request, _reexport.rpc_context(face_rpc_context))
implementations[name] = assembly_utilities.unary_stream_inline(service) implementations[name] = face_utilities.unary_stream_inline(service)
elif cardinality is interfaces.Cardinality.STREAM_UNARY: elif cardinality is interfaces.Cardinality.STREAM_UNARY:
def service( def service(
request_iterator, face_rpc_context, request_iterator, face_rpc_context,
service_behavior=method_description.service_stream_unary): service_behavior=method_description.service_stream_unary):
return service_behavior( return service_behavior(
request_iterator, _reexport.rpc_context(face_rpc_context)) request_iterator, _reexport.rpc_context(face_rpc_context))
implementations[name] = assembly_utilities.stream_unary_inline(service) implementations[name] = face_utilities.stream_unary_inline(service)
elif cardinality is interfaces.Cardinality.STREAM_STREAM: elif cardinality is interfaces.Cardinality.STREAM_STREAM:
def service( def service(
request_iterator, face_rpc_context, request_iterator, face_rpc_context,
service_behavior=method_description.service_stream_stream): service_behavior=method_description.service_stream_stream):
return service_behavior( return service_behavior(
request_iterator, _reexport.rpc_context(face_rpc_context)) request_iterator, _reexport.rpc_context(face_rpc_context))
implementations[name] = assembly_utilities.stream_stream_inline(service) implementations[name] = face_utilities.stream_stream_inline(service)
request_deserializers[name] = method_description.deserialize_request request_deserializers[name] = method_description.deserialize_request
response_serializers[name] = method_description.serialize_response response_serializers[name] = method_description.serialize_response

@ -27,12 +27,20 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from grpc.framework.common import cardinality
from grpc.framework.face import exceptions as face_exceptions from grpc.framework.face import exceptions as face_exceptions
from grpc.framework.face import interfaces as face_interfaces from grpc.framework.face import interfaces as face_interfaces
from grpc.framework.foundation import future from grpc.framework.foundation import future
from grpc.early_adopter import exceptions from grpc.early_adopter import exceptions
from grpc.early_adopter import interfaces from grpc.early_adopter import interfaces
_EARLY_ADOPTER_CARDINALITY_TO_COMMON_CARDINALITY = {
interfaces.Cardinality.UNARY_UNARY: cardinality.Cardinality.UNARY_UNARY,
interfaces.Cardinality.UNARY_STREAM: cardinality.Cardinality.UNARY_STREAM,
interfaces.Cardinality.STREAM_UNARY: cardinality.Cardinality.STREAM_UNARY,
interfaces.Cardinality.STREAM_STREAM: cardinality.Cardinality.STREAM_STREAM,
}
_ABORTION_REEXPORT = { _ABORTION_REEXPORT = {
face_interfaces.Abortion.CANCELLED: interfaces.Abortion.CANCELLED, face_interfaces.Abortion.CANCELLED: interfaces.Abortion.CANCELLED,
face_interfaces.Abortion.EXPIRED: interfaces.Abortion.EXPIRED, face_interfaces.Abortion.EXPIRED: interfaces.Abortion.EXPIRED,
@ -142,28 +150,28 @@ class _RpcContext(interfaces.RpcContext):
class _UnaryUnarySyncAsync(interfaces.UnaryUnarySyncAsync): class _UnaryUnarySyncAsync(interfaces.UnaryUnarySyncAsync):
def __init__(self, face_unary_unary_sync_async): def __init__(self, face_unary_unary_multi_callable):
self._underlying = face_unary_unary_sync_async self._underlying = face_unary_unary_multi_callable
def __call__(self, request, timeout): def __call__(self, request, timeout):
return _call_reexporting_errors( return _call_reexporting_errors(
self._underlying, request, timeout) self._underlying, request, timeout)
def async(self, request, timeout): def async(self, request, timeout):
return _ReexportedFuture(self._underlying.async(request, timeout)) return _ReexportedFuture(self._underlying.future(request, timeout))
class _StreamUnarySyncAsync(interfaces.StreamUnarySyncAsync): class _StreamUnarySyncAsync(interfaces.StreamUnarySyncAsync):
def __init__(self, face_stream_unary_sync_async): def __init__(self, face_stream_unary_multi_callable):
self._underlying = face_stream_unary_sync_async self._underlying = face_stream_unary_multi_callable
def __call__(self, request_iterator, timeout): def __call__(self, request_iterator, timeout):
return _call_reexporting_errors( return _call_reexporting_errors(
self._underlying, request_iterator, timeout) self._underlying, request_iterator, timeout)
def async(self, request_iterator, timeout): def async(self, request_iterator, timeout):
return _ReexportedFuture(self._underlying.async(request_iterator, timeout)) return _ReexportedFuture(self._underlying.future(request_iterator, timeout))
class _Stub(interfaces.Stub): class _Stub(interfaces.Stub):
@ -182,31 +190,40 @@ class _Stub(interfaces.Stub):
def __getattr__(self, attr): def __getattr__(self, attr):
underlying_attr = self._assembly_stub.__getattr__(attr) underlying_attr = self._assembly_stub.__getattr__(attr)
cardinality = self._cardinalities.get(attr) method_cardinality = self._cardinalities.get(attr)
# TODO(nathaniel): unify this trick with its other occurrence in the code. # TODO(nathaniel): unify this trick with its other occurrence in the code.
if cardinality is None: if method_cardinality is None:
for name, cardinality in self._cardinalities.iteritems(): for name, method_cardinality in self._cardinalities.iteritems():
last_slash_index = name.rfind('/') last_slash_index = name.rfind('/')
if 0 <= last_slash_index and name[last_slash_index + 1:] == attr: if 0 <= last_slash_index and name[last_slash_index + 1:] == attr:
break break
else: else:
raise AttributeError(attr) raise AttributeError(attr)
if cardinality is interfaces.Cardinality.UNARY_UNARY: if method_cardinality is interfaces.Cardinality.UNARY_UNARY:
return _UnaryUnarySyncAsync(underlying_attr) return _UnaryUnarySyncAsync(underlying_attr)
elif cardinality is interfaces.Cardinality.UNARY_STREAM: elif method_cardinality is interfaces.Cardinality.UNARY_STREAM:
return lambda request, timeout: _CancellableIterator( return lambda request, timeout: _CancellableIterator(
underlying_attr(request, timeout)) underlying_attr(request, timeout))
elif cardinality is interfaces.Cardinality.STREAM_UNARY: elif method_cardinality is interfaces.Cardinality.STREAM_UNARY:
return _StreamUnarySyncAsync(underlying_attr) return _StreamUnarySyncAsync(underlying_attr)
elif cardinality is interfaces.Cardinality.STREAM_STREAM: elif method_cardinality is interfaces.Cardinality.STREAM_STREAM:
return lambda request_iterator, timeout: _CancellableIterator( return lambda request_iterator, timeout: _CancellableIterator(
underlying_attr(request_iterator, timeout)) underlying_attr(request_iterator, timeout))
else: else:
raise AttributeError(attr) raise AttributeError(attr)
def common_cardinalities(early_adopter_cardinalities):
common_cardinalities = {}
for name, early_adopter_cardinality in early_adopter_cardinalities.iteritems():
common_cardinalities[name] = _EARLY_ADOPTER_CARDINALITY_TO_COMMON_CARDINALITY[
early_adopter_cardinality]
return common_cardinalities
def rpc_context(face_rpc_context): def rpc_context(face_rpc_context):
return _RpcContext(face_rpc_context) return _RpcContext(face_rpc_context)
def stub(assembly_stub, cardinalities): def stub(face_stub, cardinalities):
return _Stub(assembly_stub, cardinalities) return _Stub(face_stub, cardinalities)

@ -33,7 +33,7 @@ import threading
from grpc._adapter import fore as _fore from grpc._adapter import fore as _fore
from grpc._adapter import rear as _rear from grpc._adapter import rear as _rear
from grpc.early_adopter import _assembly_utilities from grpc.early_adopter import _face_utilities
from grpc.early_adopter import _reexport from grpc.early_adopter import _reexport
from grpc.early_adopter import interfaces from grpc.early_adopter import interfaces
from grpc.framework.assembly import implementations as _assembly_implementations from grpc.framework.assembly import implementations as _assembly_implementations
@ -95,12 +95,13 @@ class _Server(interfaces.Server):
def _build_stub(breakdown, activated_rear_link): def _build_stub(breakdown, activated_rear_link):
assembly_stub = _assembly_implementations.assemble_dynamic_inline_stub( assembly_stub = _assembly_implementations.assemble_dynamic_inline_stub(
breakdown.implementations, activated_rear_link) _reexport.common_cardinalities(breakdown.cardinalities),
activated_rear_link)
return _reexport.stub(assembly_stub, breakdown.cardinalities) return _reexport.stub(assembly_stub, breakdown.cardinalities)
def _build_server(methods, port, private_key, certificate_chain): def _build_server(methods, port, private_key, certificate_chain):
breakdown = _assembly_utilities.break_down_service(methods) breakdown = _face_utilities.break_down_service(methods)
return _Server(breakdown, port, private_key, certificate_chain) return _Server(breakdown, port, private_key, certificate_chain)
@ -117,7 +118,7 @@ def insecure_stub(methods, host, port):
Returns: Returns:
An interfaces.Stub affording RPC invocation. An interfaces.Stub affording RPC invocation.
""" """
breakdown = _assembly_utilities.break_down_invocation(methods) breakdown = _face_utilities.break_down_invocation(methods)
activated_rear_link = _rear.activated_rear_link( activated_rear_link = _rear.activated_rear_link(
host, port, breakdown.request_serializers, host, port, breakdown.request_serializers,
breakdown.response_deserializers) breakdown.response_deserializers)
@ -125,7 +126,8 @@ def insecure_stub(methods, host, port):
def secure_stub( def secure_stub(
methods, host, port, root_certificates, private_key, certificate_chain): methods, host, port, root_certificates, private_key, certificate_chain,
server_host_override=None):
"""Constructs an insecure interfaces.Stub. """Constructs an insecure interfaces.Stub.
Args: Args:
@ -140,15 +142,17 @@ def secure_stub(
should be used. should be used.
certificate_chain: The PEM-encoded certificate chain to use or None if no certificate_chain: The PEM-encoded certificate chain to use or None if no
certificate chain should be used. certificate chain should be used.
server_host_override: (For testing only) the target name used for SSL
host name checking.
Returns: Returns:
An interfaces.Stub affording RPC invocation. An interfaces.Stub affording RPC invocation.
""" """
breakdown = _assembly_utilities.break_down_invocation(methods) breakdown = _face_utilities.break_down_invocation(methods)
activated_rear_link = _rear.secure_activated_rear_link( activated_rear_link = _rear.secure_activated_rear_link(
host, port, breakdown.request_serializers, host, port, breakdown.request_serializers,
breakdown.response_deserializers, root_certificates, private_key, breakdown.response_deserializers, root_certificates, private_key,
certificate_chain) certificate_chain, server_host_override=server_host_override)
return _build_stub(breakdown, activated_rear_link) return _build_stub(breakdown, activated_rear_link)

@ -66,7 +66,7 @@ class _FaceStub(object):
self._rear_link.start() self._rear_link.start()
self._rear_link.join_fore_link(self._front) self._rear_link.join_fore_link(self._front)
self._front.join_rear_link(self._rear_link) self._front.join_rear_link(self._rear_link)
self._under_stub = face_implementations.stub(self._front, self._pool) self._under_stub = face_implementations.generic_stub(self._front, self._pool)
def __exit__(self, exc_type, exc_val, exc_tb): def __exit__(self, exc_type, exc_val, exc_tb):
with self._lock: with self._lock:
@ -86,18 +86,18 @@ class _FaceStub(object):
return getattr(self._under_stub, attr) return getattr(self._under_stub, attr)
def _behaviors(implementations, front, pool): def _behaviors(method_cardinalities, front, pool):
behaviors = {} behaviors = {}
stub = face_implementations.stub(front, pool) stub = face_implementations.generic_stub(front, pool)
for name, implementation in implementations.iteritems(): for name, method_cardinality in method_cardinalities.iteritems():
if implementation.cardinality is cardinality.Cardinality.UNARY_UNARY: if method_cardinality is cardinality.Cardinality.UNARY_UNARY:
behaviors[name] = stub.unary_unary_sync_async(name) behaviors[name] = stub.unary_unary_multi_callable(name)
elif implementation.cardinality is cardinality.Cardinality.UNARY_STREAM: elif method_cardinality is cardinality.Cardinality.UNARY_STREAM:
behaviors[name] = lambda request, context, bound_name=name: ( behaviors[name] = lambda request, context, bound_name=name: (
stub.inline_value_in_stream_out(bound_name, request, context)) stub.inline_value_in_stream_out(bound_name, request, context))
elif implementation.cardinality is cardinality.Cardinality.STREAM_UNARY: elif method_cardinality is cardinality.Cardinality.STREAM_UNARY:
behaviors[name] = stub.stream_unary_sync_async(name) behaviors[name] = stub.stream_unary_multi_callable(name)
elif implementation.cardinality is cardinality.Cardinality.STREAM_STREAM: elif method_cardinality is cardinality.Cardinality.STREAM_STREAM:
behaviors[name] = lambda request_iterator, context, bound_name=name: ( behaviors[name] = lambda request_iterator, context, bound_name=name: (
stub.inline_stream_in_stream_out( stub.inline_stream_in_stream_out(
bound_name, request_iterator, context)) bound_name, request_iterator, context))
@ -106,8 +106,8 @@ def _behaviors(implementations, front, pool):
class _DynamicInlineStub(object): class _DynamicInlineStub(object):
def __init__(self, implementations, rear_link): def __init__(self, cardinalities, rear_link):
self._implementations = implementations self._cardinalities = cardinalities
self._rear_link = rear_link self._rear_link = rear_link
self._lock = threading.Lock() self._lock = threading.Lock()
self._pool = None self._pool = None
@ -123,7 +123,7 @@ class _DynamicInlineStub(object):
self._rear_link.join_fore_link(self._front) self._rear_link.join_fore_link(self._front)
self._front.join_rear_link(self._rear_link) self._front.join_rear_link(self._rear_link)
self._behaviors = _behaviors( self._behaviors = _behaviors(
self._implementations, self._front, self._pool) self._cardinalities, self._front, self._pool)
return self return self
def __exit__(self, exc_type, exc_val, exc_tb): def __exit__(self, exc_type, exc_val, exc_tb):
@ -151,58 +151,6 @@ class _DynamicInlineStub(object):
return behavior return behavior
def _servicer(implementations, pool):
inline_value_in_value_out_methods = {}
inline_value_in_stream_out_methods = {}
inline_stream_in_value_out_methods = {}
inline_stream_in_stream_out_methods = {}
event_value_in_value_out_methods = {}
event_value_in_stream_out_methods = {}
event_stream_in_value_out_methods = {}
event_stream_in_stream_out_methods = {}
for name, implementation in implementations.iteritems():
if implementation.cardinality is cardinality.Cardinality.UNARY_UNARY:
if implementation.style is style.Service.INLINE:
inline_value_in_value_out_methods[name] = (
face_utilities.inline_unary_unary_method(implementation.unary_unary_inline))
elif implementation.style is style.Service.EVENT:
event_value_in_value_out_methods[name] = (
face_utilities.event_unary_unary_method(implementation.unary_unary_event))
elif implementation.cardinality is cardinality.Cardinality.UNARY_STREAM:
if implementation.style is style.Service.INLINE:
inline_value_in_stream_out_methods[name] = (
face_utilities.inline_unary_stream_method(implementation.unary_stream_inline))
elif implementation.style is style.Service.EVENT:
event_value_in_stream_out_methods[name] = (
face_utilities.event_unary_stream_method(implementation.unary_stream_event))
if implementation.cardinality is cardinality.Cardinality.STREAM_UNARY:
if implementation.style is style.Service.INLINE:
inline_stream_in_value_out_methods[name] = (
face_utilities.inline_stream_unary_method(implementation.stream_unary_inline))
elif implementation.style is style.Service.EVENT:
event_stream_in_value_out_methods[name] = (
face_utilities.event_stream_unary_method(implementation.stream_unary_event))
elif implementation.cardinality is cardinality.Cardinality.STREAM_STREAM:
if implementation.style is style.Service.INLINE:
inline_stream_in_stream_out_methods[name] = (
face_utilities.inline_stream_stream_method(implementation.stream_stream_inline))
elif implementation.style is style.Service.EVENT:
event_stream_in_stream_out_methods[name] = (
face_utilities.event_stream_stream_method(implementation.stream_stream_event))
return face_implementations.servicer(
pool,
inline_value_in_value_out_methods=inline_value_in_value_out_methods,
inline_value_in_stream_out_methods=inline_value_in_stream_out_methods,
inline_stream_in_value_out_methods=inline_stream_in_value_out_methods,
inline_stream_in_stream_out_methods=inline_stream_in_stream_out_methods,
event_value_in_value_out_methods=event_value_in_value_out_methods,
event_value_in_stream_out_methods=event_value_in_stream_out_methods,
event_stream_in_value_out_methods=event_stream_in_value_out_methods,
event_stream_in_stream_out_methods=event_stream_in_stream_out_methods)
class _ServiceAssembly(interfaces.Server): class _ServiceAssembly(interfaces.Server):
def __init__(self, implementations, fore_link): def __init__(self, implementations, fore_link):
@ -215,7 +163,8 @@ class _ServiceAssembly(interfaces.Server):
def _start(self): def _start(self):
with self._lock: with self._lock:
self._pool = logging_pool.pool(_THREAD_POOL_SIZE) self._pool = logging_pool.pool(_THREAD_POOL_SIZE)
servicer = _servicer(self._implementations, self._pool) servicer = face_implementations.servicer(
self._pool, self._implementations, None)
self._back = tickets_implementations.back( self._back = tickets_implementations.back(
servicer, self._pool, self._pool, self._pool, _ONE_DAY_IN_SECONDS, servicer, self._pool, self._pool, self._pool, _ONE_DAY_IN_SECONDS,
_ONE_DAY_IN_SECONDS) _ONE_DAY_IN_SECONDS)
@ -251,7 +200,7 @@ class _ServiceAssembly(interfaces.Server):
def assemble_face_stub(activated_rear_link): def assemble_face_stub(activated_rear_link):
"""Assembles a face_interfaces.Stub. """Assembles a face_interfaces.GenericStub.
The returned object is a context manager and may only be used in context to The returned object is a context manager and may only be used in context to
invoke RPCs. invoke RPCs.
@ -262,12 +211,12 @@ def assemble_face_stub(activated_rear_link):
when passed to this method. when passed to this method.
Returns: Returns:
A face_interfaces.Stub on which, in context, RPCs can be invoked. A face_interfaces.GenericStub on which, in context, RPCs can be invoked.
""" """
return _FaceStub(activated_rear_link) return _FaceStub(activated_rear_link)
def assemble_dynamic_inline_stub(implementations, activated_rear_link): def assemble_dynamic_inline_stub(cardinalities, activated_rear_link):
"""Assembles a stub with method names for attributes. """Assembles a stub with method names for attributes.
The returned object is a context manager and may only be used in context to The returned object is a context manager and may only be used in context to
@ -276,29 +225,27 @@ def assemble_dynamic_inline_stub(implementations, activated_rear_link):
The returned object, when used in context, will respond to attribute access The returned object, when used in context, will respond to attribute access
as follows: if the requested attribute is the name of a unary-unary RPC as follows: if the requested attribute is the name of a unary-unary RPC
method, the value of the attribute will be a method, the value of the attribute will be a
face_interfaces.UnaryUnarySyncAsync with which to invoke the RPC method. If face_interfaces.UnaryUnaryMultiCallable with which to invoke the RPC method.
the requested attribute is the name of a unary-stream RPC method, the value If the requested attribute is the name of a unary-stream RPC method, the
of the attribute will be a callable with the semantics of value of the attribute will be a face_interfaces.UnaryStreamMultiCallable
face_interfaces.Stub.inline_value_in_stream_out, minus the "name" parameter,
with which to invoke the RPC method. If the requested attribute is the name with which to invoke the RPC method. If the requested attribute is the name
of a stream-unary RPC method, the value of the attribute will be a of a stream-unary RPC method, the value of the attribute will be a
face_interfaces.StreamUnarySyncAsync with which to invoke the RPC method. If face_interfaces.StreamUnaryMultiCallable with which to invoke the RPC method.
the requested attribute is the name of a stream-stream RPC method, the value If the requested attribute is the name of a stream-stream RPC method, the
of the attribute will be a callable with the semantics of value of the attribute will be a face_interfaces.StreamStreamMultiCallable
face_interfaces.Stub.inline_stream_in_stream_out, minus the "name" parameter,
with which to invoke the RPC method. with which to invoke the RPC method.
Args: Args:
implementations: A dictionary from RPC method name to cardinalities: A dictionary from RPC method name to cardinality.Cardinality
interfaces.MethodImplementation. value identifying the cardinality of the named RPC method.
activated_rear_link: An object that is both a tickets_interfaces.RearLink activated_rear_link: An object that is both a tickets_interfaces.RearLink
and an activated.Activated. The object should be in the inactive state and an activated.Activated. The object should be in the inactive state
when passed to this method. when passed to this method.
Returns: Returns:
A stub on which, in context, RPCs can be invoked. A face_interfaces.DynamicStub on which, in context, RPCs can be invoked.
""" """
return _DynamicInlineStub(implementations, activated_rear_link) return _DynamicInlineStub(cardinalities, activated_rear_link)
def assemble_service(implementations, activated_fore_link): def assemble_service(implementations, activated_fore_link):
@ -306,7 +253,7 @@ def assemble_service(implementations, activated_fore_link):
Args: Args:
implementations: A dictionary from RPC method name to implementations: A dictionary from RPC method name to
interfaces.MethodImplementation. face_interfaces.MethodImplementation.
activated_fore_link: An object that is both a tickets_interfaces.ForeLink activated_fore_link: An object that is both a tickets_interfaces.ForeLink
and an activated.Activated. The object should be in the inactive state and an activated.Activated. The object should be in the inactive state
when passed to this method. when passed to this method.

@ -35,11 +35,11 @@ import threading
import unittest import unittest
from grpc.framework.assembly import implementations from grpc.framework.assembly import implementations
from grpc.framework.assembly import utilities
from grpc.framework.base import interfaces from grpc.framework.base import interfaces
from grpc.framework.base.packets import packets as tickets from grpc.framework.base.packets import packets as tickets
from grpc.framework.base.packets import interfaces as tickets_interfaces from grpc.framework.base.packets import interfaces as tickets_interfaces
from grpc.framework.base.packets import null from grpc.framework.base.packets import null
from grpc.framework.face import utilities as face_utilities
from grpc.framework.foundation import logging_pool from grpc.framework.foundation import logging_pool
from grpc._junkdrawer import math_pb2 from grpc._junkdrawer import math_pb2
@ -81,12 +81,16 @@ def _sum(request_iterator, unused_context):
_IMPLEMENTATIONS = { _IMPLEMENTATIONS = {
DIV: utilities.unary_unary_inline(_div), DIV: face_utilities.unary_unary_inline(_div),
DIV_MANY: utilities.stream_stream_inline(_div_many), DIV_MANY: face_utilities.stream_stream_inline(_div_many),
FIB: utilities.unary_stream_inline(_fib), FIB: face_utilities.unary_stream_inline(_fib),
SUM: utilities.stream_unary_inline(_sum), SUM: face_utilities.stream_unary_inline(_sum),
} }
_CARDINALITIES = {
name: implementation.cardinality
for name, implementation in _IMPLEMENTATIONS.iteritems()}
_TIMEOUT = 10 _TIMEOUT = 10
@ -170,8 +174,8 @@ class FaceStubTest(unittest.TestCase):
face_stub = implementations.assemble_face_stub(pipe) face_stub = implementations.assemble_face_stub(pipe)
with service, face_stub: with service, face_stub:
sync_async = face_stub.stream_unary_sync_async(SUM) multi_callable = face_stub.stream_unary_multi_callable(SUM)
response_future = sync_async.async( response_future = multi_callable.future(
(math_pb2.Num(num=index) for index in range(stream_length)), (math_pb2.Num(num=index) for index in range(stream_length)),
_TIMEOUT) _TIMEOUT)
self.assertEqual( self.assertEqual(
@ -214,7 +218,7 @@ class DynamicInlineStubTest(unittest.TestCase):
pipe = PipeLink() pipe = PipeLink()
service = implementations.assemble_service(_IMPLEMENTATIONS, pipe) service = implementations.assemble_service(_IMPLEMENTATIONS, pipe)
dynamic_stub = implementations.assemble_dynamic_inline_stub( dynamic_stub = implementations.assemble_dynamic_inline_stub(
_IMPLEMENTATIONS, pipe) _CARDINALITIES, pipe)
service.start() service.start()
with dynamic_stub: with dynamic_stub:
@ -229,7 +233,7 @@ class DynamicInlineStubTest(unittest.TestCase):
pipe = PipeLink() pipe = PipeLink()
service = implementations.assemble_service(_IMPLEMENTATIONS, pipe) service = implementations.assemble_service(_IMPLEMENTATIONS, pipe)
dynamic_stub = implementations.assemble_dynamic_inline_stub( dynamic_stub = implementations.assemble_dynamic_inline_stub(
_IMPLEMENTATIONS, pipe) _CARDINALITIES, pipe)
with service, dynamic_stub: with service, dynamic_stub:
response_iterator = dynamic_stub.Fib( response_iterator = dynamic_stub.Fib(
@ -244,10 +248,10 @@ class DynamicInlineStubTest(unittest.TestCase):
pipe = PipeLink() pipe = PipeLink()
service = implementations.assemble_service(_IMPLEMENTATIONS, pipe) service = implementations.assemble_service(_IMPLEMENTATIONS, pipe)
dynamic_stub = implementations.assemble_dynamic_inline_stub( dynamic_stub = implementations.assemble_dynamic_inline_stub(
_IMPLEMENTATIONS, pipe) _CARDINALITIES, pipe)
with service, dynamic_stub: with service, dynamic_stub:
response_future = dynamic_stub.Sum.async( response_future = dynamic_stub.Sum.future(
(math_pb2.Num(num=index) for index in range(stream_length)), (math_pb2.Num(num=index) for index in range(stream_length)),
_TIMEOUT) _TIMEOUT)
self.assertEqual( self.assertEqual(
@ -261,7 +265,7 @@ class DynamicInlineStubTest(unittest.TestCase):
pipe = PipeLink() pipe = PipeLink()
service = implementations.assemble_service(_IMPLEMENTATIONS, pipe) service = implementations.assemble_service(_IMPLEMENTATIONS, pipe)
dynamic_stub = implementations.assemble_dynamic_inline_stub( dynamic_stub = implementations.assemble_dynamic_inline_stub(
_IMPLEMENTATIONS, pipe) _CARDINALITIES, pipe)
with service, dynamic_stub: with service, dynamic_stub:
response_iterator = dynamic_stub.DivMany( response_iterator = dynamic_stub.DivMany(

@ -33,63 +33,7 @@
import abc import abc
# cardinality, style, and stream are referenced from specification in this
# module.
from grpc.framework.common import cardinality # pylint: disable=unused-import
from grpc.framework.common import style # pylint: disable=unused-import
from grpc.framework.foundation import activated from grpc.framework.foundation import activated
from grpc.framework.foundation import stream # pylint: disable=unused-import
class MethodImplementation(object):
"""A sum type that describes an RPC method implementation.
Attributes:
cardinality: A cardinality.Cardinality value.
style: A style.Service value.
unary_unary_inline: The implementation of the RPC method as a callable
value that takes a request value and a face_interfaces.RpcContext object
and returns a response value. Only non-None if cardinality is
cardinality.Cardinality.UNARY_UNARY and style is style.Service.INLINE.
unary_stream_inline: The implementation of the RPC method as a callable
value that takes a request value and a face_interfaces.RpcContext object
and returns an iterator of response values. Only non-None if cardinality
is cardinality.Cardinality.UNARY_STREAM and style is
style.Service.INLINE.
stream_unary_inline: The implementation of the RPC method as a callable
value that takes an iterator of request values and a
face_interfaces.RpcContext object and returns a response value. Only
non-None if cardinality is cardinality.Cardinality.STREAM_UNARY and style
is style.Service.INLINE.
stream_stream_inline: The implementation of the RPC method as a callable
value that takes an iterator of request values and a
face_interfaces.RpcContext object and returns an iterator of response
values. Only non-None if cardinality is
cardinality.Cardinality.STREAM_STREAM and style is style.Service.INLINE.
unary_unary_event: The implementation of the RPC method as a callable value
that takes a request value, a response callback to which to pass the
response value of the RPC, and a face_interfaces.RpcContext. Only
non-None if cardinality is cardinality.Cardinality.UNARY_UNARY and style
is style.Service.EVENT.
unary_stream_event: The implementation of the RPC method as a callable
value that takes a request value, a stream.Consumer to which to pass the
the response values of the RPC, and a face_interfaces.RpcContext. Only
non-None if cardinality is cardinality.Cardinality.UNARY_STREAM and style
is style.Service.EVENT.
stream_unary_event: The implementation of the RPC method as a callable
value that takes a response callback to which to pass the response value
of the RPC and a face_interfaces.RpcContext and returns a stream.Consumer
to which the request values of the RPC should be passed. Only non-None if
cardinality is cardinality.Cardinality.STREAM_UNARY and style is
style.Service.EVENT.
stream_stream_event: The implementation of the RPC method as a callable
value that takes a stream.Consumer to which to pass the response values
of the RPC and a face_interfaces.RpcContext and returns a stream.Consumer
to which the request values of the RPC should be passed. Only non-None if
cardinality is cardinality.Cardinality.STREAM_STREAM and style is
style.Service.EVENT.
"""
__metaclass__ = abc.ABCMeta
class Server(activated.Activated): class Server(activated.Activated):

@ -1,179 +0,0 @@
# Copyright 2015, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Utilities for assembling RPC framework values."""
import collections
from grpc.framework.assembly import interfaces
from grpc.framework.common import cardinality
from grpc.framework.common import style
from grpc.framework.face import interfaces as face_interfaces
from grpc.framework.foundation import stream
class _MethodImplementation(
interfaces.MethodImplementation,
collections.namedtuple(
'_MethodImplementation',
['cardinality', 'style', 'unary_unary_inline', 'unary_stream_inline',
'stream_unary_inline', 'stream_stream_inline', 'unary_unary_event',
'unary_stream_event', 'stream_unary_event', 'stream_stream_event',])):
pass
def unary_unary_inline(behavior):
"""Creates an interfaces.MethodImplementation for the given behavior.
Args:
behavior: The implementation of a unary-unary RPC method as a callable value
that takes a request value and a face_interfaces.RpcContext object and
returns a response value.
Returns:
An interfaces.MethodImplementation derived from the given behavior.
"""
return _MethodImplementation(
cardinality.Cardinality.UNARY_UNARY, style.Service.INLINE, behavior,
None, None, None, None, None, None, None)
def unary_stream_inline(behavior):
"""Creates an interfaces.MethodImplementation for the given behavior.
Args:
behavior: The implementation of a unary-stream RPC method as a callable
value that takes a request value and a face_interfaces.RpcContext object
and returns an iterator of response values.
Returns:
An interfaces.MethodImplementation derived from the given behavior.
"""
return _MethodImplementation(
cardinality.Cardinality.UNARY_STREAM, style.Service.INLINE, None,
behavior, None, None, None, None, None, None)
def stream_unary_inline(behavior):
"""Creates an interfaces.MethodImplementation for the given behavior.
Args:
behavior: The implementation of a stream-unary RPC method as a callable
value that takes an iterator of request values and a
face_interfaces.RpcContext object and returns a response value.
Returns:
An interfaces.MethodImplementation derived from the given behavior.
"""
return _MethodImplementation(
cardinality.Cardinality.STREAM_UNARY, style.Service.INLINE, None, None,
behavior, None, None, None, None, None)
def stream_stream_inline(behavior):
"""Creates an interfaces.MethodImplementation for the given behavior.
Args:
behavior: The implementation of a stream-stream RPC method as a callable
value that takes an iterator of request values and a
face_interfaces.RpcContext object and returns an iterator of response
values.
Returns:
An interfaces.MethodImplementation derived from the given behavior.
"""
return _MethodImplementation(
cardinality.Cardinality.STREAM_STREAM, style.Service.INLINE, None, None,
None, behavior, None, None, None, None)
def unary_unary_event(behavior):
"""Creates an interfaces.MethodImplementation for the given behavior.
Args:
behavior: The implementation of a unary-unary RPC method as a callable
value that takes a request value, a response callback to which to pass
the response value of the RPC, and a face_interfaces.RpcContext.
Returns:
An interfaces.MethodImplementation derived from the given behavior.
"""
return _MethodImplementation(
cardinality.Cardinality.UNARY_UNARY, style.Service.EVENT, None, None,
None, None, behavior, None, None, None)
def unary_stream_event(behavior):
"""Creates an interfaces.MethodImplementation for the given behavior.
Args:
behavior: The implementation of a unary-stream RPC method as a callable
value that takes a request value, a stream.Consumer to which to pass the
the response values of the RPC, and a face_interfaces.RpcContext.
Returns:
An interfaces.MethodImplementation derived from the given behavior.
"""
return _MethodImplementation(
cardinality.Cardinality.UNARY_STREAM, style.Service.EVENT, None, None,
None, None, None, behavior, None, None)
def stream_unary_event(behavior):
"""Creates an interfaces.MethodImplementation for the given behavior.
Args:
behavior: The implementation of a stream-unary RPC method as a callable
value that takes a response callback to which to pass the response value
of the RPC and a face_interfaces.RpcContext and returns a stream.Consumer
to which the request values of the RPC should be passed.
Returns:
An interfaces.MethodImplementation derived from the given behavior.
"""
return _MethodImplementation(
cardinality.Cardinality.STREAM_UNARY, style.Service.EVENT, None, None,
None, None, None, None, behavior, None)
def stream_stream_event(behavior):
"""Creates an interfaces.MethodImplementation for the given behavior.
Args:
behavior: The implementation of a stream-stream RPC method as a callable
value that takes a stream.Consumer to which to pass the response values
of the RPC and a face_interfaces.RpcContext and returns a stream.Consumer
to which the request values of the RPC should be passed.
Returns:
An interfaces.MethodImplementation derived from the given behavior.
"""
return _MethodImplementation(
cardinality.Cardinality.STREAM_STREAM, style.Service.EVENT, None, None,
None, None, None, None, None, behavior)

@ -105,15 +105,14 @@ def adapt_inline_value_in_value_out(method):
def adaptation(response_consumer, operation_context): def adaptation(response_consumer, operation_context):
rpc_context = _control.RpcContext(operation_context) rpc_context = _control.RpcContext(operation_context)
return stream_util.TransformingConsumer( return stream_util.TransformingConsumer(
lambda request: method.service(request, rpc_context), response_consumer) lambda request: method(request, rpc_context), response_consumer)
return adaptation return adaptation
def adapt_inline_value_in_stream_out(method): def adapt_inline_value_in_stream_out(method):
def adaptation(response_consumer, operation_context): def adaptation(response_consumer, operation_context):
rpc_context = _control.RpcContext(operation_context) rpc_context = _control.RpcContext(operation_context)
return _ValueInStreamOutConsumer( return _ValueInStreamOutConsumer(method, rpc_context, response_consumer)
method.service, rpc_context, response_consumer)
return adaptation return adaptation
@ -123,7 +122,7 @@ def adapt_inline_stream_in_value_out(method, pool):
operation_context.add_termination_callback(rendezvous.set_outcome) operation_context.add_termination_callback(rendezvous.set_outcome)
def in_pool_thread(): def in_pool_thread():
response_consumer.consume_and_terminate( response_consumer.consume_and_terminate(
method.service(rendezvous, _control.RpcContext(operation_context))) method(rendezvous, _control.RpcContext(operation_context)))
pool.submit(_pool_wrap(in_pool_thread, operation_context)) pool.submit(_pool_wrap(in_pool_thread, operation_context))
return rendezvous return rendezvous
return adaptation return adaptation
@ -149,7 +148,7 @@ def adapt_inline_stream_in_stream_out(method, pool):
operation_context.add_termination_callback(rendezvous.set_outcome) operation_context.add_termination_callback(rendezvous.set_outcome)
def in_pool_thread(): def in_pool_thread():
_control.pipe_iterator_to_consumer( _control.pipe_iterator_to_consumer(
method.service(rendezvous, _control.RpcContext(operation_context)), method(rendezvous, _control.RpcContext(operation_context)),
response_consumer, operation_context.is_active, True) response_consumer, operation_context.is_active, True)
pool.submit(_pool_wrap(in_pool_thread, operation_context)) pool.submit(_pool_wrap(in_pool_thread, operation_context))
return rendezvous return rendezvous
@ -159,7 +158,7 @@ def adapt_inline_stream_in_stream_out(method, pool):
def adapt_event_value_in_value_out(method): def adapt_event_value_in_value_out(method):
def adaptation(response_consumer, operation_context): def adaptation(response_consumer, operation_context):
def on_payload(payload): def on_payload(payload):
method.service( method(
payload, response_consumer.consume_and_terminate, payload, response_consumer.consume_and_terminate,
_control.RpcContext(operation_context)) _control.RpcContext(operation_context))
return _control.UnaryConsumer(on_payload) return _control.UnaryConsumer(on_payload)
@ -169,7 +168,7 @@ def adapt_event_value_in_value_out(method):
def adapt_event_value_in_stream_out(method): def adapt_event_value_in_stream_out(method):
def adaptation(response_consumer, operation_context): def adaptation(response_consumer, operation_context):
def on_payload(payload): def on_payload(payload):
method.service( method(
payload, response_consumer, _control.RpcContext(operation_context)) payload, response_consumer, _control.RpcContext(operation_context))
return _control.UnaryConsumer(on_payload) return _control.UnaryConsumer(on_payload)
return adaptation return adaptation
@ -178,12 +177,11 @@ def adapt_event_value_in_stream_out(method):
def adapt_event_stream_in_value_out(method): def adapt_event_stream_in_value_out(method):
def adaptation(response_consumer, operation_context): def adaptation(response_consumer, operation_context):
rpc_context = _control.RpcContext(operation_context) rpc_context = _control.RpcContext(operation_context)
return method.service(response_consumer.consume_and_terminate, rpc_context) return method(response_consumer.consume_and_terminate, rpc_context)
return adaptation return adaptation
def adapt_event_stream_in_stream_out(method): def adapt_event_stream_in_stream_out(method):
def adaptation(response_consumer, operation_context): def adaptation(response_consumer, operation_context):
return method.service( return method(response_consumer, _control.RpcContext(operation_context))
response_consumer, _control.RpcContext(operation_context))
return adaptation return adaptation

@ -42,37 +42,17 @@ class FaceTestCase(test_case.FaceTestCase):
"""Provides abstract Face-layer tests an in-memory implementation.""" """Provides abstract Face-layer tests an in-memory implementation."""
def set_up_implementation( def set_up_implementation(
self, self, name, methods, method_implementations,
name, multi_method_implementation):
methods,
inline_value_in_value_out_methods,
inline_value_in_stream_out_methods,
inline_stream_in_value_out_methods,
inline_stream_in_stream_out_methods,
event_value_in_value_out_methods,
event_value_in_stream_out_methods,
event_stream_in_value_out_methods,
event_stream_in_stream_out_methods,
multi_method):
servicer_pool = logging_pool.pool(_MAXIMUM_POOL_SIZE) servicer_pool = logging_pool.pool(_MAXIMUM_POOL_SIZE)
stub_pool = logging_pool.pool(_MAXIMUM_POOL_SIZE) stub_pool = logging_pool.pool(_MAXIMUM_POOL_SIZE)
servicer = implementations.servicer( servicer = implementations.servicer(
servicer_pool, servicer_pool, method_implementations, multi_method_implementation)
inline_value_in_value_out_methods=inline_value_in_value_out_methods,
inline_value_in_stream_out_methods=inline_value_in_stream_out_methods,
inline_stream_in_value_out_methods=inline_stream_in_value_out_methods,
inline_stream_in_stream_out_methods=inline_stream_in_stream_out_methods,
event_value_in_value_out_methods=event_value_in_value_out_methods,
event_value_in_stream_out_methods=event_value_in_stream_out_methods,
event_stream_in_value_out_methods=event_stream_in_value_out_methods,
event_stream_in_stream_out_methods=event_stream_in_stream_out_methods,
multi_method=multi_method)
linked_pair = base_util.linked_pair(servicer, _TIMEOUT) linked_pair = base_util.linked_pair(servicer, _TIMEOUT)
server = implementations.server() stub = implementations.generic_stub(linked_pair.front, stub_pool)
stub = implementations.stub(linked_pair.front, stub_pool) return stub, (servicer_pool, stub_pool, linked_pair)
return server, stub, (servicer_pool, stub_pool, linked_pair)
def tear_down_implementation(self, memo): def tear_down_implementation(self, memo):
servicer_pool, stub_pool, linked_pair = memo servicer_pool, stub_pool, linked_pair = memo

@ -29,6 +29,8 @@
"""Entry points into the Face layer of RPC Framework.""" """Entry points into the Face layer of RPC Framework."""
from grpc.framework.common import cardinality
from grpc.framework.common import style
from grpc.framework.base import exceptions as _base_exceptions from grpc.framework.base import exceptions as _base_exceptions
from grpc.framework.base import interfaces as base_interfaces from grpc.framework.base import interfaces as base_interfaces
from grpc.framework.face import _calls from grpc.framework.face import _calls
@ -56,7 +58,7 @@ class _BaseServicer(base_interfaces.Servicer):
raise _base_exceptions.NoSuchMethodError() raise _base_exceptions.NoSuchMethodError()
class _UnaryUnarySyncAsync(interfaces.UnaryUnarySyncAsync): class _UnaryUnaryMultiCallable(interfaces.UnaryUnaryMultiCallable):
def __init__(self, front, name): def __init__(self, front, name):
self._front = front self._front = front
@ -66,12 +68,33 @@ class _UnaryUnarySyncAsync(interfaces.UnaryUnarySyncAsync):
return _calls.blocking_value_in_value_out( return _calls.blocking_value_in_value_out(
self._front, self._name, request, timeout, 'unused trace ID') self._front, self._name, request, timeout, 'unused trace ID')
def async(self, request, timeout): def future(self, request, timeout):
return _calls.future_value_in_value_out( return _calls.future_value_in_value_out(
self._front, self._name, request, timeout, 'unused trace ID') self._front, self._name, request, timeout, 'unused trace ID')
def event(self, request, response_callback, abortion_callback, timeout):
return _calls.event_value_in_value_out(
self._front, self._name, request, response_callback, abortion_callback,
timeout, 'unused trace ID')
class _UnaryStreamMultiCallable(interfaces.UnaryStreamMultiCallable):
def __init__(self, front, name):
self._front = front
self._name = name
class _StreamUnarySyncAsync(interfaces.StreamUnarySyncAsync): def __call__(self, request, timeout):
return _calls.inline_value_in_stream_out(
self._front, self._name, request, timeout, 'unused trace ID')
def event(self, request, response_consumer, abortion_callback, timeout):
return _calls.event_value_in_stream_out(
self._front, self._name, request, response_consumer, abortion_callback,
timeout, 'unused trace ID')
class _StreamUnaryMultiCallable(interfaces.StreamUnaryMultiCallable):
def __init__(self, front, name, pool): def __init__(self, front, name, pool):
self._front = front self._front = front
@ -82,18 +105,37 @@ class _StreamUnarySyncAsync(interfaces.StreamUnarySyncAsync):
return _calls.blocking_stream_in_value_out( return _calls.blocking_stream_in_value_out(
self._front, self._name, request_iterator, timeout, 'unused trace ID') self._front, self._name, request_iterator, timeout, 'unused trace ID')
def async(self, request_iterator, timeout): def future(self, request_iterator, timeout):
return _calls.future_stream_in_value_out( return _calls.future_stream_in_value_out(
self._front, self._name, request_iterator, timeout, 'unused trace ID', self._front, self._name, request_iterator, timeout, 'unused trace ID',
self._pool) self._pool)
def event(self, response_callback, abortion_callback, timeout):
return _calls.event_stream_in_value_out(
self._front, self._name, response_callback, abortion_callback, timeout,
'unused trace ID')
class _Server(interfaces.Server):
"""An interfaces.Server implementation."""
class _StreamStreamMultiCallable(interfaces.StreamStreamMultiCallable):
class _Stub(interfaces.Stub): def __init__(self, front, name, pool):
"""An interfaces.Stub implementation.""" self._front = front
self._name = name
self._pool = pool
def __call__(self, request_iterator, timeout):
return _calls.inline_stream_in_stream_out(
self._front, self._name, request_iterator, timeout, 'unused trace ID',
self._pool)
def event(self, response_consumer, abortion_callback, timeout):
return _calls.event_stream_in_stream_out(
self._front, self._name, response_consumer, abortion_callback, timeout,
'unused trace ID')
class _GenericStub(interfaces.GenericStub):
"""An interfaces.GenericStub implementation."""
def __init__(self, front, pool): def __init__(self, front, pool):
self._front = front self._front = front
@ -149,136 +191,128 @@ class _Stub(interfaces.Stub):
self._front, name, response_consumer, abortion_callback, timeout, self._front, name, response_consumer, abortion_callback, timeout,
'unused trace ID') 'unused trace ID')
def unary_unary_sync_async(self, name): def unary_unary_multi_callable(self, name):
return _UnaryUnarySyncAsync(self._front, name) return _UnaryUnaryMultiCallable(self._front, name)
def stream_unary_sync_async(self, name): def unary_stream_multi_callable(self, name):
return _StreamUnarySyncAsync(self._front, name, self._pool) return _UnaryStreamMultiCallable(self._front, name)
def stream_unary_multi_callable(self, name):
def _aggregate_methods( return _StreamUnaryMultiCallable(self._front, name, self._pool)
pool,
inline_value_in_value_out_methods, def stream_stream_multi_callable(self, name):
inline_value_in_stream_out_methods, return _StreamStreamMultiCallable(self._front, name, self._pool)
inline_stream_in_value_out_methods,
inline_stream_in_stream_out_methods,
event_value_in_value_out_methods, class _DynamicStub(interfaces.DynamicStub):
event_value_in_stream_out_methods, """An interfaces.DynamicStub implementation."""
event_stream_in_value_out_methods,
event_stream_in_stream_out_methods): def __init__(self, cardinalities, front, pool):
"""Aggregates methods coded in according to different interfaces.""" self._cardinalities = cardinalities
methods = {} self._front = front
self._pool = pool
def adapt_unpooled_methods(adapted_methods, unadapted_methods, adaptation):
if unadapted_methods is not None: def __getattr__(self, attr):
for name, unadapted_method in unadapted_methods.iteritems(): cardinality = self._cardinalities.get(attr)
adapted_methods[name] = adaptation(unadapted_method) if cardinality is cardinality.Cardinality.UNARY_UNARY:
return _UnaryUnaryMultiCallable(self._front, attr)
def adapt_pooled_methods(adapted_methods, unadapted_methods, adaptation): elif cardinality is cardinality.Cardinality.UNARY_STREAM:
if unadapted_methods is not None: return _UnaryStreamMultiCallable(self._front, attr)
for name, unadapted_method in unadapted_methods.iteritems(): elif cardinality is cardinality.Cardinality.STREAM_UNARY:
adapted_methods[name] = adaptation(unadapted_method, pool) return _StreamUnaryMultiCallable(self._front, attr, self._pool)
elif cardinality is cardinality.Cardinality.STREAM_STREAM:
adapt_unpooled_methods( return _StreamStreamMultiCallable(self._front, attr, self._pool)
methods, inline_value_in_value_out_methods, else:
_service.adapt_inline_value_in_value_out) raise AttributeError('_DynamicStub object has no attribute "%s"!' % attr)
adapt_unpooled_methods(
methods, inline_value_in_stream_out_methods,
_service.adapt_inline_value_in_stream_out) def _adapt_method_implementations(method_implementations, pool):
adapt_pooled_methods( adapted_implementations = {}
methods, inline_stream_in_value_out_methods, for name, method_implementation in method_implementations.iteritems():
_service.adapt_inline_stream_in_value_out) if method_implementation.style is style.Service.INLINE:
adapt_pooled_methods( if method_implementation.cardinality is cardinality.Cardinality.UNARY_UNARY:
methods, inline_stream_in_stream_out_methods, adapted_implementations[name] = _service.adapt_inline_value_in_value_out(
_service.adapt_inline_stream_in_stream_out) method_implementation.unary_unary_inline)
adapt_unpooled_methods( elif method_implementation.cardinality is cardinality.Cardinality.UNARY_STREAM:
methods, event_value_in_value_out_methods, adapted_implementations[name] = _service.adapt_inline_value_in_stream_out(
_service.adapt_event_value_in_value_out) method_implementation.unary_stream_inline)
adapt_unpooled_methods( elif method_implementation.cardinality is cardinality.Cardinality.STREAM_UNARY:
methods, event_value_in_stream_out_methods, adapted_implementations[name] = _service.adapt_inline_stream_in_value_out(
_service.adapt_event_value_in_stream_out) method_implementation.stream_unary_inline, pool)
adapt_unpooled_methods( elif method_implementation.cardinality is cardinality.Cardinality.STREAM_STREAM:
methods, event_stream_in_value_out_methods, adapted_implementations[name] = _service.adapt_inline_stream_in_stream_out(
_service.adapt_event_stream_in_value_out) method_implementation.stream_stream_inline, pool)
adapt_unpooled_methods( elif method_implementation.style is style.Service.EVENT:
methods, event_stream_in_stream_out_methods, if method_implementation.cardinality is cardinality.Cardinality.UNARY_UNARY:
_service.adapt_event_stream_in_stream_out) adapted_implementations[name] = _service.adapt_event_value_in_value_out(
method_implementation.unary_unary_event)
return methods elif method_implementation.cardinality is cardinality.Cardinality.UNARY_STREAM:
adapted_implementations[name] = _service.adapt_event_value_in_stream_out(
method_implementation.unary_stream_event)
def servicer( elif method_implementation.cardinality is cardinality.Cardinality.STREAM_UNARY:
pool, adapted_implementations[name] = _service.adapt_event_stream_in_value_out(
inline_value_in_value_out_methods=None, method_implementation.stream_unary_event)
inline_value_in_stream_out_methods=None, elif method_implementation.cardinality is cardinality.Cardinality.STREAM_STREAM:
inline_stream_in_value_out_methods=None, adapted_implementations[name] = _service.adapt_event_stream_in_stream_out(
inline_stream_in_stream_out_methods=None, method_implementation.stream_stream_event)
event_value_in_value_out_methods=None, return adapted_implementations
event_value_in_stream_out_methods=None,
event_stream_in_value_out_methods=None,
event_stream_in_stream_out_methods=None, def servicer(pool, method_implementations, multi_method_implementation):
multi_method=None):
"""Creates a base_interfaces.Servicer. """Creates a base_interfaces.Servicer.
The key sets of the passed dictionaries must be disjoint. It is guaranteed It is guaranteed that any passed interfaces.MultiMethodImplementation will
that any passed MultiMethod implementation will only be called to service an only be called to service an RPC if there is no
RPC if the RPC method name is not present in the key sets of the passed interfaces.MethodImplementation for the RPC method in the passed
dictionaries. method_implementations dictionary.
Args: Args:
pool: A thread pool. pool: A thread pool.
inline_value_in_value_out_methods: A dictionary mapping method names to method_implementations: A dictionary from RPC method name to
interfaces.InlineValueInValueOutMethod implementations. interfaces.MethodImplementation object to be used to service the named
inline_value_in_stream_out_methods: A dictionary mapping method names to RPC method.
interfaces.InlineValueInStreamOutMethod implementations. multi_method_implementation: An interfaces.MultiMethodImplementation to be
inline_stream_in_value_out_methods: A dictionary mapping method names to used to service any RPCs not serviced by the
interfaces.InlineStreamInValueOutMethod implementations. interfaces.MethodImplementations given in the method_implementations
inline_stream_in_stream_out_methods: A dictionary mapping method names to dictionary, or None.
interfaces.InlineStreamInStreamOutMethod implementations.
event_value_in_value_out_methods: A dictionary mapping method names to
interfaces.EventValueInValueOutMethod implementations.
event_value_in_stream_out_methods: A dictionary mapping method names to
interfaces.EventValueInStreamOutMethod implementations.
event_stream_in_value_out_methods: A dictionary mapping method names to
interfaces.EventStreamInValueOutMethod implementations.
event_stream_in_stream_out_methods: A dictionary mapping method names to
interfaces.EventStreamInStreamOutMethod implementations.
multi_method: An implementation of interfaces.MultiMethod.
Returns: Returns:
A base_interfaces.Servicer that services RPCs via the given implementations. A base_interfaces.Servicer that services RPCs via the given implementations.
""" """
methods = _aggregate_methods( adapted_implementations = _adapt_method_implementations(
pool, method_implementations, pool)
inline_value_in_value_out_methods, return _BaseServicer(adapted_implementations, multi_method_implementation)
inline_value_in_stream_out_methods,
inline_stream_in_value_out_methods,
inline_stream_in_stream_out_methods,
event_value_in_value_out_methods,
event_value_in_stream_out_methods,
event_stream_in_value_out_methods,
event_stream_in_stream_out_methods)
return _BaseServicer(methods, multi_method)
def generic_stub(front, pool):
"""Creates an interfaces.GenericStub.
def server(): Args:
"""Creates an interfaces.Server. front: A base_interfaces.Front.
pool: A futures.ThreadPoolExecutor.
Returns: Returns:
An interfaces.Server. An interfaces.GenericStub that performs RPCs via the given
base_interfaces.Front.
""" """
return _Server() return _GenericStub(front, pool)
def stub(front, pool): def dynamic_stub(cardinalities, front, pool, prefix):
"""Creates an interfaces.Stub. """Creates an interfaces.DynamicStub.
Args: Args:
cardinalities: A dict from RPC method name to cardinality.Cardinality
value identifying the cardinality of every RPC method to be supported by
the created interfaces.DynamicStub.
front: A base_interfaces.Front. front: A base_interfaces.Front.
pool: A futures.ThreadPoolExecutor. pool: A futures.ThreadPoolExecutor.
prefix: A string to prepend when mapping requested attribute name to RPC
method name during attribute access on the created
interfaces.DynamicStub.
Returns: Returns:
An interfaces.Stub that performs RPCs via the given base_interfaces.Front. An interfaces.DynamicStub that performs RPCs via the given
base_interfaces.Front.
""" """
return _Stub(front, pool) return _DynamicStub(cardinalities, front, pool, prefix)

@ -32,11 +32,24 @@
import abc import abc
import enum import enum
# exceptions, abandonment, and future are referenced from specification in this # cardinality, style, exceptions, abandonment, future, and stream are
# module. # referenced from specification in this module.
from grpc.framework.common import cardinality # pylint: disable=unused-import
from grpc.framework.common import style # pylint: disable=unused-import
from grpc.framework.face import exceptions # pylint: disable=unused-import from grpc.framework.face import exceptions # pylint: disable=unused-import
from grpc.framework.foundation import abandonment # pylint: disable=unused-import from grpc.framework.foundation import abandonment # pylint: disable=unused-import
from grpc.framework.foundation import future # pylint: disable=unused-import from grpc.framework.foundation import future # pylint: disable=unused-import
from grpc.framework.foundation import stream # pylint: disable=unused-import
@enum.unique
class Abortion(enum.Enum):
"""Categories of RPC abortion."""
CANCELLED = 'cancelled'
EXPIRED = 'expired'
NETWORK_FAILURE = 'network failure'
SERVICED_FAILURE = 'serviced failure'
SERVICER_FAILURE = 'servicer failure'
class CancellableIterator(object): class CancellableIterator(object):
@ -59,69 +72,61 @@ class CancellableIterator(object):
raise NotImplementedError() raise NotImplementedError()
class UnaryUnarySyncAsync(object): class RpcContext(object):
"""Affords invoking a unary-unary RPC synchronously or asynchronously. """Provides RPC-related information and action."""
Values implementing this interface are directly callable and present an
"async" method. Both calls take a request value and a numeric timeout.
Direct invocation of a value of this type invokes its associated RPC and
blocks until the RPC's response is available. Calling the "async" method
of a value of this type invokes its associated RPC and immediately returns a
future.Future bound to the asynchronous execution of the RPC.
"""
__metaclass__ = abc.ABCMeta __metaclass__ = abc.ABCMeta
@abc.abstractmethod @abc.abstractmethod
def __call__(self, request, timeout): def is_active(self):
"""Synchronously invokes the underlying RPC. """Describes whether the RPC is active or has terminated."""
raise NotImplementedError()
Args: @abc.abstractmethod
request: The request value for the RPC. def time_remaining(self):
timeout: A duration of time in seconds to allow for the RPC. """Describes the length of allowed time remaining for the RPC.
Returns: Returns:
The response value for the RPC. A nonnegative float indicating the length of allowed time in seconds
remaining for the RPC to complete before it is considered to have timed
Raises: out.
exceptions.RpcError: Indicating that the RPC was aborted.
""" """
raise NotImplementedError() raise NotImplementedError()
@abc.abstractmethod @abc.abstractmethod
def async(self, request, timeout): def add_abortion_callback(self, abortion_callback):
"""Asynchronously invokes the underlying RPC. """Registers a callback to be called if the RPC is aborted.
Args: Args:
request: The request value for the RPC. abortion_callback: A callable to be called and passed an Abortion value
timeout: A duration of time in seconds to allow for the RPC. in the event of RPC abortion.
Returns:
A future.Future representing the RPC. In the event of RPC completion, the
returned Future's result value will be the response value of the RPC.
In the event of RPC abortion, the returned Future's exception value
will be an exceptions.RpcError.
""" """
raise NotImplementedError() raise NotImplementedError()
class StreamUnarySyncAsync(object): class Call(object):
"""Affords invoking a stream-unary RPC synchronously or asynchronously. """Invocation-side representation of an RPC.
Values implementing this interface are directly callable and present an Attributes:
"async" method. Both calls take an iterator of request values and a numeric context: An RpcContext affording information about the RPC.
timeout. Direct invocation of a value of this type invokes its associated RPC
and blocks until the RPC's response is available. Calling the "async" method
of a value of this type invokes its associated RPC and immediately returns a
future.Future bound to the asynchronous execution of the RPC.
""" """
__metaclass__ = abc.ABCMeta __metaclass__ = abc.ABCMeta
@abc.abstractmethod @abc.abstractmethod
def __call__(self, request_iterator, timeout): def cancel(self):
"""Requests cancellation of the RPC."""
raise NotImplementedError()
class UnaryUnaryMultiCallable(object):
"""Affords invoking a unary-unary RPC in any call style."""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def __call__(self, request, timeout):
"""Synchronously invokes the underlying RPC. """Synchronously invokes the underlying RPC.
Args: Args:
request_iterator: An iterator that yields request values for the RPC. request: The request value for the RPC.
timeout: A duration of time in seconds to allow for the RPC. timeout: A duration of time in seconds to allow for the RPC.
Returns: Returns:
@ -133,11 +138,11 @@ class StreamUnarySyncAsync(object):
raise NotImplementedError() raise NotImplementedError()
@abc.abstractmethod @abc.abstractmethod
def async(self, request, timeout): def future(self, request, timeout):
"""Asynchronously invokes the underlying RPC. """Asynchronously invokes the underlying RPC.
Args: Args:
request_iterator: An iterator that yields request values for the RPC. request: The request value for the RPC.
timeout: A duration of time in seconds to allow for the RPC. timeout: A duration of time in seconds to allow for the RPC.
Returns: Returns:
@ -148,248 +153,204 @@ class StreamUnarySyncAsync(object):
""" """
raise NotImplementedError() raise NotImplementedError()
@enum.unique
class Abortion(enum.Enum):
"""Categories of RPC abortion."""
CANCELLED = 'cancelled'
EXPIRED = 'expired'
NETWORK_FAILURE = 'network failure'
SERVICED_FAILURE = 'serviced failure'
SERVICER_FAILURE = 'servicer failure'
class RpcContext(object):
"""Provides RPC-related information and action."""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def is_active(self):
"""Describes whether the RPC is active or has terminated."""
raise NotImplementedError()
@abc.abstractmethod
def time_remaining(self):
"""Describes the length of allowed time remaining for the RPC.
Returns:
A nonnegative float indicating the length of allowed time in seconds
remaining for the RPC to complete before it is considered to have timed
out.
"""
raise NotImplementedError()
@abc.abstractmethod @abc.abstractmethod
def add_abortion_callback(self, abortion_callback): def event(self, request, response_callback, abortion_callback, timeout):
"""Registers a callback to be called if the RPC is aborted. """Asynchronously invokes the underlying RPC.
Args: Args:
abortion_callback: A callable to be called and passed an Abortion value request: The request value for the RPC.
response_callback: A callback to be called to accept the restponse value
of the RPC.
abortion_callback: A callback to be called and passed an Abortion value
in the event of RPC abortion. in the event of RPC abortion.
""" timeout: A duration of time in seconds to allow for the RPC.
raise NotImplementedError()
class InlineValueInValueOutMethod(object):
"""A type for inline unary-request-unary-response RPC methods."""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def service(self, request, context):
"""Services an RPC that accepts one value and produces one value.
Args:
request: The single request value for the RPC.
context: An RpcContext object.
Returns: Returns:
The single response value for the RPC. A Call object for the RPC.
Raises:
abandonment.Abandoned: If no response is necessary because the RPC has
been aborted.
""" """
raise NotImplementedError() raise NotImplementedError()
class InlineValueInStreamOutMethod(object): class UnaryStreamMultiCallable(object):
"""A type for inline unary-request-stream-response RPC methods.""" """Affords invoking a unary-stream RPC in any call style."""
__metaclass__ = abc.ABCMeta __metaclass__ = abc.ABCMeta
@abc.abstractmethod @abc.abstractmethod
def service(self, request, context): def __call__(self, request, timeout):
"""Services an RPC that accepts one value and produces a stream of values. """Synchronously invokes the underlying RPC.
Args: Args:
request: The single request value for the RPC. request: The request value for the RPC.
context: An RpcContext object. timeout: A duration of time in seconds to allow for the RPC.
Yields:
The values that comprise the response stream of the RPC.
Raises: Returns:
abandonment.Abandoned: If completing the response stream is not necessary A CancellableIterator that yields the response values of the RPC and
because the RPC has been aborted. affords RPC cancellation. Drawing response values from the returned
CancellableIterator may raise exceptions.RpcError indicating abortion
of the RPC.
""" """
raise NotImplementedError() raise NotImplementedError()
class InlineStreamInValueOutMethod(object):
"""A type for inline stream-request-unary-response RPC methods."""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod @abc.abstractmethod
def service(self, request_iterator, context): def event(self, request, response_consumer, abortion_callback, timeout):
"""Services an RPC that accepts a stream of values and produces one value. """Asynchronously invokes the underlying RPC.
Args: Args:
request_iterator: An iterator that yields the request values of the RPC. request: The request value for the RPC.
Drawing values from this iterator may also raise exceptions.RpcError to response_consumer: A stream.Consumer to be called to accept the restponse
indicate abortion of the RPC. values of the RPC.
context: An RpcContext object. abortion_callback: A callback to be called and passed an Abortion value
in the event of RPC abortion.
Yields: timeout: A duration of time in seconds to allow for the RPC.
The values that comprise the response stream of the RPC.
Raises: Returns:
abandonment.Abandoned: If no response is necessary because the RPC has A Call object for the RPC.
been aborted.
exceptions.RpcError: Implementations of this method must not deliberately
raise exceptions.RpcError but may allow such errors raised by the
request_iterator passed to them to propagate through their bodies
uncaught.
""" """
raise NotImplementedError() raise NotImplementedError()
class InlineStreamInStreamOutMethod(object): class StreamUnaryMultiCallable(object):
"""A type for inline stream-request-stream-response RPC methods.""" """Affords invoking a stream-unary RPC in any call style."""
__metaclass__ = abc.ABCMeta __metaclass__ = abc.ABCMeta
@abc.abstractmethod @abc.abstractmethod
def service(self, request_iterator, context): def __call__(self, request_iterator, timeout):
"""Services an RPC that accepts and produces streams of values. """Synchronously invokes the underlying RPC.
Args: Args:
request_iterator: An iterator that yields the request values of the RPC. request_iterator: An iterator that yields request values for the RPC.
Drawing values from this iterator may also raise exceptions.RpcError to timeout: A duration of time in seconds to allow for the RPC.
indicate abortion of the RPC.
context: An RpcContext object.
Yields: Returns:
The values that comprise the response stream of the RPC. The response value for the RPC.
Raises: Raises:
abandonment.Abandoned: If completing the response stream is not necessary exceptions.RpcError: Indicating that the RPC was aborted.
because the RPC has been aborted.
exceptions.RpcError: Implementations of this method must not deliberately
raise exceptions.RpcError but may allow such errors raised by the
request_iterator passed to them to propagate through their bodies
uncaught.
""" """
raise NotImplementedError() raise NotImplementedError()
class EventValueInValueOutMethod(object):
"""A type for event-driven unary-request-unary-response RPC methods."""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod @abc.abstractmethod
def service(self, request, response_callback, context): def future(self, request_iterator, timeout):
"""Services an RPC that accepts one value and produces one value. """Asynchronously invokes the underlying RPC.
Args: Args:
request: The single request value for the RPC. request_iterator: An iterator that yields request values for the RPC.
response_callback: A callback to be called to accept the response value of timeout: A duration of time in seconds to allow for the RPC.
the RPC.
context: An RpcContext object.
Raises: Returns:
abandonment.Abandoned: May or may not be raised when the RPC has been A future.Future representing the RPC. In the event of RPC completion, the
aborted. returned Future's result value will be the response value of the RPC.
In the event of RPC abortion, the returned Future's exception value
will be an exceptions.RpcError.
""" """
raise NotImplementedError() raise NotImplementedError()
class EventValueInStreamOutMethod(object):
"""A type for event-driven unary-request-stream-response RPC methods."""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod @abc.abstractmethod
def service(self, request, response_consumer, context): def event(self, response_callback, abortion_callback, timeout):
"""Services an RPC that accepts one value and produces a stream of values. """Asynchronously invokes the underlying RPC.
Args: Args:
request: The single request value for the RPC. request: The request value for the RPC.
response_consumer: A stream.Consumer to be called to accept the response response_callback: A callback to be called to accept the restponse value
values of the RPC. of the RPC.
context: An RpcContext object. abortion_callback: A callback to be called and passed an Abortion value
in the event of RPC abortion.
timeout: A duration of time in seconds to allow for the RPC.
Raises: Returns:
abandonment.Abandoned: May or may not be raised when the RPC has been A pair of a Call object for the RPC and a stream.Consumer to which the
aborted. request values of the RPC should be passed.
""" """
raise NotImplementedError() raise NotImplementedError()
class EventStreamInValueOutMethod(object): class StreamStreamMultiCallable(object):
"""A type for event-driven stream-request-unary-response RPC methods.""" """Affords invoking a stream-stream RPC in any call style."""
__metaclass__ = abc.ABCMeta __metaclass__ = abc.ABCMeta
@abc.abstractmethod @abc.abstractmethod
def service(self, response_callback, context): def __call__(self, request_iterator, timeout):
"""Services an RPC that accepts a stream of values and produces one value. """Synchronously invokes the underlying RPC.
Args: Args:
response_callback: A callback to be called to accept the response value of request_iterator: An iterator that yields request values for the RPC.
the RPC. timeout: A duration of time in seconds to allow for the RPC.
context: An RpcContext object.
Returns: Returns:
A stream.Consumer with which to accept the request values of the RPC. The A CancellableIterator that yields the response values of the RPC and
consumer returned from this method may or may not be invoked to affords RPC cancellation. Drawing response values from the returned
completion: in the case of RPC abortion, RPC Framework will simply stop CancellableIterator may raise exceptions.RpcError indicating abortion
passing values to this object. Implementations must not assume that this of the RPC.
object will be called to completion of the request stream or even called
at all.
Raises:
abandonment.Abandoned: May or may not be raised when the RPC has been
aborted.
""" """
raise NotImplementedError() raise NotImplementedError()
class EventStreamInStreamOutMethod(object):
"""A type for event-driven stream-request-stream-response RPC methods."""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod @abc.abstractmethod
def service(self, response_consumer, context): def event(self, response_consumer, abortion_callback, timeout):
"""Services an RPC that accepts and produces streams of values. """Asynchronously invokes the underlying RPC.
Args: l Args:
response_consumer: A stream.Consumer to be called to accept the response response_consumer: A stream.Consumer to be called to accept the restponse
values of the RPC. values of the RPC.
context: An RpcContext object. abortion_callback: A callback to be called and passed an Abortion value
in the event of RPC abortion.
timeout: A duration of time in seconds to allow for the RPC.
Returns: Returns:
A stream.Consumer with which to accept the request values of the RPC. The A pair of a Call object for the RPC and a stream.Consumer to which the
consumer returned from this method may or may not be invoked to request values of the RPC should be passed.
completion: in the case of RPC abortion, RPC Framework will simply stop
passing values to this object. Implementations must not assume that this
object will be called to completion of the request stream or even called
at all.
Raises:
abandonment.Abandoned: May or may not be raised when the RPC has been
aborted.
""" """
raise NotImplementedError() raise NotImplementedError()
class MultiMethod(object): class MethodImplementation(object):
"""A sum type that describes an RPC method implementation.
Attributes:
cardinality: A cardinality.Cardinality value.
style: A style.Service value.
unary_unary_inline: The implementation of the RPC method as a callable
value that takes a request value and an RpcContext object and returns a
response value. Only non-None if cardinality is
cardinality.Cardinality.UNARY_UNARY and style is style.Service.INLINE.
unary_stream_inline: The implementation of the RPC method as a callable
value that takes a request value and an RpcContext object and returns an
iterator of response values. Only non-None if cardinality is
cardinality.Cardinality.UNARY_STREAM and style is style.Service.INLINE.
stream_unary_inline: The implementation of the RPC method as a callable
value that takes an iterator of request values and an RpcContext object
and returns a response value. Only non-None if cardinality is
cardinality.Cardinality.STREAM_UNARY and style is style.Service.INLINE.
stream_stream_inline: The implementation of the RPC method as a callable
value that takes an iterator of request values and an RpcContext object
and returns an iterator of response values. Only non-None if cardinality
is cardinality.Cardinality.STREAM_STREAM and style is
style.Service.INLINE.
unary_unary_event: The implementation of the RPC method as a callable value
that takes a request value, a response callback to which to pass the
response value of the RPC, and an RpcContext. Only non-None if
cardinality is cardinality.Cardinality.UNARY_UNARY and style is
style.Service.EVENT.
unary_stream_event: The implementation of the RPC method as a callable
value that takes a request value, a stream.Consumer to which to pass the
the response values of the RPC, and an RpcContext. Only non-None if
cardinality is cardinality.Cardinality.UNARY_STREAM and style is
style.Service.EVENT.
stream_unary_event: The implementation of the RPC method as a callable
value that takes a response callback to which to pass the response value
of the RPC and an RpcContext and returns a stream.Consumer to which the
request values of the RPC should be passed. Only non-None if cardinality
is cardinality.Cardinality.STREAM_UNARY and style is style.Service.EVENT.
stream_stream_event: The implementation of the RPC method as a callable
value that takes a stream.Consumer to which to pass the response values
of the RPC and an RpcContext and returns a stream.Consumer to which the
request values of the RPC should be passed. Only non-None if cardinality
is cardinality.Cardinality.STREAM_STREAM and style is
style.Service.EVENT.
"""
__metaclass__ = abc.ABCMeta
class MultiMethodImplementation(object):
"""A general type able to service many RPC methods.""" """A general type able to service many RPC methods."""
__metaclass__ = abc.ABCMeta __metaclass__ = abc.ABCMeta
@ -420,26 +381,7 @@ class MultiMethod(object):
raise NotImplementedError() raise NotImplementedError()
class Server(object): class GenericStub(object):
"""Specification of a running server that services RPCs."""
__metaclass__ = abc.ABCMeta
class Call(object):
"""Invocation-side representation of an RPC.
Attributes:
context: An RpcContext affording information about the RPC.
"""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def cancel(self):
"""Requests cancellation of the RPC."""
raise NotImplementedError()
class Stub(object):
"""Affords RPC methods to callers.""" """Affords RPC methods to callers."""
__metaclass__ = abc.ABCMeta __metaclass__ = abc.ABCMeta
@ -632,25 +574,67 @@ class Stub(object):
raise NotImplementedError() raise NotImplementedError()
@abc.abstractmethod @abc.abstractmethod
def unary_unary_sync_async(self, name): def unary_unary_multi_callable(self, name):
"""Creates a UnaryUnarySyncAsync value for a unary-unary RPC method. """Creates a UnaryUnaryMultiCallable for a unary-unary RPC method.
Args:
name: The RPC method name.
Returns:
A UnaryUnaryMultiCallable value for the named unary-unary RPC method.
"""
raise NotImplementedError()
@abc.abstractmethod
def unary_stream_multi_callable(self, name):
"""Creates a UnaryStreamMultiCallable for a unary-stream RPC method.
Args: Args:
name: The RPC method name. name: The RPC method name.
Returns: Returns:
A UnaryUnarySyncAsync value for the named unary-unary RPC method. A UnaryStreamMultiCallable value for the name unary-stream RPC method.
""" """
raise NotImplementedError() raise NotImplementedError()
@abc.abstractmethod @abc.abstractmethod
def stream_unary_sync_async(self, name): def stream_unary_multi_callable(self, name):
"""Creates a StreamUnarySyncAsync value for a stream-unary RPC method. """Creates a StreamUnaryMultiCallable for a stream-unary RPC method.
Args: Args:
name: The RPC method name. name: The RPC method name.
Returns: Returns:
A StreamUnarySyncAsync value for the named stream-unary RPC method. A StreamUnaryMultiCallable value for the named stream-unary RPC method.
""" """
raise NotImplementedError() raise NotImplementedError()
@abc.abstractmethod
def stream_stream_multi_callable(self, name):
"""Creates a StreamStreamMultiCallable for a stream-stream RPC method.
Args:
name: The RPC method name.
Returns:
A StreamStreamMultiCallable value for the named stream-stream RPC method.
"""
raise NotImplementedError()
class DynamicStub(object):
"""A stub with RPC-method-bound multi-callable attributes.
Instances of this type responsd to attribute access as follows: if the
requested attribute is the name of a unary-unary RPC method, the value of the
attribute will be a UnaryUnaryMultiCallable with which to invoke the RPC
method; if the requested attribute is the name of a unary-stream RPC method,
the value of the attribute will be a UnaryStreamMultiCallable with which to
invoke the RPC method; if the requested attribute is the name of a
stream-unary RPC method, the value of the attribute will be a
StreamUnaryMultiCallable with which to invoke the RPC method; and if the
requested attribute is the name of a stream-stream RPC method, the value of
the attribute will be a StreamStreamMultiCallable with which to invoke the
RPC method.
"""
__metaclass__ = abc.ABCMeta

@ -61,13 +61,9 @@ class BlockingInvocationInlineServiceTestCase(
self.digest = digest.digest( self.digest = digest.digest(
stock_service.STOCK_TEST_SERVICE, self.control, None) stock_service.STOCK_TEST_SERVICE, self.control, None)
self.server, self.stub, self.memo = self.set_up_implementation( self.stub, self.memo = self.set_up_implementation(
self.digest.name, self.digest.methods, self.digest.name, self.digest.methods,
self.digest.inline_unary_unary_methods, self.digest.inline_method_implementations, None)
self.digest.inline_unary_stream_methods,
self.digest.inline_stream_unary_methods,
self.digest.inline_stream_stream_methods,
{}, {}, {}, {}, None)
def tearDown(self): def tearDown(self):
"""See unittest.TestCase.tearDown for full specification. """See unittest.TestCase.tearDown for full specification.
@ -147,8 +143,8 @@ class BlockingInvocationInlineServiceTestCase(
with self.control.pause(), self.assertRaises( with self.control.pause(), self.assertRaises(
exceptions.ExpirationError): exceptions.ExpirationError):
sync_async = self.stub.unary_unary_sync_async(name) multi_callable = self.stub.unary_unary_multi_callable(name)
sync_async(request, _TIMEOUT) multi_callable(request, _TIMEOUT)
def testExpiredUnaryRequestStreamResponse(self): def testExpiredUnaryRequestStreamResponse(self):
for name, test_messages_sequence in ( for name, test_messages_sequence in (
@ -170,8 +166,8 @@ class BlockingInvocationInlineServiceTestCase(
with self.control.pause(), self.assertRaises( with self.control.pause(), self.assertRaises(
exceptions.ExpirationError): exceptions.ExpirationError):
sync_async = self.stub.stream_unary_sync_async(name) multi_callable = self.stub.stream_unary_multi_callable(name)
sync_async(iter(requests), _TIMEOUT) multi_callable(iter(requests), _TIMEOUT)
def testExpiredStreamRequestStreamResponse(self): def testExpiredStreamRequestStreamResponse(self):
for name, test_messages_sequence in ( for name, test_messages_sequence in (

@ -34,6 +34,8 @@ import threading
# testing_control, interfaces, and testing_service are referenced from # testing_control, interfaces, and testing_service are referenced from
# specification in this module. # specification in this module.
from grpc.framework.common import cardinality
from grpc.framework.common import style
from grpc.framework.face import exceptions from grpc.framework.face import exceptions
from grpc.framework.face import interfaces as face_interfaces from grpc.framework.face import interfaces as face_interfaces
from grpc.framework.face.testing import control as testing_control # pylint: disable=unused-import from grpc.framework.face.testing import control as testing_control # pylint: disable=unused-import
@ -50,15 +52,9 @@ class TestServiceDigest(
'TestServiceDigest', 'TestServiceDigest',
['name', ['name',
'methods', 'methods',
'inline_unary_unary_methods', 'inline_method_implementations',
'inline_unary_stream_methods', 'event_method_implementations',
'inline_stream_unary_methods', 'multi_method_implementation',
'inline_stream_stream_methods',
'event_unary_unary_methods',
'event_unary_stream_methods',
'event_stream_unary_methods',
'event_stream_stream_methods',
'multi_method',
'unary_unary_messages_sequences', 'unary_unary_messages_sequences',
'unary_stream_messages_sequences', 'unary_stream_messages_sequences',
'stream_unary_messages_sequences', 'stream_unary_messages_sequences',
@ -69,32 +65,14 @@ class TestServiceDigest(
name: The RPC service name to be used in the test. name: The RPC service name to be used in the test.
methods: A sequence of interfaces.Method objects describing the RPC methods: A sequence of interfaces.Method objects describing the RPC
methods that will be called during the test. methods that will be called during the test.
inline_unary_unary_methods: A dict from method name to inline_method_implementations: A dict from RPC method name to
face_interfaces.InlineValueInValueOutMethod object to be used in tests of face_interfaces.MethodImplementation object to be used in tests of
in-line calls to behaviors under test. in-line calls to behaviors under test.
inline_unary_stream_methods: A dict from method name to event_method_implementations: A dict from RPC method name to
face_interfaces.InlineValueInStreamOutMethod object to be used in tests of face_interfaces.MethodImplementation object to be used in tests of
in-line calls to behaviors under test.
inline_stream_unary_methods: A dict from method name to
face_interfaces.InlineStreamInValueOutMethod object to be used in tests of
in-line calls to behaviors under test.
inline_stream_stream_methods: A dict from method name to
face_interfaces.InlineStreamInStreamOutMethod object to be used in tests
of in-line calls to behaviors under test.
event_unary_unary_methods: A dict from method name to
face_interfaces.EventValueInValueOutMethod object to be used in tests of
event-driven calls to behaviors under test.
event_unary_stream_methods: A dict from method name to
face_interfaces.EventValueInStreamOutMethod object to be used in tests of
event-driven calls to behaviors under test.
event_stream_unary_methods: A dict from method name to
face_interfaces.EventStreamInValueOutMethod object to be used in tests of
event-driven calls to behaviors under test. event-driven calls to behaviors under test.
event_stream_stream_methods: A dict from method name to multi_method_implementation: A face_interfaces.MultiMethodImplementation to
face_interfaces.EventStreamInStreamOutMethod object to be used in tests of be used in tests of generic calls to behaviors under test.
event-driven calls to behaviors under test.
multi_method: A face_interfaces.MultiMethod to be used in tests of generic
calls to behaviors under test.
unary_unary_messages_sequences: A dict from method name to sequence of unary_unary_messages_sequences: A dict from method name to sequence of
service.UnaryUnaryTestMessages objects to be used to test the method service.UnaryUnaryTestMessages objects to be used to test the method
with the given name. with the given name.
@ -130,27 +108,33 @@ class _BufferingConsumer(stream.Consumer):
self.terminated = True self.terminated = True
class _InlineUnaryUnaryMethod(face_interfaces.InlineValueInValueOutMethod): class _InlineUnaryUnaryMethod(face_interfaces.MethodImplementation):
def __init__(self, unary_unary_test_method, control): def __init__(self, unary_unary_test_method, control):
self._test_method = unary_unary_test_method self._test_method = unary_unary_test_method
self._control = control self._control = control
def service(self, request, context): self.cardinality = cardinality.Cardinality.UNARY_UNARY
self.style = style.Service.INLINE
def unary_unary_inline(self, request, context):
response_list = [] response_list = []
self._test_method.service( self._test_method.service(
request, response_list.append, context, self._control) request, response_list.append, context, self._control)
return response_list.pop(0) return response_list.pop(0)
class _EventUnaryUnaryMethod(face_interfaces.EventValueInValueOutMethod): class _EventUnaryUnaryMethod(face_interfaces.MethodImplementation):
def __init__(self, unary_unary_test_method, control, pool): def __init__(self, unary_unary_test_method, control, pool):
self._test_method = unary_unary_test_method self._test_method = unary_unary_test_method
self._control = control self._control = control
self._pool = pool self._pool = pool
def service(self, request, response_callback, context): self.cardinality = cardinality.Cardinality.UNARY_UNARY
self.style = style.Service.EVENT
def unary_unary_event(self, request, response_callback, context):
if self._pool is None: if self._pool is None:
self._test_method.service( self._test_method.service(
request, response_callback, context, self._control) request, response_callback, context, self._control)
@ -160,13 +144,16 @@ class _EventUnaryUnaryMethod(face_interfaces.EventValueInValueOutMethod):
self._control) self._control)
class _InlineUnaryStreamMethod(face_interfaces.InlineValueInStreamOutMethod): class _InlineUnaryStreamMethod(face_interfaces.MethodImplementation):
def __init__(self, unary_stream_test_method, control): def __init__(self, unary_stream_test_method, control):
self._test_method = unary_stream_test_method self._test_method = unary_stream_test_method
self._control = control self._control = control
def service(self, request, context): self.cardinality = cardinality.Cardinality.UNARY_STREAM
self.style = style.Service.INLINE
def unary_stream_inline(self, request, context):
response_consumer = _BufferingConsumer() response_consumer = _BufferingConsumer()
self._test_method.service( self._test_method.service(
request, response_consumer, context, self._control) request, response_consumer, context, self._control)
@ -174,14 +161,17 @@ class _InlineUnaryStreamMethod(face_interfaces.InlineValueInStreamOutMethod):
yield response yield response
class _EventUnaryStreamMethod(face_interfaces.EventValueInStreamOutMethod): class _EventUnaryStreamMethod(face_interfaces.MethodImplementation):
def __init__(self, unary_stream_test_method, control, pool): def __init__(self, unary_stream_test_method, control, pool):
self._test_method = unary_stream_test_method self._test_method = unary_stream_test_method
self._control = control self._control = control
self._pool = pool self._pool = pool
def service(self, request, response_consumer, context): self.cardinality = cardinality.Cardinality.UNARY_STREAM
self.style = style.Service.EVENT
def unary_stream_event(self, request, response_consumer, context):
if self._pool is None: if self._pool is None:
self._test_method.service( self._test_method.service(
request, response_consumer, context, self._control) request, response_consumer, context, self._control)
@ -191,13 +181,16 @@ class _EventUnaryStreamMethod(face_interfaces.EventValueInStreamOutMethod):
self._control) self._control)
class _InlineStreamUnaryMethod(face_interfaces.InlineStreamInValueOutMethod): class _InlineStreamUnaryMethod(face_interfaces.MethodImplementation):
def __init__(self, stream_unary_test_method, control): def __init__(self, stream_unary_test_method, control):
self._test_method = stream_unary_test_method self._test_method = stream_unary_test_method
self._control = control self._control = control
def service(self, request_iterator, context): self.cardinality = cardinality.Cardinality.STREAM_UNARY
self.style = style.Service.INLINE
def stream_unary_inline(self, request_iterator, context):
response_list = [] response_list = []
request_consumer = self._test_method.service( request_consumer = self._test_method.service(
response_list.append, context, self._control) response_list.append, context, self._control)
@ -207,14 +200,17 @@ class _InlineStreamUnaryMethod(face_interfaces.InlineStreamInValueOutMethod):
return response_list.pop(0) return response_list.pop(0)
class _EventStreamUnaryMethod(face_interfaces.EventStreamInValueOutMethod): class _EventStreamUnaryMethod(face_interfaces.MethodImplementation):
def __init__(self, stream_unary_test_method, control, pool): def __init__(self, stream_unary_test_method, control, pool):
self._test_method = stream_unary_test_method self._test_method = stream_unary_test_method
self._control = control self._control = control
self._pool = pool self._pool = pool
def service(self, response_callback, context): self.cardinality = cardinality.Cardinality.STREAM_UNARY
self.style = style.Service.EVENT
def stream_unary_event(self, response_callback, context):
request_consumer = self._test_method.service( request_consumer = self._test_method.service(
response_callback, context, self._control) response_callback, context, self._control)
if self._pool is None: if self._pool is None:
@ -223,13 +219,16 @@ class _EventStreamUnaryMethod(face_interfaces.EventStreamInValueOutMethod):
return stream_util.ThreadSwitchingConsumer(request_consumer, self._pool) return stream_util.ThreadSwitchingConsumer(request_consumer, self._pool)
class _InlineStreamStreamMethod(face_interfaces.InlineStreamInStreamOutMethod): class _InlineStreamStreamMethod(face_interfaces.MethodImplementation):
def __init__(self, stream_stream_test_method, control): def __init__(self, stream_stream_test_method, control):
self._test_method = stream_stream_test_method self._test_method = stream_stream_test_method
self._control = control self._control = control
def service(self, request_iterator, context): self.cardinality = cardinality.Cardinality.STREAM_STREAM
self.style = style.Service.INLINE
def stream_stream_inline(self, request_iterator, context):
response_consumer = _BufferingConsumer() response_consumer = _BufferingConsumer()
request_consumer = self._test_method.service( request_consumer = self._test_method.service(
response_consumer, context, self._control) response_consumer, context, self._control)
@ -241,14 +240,17 @@ class _InlineStreamStreamMethod(face_interfaces.InlineStreamInStreamOutMethod):
response_consumer.terminate() response_consumer.terminate()
class _EventStreamStreamMethod(face_interfaces.EventStreamInStreamOutMethod): class _EventStreamStreamMethod(face_interfaces.MethodImplementation):
def __init__(self, stream_stream_test_method, control, pool): def __init__(self, stream_stream_test_method, control, pool):
self._test_method = stream_stream_test_method self._test_method = stream_stream_test_method
self._control = control self._control = control
self._pool = pool self._pool = pool
def service(self, response_consumer, context): self.cardinality = cardinality.Cardinality.STREAM_STREAM
self.style = style.Service.EVENT
def stream_stream_event(self, response_consumer, context):
request_consumer = self._test_method.service( request_consumer = self._test_method.service(
response_consumer, context, self._control) response_consumer, context, self._control)
if self._pool is None: if self._pool is None:
@ -332,7 +334,7 @@ class _StreamUnaryAdaptation(object):
response_consumer.consume_and_terminate, context, control) response_consumer.consume_and_terminate, context, control)
class _MultiMethod(face_interfaces.MultiMethod): class _MultiMethodImplementation(face_interfaces.MultiMethodImplementation):
def __init__(self, methods, control, pool): def __init__(self, methods, control, pool):
self._methods = methods self._methods = methods
@ -427,19 +429,21 @@ def digest(service, control, pool):
adaptations.update(unary_stream.adaptations) adaptations.update(unary_stream.adaptations)
adaptations.update(stream_unary.adaptations) adaptations.update(stream_unary.adaptations)
adaptations.update(stream_stream.adaptations) adaptations.update(stream_stream.adaptations)
inlines = dict(unary_unary.inlines)
inlines.update(unary_stream.inlines)
inlines.update(stream_unary.inlines)
inlines.update(stream_stream.inlines)
events = dict(unary_unary.events)
events.update(unary_stream.events)
events.update(stream_unary.events)
events.update(stream_stream.events)
return TestServiceDigest( return TestServiceDigest(
service.name(), service.name(),
methods, methods,
unary_unary.inlines, inlines,
unary_stream.inlines, events,
stream_unary.inlines, _MultiMethodImplementation(adaptations, control, pool),
stream_stream.inlines,
unary_unary.events,
unary_stream.events,
stream_unary.events,
stream_stream.events,
_MultiMethod(adaptations, control, pool),
unary_unary.messages, unary_unary.messages,
unary_stream.messages, unary_stream.messages,
stream_unary.messages, stream_unary.messages,

@ -60,14 +60,9 @@ class EventInvocationSynchronousEventServiceTestCase(
self.digest = digest.digest( self.digest = digest.digest(
stock_service.STOCK_TEST_SERVICE, self.control, None) stock_service.STOCK_TEST_SERVICE, self.control, None)
self.server, self.stub, self.memo = self.set_up_implementation( self.stub, self.memo = self.set_up_implementation(
self.digest.name, self.digest.methods, self.digest.name, self.digest.methods,
{}, {}, {}, {}, self.digest.event_method_implementations, None)
self.digest.event_unary_unary_methods,
self.digest.event_unary_stream_methods,
self.digest.event_stream_unary_methods,
self.digest.event_stream_stream_methods,
None)
def tearDown(self): def tearDown(self):
"""See unittest.TestCase.tearDown for full specification. """See unittest.TestCase.tearDown for full specification.

@ -91,14 +91,9 @@ class FutureInvocationAsynchronousEventServiceTestCase(
self.digest = digest.digest( self.digest = digest.digest(
stock_service.STOCK_TEST_SERVICE, self.control, self.digest_pool) stock_service.STOCK_TEST_SERVICE, self.control, self.digest_pool)
self.server, self.stub, self.memo = self.set_up_implementation( self.stub, self.memo = self.set_up_implementation(
self.digest.name, self.digest.methods, self.digest.name, self.digest.methods,
{}, {}, {}, {}, self.digest.event_method_implementations, None)
self.digest.event_unary_unary_methods,
self.digest.event_unary_stream_methods,
self.digest.event_stream_unary_methods,
self.digest.event_stream_stream_methods,
None)
def tearDown(self): def tearDown(self):
"""See unittest.TestCase.tearDown for full specification. """See unittest.TestCase.tearDown for full specification.
@ -190,8 +185,8 @@ class FutureInvocationAsynchronousEventServiceTestCase(
request = test_messages.request() request = test_messages.request()
with self.control.pause(): with self.control.pause():
sync_async = self.stub.unary_unary_sync_async(name) multi_callable = self.stub.unary_unary_multi_callable(name)
response_future = sync_async.async(request, _TIMEOUT) response_future = multi_callable.future(request, _TIMEOUT)
self.assertIsInstance( self.assertIsInstance(
response_future.exception(), exceptions.ExpirationError) response_future.exception(), exceptions.ExpirationError)
with self.assertRaises(exceptions.ExpirationError): with self.assertRaises(exceptions.ExpirationError):
@ -216,8 +211,8 @@ class FutureInvocationAsynchronousEventServiceTestCase(
requests = test_messages.requests() requests = test_messages.requests()
with self.control.pause(): with self.control.pause():
sync_async = self.stub.stream_unary_sync_async(name) multi_callable = self.stub.stream_unary_multi_callable(name)
response_future = sync_async.async(iter(requests), _TIMEOUT) response_future = multi_callable.future(iter(requests), _TIMEOUT)
self.assertIsInstance( self.assertIsInstance(
response_future.exception(), exceptions.ExpirationError) response_future.exception(), exceptions.ExpirationError)
with self.assertRaises(exceptions.ExpirationError): with self.assertRaises(exceptions.ExpirationError):

@ -36,8 +36,8 @@ from grpc.framework.face import interfaces as face_interfaces # pylint: disable
from grpc.framework.face.testing import interfaces from grpc.framework.face.testing import interfaces
class UnaryUnaryTestMethod(interfaces.Method): class UnaryUnaryTestMethodImplementation(interfaces.Method):
"""Like face_interfaces.EventValueInValueOutMethod but with a control.""" """A controllable implementation of a unary-unary RPC method."""
__metaclass__ = abc.ABCMeta __metaclass__ = abc.ABCMeta
@ -93,8 +93,8 @@ class UnaryUnaryTestMessages(object):
raise NotImplementedError() raise NotImplementedError()
class UnaryStreamTestMethod(interfaces.Method): class UnaryStreamTestMethodImplementation(interfaces.Method):
"""Like face_interfaces.EventValueInStreamOutMethod but with a control.""" """A controllable implementation of a unary-stream RPC method."""
__metaclass__ = abc.ABCMeta __metaclass__ = abc.ABCMeta
@ -106,7 +106,7 @@ class UnaryStreamTestMethod(interfaces.Method):
request: The single request message for the RPC. request: The single request message for the RPC.
response_consumer: A stream.Consumer to be called to accept the response response_consumer: A stream.Consumer to be called to accept the response
messages of the RPC. messages of the RPC.
context: An RpcContext object. context: A face_interfaces.RpcContext object.
control: A test_control.Control to control execution of this method. control: A test_control.Control to control execution of this method.
Raises: Raises:
@ -150,8 +150,8 @@ class UnaryStreamTestMessages(object):
raise NotImplementedError() raise NotImplementedError()
class StreamUnaryTestMethod(interfaces.Method): class StreamUnaryTestMethodImplementation(interfaces.Method):
"""Like face_interfaces.EventStreamInValueOutMethod but with a control.""" """A controllable implementation of a stream-unary RPC method."""
__metaclass__ = abc.ABCMeta __metaclass__ = abc.ABCMeta
@ -162,7 +162,7 @@ class StreamUnaryTestMethod(interfaces.Method):
Args: Args:
response_callback: A callback to be called to accept the response message response_callback: A callback to be called to accept the response message
of the RPC. of the RPC.
context: An RpcContext object. context: A face_interfaces.RpcContext object.
control: A test_control.Control to control execution of this method. control: A test_control.Control to control execution of this method.
Returns: Returns:
@ -214,8 +214,8 @@ class StreamUnaryTestMessages(object):
raise NotImplementedError() raise NotImplementedError()
class StreamStreamTestMethod(interfaces.Method): class StreamStreamTestMethodImplementation(interfaces.Method):
"""Like face_interfaces.EventStreamInStreamOutMethod but with a control.""" """A controllable implementation of a stream-stream RPC method."""
__metaclass__ = abc.ABCMeta __metaclass__ = abc.ABCMeta
@ -226,7 +226,7 @@ class StreamStreamTestMethod(interfaces.Method):
Args: Args:
response_consumer: A stream.Consumer to be called to accept the response response_consumer: A stream.Consumer to be called to accept the response
messages of the RPC. messages of the RPC.
context: An RpcContext object. context: A face_interfaces.RpcContext object.
control: A test_control.Control to control execution of this method. control: A test_control.Control to control execution of this method.
Returns: Returns:
@ -298,8 +298,8 @@ class TestService(object):
Returns: Returns:
A dict from method name to pair. The first element of the pair A dict from method name to pair. The first element of the pair
is a UnaryUnaryTestMethod object and the second element is a sequence is a UnaryUnaryTestMethodImplementation object and the second element
of UnaryUnaryTestMethodMessages objects. is a sequence of UnaryUnaryTestMethodMessages objects.
""" """
raise NotImplementedError() raise NotImplementedError()
@ -309,8 +309,8 @@ class TestService(object):
Returns: Returns:
A dict from method name to pair. The first element of the pair is a A dict from method name to pair. The first element of the pair is a
UnaryStreamTestMethod object and the second element is a sequence of UnaryStreamTestMethodImplementation object and the second element is a
UnaryStreamTestMethodMessages objects. sequence of UnaryStreamTestMethodMessages objects.
""" """
raise NotImplementedError() raise NotImplementedError()
@ -320,8 +320,8 @@ class TestService(object):
Returns: Returns:
A dict from method name to pair. The first element of the pair is a A dict from method name to pair. The first element of the pair is a
StreamUnaryTestMethod object and the second element is a sequence of StreamUnaryTestMethodImplementation object and the second element is a
StreamUnaryTestMethodMessages objects. sequence of StreamUnaryTestMethodMessages objects.
""" """
raise NotImplementedError() raise NotImplementedError()
@ -331,7 +331,7 @@ class TestService(object):
Returns: Returns:
A dict from method name to pair. The first element of the pair is a A dict from method name to pair. The first element of the pair is a
StreamStreamTestMethod object and the second element is a sequence of StreamStreamTestMethodImplementation object and the second element is a
StreamStreamTestMethodMessages objects. sequence of StreamStreamTestMethodMessages objects.
""" """
raise NotImplementedError() raise NotImplementedError()

@ -139,7 +139,7 @@ def _get_highest_trade_price(stock_reply_callback, control, active):
return StockRequestConsumer() return StockRequestConsumer()
class GetLastTradePrice(service.UnaryUnaryTestMethod): class GetLastTradePrice(service.UnaryUnaryTestMethodImplementation):
"""GetLastTradePrice for use in tests.""" """GetLastTradePrice for use in tests."""
def name(self): def name(self):
@ -186,7 +186,7 @@ class GetLastTradePriceMessages(service.UnaryUnaryTestMessages):
test_case.assertEqual(_price(request.symbol), response.price) test_case.assertEqual(_price(request.symbol), response.price)
class GetLastTradePriceMultiple(service.StreamStreamTestMethod): class GetLastTradePriceMultiple(service.StreamStreamTestMethodImplementation):
"""GetLastTradePriceMultiple for use in tests.""" """GetLastTradePriceMultiple for use in tests."""
def name(self): def name(self):
@ -238,7 +238,7 @@ class GetLastTradePriceMultipleMessages(service.StreamStreamTestMessages):
test_case.assertEqual(_price(stock_request.symbol), stock_reply.price) test_case.assertEqual(_price(stock_request.symbol), stock_reply.price)
class WatchFutureTrades(service.UnaryStreamTestMethod): class WatchFutureTrades(service.UnaryStreamTestMethodImplementation):
"""WatchFutureTrades for use in tests.""" """WatchFutureTrades for use in tests."""
def name(self): def name(self):
@ -288,7 +288,7 @@ class WatchFutureTradesMessages(service.UnaryStreamTestMessages):
test_case.assertEqual(base_price + index, response.price) test_case.assertEqual(base_price + index, response.price)
class GetHighestTradePrice(service.StreamUnaryTestMethod): class GetHighestTradePrice(service.StreamUnaryTestMethodImplementation):
"""GetHighestTradePrice for use in tests.""" """GetHighestTradePrice for use in tests."""
def name(self): def name(self):

@ -46,55 +46,24 @@ class FaceTestCase(object):
@abc.abstractmethod @abc.abstractmethod
def set_up_implementation( def set_up_implementation(
self, self, name, methods, method_implementations,
name, multi_method_implementation):
methods,
inline_value_in_value_out_methods,
inline_value_in_stream_out_methods,
inline_stream_in_value_out_methods,
inline_stream_in_stream_out_methods,
event_value_in_value_out_methods,
event_value_in_stream_out_methods,
event_stream_in_value_out_methods,
event_stream_in_stream_out_methods,
multi_method):
"""Instantiates the Face Layer implementation under test. """Instantiates the Face Layer implementation under test.
Args: Args:
name: The service name to be used in the test. name: The service name to be used in the test.
methods: A sequence of interfaces.Method objects describing the RPC methods: A sequence of interfaces.Method objects describing the RPC
methods that will be called during the test. methods that will be called during the test.
inline_value_in_value_out_methods: A dictionary from string method names method_implementations: A dictionary from string RPC method name to
to face_interfaces.InlineValueInValueOutMethod implementations of those face_interfaces.MethodImplementation object specifying
methods. implementation of an RPC method.
inline_value_in_stream_out_methods: A dictionary from string method names multi_method_implementation: An face_interfaces.MultiMethodImplementation
to face_interfaces.InlineValueInStreamOutMethod implementations of those or None.
methods.
inline_stream_in_value_out_methods: A dictionary from string method names
to face_interfaces.InlineStreamInValueOutMethod implementations of those
methods.
inline_stream_in_stream_out_methods: A dictionary from string method names
to face_interfaces.InlineStreamInStreamOutMethod implementations of
those methods.
event_value_in_value_out_methods: A dictionary from string method names
to face_interfaces.EventValueInValueOutMethod implementations of those
methods.
event_value_in_stream_out_methods: A dictionary from string method names
to face_interfaces.EventValueInStreamOutMethod implementations of those
methods.
event_stream_in_value_out_methods: A dictionary from string method names
to face_interfaces.EventStreamInValueOutMethod implementations of those
methods.
event_stream_in_stream_out_methods: A dictionary from string method names
to face_interfaces.EventStreamInStreamOutMethod implementations of those
methods.
multi_method: An face_interfaces.MultiMethod, or None.
Returns: Returns:
A sequence of length three the first element of which is a A sequence of length two the first element of which is a
face_interfaces.Server, the second element of which is a face_interfaces.GenericStub (backed by the given method
face_interfaces.Stub, (both of which are backed by the given method implementations), and the second element of which is an arbitrary memo
implementations), and the third element of which is an arbitrary memo
object to be kept and passed to tearDownImplementation at the conclusion object to be kept and passed to tearDownImplementation at the conclusion
of the test. of the test.
""" """
@ -105,7 +74,7 @@ class FaceTestCase(object):
"""Destroys the Face layer implementation under test. """Destroys the Face layer implementation under test.
Args: Args:
memo: The object from the third position of the return value of memo: The object from the second position of the return value of
set_up_implementation. set_up_implementation.
""" """
raise NotImplementedError() raise NotImplementedError()

@ -27,101 +27,44 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Utilities for the face layer of RPC Framework.""" """Utilities for RPC framework's face layer."""
# stream is referenced from specification in this module. import collections
from grpc.framework.face import interfaces
from grpc.framework.foundation import stream # pylint: disable=unused-import
class _InlineUnaryUnaryMethod(interfaces.InlineValueInValueOutMethod):
def __init__(self, behavior):
self._behavior = behavior
def service(self, request, context):
return self._behavior(request, context)
class _InlineUnaryStreamMethod(interfaces.InlineValueInStreamOutMethod):
def __init__(self, behavior):
self._behavior = behavior
def service(self, request, context):
return self._behavior(request, context)
class _InlineStreamUnaryMethod(interfaces.InlineStreamInValueOutMethod):
def __init__(self, behavior):
self._behavior = behavior
def service(self, request_iterator, context):
return self._behavior(request_iterator, context)
class _InlineStreamStreamMethod(interfaces.InlineStreamInStreamOutMethod):
def __init__(self, behavior):
self._behavior = behavior
def service(self, request_iterator, context):
return self._behavior(request_iterator, context)
from grpc.framework.common import cardinality
from grpc.framework.common import style
from grpc.framework.face import interfaces
from grpc.framework.foundation import stream
class _EventUnaryUnaryMethod(interfaces.EventValueInValueOutMethod):
def __init__(self, behavior):
self._behavior = behavior
def service(self, request, response_callback, context):
return self._behavior(request, response_callback, context)
class _EventUnaryStreamMethod(interfaces.EventValueInStreamOutMethod):
def __init__(self, behavior):
self._behavior = behavior
def service(self, request, response_consumer, context):
return self._behavior(request, response_consumer, context)
class _EventStreamUnaryMethod(interfaces.EventStreamInValueOutMethod):
def __init__(self, behavior):
self._behavior = behavior
def service(self, response_callback, context):
return self._behavior(response_callback, context)
class _EventStreamStreamMethod(interfaces.EventStreamInStreamOutMethod):
def __init__(self, behavior):
self._behavior = behavior
def service(self, response_consumer, context): class _MethodImplementation(
return self._behavior(response_consumer, context) interfaces.MethodImplementation,
collections.namedtuple(
'_MethodImplementation',
['cardinality', 'style', 'unary_unary_inline', 'unary_stream_inline',
'stream_unary_inline', 'stream_stream_inline', 'unary_unary_event',
'unary_stream_event', 'stream_unary_event', 'stream_stream_event',])):
pass
def inline_unary_unary_method(behavior): def unary_unary_inline(behavior):
"""Creates an interfaces.InlineValueInValueOutMethod from a behavior. """Creates an interfaces.MethodImplementation for the given behavior.
Args: Args:
behavior: The implementation of a unary-unary RPC method as a callable behavior: The implementation of a unary-unary RPC method as a callable value
value that takes a request value and an interfaces.RpcContext object and that takes a request value and an interfaces.RpcContext object and
returns a response value. returns a response value.
Returns: Returns:
An interfaces.InlineValueInValueOutMethod derived from the given behavior. An interfaces.MethodImplementation derived from the given behavior.
""" """
return _InlineUnaryUnaryMethod(behavior) return _MethodImplementation(
cardinality.Cardinality.UNARY_UNARY, style.Service.INLINE, behavior,
None, None, None, None, None, None, None)
def inline_unary_stream_method(behavior): def unary_stream_inline(behavior):
"""Creates an interfaces.InlineValueInStreamOutMethod from a behavior. """Creates an interfaces.MethodImplementation for the given behavior.
Args: Args:
behavior: The implementation of a unary-stream RPC method as a callable behavior: The implementation of a unary-stream RPC method as a callable
@ -129,13 +72,15 @@ def inline_unary_stream_method(behavior):
returns an iterator of response values. returns an iterator of response values.
Returns: Returns:
An interfaces.InlineValueInStreamOutMethod derived from the given behavior. An interfaces.MethodImplementation derived from the given behavior.
""" """
return _InlineUnaryStreamMethod(behavior) return _MethodImplementation(
cardinality.Cardinality.UNARY_STREAM, style.Service.INLINE, None,
behavior, None, None, None, None, None, None)
def inline_stream_unary_method(behavior): def stream_unary_inline(behavior):
"""Creates an interfaces.InlineStreamInValueOutMethod from a behavior. """Creates an interfaces.MethodImplementation for the given behavior.
Args: Args:
behavior: The implementation of a stream-unary RPC method as a callable behavior: The implementation of a stream-unary RPC method as a callable
@ -143,13 +88,15 @@ def inline_stream_unary_method(behavior):
interfaces.RpcContext object and returns a response value. interfaces.RpcContext object and returns a response value.
Returns: Returns:
An interfaces.InlineStreamInValueOutMethod derived from the given behavior. An interfaces.MethodImplementation derived from the given behavior.
""" """
return _InlineStreamUnaryMethod(behavior) return _MethodImplementation(
cardinality.Cardinality.STREAM_UNARY, style.Service.INLINE, None, None,
behavior, None, None, None, None, None)
def inline_stream_stream_method(behavior): def stream_stream_inline(behavior):
"""Creates an interfaces.InlineStreamInStreamOutMethod from a behavior. """Creates an interfaces.MethodImplementation for the given behavior.
Args: Args:
behavior: The implementation of a stream-stream RPC method as a callable behavior: The implementation of a stream-stream RPC method as a callable
@ -157,14 +104,15 @@ def inline_stream_stream_method(behavior):
interfaces.RpcContext object and returns an iterator of response values. interfaces.RpcContext object and returns an iterator of response values.
Returns: Returns:
An interfaces.InlineStreamInStreamOutMethod derived from the given An interfaces.MethodImplementation derived from the given behavior.
behavior.
""" """
return _InlineStreamStreamMethod(behavior) return _MethodImplementation(
cardinality.Cardinality.STREAM_STREAM, style.Service.INLINE, None, None,
None, behavior, None, None, None, None)
def event_unary_unary_method(behavior): def unary_unary_event(behavior):
"""Creates an interfaces.EventValueInValueOutMethod from a behavior. """Creates an interfaces.MethodImplementation for the given behavior.
Args: Args:
behavior: The implementation of a unary-unary RPC method as a callable behavior: The implementation of a unary-unary RPC method as a callable
@ -172,27 +120,31 @@ def event_unary_unary_method(behavior):
the response value of the RPC, and an interfaces.RpcContext. the response value of the RPC, and an interfaces.RpcContext.
Returns: Returns:
An interfaces.EventValueInValueOutMethod derived from the given behavior. An interfaces.MethodImplementation derived from the given behavior.
""" """
return _EventUnaryUnaryMethod(behavior) return _MethodImplementation(
cardinality.Cardinality.UNARY_UNARY, style.Service.EVENT, None, None,
None, None, behavior, None, None, None)
def event_unary_stream_method(behavior): def unary_stream_event(behavior):
"""Creates an interfaces.EventValueInStreamOutMethod from a behavior. """Creates an interfaces.MethodImplementation for the given behavior.
Args: Args:
behavior: The implementation of a unary-stream RPC method as a callable behavior: The implementation of a unary-stream RPC method as a callable
value that takes a request value, a stream.Consumer to which to pass the value that takes a request value, a stream.Consumer to which to pass the
response values of the RPC, and an interfaces.RpcContext. the response values of the RPC, and an interfaces.RpcContext.
Returns: Returns:
An interfaces.EventValueInStreamOutMethod derived from the given behavior. An interfaces.MethodImplementation derived from the given behavior.
""" """
return _EventUnaryStreamMethod(behavior) return _MethodImplementation(
cardinality.Cardinality.UNARY_STREAM, style.Service.EVENT, None, None,
None, None, None, behavior, None, None)
def event_stream_unary_method(behavior): def stream_unary_event(behavior):
"""Creates an interfaces.EventStreamInValueOutMethod from a behavior. """Creates an interfaces.MethodImplementation for the given behavior.
Args: Args:
behavior: The implementation of a stream-unary RPC method as a callable behavior: The implementation of a stream-unary RPC method as a callable
@ -201,13 +153,15 @@ def event_stream_unary_method(behavior):
which the request values of the RPC should be passed. which the request values of the RPC should be passed.
Returns: Returns:
An interfaces.EventStreamInValueOutMethod derived from the given behavior. An interfaces.MethodImplementation derived from the given behavior.
""" """
return _EventStreamUnaryMethod(behavior) return _MethodImplementation(
cardinality.Cardinality.STREAM_UNARY, style.Service.EVENT, None, None,
None, None, None, None, behavior, None)
def event_stream_stream_method(behavior): def stream_stream_event(behavior):
"""Creates an interfaces.EventStreamInStreamOutMethod from a behavior. """Creates an interfaces.MethodImplementation for the given behavior.
Args: Args:
behavior: The implementation of a stream-stream RPC method as a callable behavior: The implementation of a stream-stream RPC method as a callable
@ -216,6 +170,8 @@ def event_stream_stream_method(behavior):
which the request values of the RPC should be passed. which the request values of the RPC should be passed.
Returns: Returns:
An interfaces.EventStreamInStreamOutMethod derived from the given behavior. An interfaces.MethodImplementation derived from the given behavior.
""" """
return _EventStreamStreamMethod(behavior) return _MethodImplementation(
cardinality.Cardinality.STREAM_STREAM, style.Service.EVENT, None, None,
None, None, None, None, None, behavior)

@ -176,12 +176,11 @@ end
def main def main
opts = parse_options opts = parse_options
host = "0.0.0.0:#{opts['port']}" host = "0.0.0.0:#{opts['port']}"
s = GRPC::RpcServer.new
if opts['secure'] if opts['secure']
s = GRPC::RpcServer.new(creds: test_server_creds) s.add_http2_port(host, test_server_creds)
s.add_http2_port(host, true)
logger.info("... running securely on #{host}") logger.info("... running securely on #{host}")
else else
s = GRPC::RpcServer.new
s.add_http2_port(host) s.add_http2_port(host)
logger.info("... running insecurely on #{host}") logger.info("... running insecurely on #{host}")
end end

@ -173,12 +173,11 @@ def main
end end
end.parse! end.parse!
s = GRPC::RpcServer.new
if options['secure'] if options['secure']
s = GRPC::RpcServer.new(creds: test_server_creds) s.add_http2_port(options['host'], test_server_creds)
s.add_http2_port(options['host'], true)
logger.info("... running securely on #{options['host']}") logger.info("... running securely on #{options['host']}")
else else
s = GRPC::RpcServer.new
s.add_http2_port(options['host']) s.add_http2_port(options['host'])
logger.info("... running insecurely on #{options['host']}") logger.info("... running insecurely on #{options['host']}")
end end

@ -95,12 +95,11 @@ def main
end end
end.parse! end.parse!
s = GRPC::RpcServer.new
if options['secure'] if options['secure']
s = GRPC::RpcServer.new(creds: test_server_creds) s.add_http2_port(options['host'], test_server_creds)
s.add_http2_port(options['host'], true)
logger.info("... running securely on #{options['host']}") logger.info("... running securely on #{options['host']}")
else else
s = GRPC::RpcServer.new
s.add_http2_port(options['host']) s.add_http2_port(options['host'])
logger.info("... running insecurely on #{options['host']}") logger.info("... running insecurely on #{options['host']}")
end end

@ -97,35 +97,19 @@ static VALUE grpc_rb_server_alloc(VALUE cls) {
/* /*
call-seq: call-seq:
cq = CompletionQueue.new cq = CompletionQueue.new
insecure_server = Server.new(cq, {'arg1': 'value1'}) server = Server.new(cq, {'arg1': 'value1'})
server_creds = ...
secure_server = Server.new(cq, {'arg1': 'value1'}, server_creds)
Initializes server instances. */ Initializes server instances. */
static VALUE grpc_rb_server_init(int argc, VALUE *argv, VALUE self) { static VALUE grpc_rb_server_init(VALUE self, VALUE cqueue, VALUE channel_args) {
VALUE cqueue = Qnil;
VALUE credentials = Qnil;
VALUE channel_args = Qnil;
grpc_completion_queue *cq = NULL; grpc_completion_queue *cq = NULL;
grpc_server_credentials *creds = NULL;
grpc_rb_server *wrapper = NULL; grpc_rb_server *wrapper = NULL;
grpc_server *srv = NULL; grpc_server *srv = NULL;
grpc_channel_args args; grpc_channel_args args;
MEMZERO(&args, grpc_channel_args, 1); MEMZERO(&args, grpc_channel_args, 1);
/* "21" == 2 mandatory args, 1 (credentials) is optional */
rb_scan_args(argc, argv, "21", &cqueue, &channel_args, &credentials);
cq = grpc_rb_get_wrapped_completion_queue(cqueue); cq = grpc_rb_get_wrapped_completion_queue(cqueue);
Data_Get_Struct(self, grpc_rb_server, wrapper); Data_Get_Struct(self, grpc_rb_server, wrapper);
grpc_rb_hash_convert_to_channel_args(channel_args, &args); grpc_rb_hash_convert_to_channel_args(channel_args, &args);
srv = grpc_server_create(cq, &args); srv = grpc_server_create(cq, &args);
if (credentials == Qnil) {
srv = grpc_server_create(cq, &args);
} else {
creds = grpc_rb_get_wrapped_server_credentials(credentials);
srv = grpc_secure_server_create(creds, cq, &args);
}
if (args.args != NULL) { if (args.args != NULL) {
xfree(args.args); /* Allocated by grpc_rb_hash_convert_to_channel_args */ xfree(args.args); /* Allocated by grpc_rb_hash_convert_to_channel_args */
@ -215,33 +199,36 @@ static VALUE grpc_rb_server_destroy(VALUE self) {
// secure port // secure port
server_creds = ... server_creds = ...
secure_server = Server.new(cq, {'arg1': 'value1'}, creds) secure_server = Server.new(cq, {'arg1': 'value1'})
secure_server.add_http_port('mydomain:7575', True) secure_server.add_http_port('mydomain:7575', server_creds)
Adds a http2 port to server */ Adds a http2 port to server */
static VALUE grpc_rb_server_add_http2_port(int argc, VALUE *argv, VALUE self) { static VALUE grpc_rb_server_add_http2_port(int argc, VALUE *argv, VALUE self) {
VALUE port = Qnil; VALUE port = Qnil;
VALUE is_secure = Qnil; VALUE rb_creds = Qnil;
grpc_rb_server *s = NULL; grpc_rb_server *s = NULL;
grpc_server_credentials *creds = NULL;
int recvd_port = 0; int recvd_port = 0;
/* "11" == 1 mandatory args, 1 (is_secure) is optional */ /* "11" == 1 mandatory args, 1 (rb_creds) is optional */
rb_scan_args(argc, argv, "11", &port, &is_secure); rb_scan_args(argc, argv, "11", &port, &rb_creds);
Data_Get_Struct(self, grpc_rb_server, s); Data_Get_Struct(self, grpc_rb_server, s);
if (s->wrapped == NULL) { if (s->wrapped == NULL) {
rb_raise(rb_eRuntimeError, "closed!"); rb_raise(rb_eRuntimeError, "closed!");
return Qnil; return Qnil;
} else if (is_secure == Qnil || TYPE(is_secure) != T_TRUE) { } else if (rb_creds == Qnil) {
recvd_port = grpc_server_add_http2_port(s->wrapped, StringValueCStr(port)); recvd_port = grpc_server_add_http2_port(s->wrapped, StringValueCStr(port));
if (recvd_port == 0) { if (recvd_port == 0) {
rb_raise(rb_eRuntimeError, rb_raise(rb_eRuntimeError,
"could not add port %s to server, not sure why", "could not add port %s to server, not sure why",
StringValueCStr(port)); StringValueCStr(port));
} }
} else if (TYPE(is_secure) != T_FALSE) { } else {
creds = grpc_rb_get_wrapped_server_credentials(rb_creds);
recvd_port = recvd_port =
grpc_server_add_secure_http2_port(s->wrapped, StringValueCStr(port)); grpc_server_add_secure_http2_port(s->wrapped, StringValueCStr(port),
creds);
if (recvd_port == 0) { if (recvd_port == 0) {
rb_raise(rb_eRuntimeError, rb_raise(rb_eRuntimeError,
"could not add secure port %s to server, not sure why", "could not add secure port %s to server, not sure why",
@ -258,7 +245,7 @@ void Init_grpc_server() {
rb_define_alloc_func(rb_cServer, grpc_rb_server_alloc); rb_define_alloc_func(rb_cServer, grpc_rb_server_alloc);
/* Provides a ruby constructor and support for dup/clone. */ /* Provides a ruby constructor and support for dup/clone. */
rb_define_method(rb_cServer, "initialize", grpc_rb_server_init, -1); rb_define_method(rb_cServer, "initialize", grpc_rb_server_init, 2);
rb_define_method(rb_cServer, "initialize_copy", grpc_rb_server_init_copy, 1); rb_define_method(rb_cServer, "initialize_copy", grpc_rb_server_init_copy, 1);
/* Add the server methods. */ /* Add the server methods. */

@ -21,14 +21,10 @@ Gem::Specification.new do |s|
s.require_paths = ['lib'] s.require_paths = ['lib']
s.platform = Gem::Platform::RUBY s.platform = Gem::Platform::RUBY
s.add_dependency 'faraday', '~> 0.9'
s.add_dependency 'google-protobuf', '~> 3.0.0alpha.1.1' s.add_dependency 'google-protobuf', '~> 3.0.0alpha.1.1'
s.add_dependency 'googleauth', '~> 0.1' s.add_dependency 'googleauth', '~> 0.1'
s.add_dependency 'logging', '~> 1.8' s.add_dependency 'logging', '~> 1.8'
s.add_dependency 'jwt', '~> 1.2.1'
s.add_dependency 'minitest', '~> 5.4' # reqd for interop tests s.add_dependency 'minitest', '~> 5.4' # reqd for interop tests
s.add_dependency 'multi_json', '1.10.1'
s.add_dependency 'signet', '~> 0.6.0'
s.add_dependency 'xray', '~> 1.1' s.add_dependency 'xray', '~> 1.1'
s.add_development_dependency 'bundler', '~> 1.7' s.add_development_dependency 'bundler', '~> 1.7'

@ -39,6 +39,25 @@ module GRPC
# Default deadline is 5 seconds. # Default deadline is 5 seconds.
DEFAULT_DEADLINE = 5 DEFAULT_DEADLINE = 5
# setup_channel is used by #initialize to constuct a channel from its
# arguments.
def self.setup_channel(alt_chan, host, creds, **kw)
unless alt_chan.nil?
fail(TypeError, '!Channel') unless alt_chan.is_a?(Core::Channel)
return alt_chan
end
return Core::Channel.new(host, kw) if creds.nil?
fail(TypeError, '!Credentials') unless creds.is_a?(Core::Credentials)
Core::Channel.new(host, kw, creds)
end
# check_update_metadata is used by #initialize verify that it's a Proc.
def self.check_update_metadata(update_metadata)
return update_metadata if update_metadata.nil?
fail(TypeError, '!is_a?Proc') unless update_metadata.is_a?(Proc)
update_metadata
end
# Creates a new ClientStub. # Creates a new ClientStub.
# #
# Minimally, a stub is created with the just the host of the gRPC service # Minimally, a stub is created with the just the host of the gRPC service
@ -73,40 +92,17 @@ module GRPC
# @param update_metadata a func that updates metadata as described above # @param update_metadata a func that updates metadata as described above
# @param kw [KeywordArgs]the channel arguments # @param kw [KeywordArgs]the channel arguments
def initialize(host, q, def initialize(host, q,
channel_override:nil, channel_override: nil,
deadline: DEFAULT_DEADLINE, deadline: DEFAULT_DEADLINE,
creds: nil, creds: nil,
update_metadata: nil, update_metadata: nil,
**kw) **kw)
unless q.is_a? Core::CompletionQueue fail(TypeError, '!CompletionQueue') unless q.is_a?(Core::CompletionQueue)
fail(ArgumentError, 'not a CompletionQueue')
end
@queue = q @queue = q
@ch = ClientStub.setup_channel(channel_override, host, creds, **kw)
# set the channel instance @update_metadata = ClientStub.check_update_metadata(update_metadata)
if !channel_override.nil? alt_host = kw[Core::Channel::SSL_TARGET]
ch = channel_override @host = alt_host.nil? ? host : alt_host
fail(ArgumentError, 'not a Channel') unless ch.is_a? Core::Channel
else
if creds.nil?
ch = Core::Channel.new(host, kw)
elsif !creds.is_a?(Core::Credentials)
fail(ArgumentError, 'not a Credentials')
else
ch = Core::Channel.new(host, kw, creds)
end
end
@ch = ch
@update_metadata = nil
unless update_metadata.nil?
unless update_metadata.is_a? Proc
fail(ArgumentError, 'update_metadata is not a Proc')
end
@update_metadata = update_metadata
end
@host = host
@deadline = deadline @deadline = deadline
end end
@ -400,12 +396,7 @@ module GRPC
# @param deadline [TimeConst] # @param deadline [TimeConst]
def new_active_call(ch, marshal, unmarshal, deadline = nil) def new_active_call(ch, marshal, unmarshal, deadline = nil)
absolute_deadline = Core::TimeConsts.from_relative_time(deadline) absolute_deadline = Core::TimeConsts.from_relative_time(deadline)
# It should be OK to to pass the hostname:port to create_call, but at call = @ch.create_call(ch, @host, absolute_deadline)
# the moment this fails a security check. This will be corrected.
#
# TODO: # remove this after create_call is updated
host = @host.split(':')[0]
call = @ch.create_call(ch, host, absolute_deadline)
ActiveCall.new(call, @queue, marshal, unmarshal, absolute_deadline, ActiveCall.new(call, @queue, marshal, unmarshal, absolute_deadline,
started: false) started: false)
end end

@ -81,7 +81,6 @@ module GRPC
max_waiting_requests:DEFAULT_MAX_WAITING_REQUESTS, max_waiting_requests:DEFAULT_MAX_WAITING_REQUESTS,
poll_period:INFINITE_FUTURE, poll_period:INFINITE_FUTURE,
completion_queue_override:nil, completion_queue_override:nil,
creds:nil,
server_override:nil, server_override:nil,
**kw) **kw)
if completion_queue_override.nil? if completion_queue_override.nil?
@ -95,13 +94,7 @@ module GRPC
@cq = cq @cq = cq
if server_override.nil? if server_override.nil?
if creds.nil? srv = Core::Server.new(@cq, kw)
srv = Core::Server.new(@cq, kw)
elsif !creds.is_a? Core::ServerCredentials
fail(ArgumentError, 'not a ServerCredentials')
else
srv = Core::Server.new(@cq, kw, creds)
end
else else
srv = server_override srv = server_override
fail(ArgumentError, 'not a Server') unless srv.is_a? Core::Server fail(ArgumentError, 'not a Server') unless srv.is_a? Core::Server

@ -95,7 +95,7 @@ shared_context 'setup: tags' do
end end
def new_client_call def new_client_call
@ch.create_call('/method', 'localhost', deadline) @ch.create_call('/method', 'foo.test.google.fr', deadline)
end end
end end
@ -346,12 +346,12 @@ end
describe 'the secure http client/server' do describe 'the secure http client/server' do
before(:example) do before(:example) do
certs = load_test_certs certs = load_test_certs
server_host = 'localhost:0' server_host = '0.0.0.0:0'
@client_queue = GRPC::Core::CompletionQueue.new @client_queue = GRPC::Core::CompletionQueue.new
@server_queue = GRPC::Core::CompletionQueue.new @server_queue = GRPC::Core::CompletionQueue.new
server_creds = GRPC::Core::ServerCredentials.new(nil, certs[1], certs[2]) server_creds = GRPC::Core::ServerCredentials.new(nil, certs[1], certs[2])
@server = GRPC::Core::Server.new(@server_queue, nil, server_creds) @server = GRPC::Core::Server.new(@server_queue, nil)
server_port = @server.add_http2_port(server_host, true) server_port = @server.add_http2_port(server_host, server_creds)
@server.start @server.start
args = { Channel::SSL_TARGET => 'foo.test.google.fr' } args = { Channel::SSL_TARGET => 'foo.test.google.fr' }
@ch = Channel.new("0.0.0.0:#{server_port}", args, @ch = Channel.new("0.0.0.0:#{server_port}", args,
@ -362,11 +362,9 @@ describe 'the secure http client/server' do
@server.close @server.close
end end
# TODO: uncomment after updating the to the new c api it_behaves_like 'basic GRPC message delivery is OK' do
# it_behaves_like 'basic GRPC message delivery is OK' do end
# end
# TODO: uncomment after updating the to the new c api it_behaves_like 'GRPC metadata delivery works OK' do
# it_behaves_like 'GRPC metadata delivery works OK' do end
# end
end end

@ -164,19 +164,6 @@ describe GRPC::RpcServer do
expect(&blk).to raise_error expect(&blk).to raise_error
end end
it 'can be created with the creds as valid ServerCedentials' do
certs = load_test_certs
server_creds = GRPC::Core::ServerCredentials.new(nil, certs[1], certs[2])
blk = proc do
opts = {
a_channel_arg: 'an_arg',
creds: server_creds
}
RpcServer.new(**opts)
end
expect(&blk).to_not raise_error
end
it 'can be created with a server override' do it 'can be created with a server override' do
opts = { a_channel_arg: 'an_arg', server_override: @server } opts = { a_channel_arg: 'an_arg', server_override: @server }
blk = proc do blk = proc do

@ -118,10 +118,11 @@ describe Server do
end end
describe 'for secure servers' do describe 'for secure servers' do
let(:cert) { create_test_cert }
it 'runs without failing' do it 'runs without failing' do
blk = proc do blk = proc do
s = Server.new(@cq, nil) s = Server.new(@cq, nil)
s.add_http2_port('localhost:0', true) s.add_http2_port('localhost:0', cert)
s.close s.close
end end
expect(&blk).to_not raise_error expect(&blk).to_not raise_error
@ -130,7 +131,7 @@ describe Server do
it 'fails if the server is closed' do it 'fails if the server is closed' do
s = Server.new(@cq, nil) s = Server.new(@cq, nil)
s.close s.close
blk = proc { s.add_http2_port('localhost:0', true) } blk = proc { s.add_http2_port('localhost:0', cert) }
expect(&blk).to raise_error(RuntimeError) expect(&blk).to raise_error(RuntimeError)
end end
end end
@ -138,7 +139,7 @@ describe Server do
shared_examples '#new' do shared_examples '#new' do
it 'takes a completion queue with nil channel args' do it 'takes a completion queue with nil channel args' do
expect { Server.new(@cq, nil, create_test_cert) }.to_not raise_error expect { Server.new(@cq, nil) }.to_not raise_error
end end
it 'does not take a hash with bad keys as channel args' do it 'does not take a hash with bad keys as channel args' do
@ -195,14 +196,6 @@ describe Server do
it_behaves_like '#new' it_behaves_like '#new'
end end
describe '#new with a secure channel' do
def construct_with_args(a)
proc { Server.new(@cq, a, create_test_cert) }
end
it_behaves_like '#new'
end
def start_a_server def start_a_server
s = Server.new(@cq, nil) s = Server.new(@cq, nil)
s.add_http2_port('0.0.0.0:0') s.add_http2_port('0.0.0.0:0')

@ -917,7 +917,7 @@ PUBLIC_HEADERS_C += \\
LIB${lib.name.upper()}_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIB${lib.name.upper()}_SRC)))) LIB${lib.name.upper()}_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIB${lib.name.upper()}_SRC))))
## If the library requires OpenSSL with ALPN, let's add some restrictions. ## If the library requires OpenSSL with ALPN, let's add some restrictions.
% if lib.get('secure', True): % if lib.get('secure', 'check') == 'yes' or lib.get('secure', 'check') == 'check':
ifeq ($(NO_SECURE),true) ifeq ($(NO_SECURE),true)
# You can't build secure libraries if you don't have OpenSSL with ALPN. # You can't build secure libraries if you don't have OpenSSL with ALPN.
@ -993,14 +993,14 @@ $(LIBDIR)/$(CONFIG)/lib${lib.name}.a: $(ZLIB_DEP)\
$(Q) rm -f $(LIBDIR)/$(CONFIG)/lib${lib.name}.a $(Q) rm -f $(LIBDIR)/$(CONFIG)/lib${lib.name}.a
$(Q) $(AR) rcs $(LIBDIR)/$(CONFIG)/lib${lib.name}.a $(LIB${lib.name.upper()}_OBJS) $(Q) $(AR) rcs $(LIBDIR)/$(CONFIG)/lib${lib.name}.a $(LIB${lib.name.upper()}_OBJS)
% if lib.get('baselib', False): % if lib.get('baselib', False):
% if lib.get('secure', True): % if lib.get('secure', 'check') == 'yes':
$(Q) rm -rf tmp-merge $(Q) rm -rf tmp-merge-${lib.name}
$(Q) mkdir tmp-merge $(Q) mkdir tmp-merge-${lib.name}
$(Q) ( cd tmp-merge ; $(AR) x ../$(LIBDIR)/$(CONFIG)/lib${lib.name}.a ) $(Q) ( cd tmp-merge-${lib.name} ; $(AR) x ../$(LIBDIR)/$(CONFIG)/lib${lib.name}.a )
$(Q) for l in $(OPENSSL_MERGE_LIBS) ; do ( cd tmp-merge ; <%text>ar x ../$${l}</%text> ) ; done $(Q) for l in $(OPENSSL_MERGE_LIBS) ; do ( cd tmp-merge-${lib.name} ; <%text>ar x ../$${l}</%text> ) ; done
$(Q) rm -f $(LIBDIR)/$(CONFIG)/lib${lib.name}.a tmp-merge/__.SYMDEF* $(Q) rm -f $(LIBDIR)/$(CONFIG)/lib${lib.name}.a tmp-merge-${lib.name}/__.SYMDEF*
$(Q) ar rcs $(LIBDIR)/$(CONFIG)/lib${lib.name}.a tmp-merge/* $(Q) ar rcs $(LIBDIR)/$(CONFIG)/lib${lib.name}.a tmp-merge-${lib.name}/*
$(Q) rm -rf tmp-merge $(Q) rm -rf tmp-merge-${lib.name}
% endif % endif
% endif % endif
ifeq ($(SYSTEM),Darwin) ifeq ($(SYSTEM),Darwin)
@ -1028,8 +1028,10 @@ endif
mingw_libs = mingw_libs + ' -l' + dep + '-imp' mingw_libs = mingw_libs + ' -l' + dep + '-imp'
mingw_lib_deps = mingw_lib_deps + '$(LIBDIR)/$(CONFIG)/' + dep + '.$(SHARED_EXT)' mingw_lib_deps = mingw_lib_deps + '$(LIBDIR)/$(CONFIG)/' + dep + '.$(SHARED_EXT)'
if lib.get('secure', True): if lib.get('secure', 'check') == 'yes':
common = common + ' $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS)' common = common + ' $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS)'
if lib.get('secure', 'check') == 'yes' or lib.get('secure', 'check') == 'check':
lib_deps = lib_deps + ' $(OPENSSL_DEP)' lib_deps = lib_deps + ' $(OPENSSL_DEP)'
mingw_lib_deps = mingw_lib_deps + ' $(OPENSSL_DEP)' mingw_lib_deps = mingw_lib_deps + ' $(OPENSSL_DEP)'
@ -1056,7 +1058,7 @@ else
endif endif
endif endif
% endif % endif
% if lib.get('secure', True): % if lib.get('secure', 'check') == 'yes' or lib.get('secure', 'check') == 'check':
## If the lib was secure, we have to close the Makefile's if that tested ## If the lib was secure, we have to close the Makefile's if that tested
## the presence of an ALPN-capable OpenSSL. ## the presence of an ALPN-capable OpenSSL.
@ -1069,13 +1071,13 @@ endif
endif endif
% endif % endif
% if lib.get('secure', True): % if lib.get('secure', 'check') == 'yes' or lib.get('secure', 'check') == 'check':
ifneq ($(NO_SECURE),true) ifneq ($(NO_SECURE),true)
% endif % endif
ifneq ($(NO_DEPS),true) ifneq ($(NO_DEPS),true)
-include $(LIB${lib.name.upper()}_OBJS:.o=.dep) -include $(LIB${lib.name.upper()}_OBJS:.o=.dep)
endif endif
% if lib.get('secure', True): % if lib.get('secure', 'check') == 'yes' or lib.get('secure', 'check') == 'check':
endif endif
% endif % endif
@ -1102,7 +1104,7 @@ ${tgt.name.upper()}_SRC = \\
${tgt.name.upper()}_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(${tgt.name.upper()}_SRC)))) ${tgt.name.upper()}_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(${tgt.name.upper()}_SRC))))
% if tgt.get('secure', True): % if tgt.get('secure', 'check') == 'yes' or tgt.get('secure', 'check') == 'check':
ifeq ($(NO_SECURE),true) ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL with ALPN. # You can't build secure targets if you don't have OpenSSL with ALPN.
@ -1176,7 +1178,7 @@ $(BINDIR)/$(CONFIG)/${tgt.name}: $(${tgt.name.upper()}_OBJS)\
% endif % endif
% if tgt.build == 'protoc': % if tgt.build == 'protoc':
$(HOST_LDLIBS_PROTOC)\ $(HOST_LDLIBS_PROTOC)\
% elif tgt.get('secure', True): % elif tgt.get('secure', 'check') == 'yes' or tgt.get('secure', 'check') == 'check':
$(LDLIBS_SECURE)\ $(LDLIBS_SECURE)\
% endif % endif
-o $(BINDIR)/$(CONFIG)/${tgt.name} -o $(BINDIR)/$(CONFIG)/${tgt.name}
@ -1184,7 +1186,7 @@ $(BINDIR)/$(CONFIG)/${tgt.name}: $(${tgt.name.upper()}_OBJS)\
endif endif
% endif % endif
% if tgt.get('secure', True): % if tgt.get('secure', 'check') == 'yes' or tgt.get('secure', 'check') == 'check':
endif endif
% endif % endif
@ -1199,13 +1201,13 @@ $(OBJDIR)/$(CONFIG)/${os.path.splitext(src)[0]}.o: \
deps_${tgt.name}: $(${tgt.name.upper()}_OBJS:.o=.dep) deps_${tgt.name}: $(${tgt.name.upper()}_OBJS:.o=.dep)
% if tgt.get('secure', True): % if tgt.get('secure', 'check') == 'yes' or tgt.get('secure', 'check') == 'check':
ifneq ($(NO_SECURE),true) ifneq ($(NO_SECURE),true)
% endif % endif
ifneq ($(NO_DEPS),true) ifneq ($(NO_DEPS),true)
-include $(${tgt.name.upper()}_OBJS:.o=.dep) -include $(${tgt.name.upper()}_OBJS:.o=.dep)
endif endif
% if tgt.get('secure', True): % if tgt.get('secure', 'check') == 'yes' or tgt.get('secure', 'check') == 'check':
endif endif
% endif % endif
</%def> </%def>

@ -143,8 +143,8 @@ int main(int argc, char **argv) {
test_server1_cert}; test_server1_cert};
grpc_server_credentials *ssl_creds = grpc_server_credentials *ssl_creds =
grpc_ssl_server_credentials_create(NULL, &pem_key_cert_pair, 1); grpc_ssl_server_credentials_create(NULL, &pem_key_cert_pair, 1);
server = grpc_secure_server_create(ssl_creds, cq, &args); server = grpc_server_create(cq, &args);
GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr)); GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, ssl_creds));
grpc_server_credentials_release(ssl_creds); grpc_server_credentials_release(ssl_creds);
} else { } else {
server = grpc_server_create(cq, &args); server = grpc_server_create(cq, &args);

@ -84,9 +84,9 @@ static void chttp2_init_server_secure_fullstack(
grpc_server_destroy(f->server); grpc_server_destroy(f->server);
} }
f->server = f->server =
grpc_secure_server_create(server_creds, f->server_cq, server_args); grpc_server_create(f->server_cq, server_args);
GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, server_creds));
grpc_server_credentials_release(server_creds); grpc_server_credentials_release(server_creds);
GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr));
grpc_server_start(f->server); grpc_server_start(f->server);
} }

@ -87,9 +87,9 @@ static void chttp2_init_server_secure_fullstack(
grpc_server_destroy(f->server); grpc_server_destroy(f->server);
} }
f->server = f->server =
grpc_secure_server_create(server_creds, f->server_cq, server_args); grpc_server_create(f->server_cq, server_args);
GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, server_creds));
grpc_server_credentials_release(server_creds); grpc_server_credentials_release(server_creds);
GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr));
grpc_server_start(f->server); grpc_server_start(f->server);
} }

@ -85,9 +85,9 @@ static void chttp2_init_server_secure_fullstack(
grpc_server_destroy(f->server); grpc_server_destroy(f->server);
} }
f->server = f->server =
grpc_secure_server_create(server_creds, f->server_cq, server_args); grpc_server_create(f->server_cq, server_args);
GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, server_creds));
grpc_server_credentials_release(server_creds); grpc_server_credentials_release(server_creds);
GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr));
grpc_server_start(f->server); grpc_server_start(f->server);
} }

@ -107,7 +107,7 @@ def main():
'name': 'end2end_fixture_%s' % f, 'name': 'end2end_fixture_%s' % f,
'build': 'private', 'build': 'private',
'language': 'c', 'language': 'c',
'secure': True, 'secure': 'check',
'src': ['test/core/end2end/fixtures/%s.c' % f] 'src': ['test/core/end2end/fixtures/%s.c' % f]
} }
for f in END2END_FIXTURES] + [ for f in END2END_FIXTURES] + [
@ -115,7 +115,7 @@ def main():
'name': 'end2end_test_%s' % t, 'name': 'end2end_test_%s' % t,
'build': 'private', 'build': 'private',
'language': 'c', 'language': 'c',
'secure': False, 'secure': 'no',
'src': ['test/core/end2end/tests/%s.c' % t], 'src': ['test/core/end2end/tests/%s.c' % t],
'headers': ['test/core/end2end/tests/cancel_test_helpers.h'] 'headers': ['test/core/end2end/tests/cancel_test_helpers.h']
} }

@ -205,8 +205,8 @@ int main(int argc, char **argv) {
test_server1_cert}; test_server1_cert};
grpc_server_credentials *ssl_creds = grpc_server_credentials *ssl_creds =
grpc_ssl_server_credentials_create(NULL, &pem_key_cert_pair, 1); grpc_ssl_server_credentials_create(NULL, &pem_key_cert_pair, 1);
server = grpc_secure_server_create(ssl_creds, cq, NULL); server = grpc_server_create(cq, NULL);
GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr)); GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, ssl_creds));
grpc_server_credentials_release(ssl_creds); grpc_server_credentials_release(ssl_creds);
} else { } else {
server = grpc_server_create(cq, NULL); server = grpc_server_create(cq, NULL);

@ -654,7 +654,7 @@ int main(int argc, char **argv) {
} }
for (i = 0; i < GPR_ARRAY_SIZE(test_strategies); ++i) { for (i = 0; i < GPR_ARRAY_SIZE(test_strategies); ++i) {
if (!strcmp(test_strategies[i].name, read_strategy)) { if (strcmp(test_strategies[i].name, read_strategy) == 0) {
test_strategy = &test_strategies[i]; test_strategy = &test_strategies[i];
} }
} }

@ -58,8 +58,8 @@ static void test_simple_encode_decode_b64(int url_safe, int multiline) {
grpc_base64_encode(hello, strlen(hello), url_safe, multiline); grpc_base64_encode(hello, strlen(hello), url_safe, multiline);
gpr_slice hello_slice = grpc_base64_decode(hello_b64, url_safe); gpr_slice hello_slice = grpc_base64_decode(hello_b64, url_safe);
GPR_ASSERT(GPR_SLICE_LENGTH(hello_slice) == strlen(hello)); GPR_ASSERT(GPR_SLICE_LENGTH(hello_slice) == strlen(hello));
GPR_ASSERT(!strncmp((const char *)GPR_SLICE_START_PTR(hello_slice), hello, GPR_ASSERT(strncmp((const char *)GPR_SLICE_START_PTR(hello_slice), hello,
GPR_SLICE_LENGTH(hello_slice))); GPR_SLICE_LENGTH(hello_slice)) == 0);
gpr_slice_unref(hello_slice); gpr_slice_unref(hello_slice);
gpr_free(hello_b64); gpr_free(hello_b64);
@ -141,31 +141,31 @@ static void test_rfc4648_test_vectors(void) {
char *b64; char *b64;
b64 = grpc_base64_encode("", 0, 0, 0); b64 = grpc_base64_encode("", 0, 0, 0);
GPR_ASSERT(!strcmp("", b64)); GPR_ASSERT(strcmp("", b64) == 0);
gpr_free(b64); gpr_free(b64);
b64 = grpc_base64_encode("f", 1, 0, 0); b64 = grpc_base64_encode("f", 1, 0, 0);
GPR_ASSERT(!strcmp("Zg==", b64)); GPR_ASSERT(strcmp("Zg==", b64) == 0);
gpr_free(b64); gpr_free(b64);
b64 = grpc_base64_encode("fo", 2, 0, 0); b64 = grpc_base64_encode("fo", 2, 0, 0);
GPR_ASSERT(!strcmp("Zm8=", b64)); GPR_ASSERT(strcmp("Zm8=", b64) == 0);
gpr_free(b64); gpr_free(b64);
b64 = grpc_base64_encode("foo", 3, 0, 0); b64 = grpc_base64_encode("foo", 3, 0, 0);
GPR_ASSERT(!strcmp("Zm9v", b64)); GPR_ASSERT(strcmp("Zm9v", b64) == 0);
gpr_free(b64); gpr_free(b64);
b64 = grpc_base64_encode("foob", 4, 0, 0); b64 = grpc_base64_encode("foob", 4, 0, 0);
GPR_ASSERT(!strcmp("Zm9vYg==", b64)); GPR_ASSERT(strcmp("Zm9vYg==", b64) == 0);
gpr_free(b64); gpr_free(b64);
b64 = grpc_base64_encode("fooba", 5, 0, 0); b64 = grpc_base64_encode("fooba", 5, 0, 0);
GPR_ASSERT(!strcmp("Zm9vYmE=", b64)); GPR_ASSERT(strcmp("Zm9vYmE=", b64) == 0);
gpr_free(b64); gpr_free(b64);
b64 = grpc_base64_encode("foobar", 6, 0, 0); b64 = grpc_base64_encode("foobar", 6, 0, 0);
GPR_ASSERT(!strcmp("Zm9vYmFy", b64)); GPR_ASSERT(strcmp("Zm9vYmFy", b64) == 0);
gpr_free(b64); gpr_free(b64);
} }

@ -143,9 +143,10 @@ static void test_oauth2_token_fetcher_creds_parsing_ok(void) {
GRPC_CREDENTIALS_OK); GRPC_CREDENTIALS_OK);
GPR_ASSERT(token_lifetime.tv_sec == 3599); GPR_ASSERT(token_lifetime.tv_sec == 3599);
GPR_ASSERT(token_lifetime.tv_nsec == 0); GPR_ASSERT(token_lifetime.tv_nsec == 0);
GPR_ASSERT(!strcmp(grpc_mdstr_as_c_string(token_elem->key), "Authorization")); GPR_ASSERT(strcmp(grpc_mdstr_as_c_string(token_elem->key),
GPR_ASSERT(!strcmp(grpc_mdstr_as_c_string(token_elem->value), "Authorization") == 0);
"Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_")); GPR_ASSERT(strcmp(grpc_mdstr_as_c_string(token_elem->value),
"Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_") == 0);
grpc_mdelem_unref(token_elem); grpc_mdelem_unref(token_elem);
grpc_mdctx_unref(ctx); grpc_mdctx_unref(ctx);
} }
@ -294,15 +295,16 @@ static void test_ssl_oauth2_composite_creds(void) {
grpc_composite_credentials_create(ssl_creds, oauth2_creds); grpc_composite_credentials_create(ssl_creds, oauth2_creds);
grpc_credentials_unref(ssl_creds); grpc_credentials_unref(ssl_creds);
grpc_credentials_unref(oauth2_creds); grpc_credentials_unref(oauth2_creds);
GPR_ASSERT(!strcmp(composite_creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE)); GPR_ASSERT(strcmp(composite_creds->type,
GRPC_CREDENTIALS_TYPE_COMPOSITE) == 0);
GPR_ASSERT(grpc_credentials_has_request_metadata(composite_creds)); GPR_ASSERT(grpc_credentials_has_request_metadata(composite_creds));
GPR_ASSERT(!grpc_credentials_has_request_metadata_only(composite_creds)); GPR_ASSERT(!grpc_credentials_has_request_metadata_only(composite_creds));
creds_array = grpc_composite_credentials_get_credentials(composite_creds); creds_array = grpc_composite_credentials_get_credentials(composite_creds);
GPR_ASSERT(creds_array->num_creds == 2); GPR_ASSERT(creds_array->num_creds == 2);
GPR_ASSERT( GPR_ASSERT(strcmp(creds_array->creds_array[0]->type,
!strcmp(creds_array->creds_array[0]->type, GRPC_CREDENTIALS_TYPE_SSL)); GRPC_CREDENTIALS_TYPE_SSL) == 0);
GPR_ASSERT( GPR_ASSERT(strcmp(creds_array->creds_array[1]->type,
!strcmp(creds_array->creds_array[1]->type, GRPC_CREDENTIALS_TYPE_OAUTH2)); GRPC_CREDENTIALS_TYPE_OAUTH2) == 0);
grpc_credentials_get_request_metadata(composite_creds, test_service_url, grpc_credentials_get_request_metadata(composite_creds, test_service_url,
check_ssl_oauth2_composite_metadata, check_ssl_oauth2_composite_metadata,
composite_creds); composite_creds);
@ -338,17 +340,18 @@ static void test_ssl_oauth2_iam_composite_creds(void) {
grpc_credentials_unref(oauth2_creds); grpc_credentials_unref(oauth2_creds);
grpc_credentials_unref(aux_creds); grpc_credentials_unref(aux_creds);
grpc_credentials_unref(iam_creds); grpc_credentials_unref(iam_creds);
GPR_ASSERT(!strcmp(composite_creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE)); GPR_ASSERT(strcmp(composite_creds->type,
GRPC_CREDENTIALS_TYPE_COMPOSITE) == 0);
GPR_ASSERT(grpc_credentials_has_request_metadata(composite_creds)); GPR_ASSERT(grpc_credentials_has_request_metadata(composite_creds));
GPR_ASSERT(!grpc_credentials_has_request_metadata_only(composite_creds)); GPR_ASSERT(!grpc_credentials_has_request_metadata_only(composite_creds));
creds_array = grpc_composite_credentials_get_credentials(composite_creds); creds_array = grpc_composite_credentials_get_credentials(composite_creds);
GPR_ASSERT(creds_array->num_creds == 3); GPR_ASSERT(creds_array->num_creds == 3);
GPR_ASSERT( GPR_ASSERT(strcmp(creds_array->creds_array[0]->type,
!strcmp(creds_array->creds_array[0]->type, GRPC_CREDENTIALS_TYPE_SSL)); GRPC_CREDENTIALS_TYPE_SSL) == 0);
GPR_ASSERT( GPR_ASSERT(strcmp(creds_array->creds_array[1]->type,
!strcmp(creds_array->creds_array[1]->type, GRPC_CREDENTIALS_TYPE_OAUTH2)); GRPC_CREDENTIALS_TYPE_OAUTH2) == 0);
GPR_ASSERT( GPR_ASSERT(strcmp(creds_array->creds_array[2]->type,
!strcmp(creds_array->creds_array[2]->type, GRPC_CREDENTIALS_TYPE_IAM)); GRPC_CREDENTIALS_TYPE_IAM) == 0);
grpc_credentials_get_request_metadata(composite_creds, test_service_url, grpc_credentials_get_request_metadata(composite_creds, test_service_url,
check_ssl_oauth2_iam_composite_metadata, check_ssl_oauth2_iam_composite_metadata,
composite_creds); composite_creds);
@ -359,12 +362,12 @@ static void on_oauth2_creds_get_metadata_success(
grpc_credentials_status status) { grpc_credentials_status status) {
GPR_ASSERT(status == GRPC_CREDENTIALS_OK); GPR_ASSERT(status == GRPC_CREDENTIALS_OK);
GPR_ASSERT(num_md == 1); GPR_ASSERT(num_md == 1);
GPR_ASSERT( GPR_ASSERT(strcmp(grpc_mdstr_as_c_string(md_elems[0]->key),
!strcmp(grpc_mdstr_as_c_string(md_elems[0]->key), "Authorization")); "Authorization") == 0);
GPR_ASSERT(!strcmp(grpc_mdstr_as_c_string(md_elems[0]->value), GPR_ASSERT(strcmp(grpc_mdstr_as_c_string(md_elems[0]->value),
"Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_")); "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_") == 0);
GPR_ASSERT(user_data != NULL); GPR_ASSERT(user_data != NULL);
GPR_ASSERT(!strcmp((const char *)user_data, test_user_data)); GPR_ASSERT(strcmp((const char *)user_data, test_user_data) == 0);
} }
static void on_oauth2_creds_get_metadata_failure( static void on_oauth2_creds_get_metadata_failure(
@ -373,19 +376,19 @@ static void on_oauth2_creds_get_metadata_failure(
GPR_ASSERT(status == GRPC_CREDENTIALS_ERROR); GPR_ASSERT(status == GRPC_CREDENTIALS_ERROR);
GPR_ASSERT(num_md == 0); GPR_ASSERT(num_md == 0);
GPR_ASSERT(user_data != NULL); GPR_ASSERT(user_data != NULL);
GPR_ASSERT(!strcmp((const char *)user_data, test_user_data)); GPR_ASSERT(strcmp((const char *)user_data, test_user_data) == 0);
} }
static void validate_compute_engine_http_request( static void validate_compute_engine_http_request(
const grpc_httpcli_request *request) { const grpc_httpcli_request *request) {
GPR_ASSERT(!request->use_ssl); GPR_ASSERT(!request->use_ssl);
GPR_ASSERT(!strcmp(request->host, "metadata")); GPR_ASSERT(strcmp(request->host, "metadata") == 0);
GPR_ASSERT( GPR_ASSERT(strcmp(request->path,
!strcmp(request->path, "/computeMetadata/v1/instance/service-accounts/default/token")
"/computeMetadata/v1/instance/service-accounts/default/token")); == 0);
GPR_ASSERT(request->hdr_count == 1); GPR_ASSERT(request->hdr_count == 1);
GPR_ASSERT(!strcmp(request->hdrs[0].key, "Metadata-Flavor")); GPR_ASSERT(strcmp(request->hdrs[0].key, "Metadata-Flavor") == 0);
GPR_ASSERT(!strcmp(request->hdrs[0].value, "Google")); GPR_ASSERT(strcmp(request->hdrs[0].value, "Google") == 0);
} }
static int compute_engine_httpcli_get_success_override( static int compute_engine_httpcli_get_success_override(
@ -467,19 +470,19 @@ static void validate_jwt_encode_and_sign_params(
GPR_ASSERT(json_key->private_key != NULL); GPR_ASSERT(json_key->private_key != NULL);
GPR_ASSERT(RSA_check_key(json_key->private_key)); GPR_ASSERT(RSA_check_key(json_key->private_key));
GPR_ASSERT(json_key->type != NULL && GPR_ASSERT(json_key->type != NULL &&
!(strcmp(json_key->type, "service_account"))); strcmp(json_key->type, "service_account") == 0);
GPR_ASSERT(json_key->private_key_id != NULL && GPR_ASSERT(json_key->private_key_id != NULL &&
!strcmp(json_key->private_key_id, strcmp(json_key->private_key_id,
"e6b5137873db8d2ef81e06a47289e6434ec8a165")); "e6b5137873db8d2ef81e06a47289e6434ec8a165") == 0);
GPR_ASSERT(json_key->client_id != NULL && GPR_ASSERT(json_key->client_id != NULL &&
!strcmp(json_key->client_id, strcmp(json_key->client_id,
"777-abaslkan11hlb6nmim3bpspl31ud.apps." "777-abaslkan11hlb6nmim3bpspl31ud.apps."
"googleusercontent.com")); "googleusercontent.com") == 0);
GPR_ASSERT(json_key->client_email != NULL && GPR_ASSERT(json_key->client_email != NULL &&
!strcmp(json_key->client_email, strcmp(json_key->client_email,
"777-abaslkan11hlb6nmim3bpspl31ud@developer." "777-abaslkan11hlb6nmim3bpspl31ud@developer."
"gserviceaccount.com")); "gserviceaccount.com") == 0);
if (scope != NULL) GPR_ASSERT(!strcmp(scope, test_scope)); if (scope != NULL) GPR_ASSERT(strcmp(scope, test_scope) == 0);
GPR_ASSERT(!gpr_time_cmp(token_lifetime, grpc_max_auth_token_lifetime)); GPR_ASSERT(!gpr_time_cmp(token_lifetime, grpc_max_auth_token_lifetime));
} }
@ -517,12 +520,12 @@ static void validate_service_account_http_request(
GPR_ASSERT(!memcmp(expected_body, body, body_size)); GPR_ASSERT(!memcmp(expected_body, body, body_size));
gpr_free(expected_body); gpr_free(expected_body);
GPR_ASSERT(request->use_ssl); GPR_ASSERT(request->use_ssl);
GPR_ASSERT(!strcmp(request->host, "www.googleapis.com")); GPR_ASSERT(strcmp(request->host, "www.googleapis.com") == 0);
GPR_ASSERT(!strcmp(request->path, "/oauth2/v3/token")); GPR_ASSERT(strcmp(request->path, "/oauth2/v3/token") == 0);
GPR_ASSERT(request->hdr_count == 1); GPR_ASSERT(request->hdr_count == 1);
GPR_ASSERT(!strcmp(request->hdrs[0].key, "Content-Type")); GPR_ASSERT(strcmp(request->hdrs[0].key, "Content-Type") == 0);
GPR_ASSERT( GPR_ASSERT(strcmp(request->hdrs[0].value,
!strcmp(request->hdrs[0].value, "application/x-www-form-urlencoded")); "application/x-www-form-urlencoded") == 0);
} }
static int service_account_httpcli_post_success( static int service_account_httpcli_post_success(
@ -626,12 +629,12 @@ static void on_jwt_creds_get_metadata_success(void *user_data,
gpr_asprintf(&expected_md_value, "Bearer %s", test_signed_jwt); gpr_asprintf(&expected_md_value, "Bearer %s", test_signed_jwt);
GPR_ASSERT(status == GRPC_CREDENTIALS_OK); GPR_ASSERT(status == GRPC_CREDENTIALS_OK);
GPR_ASSERT(num_md == 1); GPR_ASSERT(num_md == 1);
GPR_ASSERT( GPR_ASSERT(strcmp(grpc_mdstr_as_c_string(md_elems[0]->key),
!strcmp(grpc_mdstr_as_c_string(md_elems[0]->key), "Authorization")); "Authorization") == 0);
GPR_ASSERT( GPR_ASSERT(strcmp(grpc_mdstr_as_c_string(md_elems[0]->value),
!strcmp(grpc_mdstr_as_c_string(md_elems[0]->value), expected_md_value)); expected_md_value) == 0);
GPR_ASSERT(user_data != NULL); GPR_ASSERT(user_data != NULL);
GPR_ASSERT(!strcmp((const char *)user_data, test_user_data)); GPR_ASSERT(strcmp((const char *)user_data, test_user_data) == 0);
gpr_free(expected_md_value); gpr_free(expected_md_value);
} }
@ -642,7 +645,7 @@ static void on_jwt_creds_get_metadata_failure(void *user_data,
GPR_ASSERT(status == GRPC_CREDENTIALS_ERROR); GPR_ASSERT(status == GRPC_CREDENTIALS_ERROR);
GPR_ASSERT(num_md == 0); GPR_ASSERT(num_md == 0);
GPR_ASSERT(user_data != NULL); GPR_ASSERT(user_data != NULL);
GPR_ASSERT(!strcmp((const char *)user_data, test_user_data)); GPR_ASSERT(strcmp((const char *)user_data, test_user_data) == 0);
} }
static void test_jwt_creds_success(void) { static void test_jwt_creds_success(void) {

@ -102,18 +102,18 @@ static void test_parse_json_key_success(void) {
grpc_auth_json_key_create_from_string(json_string); grpc_auth_json_key_create_from_string(json_string);
GPR_ASSERT(grpc_auth_json_key_is_valid(&json_key)); GPR_ASSERT(grpc_auth_json_key_is_valid(&json_key));
GPR_ASSERT(json_key.type != NULL && GPR_ASSERT(json_key.type != NULL &&
!(strcmp(json_key.type, "service_account"))); strcmp(json_key.type, "service_account") == 0);
GPR_ASSERT(json_key.private_key_id != NULL && GPR_ASSERT(json_key.private_key_id != NULL &&
!strcmp(json_key.private_key_id, strcmp(json_key.private_key_id,
"e6b5137873db8d2ef81e06a47289e6434ec8a165")); "e6b5137873db8d2ef81e06a47289e6434ec8a165") == 0);
GPR_ASSERT(json_key.client_id != NULL && GPR_ASSERT(json_key.client_id != NULL &&
!strcmp(json_key.client_id, strcmp(json_key.client_id,
"777-abaslkan11hlb6nmim3bpspl31ud.apps." "777-abaslkan11hlb6nmim3bpspl31ud.apps."
"googleusercontent.com")); "googleusercontent.com") == 0);
GPR_ASSERT(json_key.client_email != NULL && GPR_ASSERT(json_key.client_email != NULL &&
!strcmp(json_key.client_email, strcmp(json_key.client_email,
"777-abaslkan11hlb6nmim3bpspl31ud@developer." "777-abaslkan11hlb6nmim3bpspl31ud@developer."
"gserviceaccount.com")); "gserviceaccount.com") == 0);
GPR_ASSERT(json_key.private_key != NULL); GPR_ASSERT(json_key.private_key != NULL);
gpr_free(json_string); gpr_free(json_string);
grpc_auth_json_key_destruct(&json_key); grpc_auth_json_key_destruct(&json_key);
@ -248,15 +248,16 @@ static void check_jwt_header(grpc_json *header) {
} }
GPR_ASSERT(alg != NULL); GPR_ASSERT(alg != NULL);
GPR_ASSERT(alg->type == GRPC_JSON_STRING); GPR_ASSERT(alg->type == GRPC_JSON_STRING);
GPR_ASSERT(!strcmp(alg->value, "RS256")); GPR_ASSERT(strcmp(alg->value, "RS256") == 0);
GPR_ASSERT(typ != NULL); GPR_ASSERT(typ != NULL);
GPR_ASSERT(typ->type == GRPC_JSON_STRING); GPR_ASSERT(typ->type == GRPC_JSON_STRING);
GPR_ASSERT(!strcmp(typ->value, "JWT")); GPR_ASSERT(strcmp(typ->value, "JWT") == 0);
GPR_ASSERT(kid != NULL); GPR_ASSERT(kid != NULL);
GPR_ASSERT(kid->type == GRPC_JSON_STRING); GPR_ASSERT(kid->type == GRPC_JSON_STRING);
GPR_ASSERT(!strcmp(kid->value, "e6b5137873db8d2ef81e06a47289e6434ec8a165")); GPR_ASSERT(strcmp(kid->value,
"e6b5137873db8d2ef81e06a47289e6434ec8a165") == 0);
} }
static void check_jwt_claim(grpc_json *claim, const char *expected_audience, static void check_jwt_claim(grpc_json *claim, const char *expected_audience,
@ -290,27 +291,26 @@ static void check_jwt_claim(grpc_json *claim, const char *expected_audience,
GPR_ASSERT(iss != NULL); GPR_ASSERT(iss != NULL);
GPR_ASSERT(iss->type == GRPC_JSON_STRING); GPR_ASSERT(iss->type == GRPC_JSON_STRING);
GPR_ASSERT( GPR_ASSERT(strcmp(iss->value,
!strcmp( "777-abaslkan11hlb6nmim3bpspl31ud@developer.gserviceaccount.com")
iss->value, ==0);
"777-abaslkan11hlb6nmim3bpspl31ud@developer.gserviceaccount.com"));
if (expected_scope != NULL) { if (expected_scope != NULL) {
GPR_ASSERT(scope != NULL); GPR_ASSERT(scope != NULL);
GPR_ASSERT(sub == NULL); GPR_ASSERT(sub == NULL);
GPR_ASSERT(scope->type == GRPC_JSON_STRING); GPR_ASSERT(scope->type == GRPC_JSON_STRING);
GPR_ASSERT(!strcmp(scope->value, expected_scope)); GPR_ASSERT(strcmp(scope->value, expected_scope) == 0);
} else { } else {
/* Claims without scope must have a sub. */ /* Claims without scope must have a sub. */
GPR_ASSERT(scope == NULL); GPR_ASSERT(scope == NULL);
GPR_ASSERT(sub != NULL); GPR_ASSERT(sub != NULL);
GPR_ASSERT(sub->type == GRPC_JSON_STRING); GPR_ASSERT(sub->type == GRPC_JSON_STRING);
GPR_ASSERT(!strcmp(iss->value, sub->value)); GPR_ASSERT(strcmp(iss->value, sub->value) == 0);
} }
GPR_ASSERT(aud != NULL); GPR_ASSERT(aud != NULL);
GPR_ASSERT(aud->type == GRPC_JSON_STRING); GPR_ASSERT(aud->type == GRPC_JSON_STRING);
GPR_ASSERT(!strcmp(aud->value, expected_audience)); GPR_ASSERT(strcmp(aud->value, expected_audience) == 0);
GPR_ASSERT(exp != NULL); GPR_ASSERT(exp != NULL);
GPR_ASSERT(exp->type == GRPC_JSON_NUMBER); GPR_ASSERT(exp->type == GRPC_JSON_NUMBER);

@ -53,7 +53,7 @@ static void test_setenv_getenv(void) {
gpr_setenv(name, value); gpr_setenv(name, value);
retrieved_value = gpr_getenv(name); retrieved_value = gpr_getenv(name);
GPR_ASSERT(retrieved_value != NULL); GPR_ASSERT(retrieved_value != NULL);
GPR_ASSERT(!strcmp(value, retrieved_value)); GPR_ASSERT(strcmp(value, retrieved_value) == 0);
gpr_free(retrieved_value); gpr_free(retrieved_value);
} }

@ -31,7 +31,7 @@
* *
*/ */
#include "src/core/surface/lame_client.h" #include <grpc/grpc.h>
#include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/cq_verifier.h"
#include "test/core/util/test_config.h" #include "test/core/util/test_config.h"

@ -47,8 +47,7 @@ class CredentialsTest : public ::testing::Test {
TEST_F(CredentialsTest, InvalidServiceAccountCreds) { TEST_F(CredentialsTest, InvalidServiceAccountCreds) {
std::unique_ptr<Credentials> bad1 = std::unique_ptr<Credentials> bad1 =
CredentialsFactory::ServiceAccountCredentials("", "", ServiceAccountCredentials("", "", std::chrono::seconds(1));
std::chrono::seconds(1));
EXPECT_EQ(nullptr, bad1.get()); EXPECT_EQ(nullptr, bad1.get());
} }

@ -47,6 +47,7 @@
#include <grpc++/server.h> #include <grpc++/server.h>
#include <grpc++/server_builder.h> #include <grpc++/server_builder.h>
#include <grpc++/server_context.h> #include <grpc++/server_context.h>
#include <grpc++/server_credentials.h>
#include <grpc++/status.h> #include <grpc++/status.h>
#include <grpc++/stream.h> #include <grpc++/stream.h>
#include "test/core/util/port.h" #include "test/core/util/port.h"
@ -84,7 +85,7 @@ class AsyncEnd2endTest : public ::testing::Test {
server_address_ << "localhost:" << port; server_address_ << "localhost:" << port;
// Setup server // Setup server
ServerBuilder builder; ServerBuilder builder;
builder.AddPort(server_address_.str()); builder.AddPort(server_address_.str(), grpc::InsecureServerCredentials());
builder.RegisterAsyncService(&service_); builder.RegisterAsyncService(&service_);
server_ = builder.BuildAndStart(); server_ = builder.BuildAndStart();
} }
@ -102,8 +103,8 @@ class AsyncEnd2endTest : public ::testing::Test {
} }
void ResetStub() { void ResetStub() {
std::shared_ptr<ChannelInterface> channel = std::shared_ptr<ChannelInterface> channel = CreateChannel(
CreateChannelDeprecated(server_address_.str(), ChannelArguments()); server_address_.str(), InsecureCredentials(), ChannelArguments());
stub_ = std::move(grpc::cpp::test::util::TestService::NewStub(channel)); stub_ = std::move(grpc::cpp::test::util::TestService::NewStub(channel));
} }

@ -47,6 +47,7 @@
#include <grpc++/server.h> #include <grpc++/server.h>
#include <grpc++/server_builder.h> #include <grpc++/server_builder.h>
#include <grpc++/server_context.h> #include <grpc++/server_context.h>
#include <grpc++/server_credentials.h>
#include <grpc++/status.h> #include <grpc++/status.h>
#include <grpc++/stream.h> #include <grpc++/stream.h>
#include "test/core/util/port.h" #include "test/core/util/port.h"
@ -150,7 +151,7 @@ class End2endTest : public ::testing::Test {
server_address_ << "localhost:" << port; server_address_ << "localhost:" << port;
// Setup server // Setup server
ServerBuilder builder; ServerBuilder builder;
builder.AddPort(server_address_.str()); builder.AddPort(server_address_.str(), InsecureServerCredentials());
builder.RegisterService(&service_); builder.RegisterService(&service_);
builder.RegisterService(&dup_pkg_service_); builder.RegisterService(&dup_pkg_service_);
builder.SetThreadPool(&thread_pool_); builder.SetThreadPool(&thread_pool_);
@ -160,8 +161,8 @@ class End2endTest : public ::testing::Test {
void TearDown() GRPC_OVERRIDE { server_->Shutdown(); } void TearDown() GRPC_OVERRIDE { server_->Shutdown(); }
void ResetStub() { void ResetStub() {
std::shared_ptr<ChannelInterface> channel = std::shared_ptr<ChannelInterface> channel = CreateChannel(
CreateChannelDeprecated(server_address_.str(), ChannelArguments()); server_address_.str(), InsecureCredentials(), ChannelArguments());
stub_ = std::move(grpc::cpp::test::util::TestService::NewStub(channel)); stub_ = std::move(grpc::cpp::test::util::TestService::NewStub(channel));
} }
@ -371,8 +372,8 @@ TEST_F(End2endTest, BidiStream) {
// Talk to the two services with the same name but different package names. // Talk to the two services with the same name but different package names.
// The two stubs are created on the same channel. // The two stubs are created on the same channel.
TEST_F(End2endTest, DiffPackageServices) { TEST_F(End2endTest, DiffPackageServices) {
std::shared_ptr<ChannelInterface> channel = std::shared_ptr<ChannelInterface> channel = CreateChannel(
CreateChannelDeprecated(server_address_.str(), ChannelArguments()); server_address_.str(), InsecureCredentials(), ChannelArguments());
EchoRequest request; EchoRequest request;
EchoResponse response; EchoResponse response;
@ -397,8 +398,7 @@ TEST_F(End2endTest, DiffPackageServices) {
// rpc and stream should fail on bad credentials. // rpc and stream should fail on bad credentials.
TEST_F(End2endTest, BadCredentials) { TEST_F(End2endTest, BadCredentials) {
std::unique_ptr<Credentials> bad_creds = std::unique_ptr<Credentials> bad_creds =
CredentialsFactory::ServiceAccountCredentials("", "", ServiceAccountCredentials("", "", std::chrono::seconds(1));
std::chrono::seconds(1));
EXPECT_EQ(nullptr, bad_creds.get()); EXPECT_EQ(nullptr, bad_creds.get());
std::shared_ptr<ChannelInterface> channel = std::shared_ptr<ChannelInterface> channel =
CreateChannel(server_address_.str(), bad_creds, ChannelArguments()); CreateChannel(server_address_.str(), bad_creds, ChannelArguments());

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save