Merge branch 'master' into node_11_cleanup_segfault

pull/991/head
murgatroid99 10 years ago
commit 44a3b4ab7d
  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. 9
      src/ruby/lib/grpc/generic/rpc_server.rb
  80. 6
      src/ruby/spec/client_server_spec.rb
  81. 13
      src/ruby/spec/generic/rpc_server_spec.rb
  82. 15
      src/ruby/spec/server_spec.rb
  83. 38
      templates/Makefile.template
  84. 4
      test/core/echo/server.c
  85. 4
      test/core/end2end/fixtures/chttp2_fake_security.c
  86. 4
      test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c
  87. 4
      test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c
  88. 4
      test/core/end2end/gen_build_json.py
  89. 4
      test/core/fling/server.c
  90. 2
      test/core/network_benchmarks/low_level_ping_pong.c
  91. 18
      test/core/security/base64_test.c
  92. 99
      test/core/security/credentials_test.c
  93. 38
      test/core/security/json_token_test.c
  94. 2
      test/core/support/env_test.c
  95. 2
      test/core/surface/lame_client_test.c
  96. 3
      test/cpp/client/credentials_test.cc
  97. 7
      test/cpp/end2end/async_end2end_test.cc
  98. 14
      test/cpp/end2end/end2end_test.cc
  99. 17
      test/cpp/interop/client.cc
  100. 12
      test/cpp/interop/server.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_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++.a
static_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
shared: shared_c shared_cxx
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)
grpc_csharp_ext: shared_csharp
@ -1844,6 +1844,8 @@ strip-static_cxx: static_cxx
ifeq ($(CONFIG),opt)
$(E) "[STRIP] Stripping libgrpc++.a"
$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++.a
$(E) "[STRIP] Stripping libgrpc++_unsecure.a"
$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
endif
strip-shared_c: shared_c
@ -1860,6 +1862,8 @@ strip-shared_cxx: shared_cxx
ifeq ($(CONFIG),opt)
$(E) "[STRIP] Stripping libgrpc++.so"
$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT)
$(E) "[STRIP] Stripping libgrpc++_unsecure.so"
$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT)
endif
strip-shared_csharp: shared_csharp
@ -2019,6 +2023,9 @@ install-static_cxx: static_cxx strip-static_cxx
$(E) "[INSTALL] Installing libgrpc++.a"
$(Q) $(INSTALL) -d $(prefix)/lib
$(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
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),Darwin)
$(Q) ldconfig || true
@ -2350,7 +2370,6 @@ LIBGRPC_SRC = \
src/core/security/server_secure_chttp2.c \
src/core/surface/init_secure.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/ssl_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/surface/init_secure.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/ssl_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) rm -f $(LIBDIR)/$(CONFIG)/libgrpc.a
$(Q) $(AR) rcs $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBGRPC_OBJS)
$(Q) rm -rf tmp-merge
$(Q) mkdir tmp-merge
$(Q) ( cd tmp-merge ; $(AR) x ../$(LIBDIR)/$(CONFIG)/libgrpc.a )
$(Q) for l in $(OPENSSL_MERGE_LIBS) ; do ( cd tmp-merge ; ar x ../$${l} ) ; done
$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc.a tmp-merge/__.SYMDEF*
$(Q) ar rcs $(LIBDIR)/$(CONFIG)/libgrpc.a tmp-merge/*
$(Q) rm -rf tmp-merge
$(Q) rm -rf tmp-merge-grpc
$(Q) mkdir tmp-merge-grpc
$(Q) ( cd tmp-merge-grpc ; $(AR) x ../$(LIBDIR)/$(CONFIG)/libgrpc.a )
$(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-grpc/__.SYMDEF*
$(Q) ar rcs $(LIBDIR)/$(CONFIG)/libgrpc.a tmp-merge-grpc/*
$(Q) rm -rf tmp-merge-grpc
ifeq ($(SYSTEM),Darwin)
$(Q) ranlib $(LIBDIR)/$(CONFIG)/libgrpc.a
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/surface/init_secure.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/ssl_transport_security.o:
$(OBJDIR)/$(CONFIG)/src/core/tsi/transport_security.o:
@ -3074,17 +3091,21 @@ $(OBJDIR)/$(CONFIG)/src/core/transport/transport.o:
LIBGRPC++_SRC = \
src/cpp/client/secure_credentials.cc \
src/cpp/server/secure_server_credentials.cc \
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 \
@ -3151,17 +3172,21 @@ ifneq ($(OPENSSL_DEP),)
# This is to ensure the embedded OpenSSL is built beforehand, properly
# installing headers to their final destination on the drive. We need this
# 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_arguments.cc: $(OPENSSL_DEP)
src/cpp/client/client_context.cc: $(OPENSSL_DEP)
src/cpp/client/client_unary_call.cc: $(OPENSSL_DEP)
src/cpp/client/create_channel.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/common/call.cc: $(OPENSSL_DEP)
src/cpp/common/completion_queue.cc: $(OPENSSL_DEP)
src/cpp/common/rpc_method.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_builder.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)
$(E) "[LD] Linking $@"
$(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
$(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT): $(LIBGRPC++_OBJS) $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(OPENSSL_DEP)
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
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
$(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
endif
@ -3210,17 +3235,21 @@ ifneq ($(NO_DEPS),true)
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_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:
@ -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
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 = \
$(GENDIR)/examples/pubsub/label.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)
$(E) "[LD] Linking $@"
$(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
$(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 $@"
$(Q) mkdir -p `dirname $@`
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
$(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
endif

@ -9,6 +9,61 @@
}
},
"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",
"public_headers": [
@ -80,7 +135,6 @@
"src/core/surface/completion_queue.h",
"src/core/surface/event_string.h",
"src/core/surface/init.h",
"src/core/surface/lame_client.h",
"src/core/surface/server.h",
"src/core/surface/surface_trace.h",
"src/core/transport/chttp2/bin_encoder.h",
@ -276,7 +330,7 @@
"src/core/support/time_posix.c",
"src/core/support/time_win32.c"
],
"secure": false,
"secure": "no",
"vs_project_guid": "{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}"
},
{
@ -333,7 +387,6 @@
"src/core/security/server_secure_chttp2.c",
"src/core/surface/init_secure.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/ssl_transport_security.c",
"src/core/tsi/transport_security.c"
@ -345,7 +398,7 @@
"filegroups": [
"grpc_base"
],
"secure": true,
"secure": "yes",
"vs_project_guid": "{29D16885-7228-4C31-81ED-5F9187C7F2A9}"
},
{
@ -385,68 +438,26 @@
"filegroups": [
"grpc_base"
],
"secure": false,
"secure": "no",
"vs_project_guid": "{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}"
},
{
"name": "grpc++",
"build": "all",
"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/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/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"
"src/cpp/client/secure_credentials.cc",
"src/cpp/server/secure_server_credentials.cc"
],
"deps": [
"gpr",
"grpc"
],
"secure": true,
"baselib": true,
"filegroups": [
"grpc++_base"
],
"secure": "check",
"vs_project_guid": "{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}"
},
{
@ -460,6 +471,20 @@
"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",
"build": "private",
@ -1686,7 +1711,7 @@
"src/compiler/cpp_plugin.cc"
],
"deps": [],
"secure": false
"secure": "no"
},
{
"name": "grpc_python_plugin",
@ -1700,7 +1725,7 @@
"src/compiler/python_plugin.cc"
],
"deps": [],
"secure": false
"secure": "no"
},
{
"name": "grpc_ruby_plugin",
@ -1711,7 +1736,7 @@
"src/compiler/ruby_plugin.cc"
],
"deps": [],
"secure": false
"secure": "no"
},
{
"name": "interop_client",

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

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

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

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

@ -62,6 +62,9 @@ class ChannelArguments {
void SetInt(const grpc::string& key, int 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:
friend class Channel;
friend class testing::ChannelArgumentsTest;
@ -73,9 +76,6 @@ class ChannelArguments {
// Returns empty string when it is not set.
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::list<grpc::string> strings_;
};

@ -43,11 +43,6 @@ namespace grpc {
class ChannelArguments;
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.
std::shared_ptr<ChannelInterface> CreateChannel(
const grpc::string& target, const std::unique_ptr<Credentials>& creds,

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

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

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

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

@ -169,17 +169,12 @@ grpc_server_credentials *grpc_fake_transport_security_server_credentials_create(
/* --- 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.
Server must have been created with grpc_secure_server_create.
Returns bound port number on success, 0 on failure.
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
}

@ -66,7 +66,7 @@ static void backup_poller(void *p) {
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)));
gpr_mu_unlock(&g_backup_pollset.mu);
/*gpr_sleep_until(next_poll);*/
gpr_sleep_until(next_poll);
gpr_mu_lock(&g_backup_pollset.mu);
last_poll = next_poll;
}

@ -109,7 +109,7 @@ grpc_resolved_addresses *grpc_blocking_resolve_address(
};
int 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);
break;
}

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

@ -33,9 +33,9 @@
#include <string.h>
#include <grpc/grpc.h>
#include "src/core/security/credentials.h"
#include "src/core/security/security_context.h"
#include "src/core/surface/lame_client.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.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(
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;
for (i = 0; i < response->hdr_count; i++) {
grpc_httpcli_header *header = &response->hdrs[i];
if (!strcmp(header->key, "Metadata-Flavor") &&
!strcmp(header->value, "Google")) {
if (strcmp(header->key, "Metadata-Flavor") == 0 &&
strcmp(header->value, "Google") == 0) {
detector->success = 1;
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) {
if (!strcmp(algorithm, GRPC_JWT_RSA_SHA256_ALGORITHM)) {
if (strcmp(algorithm, GRPC_JWT_RSA_SHA256_ALGORITHM) == 0) {
return EVP_sha256();
} else {
gpr_log(GPR_ERROR, "Unknown algorithm %s.", algorithm);

@ -42,7 +42,6 @@
#include "src/core/support/env.h"
#include "src/core/support/file.h"
#include "src/core/support/string.h"
#include "src/core/surface/lame_client.h"
#include "src/core/transport/chttp2/alpn.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
'checked' transitively during the previous peer check at the end of the
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;
} else {
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++) {
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) {
overridden_target_name = arg->value.string;
break;

@ -33,6 +33,8 @@
#include <grpc/grpc.h>
#include <string.h>
#include "src/core/channel/http_filter.h"
#include "src/core/channel/http_server_filter.h"
#include "src/core/iomgr/endpoint.h"
@ -50,6 +52,7 @@
typedef struct grpc_server_secure_state {
grpc_server *server;
grpc_tcp_server *tcp;
grpc_security_context *ctx;
int is_shutdown;
gpr_mu mu;
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) {
if (gpr_unref(&state->refcount)) {
grpc_security_context_unref(state->ctx);
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) {
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);
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 */
static void start(grpc_server *server, void *statep, grpc_pollset **pollsets,
size_t pollset_count) {
@ -126,7 +125,7 @@ static void destroy(grpc_server *server, void *statep) {
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_tcp_server *tcp = 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;
int port_num = -1;
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");
if (!resolved) {
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->server = server;
state->tcp = tcp;
state->ctx = ctx;
state->is_shutdown = 0;
gpr_mu_init(&state->mu);
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:
if (ctx) {
grpc_security_context_unref(ctx);
}
if (resolved) {
grpc_resolved_addresses_destroy(resolved);
}
if (tcp) {
grpc_tcp_server_destroy(tcp);
}
if (state) {
gpr_free(state);
}
return 0;
}

@ -31,7 +31,7 @@
*
*/
#include "src/core/surface/lame_client.h"
#include <grpc/grpc.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) {
int i;
for (i = 0; i < TSI_FAKE_HANDSHAKE_MESSAGE_MAX; i++) {
if (!strncmp(msg_string, tsi_fake_handshake_message_strings[i],
strlen(tsi_fake_handshake_message_strings[i]))) {
if (strncmp(msg_string, tsi_fake_handshake_message_strings[i],
strlen(tsi_fake_handshake_message_strings[i])) == 0) {
*msg = i;
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 ((name_length == entry_length) && !strncmp(name, entry, entry_length)) {
if ((name_length == entry_length) &&
strncmp(name, entry, entry_length) == 0) {
return 1; /* Perfect match. */
}
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--;
}
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,

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

@ -53,43 +53,23 @@
namespace grpc {
Channel::Channel(const grpc::string &target, const ChannelArguments &args)
: target_(target) {
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(const grpc::string& target, grpc_channel* channel)
: target_(target), c_channel_(channel) {}
Channel::~Channel() { grpc_channel_destroy(c_channel_); }
Call Channel::CreateCall(const RpcMethod &method, ClientContext *context,
CompletionQueue *cq) {
auto c_call =
grpc_channel_create_call(
c_channel_, cq->cq(), method.name(),
context->authority().empty() ? target_.c_str()
: context->authority().c_str(),
context->RawDeadline());
Call Channel::CreateCall(const RpcMethod& method, ClientContext* context,
CompletionQueue* cq) {
auto c_call = grpc_channel_create_call(c_channel_, cq->cq(), method.name(),
context->authority().empty()
? target_.c_str()
: context->authority().c_str(),
context->RawDeadline());
context->set_call(c_call);
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;
size_t nops = MAX_OPS;
grpc_op ops[MAX_OPS];

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

@ -40,14 +40,10 @@
namespace grpc {
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(
const grpc::string &target, const std::unique_ptr<Credentials> &creds,
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

@ -31,98 +31,10 @@
*
*/
#include <string>
#include <grpc/grpc_security.h>
#include <grpc/support/log.h>
#include <grpc++/credentials.h>
namespace grpc {
Credentials::Credentials(grpc_credentials *c_creds) : creds_(c_creds) {}
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;
}
Credentials::~Credentials() {}
} // namespace grpc

@ -31,27 +31,35 @@
*
*/
#include <grpc/grpc.h>
#include <string>
#include "src/core/channel/channel_args.h"
#include "src/core/security/security_context.h"
#include "src/core/surface/completion_queue.h"
#include "src/core/surface/server.h"
#include <grpc/grpc.h>
#include <grpc/support/log.h>
grpc_server *grpc_secure_server_create_internal(
grpc_completion_queue *cq, const grpc_channel_args *args,
grpc_security_context *context) {
grpc_arg context_arg;
grpc_channel_args *args_copy;
grpc_server *server;
if (grpc_find_security_context_in_args(args) != NULL) {
gpr_log(GPR_ERROR, "Cannot set security context in channel args.");
#include <grpc++/channel_arguments.h>
#include <grpc++/config.h>
#include <grpc++/credentials.h>
#include "src/cpp/client/channel.h"
namespace grpc {
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);
args_copy = grpc_channel_args_copy_and_add(args, &context_arg);
server = grpc_server_create_from_filters(cq, NULL, 0, args_copy);
grpc_channel_args_destroy(args_copy);
return server;
SecureCredentials* AsSecureCredentials() { return nullptr; }
};
} // namespace
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
#define GRPC_INTERNAL_CORE_SURFACE_LAME_CLIENT_H
#include <grpc/grpc_security.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. */
grpc_channel *grpc_lame_client_channel_create(void);
std::shared_ptr<ServerCredentials> InsecureServerCredentials() {
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_;
};
Server::Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned,
ServerCredentials* creds)
Server::Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned)
: started_(false),
shutdown_(false),
num_running_cb_(0),
server_(grpc_server_create(cq_.cq(), nullptr)),
thread_pool_(thread_pool),
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);
}
thread_pool_owned_(thread_pool_owned) {}
Server::~Server() {
std::unique_lock<std::mutex> lock(mu_);
@ -239,13 +226,9 @@ bool Server::RegisterAsyncService(AsynchronousService* service) {
return true;
}
int Server::AddPort(const grpc::string& addr) {
int Server::AddPort(const grpc::string& addr, ServerCredentials* creds) {
GPR_ASSERT(!started_);
if (secure_) {
return grpc_server_add_secure_http2_port(server_, addr.c_str());
} else {
return grpc_server_add_http2_port(server_, addr.c_str());
}
return creds->AddPortToServer(addr, server_);
}
bool Server::Start() {

@ -51,14 +51,10 @@ void ServerBuilder::RegisterAsyncService(AsynchronousService* service) {
async_services_.push_back(service);
}
void ServerBuilder::AddPort(const grpc::string& addr) {
ports_.push_back(addr);
}
void ServerBuilder::SetCredentials(
const std::shared_ptr<ServerCredentials>& creds) {
GPR_ASSERT(!creds_);
creds_ = creds;
void ServerBuilder::AddPort(const grpc::string& addr,
std::shared_ptr<ServerCredentials> creds,
int* selected_port) {
ports_.push_back(Port{addr, creds, selected_port});
}
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");
return nullptr;
}
if (!thread_pool_ && services_.size()) {
if (!thread_pool_ && !services_.empty()) {
int cores = gpr_cpu_num_cores();
if (!cores) cores = 4;
thread_pool_ = new ThreadPool(cores);
thread_pool_owned = true;
}
std::unique_ptr<Server> server(
new Server(thread_pool_, thread_pool_owned, creds_.get()));
std::unique_ptr<Server> server(new Server(thread_pool_, thread_pool_owned));
for (auto* service : services_) {
if (!server->RegisterService(service)) {
return nullptr;
@ -90,8 +85,10 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
}
}
for (auto& port : ports_) {
if (!server->AddPort(port)) {
return nullptr;
int r = server->AddPort(port.addr, port.creds.get());
if (!r) return nullptr;
if (port.selected_port != nullptr) {
*port.selected_port = r;
}
}
if (!server->Start()) {

@ -37,26 +37,6 @@
namespace grpc {
ServerCredentials::ServerCredentials(grpc_server_credentials *c_creds)
: 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));
}
ServerCredentials::~ServerCredentials() {}
} // namespace grpc

@ -165,19 +165,7 @@ NAN_METHOD(Server::New) {
if (args[0]->IsUndefined()) {
wrapped_server = grpc_server_create(queue, NULL);
} else if (args[0]->IsObject()) {
grpc_server_credentials *creds = NULL;
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<Object> args_hash(args[0]->ToObject());
Handle<Array> keys(args_hash->GetOwnPropertyNames());
grpc_channel_args channel_args;
channel_args.num_args = keys->Length();
@ -204,11 +192,7 @@ NAN_METHOD(Server::New) {
return NanThrowTypeError("Arg values must be strings");
}
}
if (creds == NULL) {
wrapped_server = grpc_server_create(queue, &channel_args);
} else {
wrapped_server = grpc_secure_server_create(creds, queue, &channel_args);
}
wrapped_server = grpc_server_create(queue, &channel_args);
free(channel_args.args);
} else {
return NanThrowTypeError("Server expects an object");
@ -259,11 +243,19 @@ NAN_METHOD(Server::AddSecureHttp2Port) {
"addSecureHttp2Port can only be called on a Server");
}
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());
ServerCredentials *creds = ObjectWrap::Unwrap<ServerCredentials>(
args[1]->ToObject());
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) {

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

@ -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
* "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) {
if (secure) {
return this._server.addSecureHttp2Port(port);
Server.prototype.bind = function(port, creds) {
if (creds) {
return this._server.addSecureHttp2Port(port, creds);
} else {
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
* "address:port"
* @param {boolean=} secure Whether the server should open a secure port
* @param {boolean=} creds Credentials to use for SSL
* @return {SurfaceServer} this
*/
SurfaceServer.prototype.bind = function(port, secure) {
return this.inner_server.bind(port, secure);
SurfaceServer.prototype.bind = function(port, creds) {
return this.inner_server.bind(port, creds);
};
/**

@ -96,9 +96,6 @@ PHP_METHOD(Server, __construct) {
zval *queue_obj;
zval *args_array = NULL;
grpc_channel_args args;
HashTable *array_hash;
zval **creds_obj = NULL;
wrapped_grpc_server_credentials *creds = NULL;
/* "O|a" == 1 Object, 1 optional array */
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|a", &queue_obj,
grpc_ce_completion_queue, &args_array) == FAILURE) {
@ -114,28 +111,8 @@ PHP_METHOD(Server, __construct) {
if (args_array == NULL) {
server->wrapped = grpc_server_create(queue->wrapped, NULL);
} 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);
if (creds == NULL) {
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);
}
server->wrapped = grpc_server_create(queue->wrapped, &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);
const char *addr;
int addr_len;
/* "s" == 1 string */
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &addr, &addr_len) ==
zval *creds_obj;
/* "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) {
zend_throw_exception(spl_ce_InvalidArgumentException,
"add_http2_port expects a string", 1 TSRMLS_CC);
zend_throw_exception(
spl_ce_InvalidArgumentException,
"add_http2_port expects a string and a ServerCredentials", 1 TSRMLS_CC);
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,
file_get_contents(dirname(__FILE__) . '/../data/server1.key'),
file_get_contents(dirname(__FILE__) . '/../data/server1.pem'));
$this->server = new Grpc\Server($this->server_queue,
['credentials' => $server_credentials]);
$port = $this->server->add_secure_http2_port('0.0.0.0:0');
$this->server = new Grpc\Server($this->server_queue);
$port = $this->server->add_secure_http2_port('0.0.0.0:0',
$server_credentials);
$this->channel = new Grpc\Channel(
'localhost:' . $port,
[

@ -46,7 +46,7 @@ Installing
- Install gRPC Python's dependencies
```
$ pip install -r requirements.txt
$ pip install -r src/python/requirements.txt
```
- 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()
else:
root_certificates = resources.prod_root_certificates()
# TODO(nathaniel): server host override.
stub = implementations.secure_stub(
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:
stub = implementations.insecure_stub(
methods.CLIENT_METHODS, args.server_host, args.server_port)
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():
args = _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__':

@ -29,6 +29,7 @@
"""Implementations of interoperability test methods."""
import enum
import threading
from grpc.early_adopter import utilities
@ -265,16 +266,24 @@ def _ping_pong(stub):
pipe.close()
def test_interoperability(test_case, stub):
if test_case == 'empty_unary':
_empty_unary(stub)
elif test_case == 'large_unary':
_large_unary(stub)
elif test_case == 'server_streaming':
_server_streaming(stub)
elif test_case == 'client_streaming':
_client_streaming(stub)
elif test_case == 'ping_pong':
_ping_pong(stub)
else:
raise NotImplementedError('Test case "%s" not implemented!')
@enum.unique
class TestCase(enum.Enum):
EMPTY_UNARY = 'empty_unary'
LARGE_UNARY = 'large_unary'
SERVER_STREAMING = 'server_streaming'
CLIENT_STREAMING = 'client_streaming'
PING_PONG = 'ping_pong'
def test_interoperability(self, stub):
if self is TestCase.EMPTY_UNARY:
_empty_unary(stub)
elif self is TestCase.LARGE_UNARY:
_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):
_c.init()
channel = _c.Channel('test host:12345', None)
channel = _c.Channel(
'test host:12345', None, server_host_override='ignored')
del channel
_c.shut_down()
@ -92,7 +93,7 @@ class _CTest(unittest.TestCase):
_c.init()
completion_queue = _c.CompletionQueue()
server = _c.Server(completion_queue, None)
server = _c.Server(completion_queue)
server.add_http2_addr('[::]:0')
server.start()
server.stop()
@ -102,7 +103,7 @@ class _CTest(unittest.TestCase):
service_tag = object()
completion_queue = _c.CompletionQueue()
server = _c.Server(completion_queue, None)
server = _c.Server(completion_queue)
server.add_http2_addr('[::]:0')
server.start()
server.service(service_tag)
@ -119,7 +120,7 @@ class _CTest(unittest.TestCase):
del completion_queue
completion_queue = _c.CompletionQueue()
server = _c.Server(completion_queue, None)
server = _c.Server(completion_queue)
server.add_http2_addr('[::]:0')
server.start()
thread = threading.Thread(target=completion_queue.get, args=(_FUTURE,))

@ -42,19 +42,35 @@
static int pygrpc_channel_init(Channel *self, PyObject *args, PyObject *kwds) {
const char *hostport;
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,
&hostport, &client_credentials))) {
if (!(PyArg_ParseTupleAndKeywords(args, kwds, "sO|z:Channel", kwlist,
&hostport, &client_credentials,
&server_host_override))) {
return -1;
}
if (client_credentials == Py_None) {
self->c_channel = grpc_channel_create(hostport, NULL);
return 0;
} else {
self->c_channel = grpc_secure_channel_create(
((ClientCredentials *)client_credentials)->c_client_credentials,
hostport, NULL);
if (server_host_override == NULL) {
self->c_channel = grpc_secure_channel_create(
((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;
}
}

@ -50,31 +50,12 @@ class FaceTestCase(test_case.FaceTestCase, coverage.BlockingCoverage):
"""Provides abstract Face-layer tests a GRPC-backed implementation."""
def set_up_implementation(
self,
name,
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):
self, name, methods, method_implementations,
multi_method_implementation):
pool = logging_pool.pool(_MAXIMUM_POOL_SIZE)
servicer = 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,
multi_method=multi_method)
pool, method_implementations, multi_method_implementation)
serialization = serial.serialization(methods)
@ -96,9 +77,8 @@ class FaceTestCase(test_case.FaceTestCase, coverage.BlockingCoverage):
rear_link.join_fore_link(front)
front.join_rear_link(rear_link)
server = face_implementations.server()
stub = face_implementations.stub(front, pool)
return server, stub, (rear_link, fore_link, front, back)
stub = face_implementations.generic_stub(front, pool)
return stub, (rear_link, fore_link, front, back)
def tear_down_implementation(self, memo):
rear_link, fore_link, front, back = memo

@ -82,7 +82,7 @@ class EchoTest(unittest.TestCase):
self.host = 'localhost'
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')
self.server.start()
@ -260,7 +260,7 @@ class CancellationTest(unittest.TestCase):
self.host = 'localhost'
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')
self.server.start()

@ -42,30 +42,16 @@
static int pygrpc_server_init(Server *self, PyObject *args, PyObject *kwds) {
const PyObject *completion_queue;
PyObject *server_credentials;
static char *kwlist[] = {"completion_queue", "server_credentials", NULL};
static char *kwlist[] = {"completion_queue", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O:Server", kwlist,
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!:Server", kwlist,
&pygrpc_CompletionQueueType,
&completion_queue, &server_credentials)) {
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);
&completion_queue)) {
return -1;
}
self->c_server = grpc_server_create(
((CompletionQueue *)completion_queue)->c_completion_queue, NULL);
return 0;
}
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,
PyObject *args) {
PyObject *args,
PyObject *kwargs) {
const char *addr;
PyObject *server_credentials;
static char *kwlist[] = {"addr", "server_credentials", NULL};
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;
}
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) {
PyErr_SetString(PyExc_RuntimeError, "Couldn't add port to server!");
return NULL;
@ -138,8 +132,7 @@ static PyMethodDef methods[] = {
METH_VARARGS, "Add a secure HTTP2 address."},
{"start", (PyCFunction)pygrpc_server_start, METH_NOARGS,
"Starts the server."},
{"service", (PyCFunction)pygrpc_server_service, METH_O,
"Services a call."},
{"service", (PyCFunction)pygrpc_server_service, METH_O, "Services a call."},
{"stop", (PyCFunction)pygrpc_server_stop, METH_NOARGS, "Stops the server."},
{NULL}};

@ -280,13 +280,14 @@ class ForeLink(ticket_interfaces.ForeLink, activated.Activated):
0 if self._requested_port is None else self._requested_port)
self._completion_queue = _low.CompletionQueue()
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)
else:
server_credentials = _low.ServerCredentials(
self._root_certificates, self._key_chain_pairs)
self._server = _low.Server(self._completion_queue, server_credentials)
self._port = self._server.add_secure_http2_addr(address)
self._server = _low.Server(self._completion_queue)
self._port = self._server.add_secure_http2_addr(
address, server_credentials)
self._server.start()
self._server.service(None)

@ -93,7 +93,8 @@ class RearLink(ticket_interfaces.RearLink, activated.Activated):
def __init__(
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.
Args:
@ -111,6 +112,8 @@ class RearLink(ticket_interfaces.RearLink, activated.Activated):
key should be used.
certificate_chain: The PEM-encoded certificate chain to use or None if
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._host = host
@ -132,6 +135,7 @@ class RearLink(ticket_interfaces.RearLink, activated.Activated):
self._root_certificates = root_certificates
self._private_key = private_key
self._certificate_chain = certificate_chain
self._server_host_override = server_host_override
def _on_write_event(self, operation_id, event, rpc_state):
if event.write_accepted:
@ -327,7 +331,8 @@ class RearLink(ticket_interfaces.RearLink, activated.Activated):
with self._condition:
self._completion_queue = _low.CompletionQueue()
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
def _stop(self):
@ -388,7 +393,8 @@ class _ActivatedRearLink(ticket_interfaces.RearLink, activated.Activated):
def __init__(
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._port = port
self._request_serializers = request_serializers
@ -397,6 +403,7 @@ class _ActivatedRearLink(ticket_interfaces.RearLink, activated.Activated):
self._root_certificates = root_certificates
self._private_key = private_key
self._certificate_chain = certificate_chain
self._server_host_override = server_host_override
self._lock = threading.Lock()
self._pool = None
@ -415,7 +422,8 @@ class _ActivatedRearLink(ticket_interfaces.RearLink, activated.Activated):
self._rear_link = RearLink(
self._host, self._port, self._pool, self._request_serializers,
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.start()
return self
@ -477,7 +485,7 @@ def activated_rear_link(
def secure_activated_rear_link(
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.
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.
certificate_chain: The PEM-encoded certificate chain to use or None if no
certificate chain should be used.
server_host_override: (For testing only) the target name used for SSL
host name checking.
"""
return _ActivatedRearLink(
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 collections
# assembly_interfaces is referenced from specification in this module.
from grpc.framework.assembly import interfaces as assembly_interfaces # pylint: disable=unused-import
from grpc.framework.assembly import utilities as assembly_utilities
# face_interfaces is referenced from specification in this module.
from grpc.framework.common import cardinality
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 interfaces
# TODO(issue 726): Kill the "implementations" attribute of this in favor
# of the same-information-less-bogusly-represented "cardinalities".
class InvocationBreakdown(object):
"""An intermediate representation of invocation-side views of RPC methods.
Attributes:
cardinalities: A dictionary from RPC method name to interfaces.Cardinality
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
behavior to be used serializing request values for the RPC.
response_deserializers: A dictionary from RPC method name to callable
@ -59,8 +56,7 @@ class _EasyInvocationBreakdown(
InvocationBreakdown,
collections.namedtuple(
'_EasyInvocationBreakdown',
('cardinalities', 'implementations', 'request_serializers',
'response_deserializers'))):
('cardinalities', 'request_serializers', 'response_deserializers'))):
pass
@ -68,8 +64,8 @@ class ServiceBreakdown(object):
"""An intermediate representation of service-side views of RPC methods.
Attributes:
implementations: A dictionary from RPC method name
assembly_interfaces.MethodImplementation implementing the RPC method.
implementations: A dictionary from RPC method name to
face_interfaces.MethodImplementation implementing the RPC method.
request_deserializers: A dictionary from RPC method name to callable
behavior to be used deserializing request values for the RPC.
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.
"""
cardinalities = {}
implementations = {}
request_serializers = {}
response_deserializers = {}
for name, method_description in method_descriptions.iteritems():
cardinality = 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)
cardinalities[name] = method_description.cardinality()
request_serializers[name] = method_description.serialize_request
response_deserializers[name] = method_description.deserialize_response
return _EasyInvocationBreakdown(
cardinalities, implementations, request_serializers,
response_deserializers)
cardinalities, request_serializers, response_deserializers)
def break_down_service(method_descriptions):
@ -139,28 +124,28 @@ def break_down_service(method_descriptions):
service_behavior=method_description.service_unary_unary):
return service_behavior(
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:
def service(
request, face_rpc_context,
service_behavior=method_description.service_unary_stream):
return service_behavior(
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:
def service(
request_iterator, face_rpc_context,
service_behavior=method_description.service_stream_unary):
return service_behavior(
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:
def service(
request_iterator, face_rpc_context,
service_behavior=method_description.service_stream_stream):
return service_behavior(
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
response_serializers[name] = method_description.serialize_response

@ -27,12 +27,20 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# 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 interfaces as face_interfaces
from grpc.framework.foundation import future
from grpc.early_adopter import exceptions
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 = {
face_interfaces.Abortion.CANCELLED: interfaces.Abortion.CANCELLED,
face_interfaces.Abortion.EXPIRED: interfaces.Abortion.EXPIRED,
@ -142,28 +150,28 @@ class _RpcContext(interfaces.RpcContext):
class _UnaryUnarySyncAsync(interfaces.UnaryUnarySyncAsync):
def __init__(self, face_unary_unary_sync_async):
self._underlying = face_unary_unary_sync_async
def __init__(self, face_unary_unary_multi_callable):
self._underlying = face_unary_unary_multi_callable
def __call__(self, request, timeout):
return _call_reexporting_errors(
self._underlying, 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):
def __init__(self, face_stream_unary_sync_async):
self._underlying = face_stream_unary_sync_async
def __init__(self, face_stream_unary_multi_callable):
self._underlying = face_stream_unary_multi_callable
def __call__(self, request_iterator, timeout):
return _call_reexporting_errors(
self._underlying, 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):
@ -182,31 +190,40 @@ class _Stub(interfaces.Stub):
def __getattr__(self, 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.
if cardinality is None:
for name, cardinality in self._cardinalities.iteritems():
if method_cardinality is None:
for name, method_cardinality in self._cardinalities.iteritems():
last_slash_index = name.rfind('/')
if 0 <= last_slash_index and name[last_slash_index + 1:] == attr:
break
else:
raise AttributeError(attr)
if cardinality is interfaces.Cardinality.UNARY_UNARY:
if method_cardinality is interfaces.Cardinality.UNARY_UNARY:
return _UnaryUnarySyncAsync(underlying_attr)
elif cardinality is interfaces.Cardinality.UNARY_STREAM:
elif method_cardinality is interfaces.Cardinality.UNARY_STREAM:
return lambda request, timeout: _CancellableIterator(
underlying_attr(request, timeout))
elif cardinality is interfaces.Cardinality.STREAM_UNARY:
elif method_cardinality is interfaces.Cardinality.STREAM_UNARY:
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(
underlying_attr(request_iterator, timeout))
else:
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):
return _RpcContext(face_rpc_context)
def stub(assembly_stub, cardinalities):
return _Stub(assembly_stub, cardinalities)
def stub(face_stub, cardinalities):
return _Stub(face_stub, cardinalities)

@ -33,7 +33,7 @@ import threading
from grpc._adapter import fore as _fore
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 interfaces
from grpc.framework.assembly import implementations as _assembly_implementations
@ -95,12 +95,13 @@ class _Server(interfaces.Server):
def _build_stub(breakdown, activated_rear_link):
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)
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)
@ -117,7 +118,7 @@ def insecure_stub(methods, host, port):
Returns:
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(
host, port, breakdown.request_serializers,
breakdown.response_deserializers)
@ -125,7 +126,8 @@ def insecure_stub(methods, host, port):
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.
Args:
@ -140,15 +142,17 @@ def secure_stub(
should be used.
certificate_chain: The PEM-encoded certificate chain to use or None if no
certificate chain should be used.
server_host_override: (For testing only) the target name used for SSL
host name checking.
Returns:
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(
host, port, breakdown.request_serializers,
breakdown.response_deserializers, root_certificates, private_key,
certificate_chain)
certificate_chain, server_host_override=server_host_override)
return _build_stub(breakdown, activated_rear_link)

@ -66,7 +66,7 @@ class _FaceStub(object):
self._rear_link.start()
self._rear_link.join_fore_link(self._front)
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):
with self._lock:
@ -86,18 +86,18 @@ class _FaceStub(object):
return getattr(self._under_stub, attr)
def _behaviors(implementations, front, pool):
def _behaviors(method_cardinalities, front, pool):
behaviors = {}
stub = face_implementations.stub(front, pool)
for name, implementation in implementations.iteritems():
if implementation.cardinality is cardinality.Cardinality.UNARY_UNARY:
behaviors[name] = stub.unary_unary_sync_async(name)
elif implementation.cardinality is cardinality.Cardinality.UNARY_STREAM:
stub = face_implementations.generic_stub(front, pool)
for name, method_cardinality in method_cardinalities.iteritems():
if method_cardinality is cardinality.Cardinality.UNARY_UNARY:
behaviors[name] = stub.unary_unary_multi_callable(name)
elif method_cardinality is cardinality.Cardinality.UNARY_STREAM:
behaviors[name] = lambda request, context, bound_name=name: (
stub.inline_value_in_stream_out(bound_name, request, context))
elif implementation.cardinality is cardinality.Cardinality.STREAM_UNARY:
behaviors[name] = stub.stream_unary_sync_async(name)
elif implementation.cardinality is cardinality.Cardinality.STREAM_STREAM:
elif method_cardinality is cardinality.Cardinality.STREAM_UNARY:
behaviors[name] = stub.stream_unary_multi_callable(name)
elif method_cardinality is cardinality.Cardinality.STREAM_STREAM:
behaviors[name] = lambda request_iterator, context, bound_name=name: (
stub.inline_stream_in_stream_out(
bound_name, request_iterator, context))
@ -106,8 +106,8 @@ def _behaviors(implementations, front, pool):
class _DynamicInlineStub(object):
def __init__(self, implementations, rear_link):
self._implementations = implementations
def __init__(self, cardinalities, rear_link):
self._cardinalities = cardinalities
self._rear_link = rear_link
self._lock = threading.Lock()
self._pool = None
@ -123,7 +123,7 @@ class _DynamicInlineStub(object):
self._rear_link.join_fore_link(self._front)
self._front.join_rear_link(self._rear_link)
self._behaviors = _behaviors(
self._implementations, self._front, self._pool)
self._cardinalities, self._front, self._pool)
return self
def __exit__(self, exc_type, exc_val, exc_tb):
@ -151,58 +151,6 @@ class _DynamicInlineStub(object):
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):
def __init__(self, implementations, fore_link):
@ -215,7 +163,8 @@ class _ServiceAssembly(interfaces.Server):
def _start(self):
with self._lock:
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(
servicer, self._pool, self._pool, self._pool, _ONE_DAY_IN_SECONDS,
_ONE_DAY_IN_SECONDS)
@ -251,7 +200,7 @@ class _ServiceAssembly(interfaces.Server):
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
invoke RPCs.
@ -262,12 +211,12 @@ def assemble_face_stub(activated_rear_link):
when passed to this method.
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)
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.
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
as follows: if the requested attribute is the name of a unary-unary RPC
method, the value of the attribute will be a
face_interfaces.UnaryUnarySyncAsync 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 callable with the semantics of
face_interfaces.Stub.inline_value_in_stream_out, minus the "name" parameter,
face_interfaces.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 face_interfaces.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
face_interfaces.StreamUnarySyncAsync with which to invoke the RPC method. If
the requested attribute is the name of a stream-stream RPC method, the value
of the attribute will be a callable with the semantics of
face_interfaces.Stub.inline_stream_in_stream_out, minus the "name" parameter,
face_interfaces.StreamUnaryMultiCallable with which to invoke the RPC method.
If the requested attribute is the name of a stream-stream RPC method, the
value of the attribute will be a face_interfaces.StreamStreamMultiCallable
with which to invoke the RPC method.
Args:
implementations: A dictionary from RPC method name to
interfaces.MethodImplementation.
cardinalities: A dictionary from RPC method name to cardinality.Cardinality
value identifying the cardinality of the named RPC method.
activated_rear_link: An object that is both a tickets_interfaces.RearLink
and an activated.Activated. The object should be in the inactive state
when passed to this method.
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):
@ -306,7 +253,7 @@ def assemble_service(implementations, activated_fore_link):
Args:
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
and an activated.Activated. The object should be in the inactive state
when passed to this method.

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

@ -33,63 +33,7 @@
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 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):

@ -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):
rpc_context = _control.RpcContext(operation_context)
return stream_util.TransformingConsumer(
lambda request: method.service(request, rpc_context), response_consumer)
lambda request: method(request, rpc_context), response_consumer)
return adaptation
def adapt_inline_value_in_stream_out(method):
def adaptation(response_consumer, operation_context):
rpc_context = _control.RpcContext(operation_context)
return _ValueInStreamOutConsumer(
method.service, rpc_context, response_consumer)
return _ValueInStreamOutConsumer(method, rpc_context, response_consumer)
return adaptation
@ -123,7 +122,7 @@ def adapt_inline_stream_in_value_out(method, pool):
operation_context.add_termination_callback(rendezvous.set_outcome)
def in_pool_thread():
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))
return rendezvous
return adaptation
@ -149,7 +148,7 @@ def adapt_inline_stream_in_stream_out(method, pool):
operation_context.add_termination_callback(rendezvous.set_outcome)
def in_pool_thread():
_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)
pool.submit(_pool_wrap(in_pool_thread, operation_context))
return rendezvous
@ -159,7 +158,7 @@ def adapt_inline_stream_in_stream_out(method, pool):
def adapt_event_value_in_value_out(method):
def adaptation(response_consumer, operation_context):
def on_payload(payload):
method.service(
method(
payload, response_consumer.consume_and_terminate,
_control.RpcContext(operation_context))
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 adaptation(response_consumer, operation_context):
def on_payload(payload):
method.service(
method(
payload, response_consumer, _control.RpcContext(operation_context))
return _control.UnaryConsumer(on_payload)
return adaptation
@ -178,12 +177,11 @@ def adapt_event_value_in_stream_out(method):
def adapt_event_stream_in_value_out(method):
def adaptation(response_consumer, 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
def adapt_event_stream_in_stream_out(method):
def adaptation(response_consumer, operation_context):
return method.service(
response_consumer, _control.RpcContext(operation_context))
return method(response_consumer, _control.RpcContext(operation_context))
return adaptation

@ -42,37 +42,17 @@ class FaceTestCase(test_case.FaceTestCase):
"""Provides abstract Face-layer tests an in-memory implementation."""
def set_up_implementation(
self,
name,
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):
self, name, methods, method_implementations,
multi_method_implementation):
servicer_pool = logging_pool.pool(_MAXIMUM_POOL_SIZE)
stub_pool = logging_pool.pool(_MAXIMUM_POOL_SIZE)
servicer = implementations.servicer(
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,
multi_method=multi_method)
servicer_pool, method_implementations, multi_method_implementation)
linked_pair = base_util.linked_pair(servicer, _TIMEOUT)
server = implementations.server()
stub = implementations.stub(linked_pair.front, stub_pool)
return server, stub, (servicer_pool, stub_pool, linked_pair)
stub = implementations.generic_stub(linked_pair.front, stub_pool)
return stub, (servicer_pool, stub_pool, linked_pair)
def tear_down_implementation(self, memo):
servicer_pool, stub_pool, linked_pair = memo

@ -29,6 +29,8 @@
"""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 interfaces as base_interfaces
from grpc.framework.face import _calls
@ -56,7 +58,7 @@ class _BaseServicer(base_interfaces.Servicer):
raise _base_exceptions.NoSuchMethodError()
class _UnaryUnarySyncAsync(interfaces.UnaryUnarySyncAsync):
class _UnaryUnaryMultiCallable(interfaces.UnaryUnaryMultiCallable):
def __init__(self, front, name):
self._front = front
@ -66,12 +68,33 @@ class _UnaryUnarySyncAsync(interfaces.UnaryUnarySyncAsync):
return _calls.blocking_value_in_value_out(
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(
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):
self._front = front
@ -82,18 +105,37 @@ class _StreamUnarySyncAsync(interfaces.StreamUnarySyncAsync):
return _calls.blocking_stream_in_value_out(
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(
self._front, self._name, request_iterator, timeout, 'unused trace ID',
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):
"""An interfaces.Stub implementation."""
def __init__(self, front, name, pool):
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):
self._front = front
@ -149,136 +191,128 @@ class _Stub(interfaces.Stub):
self._front, name, response_consumer, abortion_callback, timeout,
'unused trace ID')
def unary_unary_sync_async(self, name):
return _UnaryUnarySyncAsync(self._front, name)
def stream_unary_sync_async(self, name):
return _StreamUnarySyncAsync(self._front, name, self._pool)
def _aggregate_methods(
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):
"""Aggregates methods coded in according to different interfaces."""
methods = {}
def adapt_unpooled_methods(adapted_methods, unadapted_methods, adaptation):
if unadapted_methods is not None:
for name, unadapted_method in unadapted_methods.iteritems():
adapted_methods[name] = adaptation(unadapted_method)
def adapt_pooled_methods(adapted_methods, unadapted_methods, adaptation):
if unadapted_methods is not None:
for name, unadapted_method in unadapted_methods.iteritems():
adapted_methods[name] = adaptation(unadapted_method, pool)
adapt_unpooled_methods(
methods, inline_value_in_value_out_methods,
_service.adapt_inline_value_in_value_out)
adapt_unpooled_methods(
methods, inline_value_in_stream_out_methods,
_service.adapt_inline_value_in_stream_out)
adapt_pooled_methods(
methods, inline_stream_in_value_out_methods,
_service.adapt_inline_stream_in_value_out)
adapt_pooled_methods(
methods, inline_stream_in_stream_out_methods,
_service.adapt_inline_stream_in_stream_out)
adapt_unpooled_methods(
methods, event_value_in_value_out_methods,
_service.adapt_event_value_in_value_out)
adapt_unpooled_methods(
methods, event_value_in_stream_out_methods,
_service.adapt_event_value_in_stream_out)
adapt_unpooled_methods(
methods, event_stream_in_value_out_methods,
_service.adapt_event_stream_in_value_out)
adapt_unpooled_methods(
methods, event_stream_in_stream_out_methods,
_service.adapt_event_stream_in_stream_out)
return methods
def servicer(
pool,
inline_value_in_value_out_methods=None,
inline_value_in_stream_out_methods=None,
inline_stream_in_value_out_methods=None,
inline_stream_in_stream_out_methods=None,
event_value_in_value_out_methods=None,
event_value_in_stream_out_methods=None,
event_stream_in_value_out_methods=None,
event_stream_in_stream_out_methods=None,
multi_method=None):
def unary_unary_multi_callable(self, name):
return _UnaryUnaryMultiCallable(self._front, name)
def unary_stream_multi_callable(self, name):
return _UnaryStreamMultiCallable(self._front, name)
def stream_unary_multi_callable(self, name):
return _StreamUnaryMultiCallable(self._front, name, self._pool)
def stream_stream_multi_callable(self, name):
return _StreamStreamMultiCallable(self._front, name, self._pool)
class _DynamicStub(interfaces.DynamicStub):
"""An interfaces.DynamicStub implementation."""
def __init__(self, cardinalities, front, pool):
self._cardinalities = cardinalities
self._front = front
self._pool = pool
def __getattr__(self, attr):
cardinality = self._cardinalities.get(attr)
if cardinality is cardinality.Cardinality.UNARY_UNARY:
return _UnaryUnaryMultiCallable(self._front, attr)
elif cardinality is cardinality.Cardinality.UNARY_STREAM:
return _UnaryStreamMultiCallable(self._front, attr)
elif cardinality is cardinality.Cardinality.STREAM_UNARY:
return _StreamUnaryMultiCallable(self._front, attr, self._pool)
elif cardinality is cardinality.Cardinality.STREAM_STREAM:
return _StreamStreamMultiCallable(self._front, attr, self._pool)
else:
raise AttributeError('_DynamicStub object has no attribute "%s"!' % attr)
def _adapt_method_implementations(method_implementations, pool):
adapted_implementations = {}
for name, method_implementation in method_implementations.iteritems():
if method_implementation.style is style.Service.INLINE:
if method_implementation.cardinality is cardinality.Cardinality.UNARY_UNARY:
adapted_implementations[name] = _service.adapt_inline_value_in_value_out(
method_implementation.unary_unary_inline)
elif method_implementation.cardinality is cardinality.Cardinality.UNARY_STREAM:
adapted_implementations[name] = _service.adapt_inline_value_in_stream_out(
method_implementation.unary_stream_inline)
elif method_implementation.cardinality is cardinality.Cardinality.STREAM_UNARY:
adapted_implementations[name] = _service.adapt_inline_stream_in_value_out(
method_implementation.stream_unary_inline, pool)
elif method_implementation.cardinality is cardinality.Cardinality.STREAM_STREAM:
adapted_implementations[name] = _service.adapt_inline_stream_in_stream_out(
method_implementation.stream_stream_inline, pool)
elif method_implementation.style is style.Service.EVENT:
if method_implementation.cardinality is cardinality.Cardinality.UNARY_UNARY:
adapted_implementations[name] = _service.adapt_event_value_in_value_out(
method_implementation.unary_unary_event)
elif method_implementation.cardinality is cardinality.Cardinality.UNARY_STREAM:
adapted_implementations[name] = _service.adapt_event_value_in_stream_out(
method_implementation.unary_stream_event)
elif method_implementation.cardinality is cardinality.Cardinality.STREAM_UNARY:
adapted_implementations[name] = _service.adapt_event_stream_in_value_out(
method_implementation.stream_unary_event)
elif method_implementation.cardinality is cardinality.Cardinality.STREAM_STREAM:
adapted_implementations[name] = _service.adapt_event_stream_in_stream_out(
method_implementation.stream_stream_event)
return adapted_implementations
def servicer(pool, method_implementations, multi_method_implementation):
"""Creates a base_interfaces.Servicer.
The key sets of the passed dictionaries must be disjoint. It is guaranteed
that any passed MultiMethod implementation will only be called to service an
RPC if the RPC method name is not present in the key sets of the passed
dictionaries.
It is guaranteed that any passed interfaces.MultiMethodImplementation will
only be called to service an RPC if there is no
interfaces.MethodImplementation for the RPC method in the passed
method_implementations dictionary.
Args:
pool: A thread pool.
inline_value_in_value_out_methods: A dictionary mapping method names to
interfaces.InlineValueInValueOutMethod implementations.
inline_value_in_stream_out_methods: A dictionary mapping method names to
interfaces.InlineValueInStreamOutMethod implementations.
inline_stream_in_value_out_methods: A dictionary mapping method names to
interfaces.InlineStreamInValueOutMethod implementations.
inline_stream_in_stream_out_methods: A dictionary mapping method names to
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.
method_implementations: A dictionary from RPC method name to
interfaces.MethodImplementation object to be used to service the named
RPC method.
multi_method_implementation: An interfaces.MultiMethodImplementation to be
used to service any RPCs not serviced by the
interfaces.MethodImplementations given in the method_implementations
dictionary, or None.
Returns:
A base_interfaces.Servicer that services RPCs via the given implementations.
"""
methods = _aggregate_methods(
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)
adapted_implementations = _adapt_method_implementations(
method_implementations, pool)
return _BaseServicer(adapted_implementations, multi_method_implementation)
return _BaseServicer(methods, multi_method)
def generic_stub(front, pool):
"""Creates an interfaces.GenericStub.
def server():
"""Creates an interfaces.Server.
Args:
front: A base_interfaces.Front.
pool: A futures.ThreadPoolExecutor.
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):
"""Creates an interfaces.Stub.
def dynamic_stub(cardinalities, front, pool, prefix):
"""Creates an interfaces.DynamicStub.
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.
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:
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 enum
# exceptions, abandonment, and future are referenced from specification in this
# module.
# cardinality, style, exceptions, abandonment, future, 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.face import exceptions # 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 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):
@ -59,69 +72,61 @@ class CancellableIterator(object):
raise NotImplementedError()
class UnaryUnarySyncAsync(object):
"""Affords invoking a unary-unary RPC synchronously or asynchronously.
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.
"""
class RpcContext(object):
"""Provides RPC-related information and action."""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def __call__(self, request, timeout):
"""Synchronously invokes the underlying RPC.
def is_active(self):
"""Describes whether the RPC is active or has terminated."""
raise NotImplementedError()
Args:
request: The request value for the RPC.
timeout: A duration of time in seconds to allow for the RPC.
@abc.abstractmethod
def time_remaining(self):
"""Describes the length of allowed time remaining for the RPC.
Returns:
The response value for the RPC.
Raises:
exceptions.RpcError: Indicating that the RPC was aborted.
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
def async(self, request, timeout):
"""Asynchronously invokes the underlying RPC.
def add_abortion_callback(self, abortion_callback):
"""Registers a callback to be called if the RPC is aborted.
Args:
request: The request value for the RPC.
timeout: A duration of time in seconds to allow for the RPC.
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.
abortion_callback: A callable to be called and passed an Abortion value
in the event of RPC abortion.
"""
raise NotImplementedError()
class StreamUnarySyncAsync(object):
"""Affords invoking a stream-unary RPC synchronously or asynchronously.
class Call(object):
"""Invocation-side representation of an RPC.
Values implementing this interface are directly callable and present an
"async" method. Both calls take an iterator of request values 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.
Attributes:
context: An RpcContext affording information about the RPC.
"""
__metaclass__ = abc.ABCMeta
@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.
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.
Returns:
@ -133,11 +138,11 @@ class StreamUnarySyncAsync(object):
raise NotImplementedError()
@abc.abstractmethod
def async(self, request, timeout):
def future(self, request, timeout):
"""Asynchronously invokes the underlying RPC.
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.
Returns:
@ -148,248 +153,204 @@ class StreamUnarySyncAsync(object):
"""
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
def add_abortion_callback(self, abortion_callback):
"""Registers a callback to be called if the RPC is aborted.
def event(self, request, response_callback, abortion_callback, timeout):
"""Asynchronously invokes the underlying RPC.
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.
"""
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.
timeout: A duration of time in seconds to allow for the RPC.
Returns:
The single response value for the RPC.
Raises:
abandonment.Abandoned: If no response is necessary because the RPC has
been aborted.
A Call object for the RPC.
"""
raise NotImplementedError()
class InlineValueInStreamOutMethod(object):
"""A type for inline unary-request-stream-response RPC methods."""
class UnaryStreamMultiCallable(object):
"""Affords invoking a unary-stream RPC in any call style."""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def service(self, request, context):
"""Services an RPC that accepts one value and produces a stream of values.
def __call__(self, request, timeout):
"""Synchronously invokes the underlying RPC.
Args:
request: The single request value for the RPC.
context: An RpcContext object.
Yields:
The values that comprise the response stream of the RPC.
request: The request value for the RPC.
timeout: A duration of time in seconds to allow for the RPC.
Raises:
abandonment.Abandoned: If completing the response stream is not necessary
because the RPC has been aborted.
Returns:
A CancellableIterator that yields the response values of the RPC and
affords RPC cancellation. Drawing response values from the returned
CancellableIterator may raise exceptions.RpcError indicating abortion
of the RPC.
"""
raise NotImplementedError()
class InlineStreamInValueOutMethod(object):
"""A type for inline stream-request-unary-response RPC methods."""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def service(self, request_iterator, context):
"""Services an RPC that accepts a stream of values and produces one value.
def event(self, request, response_consumer, abortion_callback, timeout):
"""Asynchronously invokes the underlying RPC.
Args:
request_iterator: An iterator that yields the request values of the RPC.
Drawing values from this iterator may also raise exceptions.RpcError to
indicate abortion of the RPC.
context: An RpcContext object.
Yields:
The values that comprise the response stream of the RPC.
request: The request value for the RPC.
response_consumer: A stream.Consumer to be called to accept the restponse
values of the RPC.
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:
abandonment.Abandoned: If no response is necessary 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.
Returns:
A Call object for the RPC.
"""
raise NotImplementedError()
class InlineStreamInStreamOutMethod(object):
"""A type for inline stream-request-stream-response RPC methods."""
class StreamUnaryMultiCallable(object):
"""Affords invoking a stream-unary RPC in any call style."""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def service(self, request_iterator, context):
"""Services an RPC that accepts and produces streams of values.
def __call__(self, request_iterator, timeout):
"""Synchronously invokes the underlying RPC.
Args:
request_iterator: An iterator that yields the request values of the RPC.
Drawing values from this iterator may also raise exceptions.RpcError to
indicate abortion of the RPC.
context: An RpcContext object.
request_iterator: An iterator that yields request values for the RPC.
timeout: A duration of time in seconds to allow for the RPC.
Yields:
The values that comprise the response stream of the RPC.
Returns:
The response value for the RPC.
Raises:
abandonment.Abandoned: If completing the response stream is not necessary
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.
exceptions.RpcError: Indicating that the RPC was aborted.
"""
raise NotImplementedError()
class EventValueInValueOutMethod(object):
"""A type for event-driven unary-request-unary-response RPC methods."""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def service(self, request, response_callback, context):
"""Services an RPC that accepts one value and produces one value.
def future(self, request_iterator, timeout):
"""Asynchronously invokes the underlying RPC.
Args:
request: The single request value for the RPC.
response_callback: A callback to be called to accept the response value of
the RPC.
context: An RpcContext object.
request_iterator: An iterator that yields request values for the RPC.
timeout: A duration of time in seconds to allow for the RPC.
Raises:
abandonment.Abandoned: May or may not be raised when the RPC has been
aborted.
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()
class EventValueInStreamOutMethod(object):
"""A type for event-driven unary-request-stream-response RPC methods."""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def service(self, request, response_consumer, context):
"""Services an RPC that accepts one value and produces a stream of values.
def event(self, response_callback, abortion_callback, timeout):
"""Asynchronously invokes the underlying RPC.
Args:
request: The single request value for the RPC.
response_consumer: A stream.Consumer to be called to accept the response
values of the RPC.
context: An RpcContext object.
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.
timeout: A duration of time in seconds to allow for the RPC.
Raises:
abandonment.Abandoned: May or may not be raised when the RPC has been
aborted.
Returns:
A pair of a Call object for the RPC and a stream.Consumer to which the
request values of the RPC should be passed.
"""
raise NotImplementedError()
class EventStreamInValueOutMethod(object):
"""A type for event-driven stream-request-unary-response RPC methods."""
class StreamStreamMultiCallable(object):
"""Affords invoking a stream-stream RPC in any call style."""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def service(self, response_callback, context):
"""Services an RPC that accepts a stream of values and produces one value.
def __call__(self, request_iterator, timeout):
"""Synchronously invokes the underlying RPC.
Args:
response_callback: A callback to be called to accept the response value of
the RPC.
context: An RpcContext object.
request_iterator: An iterator that yields request values for the RPC.
timeout: A duration of time in seconds to allow for the RPC.
Returns:
A stream.Consumer with which to accept the request values of the RPC. The
consumer returned from this method may or may not be invoked to
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.
A CancellableIterator that yields the response values of the RPC and
affords RPC cancellation. Drawing response values from the returned
CancellableIterator may raise exceptions.RpcError indicating abortion
of the RPC.
"""
raise NotImplementedError()
class EventStreamInStreamOutMethod(object):
"""A type for event-driven stream-request-stream-response RPC methods."""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def service(self, response_consumer, context):
"""Services an RPC that accepts and produces streams of values.
def event(self, response_consumer, abortion_callback, timeout):
"""Asynchronously invokes the underlying RPC.
Args:
response_consumer: A stream.Consumer to be called to accept the response
l Args:
response_consumer: A stream.Consumer to be called to accept the restponse
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:
A stream.Consumer with which to accept the request values of the RPC. The
consumer returned from this method may or may not be invoked to
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.
A pair of a Call object for the RPC and a stream.Consumer to which the
request values of the RPC should be passed.
"""
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."""
__metaclass__ = abc.ABCMeta
@ -420,26 +381,7 @@ class MultiMethod(object):
raise NotImplementedError()
class Server(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):
class GenericStub(object):
"""Affords RPC methods to callers."""
__metaclass__ = abc.ABCMeta
@ -632,25 +574,67 @@ class Stub(object):
raise NotImplementedError()
@abc.abstractmethod
def unary_unary_sync_async(self, name):
"""Creates a UnaryUnarySyncAsync value for a unary-unary RPC method.
def unary_unary_multi_callable(self, name):
"""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:
name: The RPC method name.
Returns:
A UnaryUnarySyncAsync value for the named unary-unary RPC method.
A UnaryStreamMultiCallable value for the name unary-stream RPC method.
"""
raise NotImplementedError()
@abc.abstractmethod
def stream_unary_sync_async(self, name):
"""Creates a StreamUnarySyncAsync value for a stream-unary RPC method.
def stream_unary_multi_callable(self, name):
"""Creates a StreamUnaryMultiCallable for a stream-unary RPC method.
Args:
name: The RPC method name.
Returns:
A StreamUnarySyncAsync value for the named stream-unary RPC method.
A StreamUnaryMultiCallable value for the named stream-unary RPC method.
"""
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(
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.inline_unary_unary_methods,
self.digest.inline_unary_stream_methods,
self.digest.inline_stream_unary_methods,
self.digest.inline_stream_stream_methods,
{}, {}, {}, {}, None)
self.digest.inline_method_implementations, None)
def tearDown(self):
"""See unittest.TestCase.tearDown for full specification.
@ -147,8 +143,8 @@ class BlockingInvocationInlineServiceTestCase(
with self.control.pause(), self.assertRaises(
exceptions.ExpirationError):
sync_async = self.stub.unary_unary_sync_async(name)
sync_async(request, _TIMEOUT)
multi_callable = self.stub.unary_unary_multi_callable(name)
multi_callable(request, _TIMEOUT)
def testExpiredUnaryRequestStreamResponse(self):
for name, test_messages_sequence in (
@ -170,8 +166,8 @@ class BlockingInvocationInlineServiceTestCase(
with self.control.pause(), self.assertRaises(
exceptions.ExpirationError):
sync_async = self.stub.stream_unary_sync_async(name)
sync_async(iter(requests), _TIMEOUT)
multi_callable = self.stub.stream_unary_multi_callable(name)
multi_callable(iter(requests), _TIMEOUT)
def testExpiredStreamRequestStreamResponse(self):
for name, test_messages_sequence in (

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

@ -60,14 +60,9 @@ class EventInvocationSynchronousEventServiceTestCase(
self.digest = digest.digest(
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.event_unary_unary_methods,
self.digest.event_unary_stream_methods,
self.digest.event_stream_unary_methods,
self.digest.event_stream_stream_methods,
None)
self.digest.event_method_implementations, None)
def tearDown(self):
"""See unittest.TestCase.tearDown for full specification.

@ -91,14 +91,9 @@ class FutureInvocationAsynchronousEventServiceTestCase(
self.digest = digest.digest(
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.event_unary_unary_methods,
self.digest.event_unary_stream_methods,
self.digest.event_stream_unary_methods,
self.digest.event_stream_stream_methods,
None)
self.digest.event_method_implementations, None)
def tearDown(self):
"""See unittest.TestCase.tearDown for full specification.
@ -190,8 +185,8 @@ class FutureInvocationAsynchronousEventServiceTestCase(
request = test_messages.request()
with self.control.pause():
sync_async = self.stub.unary_unary_sync_async(name)
response_future = sync_async.async(request, _TIMEOUT)
multi_callable = self.stub.unary_unary_multi_callable(name)
response_future = multi_callable.future(request, _TIMEOUT)
self.assertIsInstance(
response_future.exception(), exceptions.ExpirationError)
with self.assertRaises(exceptions.ExpirationError):
@ -216,8 +211,8 @@ class FutureInvocationAsynchronousEventServiceTestCase(
requests = test_messages.requests()
with self.control.pause():
sync_async = self.stub.stream_unary_sync_async(name)
response_future = sync_async.async(iter(requests), _TIMEOUT)
multi_callable = self.stub.stream_unary_multi_callable(name)
response_future = multi_callable.future(iter(requests), _TIMEOUT)
self.assertIsInstance(
response_future.exception(), 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
class UnaryUnaryTestMethod(interfaces.Method):
"""Like face_interfaces.EventValueInValueOutMethod but with a control."""
class UnaryUnaryTestMethodImplementation(interfaces.Method):
"""A controllable implementation of a unary-unary RPC method."""
__metaclass__ = abc.ABCMeta
@ -93,8 +93,8 @@ class UnaryUnaryTestMessages(object):
raise NotImplementedError()
class UnaryStreamTestMethod(interfaces.Method):
"""Like face_interfaces.EventValueInStreamOutMethod but with a control."""
class UnaryStreamTestMethodImplementation(interfaces.Method):
"""A controllable implementation of a unary-stream RPC method."""
__metaclass__ = abc.ABCMeta
@ -106,7 +106,7 @@ class UnaryStreamTestMethod(interfaces.Method):
request: The single request message for the RPC.
response_consumer: A stream.Consumer to be called to accept the response
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.
Raises:
@ -150,8 +150,8 @@ class UnaryStreamTestMessages(object):
raise NotImplementedError()
class StreamUnaryTestMethod(interfaces.Method):
"""Like face_interfaces.EventStreamInValueOutMethod but with a control."""
class StreamUnaryTestMethodImplementation(interfaces.Method):
"""A controllable implementation of a stream-unary RPC method."""
__metaclass__ = abc.ABCMeta
@ -162,7 +162,7 @@ class StreamUnaryTestMethod(interfaces.Method):
Args:
response_callback: A callback to be called to accept the response message
of the RPC.
context: An RpcContext object.
context: A face_interfaces.RpcContext object.
control: A test_control.Control to control execution of this method.
Returns:
@ -214,8 +214,8 @@ class StreamUnaryTestMessages(object):
raise NotImplementedError()
class StreamStreamTestMethod(interfaces.Method):
"""Like face_interfaces.EventStreamInStreamOutMethod but with a control."""
class StreamStreamTestMethodImplementation(interfaces.Method):
"""A controllable implementation of a stream-stream RPC method."""
__metaclass__ = abc.ABCMeta
@ -226,7 +226,7 @@ class StreamStreamTestMethod(interfaces.Method):
Args:
response_consumer: A stream.Consumer to be called to accept the response
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.
Returns:
@ -298,8 +298,8 @@ class TestService(object):
Returns:
A dict from method name to pair. The first element of the pair
is a UnaryUnaryTestMethod object and the second element is a sequence
of UnaryUnaryTestMethodMessages objects.
is a UnaryUnaryTestMethodImplementation object and the second element
is a sequence of UnaryUnaryTestMethodMessages objects.
"""
raise NotImplementedError()
@ -309,8 +309,8 @@ class TestService(object):
Returns:
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
UnaryStreamTestMethodMessages objects.
UnaryStreamTestMethodImplementation object and the second element is a
sequence of UnaryStreamTestMethodMessages objects.
"""
raise NotImplementedError()
@ -320,8 +320,8 @@ class TestService(object):
Returns:
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
StreamUnaryTestMethodMessages objects.
StreamUnaryTestMethodImplementation object and the second element is a
sequence of StreamUnaryTestMethodMessages objects.
"""
raise NotImplementedError()
@ -331,7 +331,7 @@ class TestService(object):
Returns:
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
StreamStreamTestMethodMessages objects.
StreamStreamTestMethodImplementation object and the second element is a
sequence of StreamStreamTestMethodMessages objects.
"""
raise NotImplementedError()

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

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

@ -27,101 +27,44 @@
# (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 the face layer of RPC Framework."""
"""Utilities for RPC framework's face layer."""
# stream is referenced from specification in this module.
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)
import collections
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):
return self._behavior(response_consumer, context)
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 inline_unary_unary_method(behavior):
"""Creates an interfaces.InlineValueInValueOutMethod from a behavior.
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 an interfaces.RpcContext object and
behavior: The implementation of a unary-unary RPC method as a callable value
that takes a request value and an interfaces.RpcContext object and
returns a response value.
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):
"""Creates an interfaces.InlineValueInStreamOutMethod from a behavior.
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
@ -129,13 +72,15 @@ def inline_unary_stream_method(behavior):
returns an iterator of response values.
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):
"""Creates an interfaces.InlineStreamInValueOutMethod from a behavior.
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
@ -143,13 +88,15 @@ def inline_stream_unary_method(behavior):
interfaces.RpcContext object and returns a response value.
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):
"""Creates an interfaces.InlineStreamInStreamOutMethod from a behavior.
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
@ -157,14 +104,15 @@ def inline_stream_stream_method(behavior):
interfaces.RpcContext object and returns an iterator of response values.
Returns:
An interfaces.InlineStreamInStreamOutMethod derived from the given
behavior.
An interfaces.MethodImplementation derived from the given 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):
"""Creates an interfaces.EventValueInValueOutMethod from a behavior.
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
@ -172,27 +120,31 @@ def event_unary_unary_method(behavior):
the response value of the RPC, and an interfaces.RpcContext.
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):
"""Creates an interfaces.EventValueInStreamOutMethod from a behavior.
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
response values of the RPC, and an interfaces.RpcContext.
the response values of the RPC, and an interfaces.RpcContext.
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):
"""Creates an interfaces.EventStreamInValueOutMethod from a behavior.
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
@ -201,13 +153,15 @@ def event_stream_unary_method(behavior):
which the request values of the RPC should be passed.
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):
"""Creates an interfaces.EventStreamInStreamOutMethod from a behavior.
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
@ -216,6 +170,8 @@ def event_stream_stream_method(behavior):
which the request values of the RPC should be passed.
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
opts = parse_options
host = "0.0.0.0:#{opts['port']}"
s = GRPC::RpcServer.new
if opts['secure']
s = GRPC::RpcServer.new(creds: test_server_creds)
s.add_http2_port(host, true)
s.add_http2_port(host, test_server_creds)
logger.info("... running securely on #{host}")
else
s = GRPC::RpcServer.new
s.add_http2_port(host)
logger.info("... running insecurely on #{host}")
end

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

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

@ -97,35 +97,19 @@ static VALUE grpc_rb_server_alloc(VALUE cls) {
/*
call-seq:
cq = CompletionQueue.new
insecure_server = Server.new(cq, {'arg1': 'value1'})
server_creds = ...
secure_server = Server.new(cq, {'arg1': 'value1'}, server_creds)
server = Server.new(cq, {'arg1': 'value1'})
Initializes server instances. */
static VALUE grpc_rb_server_init(int argc, VALUE *argv, VALUE self) {
VALUE cqueue = Qnil;
VALUE credentials = Qnil;
VALUE channel_args = Qnil;
static VALUE grpc_rb_server_init(VALUE self, VALUE cqueue, VALUE channel_args) {
grpc_completion_queue *cq = NULL;
grpc_server_credentials *creds = NULL;
grpc_rb_server *wrapper = NULL;
grpc_server *srv = NULL;
grpc_channel_args args;
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);
Data_Get_Struct(self, grpc_rb_server, wrapper);
grpc_rb_hash_convert_to_channel_args(channel_args, &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) {
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
server_creds = ...
secure_server = Server.new(cq, {'arg1': 'value1'}, creds)
secure_server.add_http_port('mydomain:7575', True)
secure_server = Server.new(cq, {'arg1': 'value1'})
secure_server.add_http_port('mydomain:7575', server_creds)
Adds a http2 port to server */
static VALUE grpc_rb_server_add_http2_port(int argc, VALUE *argv, VALUE self) {
VALUE port = Qnil;
VALUE is_secure = Qnil;
VALUE rb_creds = Qnil;
grpc_rb_server *s = NULL;
grpc_server_credentials *creds = NULL;
int recvd_port = 0;
/* "11" == 1 mandatory args, 1 (is_secure) is optional */
rb_scan_args(argc, argv, "11", &port, &is_secure);
/* "11" == 1 mandatory args, 1 (rb_creds) is optional */
rb_scan_args(argc, argv, "11", &port, &rb_creds);
Data_Get_Struct(self, grpc_rb_server, s);
if (s->wrapped == NULL) {
rb_raise(rb_eRuntimeError, "closed!");
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));
if (recvd_port == 0) {
rb_raise(rb_eRuntimeError,
"could not add port %s to server, not sure why",
StringValueCStr(port));
}
} else if (TYPE(is_secure) != T_FALSE) {
} else {
creds = grpc_rb_get_wrapped_server_credentials(rb_creds);
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) {
rb_raise(rb_eRuntimeError,
"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);
/* 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);
/* Add the server methods. */

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

@ -350,8 +350,8 @@ describe 'the secure http client/server' do
@client_queue = GRPC::Core::CompletionQueue.new
@server_queue = GRPC::Core::CompletionQueue.new
server_creds = GRPC::Core::ServerCredentials.new(nil, certs[1], certs[2])
@server = GRPC::Core::Server.new(@server_queue, nil, server_creds)
server_port = @server.add_http2_port(server_host, true)
@server = GRPC::Core::Server.new(@server_queue, nil)
server_port = @server.add_http2_port(server_host, server_creds)
@server.start
args = { Channel::SSL_TARGET => 'foo.test.google.fr' }
@ch = Channel.new("0.0.0.0:#{server_port}", args,
@ -362,11 +362,9 @@ describe 'the secure http client/server' do
@server.close
end
# TODO: uncomment after updating the to the new c api
it_behaves_like 'basic GRPC message delivery is OK' do
end
# TODO: uncomment after updating the to the new c api
it_behaves_like 'GRPC metadata delivery works OK' do
end
end

@ -164,19 +164,6 @@ describe GRPC::RpcServer do
expect(&blk).to raise_error
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
opts = { a_channel_arg: 'an_arg', server_override: @server }
blk = proc do

@ -118,10 +118,11 @@ describe Server do
end
describe 'for secure servers' do
let(:cert) { create_test_cert }
it 'runs without failing' do
blk = proc do
s = Server.new(@cq, nil)
s.add_http2_port('localhost:0', true)
s.add_http2_port('localhost:0', cert)
s.close
end
expect(&blk).to_not raise_error
@ -130,7 +131,7 @@ describe Server do
it 'fails if the server is closed' do
s = Server.new(@cq, nil)
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)
end
end
@ -138,7 +139,7 @@ describe Server do
shared_examples '#new' 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
it 'does not take a hash with bad keys as channel args' do
@ -195,14 +196,6 @@ describe Server do
it_behaves_like '#new'
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
s = Server.new(@cq, nil)
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))))
## 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)
# 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) $(AR) rcs $(LIBDIR)/$(CONFIG)/lib${lib.name}.a $(LIB${lib.name.upper()}_OBJS)
% if lib.get('baselib', False):
% if lib.get('secure', True):
$(Q) rm -rf tmp-merge
$(Q) mkdir tmp-merge
$(Q) ( cd tmp-merge ; $(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) rm -f $(LIBDIR)/$(CONFIG)/lib${lib.name}.a tmp-merge/__.SYMDEF*
$(Q) ar rcs $(LIBDIR)/$(CONFIG)/lib${lib.name}.a tmp-merge/*
$(Q) rm -rf tmp-merge
% if lib.get('secure', 'check') == 'yes':
$(Q) rm -rf tmp-merge-${lib.name}
$(Q) mkdir tmp-merge-${lib.name}
$(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-${lib.name} ; <%text>ar x ../$${l}</%text> ) ; done
$(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-${lib.name}/*
$(Q) rm -rf tmp-merge-${lib.name}
% endif
% endif
ifeq ($(SYSTEM),Darwin)
@ -1028,8 +1028,10 @@ endif
mingw_libs = mingw_libs + ' -l' + dep + '-imp'
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)'
if lib.get('secure', 'check') == 'yes' or lib.get('secure', 'check') == 'check':
lib_deps = lib_deps + ' $(OPENSSL_DEP)'
mingw_lib_deps = mingw_lib_deps + ' $(OPENSSL_DEP)'
@ -1056,7 +1058,7 @@ else
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
## the presence of an ALPN-capable OpenSSL.
@ -1069,13 +1071,13 @@ endif
endif
% endif
% if lib.get('secure', True):
% if lib.get('secure', 'check') == 'yes' or lib.get('secure', 'check') == 'check':
ifneq ($(NO_SECURE),true)
% endif
ifneq ($(NO_DEPS),true)
-include $(LIB${lib.name.upper()}_OBJS:.o=.dep)
endif
% if lib.get('secure', True):
% if lib.get('secure', 'check') == 'yes' or lib.get('secure', 'check') == 'check':
endif
% endif
@ -1102,7 +1104,7 @@ ${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)
# 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
% if tgt.build == 'protoc':
$(HOST_LDLIBS_PROTOC)\
% elif tgt.get('secure', True):
% elif tgt.get('secure', 'check') == 'yes' or tgt.get('secure', 'check') == 'check':
$(LDLIBS_SECURE)\
% endif
-o $(BINDIR)/$(CONFIG)/${tgt.name}
@ -1184,7 +1186,7 @@ $(BINDIR)/$(CONFIG)/${tgt.name}: $(${tgt.name.upper()}_OBJS)\
endif
% endif
% if tgt.get('secure', True):
% if tgt.get('secure', 'check') == 'yes' or tgt.get('secure', 'check') == 'check':
endif
% endif
@ -1199,13 +1201,13 @@ $(OBJDIR)/$(CONFIG)/${os.path.splitext(src)[0]}.o: \
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)
% endif
ifneq ($(NO_DEPS),true)
-include $(${tgt.name.upper()}_OBJS:.o=.dep)
endif
% if tgt.get('secure', True):
% if tgt.get('secure', 'check') == 'yes' or tgt.get('secure', 'check') == 'check':
endif
% endif
</%def>

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

@ -84,9 +84,9 @@ static void chttp2_init_server_secure_fullstack(
grpc_server_destroy(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);
GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr));
grpc_server_start(f->server);
}

@ -87,9 +87,9 @@ static void chttp2_init_server_secure_fullstack(
grpc_server_destroy(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);
GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr));
grpc_server_start(f->server);
}

@ -85,9 +85,9 @@ static void chttp2_init_server_secure_fullstack(
grpc_server_destroy(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);
GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr));
grpc_server_start(f->server);
}

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

@ -205,8 +205,8 @@ int main(int argc, char **argv) {
test_server1_cert};
grpc_server_credentials *ssl_creds =
grpc_ssl_server_credentials_create(NULL, &pem_key_cert_pair, 1);
server = grpc_secure_server_create(ssl_creds, cq, NULL);
GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr));
server = grpc_server_create(cq, NULL);
GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, ssl_creds));
grpc_server_credentials_release(ssl_creds);
} else {
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) {
if (!strcmp(test_strategies[i].name, read_strategy)) {
if (strcmp(test_strategies[i].name, read_strategy) == 0) {
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);
gpr_slice hello_slice = grpc_base64_decode(hello_b64, url_safe);
GPR_ASSERT(GPR_SLICE_LENGTH(hello_slice) == strlen(hello));
GPR_ASSERT(!strncmp((const char *)GPR_SLICE_START_PTR(hello_slice), hello,
GPR_SLICE_LENGTH(hello_slice)));
GPR_ASSERT(strncmp((const char *)GPR_SLICE_START_PTR(hello_slice), hello,
GPR_SLICE_LENGTH(hello_slice)) == 0);
gpr_slice_unref(hello_slice);
gpr_free(hello_b64);
@ -141,31 +141,31 @@ static void test_rfc4648_test_vectors(void) {
char *b64;
b64 = grpc_base64_encode("", 0, 0, 0);
GPR_ASSERT(!strcmp("", b64));
GPR_ASSERT(strcmp("", b64) == 0);
gpr_free(b64);
b64 = grpc_base64_encode("f", 1, 0, 0);
GPR_ASSERT(!strcmp("Zg==", b64));
GPR_ASSERT(strcmp("Zg==", b64) == 0);
gpr_free(b64);
b64 = grpc_base64_encode("fo", 2, 0, 0);
GPR_ASSERT(!strcmp("Zm8=", b64));
GPR_ASSERT(strcmp("Zm8=", b64) == 0);
gpr_free(b64);
b64 = grpc_base64_encode("foo", 3, 0, 0);
GPR_ASSERT(!strcmp("Zm9v", b64));
GPR_ASSERT(strcmp("Zm9v", b64) == 0);
gpr_free(b64);
b64 = grpc_base64_encode("foob", 4, 0, 0);
GPR_ASSERT(!strcmp("Zm9vYg==", b64));
GPR_ASSERT(strcmp("Zm9vYg==", b64) == 0);
gpr_free(b64);
b64 = grpc_base64_encode("fooba", 5, 0, 0);
GPR_ASSERT(!strcmp("Zm9vYmE=", b64));
GPR_ASSERT(strcmp("Zm9vYmE=", b64) == 0);
gpr_free(b64);
b64 = grpc_base64_encode("foobar", 6, 0, 0);
GPR_ASSERT(!strcmp("Zm9vYmFy", b64));
GPR_ASSERT(strcmp("Zm9vYmFy", b64) == 0);
gpr_free(b64);
}

@ -143,9 +143,10 @@ static void test_oauth2_token_fetcher_creds_parsing_ok(void) {
GRPC_CREDENTIALS_OK);
GPR_ASSERT(token_lifetime.tv_sec == 3599);
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->value),
"Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_"));
GPR_ASSERT(strcmp(grpc_mdstr_as_c_string(token_elem->key),
"Authorization") == 0);
GPR_ASSERT(strcmp(grpc_mdstr_as_c_string(token_elem->value),
"Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_") == 0);
grpc_mdelem_unref(token_elem);
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_credentials_unref(ssl_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_only(composite_creds));
creds_array = grpc_composite_credentials_get_credentials(composite_creds);
GPR_ASSERT(creds_array->num_creds == 2);
GPR_ASSERT(
!strcmp(creds_array->creds_array[0]->type, GRPC_CREDENTIALS_TYPE_SSL));
GPR_ASSERT(
!strcmp(creds_array->creds_array[1]->type, GRPC_CREDENTIALS_TYPE_OAUTH2));
GPR_ASSERT(strcmp(creds_array->creds_array[0]->type,
GRPC_CREDENTIALS_TYPE_SSL) == 0);
GPR_ASSERT(strcmp(creds_array->creds_array[1]->type,
GRPC_CREDENTIALS_TYPE_OAUTH2) == 0);
grpc_credentials_get_request_metadata(composite_creds, test_service_url,
check_ssl_oauth2_composite_metadata,
composite_creds);
@ -338,17 +340,18 @@ static void test_ssl_oauth2_iam_composite_creds(void) {
grpc_credentials_unref(oauth2_creds);
grpc_credentials_unref(aux_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_only(composite_creds));
creds_array = grpc_composite_credentials_get_credentials(composite_creds);
GPR_ASSERT(creds_array->num_creds == 3);
GPR_ASSERT(
!strcmp(creds_array->creds_array[0]->type, GRPC_CREDENTIALS_TYPE_SSL));
GPR_ASSERT(
!strcmp(creds_array->creds_array[1]->type, GRPC_CREDENTIALS_TYPE_OAUTH2));
GPR_ASSERT(
!strcmp(creds_array->creds_array[2]->type, GRPC_CREDENTIALS_TYPE_IAM));
GPR_ASSERT(strcmp(creds_array->creds_array[0]->type,
GRPC_CREDENTIALS_TYPE_SSL) == 0);
GPR_ASSERT(strcmp(creds_array->creds_array[1]->type,
GRPC_CREDENTIALS_TYPE_OAUTH2) == 0);
GPR_ASSERT(strcmp(creds_array->creds_array[2]->type,
GRPC_CREDENTIALS_TYPE_IAM) == 0);
grpc_credentials_get_request_metadata(composite_creds, test_service_url,
check_ssl_oauth2_iam_composite_metadata,
composite_creds);
@ -359,12 +362,12 @@ static void on_oauth2_creds_get_metadata_success(
grpc_credentials_status status) {
GPR_ASSERT(status == GRPC_CREDENTIALS_OK);
GPR_ASSERT(num_md == 1);
GPR_ASSERT(
!strcmp(grpc_mdstr_as_c_string(md_elems[0]->key), "Authorization"));
GPR_ASSERT(!strcmp(grpc_mdstr_as_c_string(md_elems[0]->value),
"Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_"));
GPR_ASSERT(strcmp(grpc_mdstr_as_c_string(md_elems[0]->key),
"Authorization") == 0);
GPR_ASSERT(strcmp(grpc_mdstr_as_c_string(md_elems[0]->value),
"Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_") == 0);
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(
@ -373,19 +376,19 @@ static void on_oauth2_creds_get_metadata_failure(
GPR_ASSERT(status == GRPC_CREDENTIALS_ERROR);
GPR_ASSERT(num_md == 0);
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(
const grpc_httpcli_request *request) {
GPR_ASSERT(!request->use_ssl);
GPR_ASSERT(!strcmp(request->host, "metadata"));
GPR_ASSERT(
!strcmp(request->path,
"/computeMetadata/v1/instance/service-accounts/default/token"));
GPR_ASSERT(strcmp(request->host, "metadata") == 0);
GPR_ASSERT(strcmp(request->path,
"/computeMetadata/v1/instance/service-accounts/default/token")
== 0);
GPR_ASSERT(request->hdr_count == 1);
GPR_ASSERT(!strcmp(request->hdrs[0].key, "Metadata-Flavor"));
GPR_ASSERT(!strcmp(request->hdrs[0].value, "Google"));
GPR_ASSERT(strcmp(request->hdrs[0].key, "Metadata-Flavor") == 0);
GPR_ASSERT(strcmp(request->hdrs[0].value, "Google") == 0);
}
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(RSA_check_key(json_key->private_key));
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 &&
!strcmp(json_key->private_key_id,
"e6b5137873db8d2ef81e06a47289e6434ec8a165"));
strcmp(json_key->private_key_id,
"e6b5137873db8d2ef81e06a47289e6434ec8a165") == 0);
GPR_ASSERT(json_key->client_id != NULL &&
!strcmp(json_key->client_id,
"777-abaslkan11hlb6nmim3bpspl31ud.apps."
"googleusercontent.com"));
strcmp(json_key->client_id,
"777-abaslkan11hlb6nmim3bpspl31ud.apps."
"googleusercontent.com") == 0);
GPR_ASSERT(json_key->client_email != NULL &&
!strcmp(json_key->client_email,
"777-abaslkan11hlb6nmim3bpspl31ud@developer."
"gserviceaccount.com"));
if (scope != NULL) GPR_ASSERT(!strcmp(scope, test_scope));
strcmp(json_key->client_email,
"777-abaslkan11hlb6nmim3bpspl31ud@developer."
"gserviceaccount.com") == 0);
if (scope != NULL) GPR_ASSERT(strcmp(scope, test_scope) == 0);
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_free(expected_body);
GPR_ASSERT(request->use_ssl);
GPR_ASSERT(!strcmp(request->host, "www.googleapis.com"));
GPR_ASSERT(!strcmp(request->path, "/oauth2/v3/token"));
GPR_ASSERT(strcmp(request->host, "www.googleapis.com") == 0);
GPR_ASSERT(strcmp(request->path, "/oauth2/v3/token") == 0);
GPR_ASSERT(request->hdr_count == 1);
GPR_ASSERT(!strcmp(request->hdrs[0].key, "Content-Type"));
GPR_ASSERT(
!strcmp(request->hdrs[0].value, "application/x-www-form-urlencoded"));
GPR_ASSERT(strcmp(request->hdrs[0].key, "Content-Type") == 0);
GPR_ASSERT(strcmp(request->hdrs[0].value,
"application/x-www-form-urlencoded") == 0);
}
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_ASSERT(status == GRPC_CREDENTIALS_OK);
GPR_ASSERT(num_md == 1);
GPR_ASSERT(
!strcmp(grpc_mdstr_as_c_string(md_elems[0]->key), "Authorization"));
GPR_ASSERT(
!strcmp(grpc_mdstr_as_c_string(md_elems[0]->value), expected_md_value));
GPR_ASSERT(strcmp(grpc_mdstr_as_c_string(md_elems[0]->key),
"Authorization") == 0);
GPR_ASSERT(strcmp(grpc_mdstr_as_c_string(md_elems[0]->value),
expected_md_value) == 0);
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);
}
@ -642,7 +645,7 @@ static void on_jwt_creds_get_metadata_failure(void *user_data,
GPR_ASSERT(status == GRPC_CREDENTIALS_ERROR);
GPR_ASSERT(num_md == 0);
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) {

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

@ -53,7 +53,7 @@ static void test_setenv_getenv(void) {
gpr_setenv(name, value);
retrieved_value = gpr_getenv(name);
GPR_ASSERT(retrieved_value != NULL);
GPR_ASSERT(!strcmp(value, retrieved_value));
GPR_ASSERT(strcmp(value, retrieved_value) == 0);
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/util/test_config.h"

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

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

@ -47,6 +47,7 @@
#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++/stream.h>
#include "test/core/util/port.h"
@ -150,7 +151,7 @@ class End2endTest : public ::testing::Test {
server_address_ << "localhost:" << port;
// Setup server
ServerBuilder builder;
builder.AddPort(server_address_.str());
builder.AddPort(server_address_.str(), InsecureServerCredentials());
builder.RegisterService(&service_);
builder.RegisterService(&dup_pkg_service_);
builder.SetThreadPool(&thread_pool_);
@ -160,8 +161,8 @@ class End2endTest : public ::testing::Test {
void TearDown() GRPC_OVERRIDE { server_->Shutdown(); }
void ResetStub() {
std::shared_ptr<ChannelInterface> channel =
CreateChannelDeprecated(server_address_.str(), ChannelArguments());
std::shared_ptr<ChannelInterface> channel = CreateChannel(
server_address_.str(), InsecureCredentials(), ChannelArguments());
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.
// The two stubs are created on the same channel.
TEST_F(End2endTest, DiffPackageServices) {
std::shared_ptr<ChannelInterface> channel =
CreateChannelDeprecated(server_address_.str(), ChannelArguments());
std::shared_ptr<ChannelInterface> channel = CreateChannel(
server_address_.str(), InsecureCredentials(), ChannelArguments());
EchoRequest request;
EchoResponse response;
@ -397,8 +398,7 @@ TEST_F(End2endTest, DiffPackageServices) {
// rpc and stream should fail on bad credentials.
TEST_F(End2endTest, BadCredentials) {
std::unique_ptr<Credentials> bad_creds =
CredentialsFactory::ServiceAccountCredentials("", "",
std::chrono::seconds(1));
ServiceAccountCredentials("", "", std::chrono::seconds(1));
EXPECT_EQ(nullptr, bad_creds.get());
std::shared_ptr<ChannelInterface> channel =
CreateChannel(server_address_.str(), bad_creds, ChannelArguments());

@ -82,9 +82,10 @@ DEFINE_string(oauth_scope, "", "Scope for OAuth tokens.");
using grpc::ChannelInterface;
using grpc::ClientContext;
using grpc::ComputeEngineCredentials;
using grpc::CreateTestChannel;
using grpc::Credentials;
using grpc::CredentialsFactory;
using grpc::ServiceAccountCredentials;
using grpc::testing::ResponseParameters;
using grpc::testing::SimpleRequest;
using grpc::testing::SimpleResponse;
@ -96,8 +97,8 @@ using grpc::testing::TestService;
// In some distros, gflags is in the namespace google, and in some others,
// in gflags. This hack is enabling us to find both.
namespace google { }
namespace gflags { }
namespace google {}
namespace gflags {}
using namespace google;
using namespace gflags;
@ -135,14 +136,14 @@ std::shared_ptr<ChannelInterface> CreateChannelForTestCase(
std::unique_ptr<Credentials> creds;
GPR_ASSERT(FLAGS_enable_ssl);
grpc::string json_key = GetServiceAccountJsonKey();
creds = CredentialsFactory::ServiceAccountCredentials(
json_key, FLAGS_oauth_scope, std::chrono::hours(1));
creds = ServiceAccountCredentials(json_key, FLAGS_oauth_scope,
std::chrono::hours(1));
return CreateTestChannel(host_port, FLAGS_server_host_override,
FLAGS_enable_ssl, FLAGS_use_prod_roots, creds);
} else if (test_case == "compute_engine_creds") {
std::unique_ptr<Credentials> creds;
GPR_ASSERT(FLAGS_enable_ssl);
creds = CredentialsFactory::ComputeEngineCredentials();
creds = ComputeEngineCredentials();
return CreateTestChannel(host_port, FLAGS_server_host_override,
FLAGS_enable_ssl, FLAGS_use_prod_roots, creds);
} else {
@ -202,7 +203,7 @@ void DoComputeEngineCreds() {
GPR_ASSERT(!response.username().empty());
GPR_ASSERT(response.username().c_str() == FLAGS_default_service_account);
GPR_ASSERT(!response.oauth_scope().empty());
const char *oauth_scope_str = response.oauth_scope().c_str();
const char* oauth_scope_str = response.oauth_scope().c_str();
GPR_ASSERT(FLAGS_oauth_scope.find(oauth_scope_str) != grpc::string::npos);
gpr_log(GPR_INFO, "Large unary with compute engine creds done.");
}
@ -221,7 +222,7 @@ void DoServiceAccountCreds() {
GPR_ASSERT(!response.oauth_scope().empty());
grpc::string json_key = GetServiceAccountJsonKey();
GPR_ASSERT(json_key.find(response.username()) != grpc::string::npos);
const char *oauth_scope_str = response.oauth_scope().c_str();
const char* oauth_scope_str = response.oauth_scope().c_str();
GPR_ASSERT(FLAGS_oauth_scope.find(oauth_scope_str) != grpc::string::npos);
gpr_log(GPR_INFO, "Large unary with service account creds done.");
}

@ -60,7 +60,6 @@ using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::ServerCredentials;
using grpc::ServerCredentialsFactory;
using grpc::ServerReader;
using grpc::ServerReaderWriter;
using grpc::ServerWriter;
@ -78,8 +77,8 @@ using grpc::Status;
// In some distros, gflags is in the namespace google, and in some others,
// in gflags. This hack is enabling us to find both.
namespace google { }
namespace gflags { }
namespace google {}
namespace gflags {}
using namespace google;
using namespace gflags;
@ -211,15 +210,14 @@ void RunServer() {
SimpleResponse response;
ServerBuilder builder;
builder.AddPort(server_address.str());
builder.RegisterService(&service);
std::shared_ptr<ServerCredentials> creds = grpc::InsecureServerCredentials();
if (FLAGS_enable_ssl) {
SslServerCredentialsOptions ssl_opts = {
"", {{test_server1_key, test_server1_cert}}};
std::shared_ptr<ServerCredentials> creds =
ServerCredentialsFactory::SslCredentials(ssl_opts);
builder.SetCredentials(creds);
creds = grpc::SslServerCredentials(ssl_opts);
}
builder.AddPort(server_address.str(), creds);
std::unique_ptr<Server> server(builder.BuildAndStart());
gpr_log(GPR_INFO, "Server listening on %s", server_address.str().c_str());
while (!got_sigint) {

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

Loading…
Cancel
Save