Merge github.com:grpc/grpc into merge-parse
This commit is contained in:
commit
378ffd8cc3
|
|
@ -17,3 +17,6 @@
|
|||
[submodule "third_party/nanopb"]
|
||||
path = third_party/nanopb
|
||||
url = https://github.com/nanopb/nanopb.git
|
||||
[submodule "third_party/thrift"]
|
||||
path = third_party/thrift
|
||||
url = https://github.com/apache/thrift.git
|
||||
|
|
|
|||
102
Makefile
102
Makefile
|
|
@ -800,13 +800,6 @@ ifeq ($(MAKECMDGOALS),clean)
|
|||
NO_DEPS = true
|
||||
endif
|
||||
|
||||
INSTALL_OK = false
|
||||
ifeq ($(HAS_VALID_PROTOC),true)
|
||||
ifeq ($(HAS_SYSTEM_PROTOBUF_VERIFY),true)
|
||||
INSTALL_OK = true
|
||||
endif
|
||||
endif
|
||||
|
||||
.SECONDARY = %.pb.h %.pb.cc
|
||||
|
||||
ifeq ($(DEP_MISSING),)
|
||||
|
|
@ -1051,6 +1044,7 @@ grpc_node_plugin: $(BINDIR)/$(CONFIG)/grpc_node_plugin
|
|||
grpc_objective_c_plugin: $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin
|
||||
grpc_python_plugin: $(BINDIR)/$(CONFIG)/grpc_python_plugin
|
||||
grpc_ruby_plugin: $(BINDIR)/$(CONFIG)/grpc_ruby_plugin
|
||||
grpc_tool_test: $(BINDIR)/$(CONFIG)/grpc_tool_test
|
||||
grpclb_api_test: $(BINDIR)/$(CONFIG)/grpclb_api_test
|
||||
grpclb_test: $(BINDIR)/$(CONFIG)/grpclb_test
|
||||
hybrid_end2end_test: $(BINDIR)/$(CONFIG)/hybrid_end2end_test
|
||||
|
|
@ -1411,6 +1405,7 @@ buildtests_cxx: privatelibs_cxx \
|
|||
$(BINDIR)/$(CONFIG)/generic_end2end_test \
|
||||
$(BINDIR)/$(CONFIG)/golden_file_test \
|
||||
$(BINDIR)/$(CONFIG)/grpc_cli \
|
||||
$(BINDIR)/$(CONFIG)/grpc_tool_test \
|
||||
$(BINDIR)/$(CONFIG)/grpclb_api_test \
|
||||
$(BINDIR)/$(CONFIG)/grpclb_test \
|
||||
$(BINDIR)/$(CONFIG)/hybrid_end2end_test \
|
||||
|
|
@ -1497,6 +1492,7 @@ buildtests_cxx: privatelibs_cxx \
|
|||
$(BINDIR)/$(CONFIG)/generic_end2end_test \
|
||||
$(BINDIR)/$(CONFIG)/golden_file_test \
|
||||
$(BINDIR)/$(CONFIG)/grpc_cli \
|
||||
$(BINDIR)/$(CONFIG)/grpc_tool_test \
|
||||
$(BINDIR)/$(CONFIG)/grpclb_api_test \
|
||||
$(BINDIR)/$(CONFIG)/grpclb_test \
|
||||
$(BINDIR)/$(CONFIG)/hybrid_end2end_test \
|
||||
|
|
@ -1792,6 +1788,8 @@ test_cxx: buildtests_cxx
|
|||
$(Q) $(BINDIR)/$(CONFIG)/generic_end2end_test || ( echo test generic_end2end_test failed ; exit 1 )
|
||||
$(E) "[RUN] Testing golden_file_test"
|
||||
$(Q) $(BINDIR)/$(CONFIG)/golden_file_test || ( echo test golden_file_test failed ; exit 1 )
|
||||
$(E) "[RUN] Testing grpc_tool_test"
|
||||
$(Q) $(BINDIR)/$(CONFIG)/grpc_tool_test || ( echo test grpc_tool_test failed ; exit 1 )
|
||||
$(E) "[RUN] Testing grpclb_api_test"
|
||||
$(Q) $(BINDIR)/$(CONFIG)/grpclb_api_test || ( echo test grpclb_api_test failed ; exit 1 )
|
||||
$(E) "[RUN] Testing grpclb_test"
|
||||
|
|
@ -2171,7 +2169,7 @@ $(OBJDIR)/$(CONFIG)/%.o : %.cc
|
|||
$(Q) mkdir -p `dirname $@`
|
||||
$(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
|
||||
|
||||
install: install_c install_cxx install-plugins install-certs verify-install
|
||||
install: install_c install_cxx install-plugins install-certs
|
||||
|
||||
install_c: install-headers_c install-static_c install-shared_c
|
||||
|
||||
|
|
@ -2354,28 +2352,6 @@ install-certs: etc/roots.pem
|
|||
$(Q) $(INSTALL) -d $(prefix)/share/grpc
|
||||
$(Q) $(INSTALL) etc/roots.pem $(prefix)/share/grpc/roots.pem
|
||||
|
||||
verify-install:
|
||||
ifeq ($(INSTALL_OK),true)
|
||||
@echo "Your system looks ready to go."
|
||||
@echo
|
||||
else
|
||||
@echo "Warning: it looks like protoc 3.0.0+ isn't installed on your system,"
|
||||
@echo "which means that you won't be able to compile .proto files for use"
|
||||
@echo "with gRPC."
|
||||
@echo
|
||||
@echo "If you are just using pre-compiled protocol buffers, or you otherwise"
|
||||
@echo "have no need to compile .proto files, you can ignore this."
|
||||
@echo
|
||||
@echo "If you do need protobuf for some reason, you can download and install"
|
||||
@echo "it from:"
|
||||
@echo
|
||||
@echo " https://github.com/google/protobuf/releases"
|
||||
@echo
|
||||
@echo "Once you've done so, you can re-run this check by doing:"
|
||||
@echo
|
||||
@echo " make verify-install"
|
||||
endif
|
||||
|
||||
clean:
|
||||
$(E) "[CLEAN] Cleaning build directories."
|
||||
$(Q) $(RM) -rf $(OBJDIR) $(LIBDIR) $(BINDIR) $(GENDIR) cache.mk
|
||||
|
|
@ -4073,6 +4049,8 @@ PUBLIC_HEADERS_CXX += \
|
|||
include/grpc/impl/codegen/time.h \
|
||||
include/grpc++/impl/codegen/proto_utils.h \
|
||||
include/grpc++/impl/codegen/config_protobuf.h \
|
||||
include/grpc++/impl/codegen/thrift_serializer.h \
|
||||
include/grpc++/impl/codegen/thrift_utils.h \
|
||||
|
||||
LIBGRPC++_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_TEST_UTIL_SRC))))
|
||||
|
||||
|
|
@ -4307,6 +4285,8 @@ endif
|
|||
|
||||
LIBGRPC_CLI_LIBS_SRC = \
|
||||
test/cpp/util/cli_call.cc \
|
||||
test/cpp/util/cli_credentials.cc \
|
||||
test/cpp/util/grpc_tool.cc \
|
||||
test/cpp/util/proto_file_parser.cc \
|
||||
test/cpp/util/proto_reflection_descriptor_database.cc \
|
||||
|
||||
|
|
@ -11408,16 +11388,16 @@ $(BINDIR)/$(CONFIG)/grpc_cli: protobuf_dep_error
|
|||
|
||||
else
|
||||
|
||||
$(BINDIR)/$(CONFIG)/grpc_cli: $(PROTOBUF_DEP) $(GRPC_CLI_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
|
||||
$(BINDIR)/$(CONFIG)/grpc_cli: $(PROTOBUF_DEP) $(GRPC_CLI_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
|
||||
$(E) "[LD] Linking $@"
|
||||
$(Q) mkdir -p `dirname $@`
|
||||
$(Q) $(LDXX) $(LDFLAGS) $(GRPC_CLI_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpc_cli
|
||||
$(Q) $(LDXX) $(LDFLAGS) $(GRPC_CLI_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpc_cli
|
||||
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
$(OBJDIR)/$(CONFIG)/test/cpp/util/grpc_cli.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
|
||||
$(OBJDIR)/$(CONFIG)/test/cpp/util/grpc_cli.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
|
||||
|
||||
deps_grpc_cli: $(GRPC_CLI_OBJS:.o=.dep)
|
||||
|
||||
|
|
@ -11614,6 +11594,60 @@ ifneq ($(NO_DEPS),true)
|
|||
endif
|
||||
|
||||
|
||||
GRPC_TOOL_TEST_SRC = \
|
||||
$(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc \
|
||||
$(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc \
|
||||
test/cpp/util/grpc_tool_test.cc \
|
||||
test/cpp/util/string_ref_helper.cc \
|
||||
|
||||
GRPC_TOOL_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_TOOL_TEST_SRC))))
|
||||
ifeq ($(NO_SECURE),true)
|
||||
|
||||
# You can't build secure targets if you don't have OpenSSL.
|
||||
|
||||
$(BINDIR)/$(CONFIG)/grpc_tool_test: openssl_dep_error
|
||||
|
||||
else
|
||||
|
||||
|
||||
|
||||
|
||||
ifeq ($(NO_PROTOBUF),true)
|
||||
|
||||
# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
|
||||
|
||||
$(BINDIR)/$(CONFIG)/grpc_tool_test: protobuf_dep_error
|
||||
|
||||
else
|
||||
|
||||
$(BINDIR)/$(CONFIG)/grpc_tool_test: $(PROTOBUF_DEP) $(GRPC_TOOL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
|
||||
$(E) "[LD] Linking $@"
|
||||
$(Q) mkdir -p `dirname $@`
|
||||
$(Q) $(LDXX) $(LDFLAGS) $(GRPC_TOOL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpc_tool_test
|
||||
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
|
||||
|
||||
$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
|
||||
|
||||
$(OBJDIR)/$(CONFIG)/test/cpp/util/grpc_tool_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
|
||||
|
||||
$(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
|
||||
|
||||
deps_grpc_tool_test: $(GRPC_TOOL_TEST_OBJS:.o=.dep)
|
||||
|
||||
ifneq ($(NO_SECURE),true)
|
||||
ifneq ($(NO_DEPS),true)
|
||||
-include $(GRPC_TOOL_TEST_OBJS:.o=.dep)
|
||||
endif
|
||||
endif
|
||||
$(OBJDIR)/$(CONFIG)/test/cpp/util/grpc_tool_test.o: $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc
|
||||
$(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc
|
||||
|
||||
|
||||
GRPCLB_API_TEST_SRC = \
|
||||
$(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc \
|
||||
test/cpp/grpclb/grpclb_api_test.cc \
|
||||
|
|
@ -15377,7 +15411,9 @@ test/cpp/qps/usage_timer.cc: $(OPENSSL_DEP)
|
|||
test/cpp/util/benchmark_config.cc: $(OPENSSL_DEP)
|
||||
test/cpp/util/byte_buffer_proto_helper.cc: $(OPENSSL_DEP)
|
||||
test/cpp/util/cli_call.cc: $(OPENSSL_DEP)
|
||||
test/cpp/util/cli_credentials.cc: $(OPENSSL_DEP)
|
||||
test/cpp/util/create_test_channel.cc: $(OPENSSL_DEP)
|
||||
test/cpp/util/grpc_tool.cc: $(OPENSSL_DEP)
|
||||
test/cpp/util/proto_file_parser.cc: $(OPENSSL_DEP)
|
||||
test/cpp/util/proto_reflection_descriptor_database.cc: $(OPENSSL_DEP)
|
||||
test/cpp/util/string_ref_helper.cc: $(OPENSSL_DEP)
|
||||
|
|
|
|||
40
build.yaml
40
build.yaml
|
|
@ -793,6 +793,13 @@ filegroups:
|
|||
- src/cpp/ext/reflection.pb.cc
|
||||
uses:
|
||||
- grpc++_codegen_proto
|
||||
- name: thrift_util
|
||||
language: c++
|
||||
public_headers:
|
||||
- include/grpc++/impl/codegen/thrift_serializer.h
|
||||
- include/grpc++/impl/codegen/thrift_utils.h
|
||||
uses:
|
||||
- grpc++_codegen_base
|
||||
libs:
|
||||
- name: gpr
|
||||
build: all
|
||||
|
|
@ -1035,6 +1042,7 @@ libs:
|
|||
- grpc++_codegen_base_src
|
||||
- grpc++_codegen_proto
|
||||
- grpc++_config_proto
|
||||
- thrift_util
|
||||
- name: grpc++_unsecure
|
||||
build: all
|
||||
language: c++
|
||||
|
|
@ -1056,16 +1064,21 @@ libs:
|
|||
language: c++
|
||||
headers:
|
||||
- test/cpp/util/cli_call.h
|
||||
- test/cpp/util/cli_credentials.h
|
||||
- test/cpp/util/config_grpc_cli.h
|
||||
- test/cpp/util/grpc_tool.h
|
||||
- test/cpp/util/proto_file_parser.h
|
||||
- test/cpp/util/proto_reflection_descriptor_database.h
|
||||
src:
|
||||
- test/cpp/util/cli_call.cc
|
||||
- test/cpp/util/cli_credentials.cc
|
||||
- test/cpp/util/grpc_tool.cc
|
||||
- test/cpp/util/proto_file_parser.cc
|
||||
- test/cpp/util/proto_reflection_descriptor_database.cc
|
||||
deps:
|
||||
- grpc++_reflection
|
||||
- grpc++
|
||||
- grpc_plugin_support
|
||||
- grpc++_test_config
|
||||
- name: grpc_plugin_support
|
||||
build: protoc
|
||||
language: c++
|
||||
|
|
@ -2735,12 +2748,9 @@ targets:
|
|||
- test/cpp/util/grpc_cli.cc
|
||||
deps:
|
||||
- grpc_cli_libs
|
||||
- grpc++_test_util
|
||||
- grpc_test_util
|
||||
- grpc++_reflection
|
||||
- grpc++
|
||||
- grpc
|
||||
- gpr_test_util
|
||||
- gpr
|
||||
- grpc++_test_config
|
||||
- name: grpc_cpp_plugin
|
||||
|
|
@ -2802,6 +2812,28 @@ targets:
|
|||
secure: false
|
||||
vs_config_type: Application
|
||||
vs_project_guid: '{069E9D05-B78B-4751-9252-D21EBAE7DE8E}'
|
||||
- name: grpc_tool_test
|
||||
gtest: true
|
||||
build: test
|
||||
language: c++
|
||||
headers:
|
||||
- test/cpp/util/string_ref_helper.h
|
||||
src:
|
||||
- src/proto/grpc/testing/echo.proto
|
||||
- src/proto/grpc/testing/echo_messages.proto
|
||||
- test/cpp/util/grpc_tool_test.cc
|
||||
- test/cpp/util/string_ref_helper.cc
|
||||
deps:
|
||||
- grpc_cli_libs
|
||||
- grpc++_reflection
|
||||
- grpc_test_util
|
||||
- grpc++
|
||||
- grpc
|
||||
- gpr_test_util
|
||||
- gpr
|
||||
filegroups:
|
||||
- grpc++_codegen_proto
|
||||
- grpc++_config_proto
|
||||
- name: grpclb_api_test
|
||||
gtest: true
|
||||
build: test
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ Next we need to generate the gRPC client and server interfaces from our `.proto`
|
|||
service definition. We do this using the protocol buffer compiler `protoc` with
|
||||
a special gRPC C++ plugin.
|
||||
|
||||
For simplicity, we've provided a [makefile](route_guide/Makefile) that runs
|
||||
For simplicity, we've provided a [Makefile](route_guide/Makefile) that runs
|
||||
`protoc` for you with the appropriate plugin, input, and output (if you want to
|
||||
run this yourself, make sure you've installed protoc and followed the gRPC code
|
||||
[installation instructions](../../INSTALL.md) first):
|
||||
|
|
|
|||
|
|
@ -0,0 +1,259 @@
|
|||
// Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
// source: helloworld.proto
|
||||
#pragma warning disable 1591, 0612, 3021
|
||||
#region Designer generated code
|
||||
|
||||
using pb = global::Google.Protobuf;
|
||||
using pbc = global::Google.Protobuf.Collections;
|
||||
using pbr = global::Google.Protobuf.Reflection;
|
||||
using scg = global::System.Collections.Generic;
|
||||
namespace Helloworld {
|
||||
|
||||
/// <summary>Holder for reflection information generated from helloworld.proto</summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
public static partial class HelloworldReflection {
|
||||
|
||||
#region Descriptor
|
||||
/// <summary>File descriptor for helloworld.proto</summary>
|
||||
public static pbr::FileDescriptor Descriptor {
|
||||
get { return descriptor; }
|
||||
}
|
||||
private static pbr::FileDescriptor descriptor;
|
||||
|
||||
static HelloworldReflection() {
|
||||
byte[] descriptorData = global::System.Convert.FromBase64String(
|
||||
string.Concat(
|
||||
"ChBoZWxsb3dvcmxkLnByb3RvEgpoZWxsb3dvcmxkIhwKDEhlbGxvUmVxdWVz",
|
||||
"dBIMCgRuYW1lGAEgASgJIh0KCkhlbGxvUmVwbHkSDwoHbWVzc2FnZRgBIAEo",
|
||||
"CTJJCgdHcmVldGVyEj4KCFNheUhlbGxvEhguaGVsbG93b3JsZC5IZWxsb1Jl",
|
||||
"cXVlc3QaFi5oZWxsb3dvcmxkLkhlbGxvUmVwbHkiAEI2Chtpby5ncnBjLmV4",
|
||||
"YW1wbGVzLmhlbGxvd29ybGRCD0hlbGxvV29ybGRQcm90b1ABogIDSExXYgZw",
|
||||
"cm90bzM="));
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::Helloworld.HelloRequest), global::Helloworld.HelloRequest.Parser, new[]{ "Name" }, null, null, null),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::Helloworld.HelloReply), global::Helloworld.HelloReply.Parser, new[]{ "Message" }, null, null, null)
|
||||
}));
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
#region Messages
|
||||
/// <summary>
|
||||
/// The request message containing the user's name.
|
||||
/// </summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
public sealed partial class HelloRequest : pb::IMessage<HelloRequest> {
|
||||
private static readonly pb::MessageParser<HelloRequest> _parser = new pb::MessageParser<HelloRequest>(() => new HelloRequest());
|
||||
public static pb::MessageParser<HelloRequest> Parser { get { return _parser; } }
|
||||
|
||||
public static pbr::MessageDescriptor Descriptor {
|
||||
get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[0]; }
|
||||
}
|
||||
|
||||
pbr::MessageDescriptor pb::IMessage.Descriptor {
|
||||
get { return Descriptor; }
|
||||
}
|
||||
|
||||
public HelloRequest() {
|
||||
OnConstruction();
|
||||
}
|
||||
|
||||
partial void OnConstruction();
|
||||
|
||||
public HelloRequest(HelloRequest other) : this() {
|
||||
name_ = other.name_;
|
||||
}
|
||||
|
||||
public HelloRequest Clone() {
|
||||
return new HelloRequest(this);
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "name" field.</summary>
|
||||
public const int NameFieldNumber = 1;
|
||||
private string name_ = "";
|
||||
public string Name {
|
||||
get { return name_; }
|
||||
set {
|
||||
name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Equals(object other) {
|
||||
return Equals(other as HelloRequest);
|
||||
}
|
||||
|
||||
public bool Equals(HelloRequest other) {
|
||||
if (ReferenceEquals(other, null)) {
|
||||
return false;
|
||||
}
|
||||
if (ReferenceEquals(other, this)) {
|
||||
return true;
|
||||
}
|
||||
if (Name != other.Name) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override int GetHashCode() {
|
||||
int hash = 1;
|
||||
if (Name.Length != 0) hash ^= Name.GetHashCode();
|
||||
return hash;
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return pb::JsonFormatter.ToDiagnosticString(this);
|
||||
}
|
||||
|
||||
public void WriteTo(pb::CodedOutputStream output) {
|
||||
if (Name.Length != 0) {
|
||||
output.WriteRawTag(10);
|
||||
output.WriteString(Name);
|
||||
}
|
||||
}
|
||||
|
||||
public int CalculateSize() {
|
||||
int size = 0;
|
||||
if (Name.Length != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
public void MergeFrom(HelloRequest other) {
|
||||
if (other == null) {
|
||||
return;
|
||||
}
|
||||
if (other.Name.Length != 0) {
|
||||
Name = other.Name;
|
||||
}
|
||||
}
|
||||
|
||||
public void MergeFrom(pb::CodedInputStream input) {
|
||||
uint tag;
|
||||
while ((tag = input.ReadTag()) != 0) {
|
||||
switch(tag) {
|
||||
default:
|
||||
input.SkipLastField();
|
||||
break;
|
||||
case 10: {
|
||||
Name = input.ReadString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The response message containing the greetings
|
||||
/// </summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
public sealed partial class HelloReply : pb::IMessage<HelloReply> {
|
||||
private static readonly pb::MessageParser<HelloReply> _parser = new pb::MessageParser<HelloReply>(() => new HelloReply());
|
||||
public static pb::MessageParser<HelloReply> Parser { get { return _parser; } }
|
||||
|
||||
public static pbr::MessageDescriptor Descriptor {
|
||||
get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[1]; }
|
||||
}
|
||||
|
||||
pbr::MessageDescriptor pb::IMessage.Descriptor {
|
||||
get { return Descriptor; }
|
||||
}
|
||||
|
||||
public HelloReply() {
|
||||
OnConstruction();
|
||||
}
|
||||
|
||||
partial void OnConstruction();
|
||||
|
||||
public HelloReply(HelloReply other) : this() {
|
||||
message_ = other.message_;
|
||||
}
|
||||
|
||||
public HelloReply Clone() {
|
||||
return new HelloReply(this);
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "message" field.</summary>
|
||||
public const int MessageFieldNumber = 1;
|
||||
private string message_ = "";
|
||||
public string Message {
|
||||
get { return message_; }
|
||||
set {
|
||||
message_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Equals(object other) {
|
||||
return Equals(other as HelloReply);
|
||||
}
|
||||
|
||||
public bool Equals(HelloReply other) {
|
||||
if (ReferenceEquals(other, null)) {
|
||||
return false;
|
||||
}
|
||||
if (ReferenceEquals(other, this)) {
|
||||
return true;
|
||||
}
|
||||
if (Message != other.Message) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override int GetHashCode() {
|
||||
int hash = 1;
|
||||
if (Message.Length != 0) hash ^= Message.GetHashCode();
|
||||
return hash;
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return pb::JsonFormatter.ToDiagnosticString(this);
|
||||
}
|
||||
|
||||
public void WriteTo(pb::CodedOutputStream output) {
|
||||
if (Message.Length != 0) {
|
||||
output.WriteRawTag(10);
|
||||
output.WriteString(Message);
|
||||
}
|
||||
}
|
||||
|
||||
public int CalculateSize() {
|
||||
int size = 0;
|
||||
if (Message.Length != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeStringSize(Message);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
public void MergeFrom(HelloReply other) {
|
||||
if (other == null) {
|
||||
return;
|
||||
}
|
||||
if (other.Message.Length != 0) {
|
||||
Message = other.Message;
|
||||
}
|
||||
}
|
||||
|
||||
public void MergeFrom(pb::CodedInputStream input) {
|
||||
uint tag;
|
||||
while ((tag = input.ReadTag()) != 0) {
|
||||
switch(tag) {
|
||||
default:
|
||||
input.SkipLastField();
|
||||
break;
|
||||
case 10: {
|
||||
Message = input.ReadString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
#endregion Designer generated code
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
// Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
// source: helloworld.proto
|
||||
// Original file comments:
|
||||
// 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.
|
||||
//
|
||||
#region Designer generated code
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Grpc.Core;
|
||||
|
||||
namespace Helloworld {
|
||||
/// <summary>
|
||||
/// The greeting service definition.
|
||||
/// </summary>
|
||||
public static class Greeter
|
||||
{
|
||||
static readonly string __ServiceName = "helloworld.Greeter";
|
||||
|
||||
static readonly Marshaller<global::Helloworld.HelloRequest> __Marshaller_HelloRequest = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom);
|
||||
static readonly Marshaller<global::Helloworld.HelloReply> __Marshaller_HelloReply = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom);
|
||||
|
||||
static readonly Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply> __Method_SayHello = new Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply>(
|
||||
MethodType.Unary,
|
||||
__ServiceName,
|
||||
"SayHello",
|
||||
__Marshaller_HelloRequest,
|
||||
__Marshaller_HelloReply);
|
||||
|
||||
/// <summary>Service descriptor</summary>
|
||||
public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
|
||||
{
|
||||
get { return global::Helloworld.HelloworldReflection.Descriptor.Services[0]; }
|
||||
}
|
||||
|
||||
/// <summary>Base class for server-side implementations of Greeter</summary>
|
||||
public abstract class GreeterBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Sends a greeting
|
||||
/// </summary>
|
||||
public virtual global::System.Threading.Tasks.Task<global::Helloworld.HelloReply> SayHello(global::Helloworld.HelloRequest request, ServerCallContext context)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.Unimplemented, ""));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Client for Greeter</summary>
|
||||
public class GreeterClient : ClientBase<GreeterClient>
|
||||
{
|
||||
/// <summary>Creates a new client for Greeter</summary>
|
||||
/// <param name="channel">The channel to use to make remote calls.</param>
|
||||
public GreeterClient(Channel channel) : base(channel)
|
||||
{
|
||||
}
|
||||
/// <summary>Creates a new client for Greeter that uses a custom <c>CallInvoker</c>.</summary>
|
||||
/// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
|
||||
public GreeterClient(CallInvoker callInvoker) : base(callInvoker)
|
||||
{
|
||||
}
|
||||
/// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
|
||||
protected GreeterClient() : base()
|
||||
{
|
||||
}
|
||||
/// <summary>Protected constructor to allow creation of configured clients.</summary>
|
||||
/// <param name="configuration">The client configuration.</param>
|
||||
protected GreeterClient(ClientBaseConfiguration configuration) : base(configuration)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a greeting
|
||||
/// </summary>
|
||||
public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
return SayHello(request, new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
/// <summary>
|
||||
/// Sends a greeting
|
||||
/// </summary>
|
||||
public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, CallOptions options)
|
||||
{
|
||||
return CallInvoker.BlockingUnaryCall(__Method_SayHello, null, options, request);
|
||||
}
|
||||
/// <summary>
|
||||
/// Sends a greeting
|
||||
/// </summary>
|
||||
public virtual AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
return SayHelloAsync(request, new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
/// <summary>
|
||||
/// Sends a greeting
|
||||
/// </summary>
|
||||
public virtual AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, CallOptions options)
|
||||
{
|
||||
return CallInvoker.AsyncUnaryCall(__Method_SayHello, null, options, request);
|
||||
}
|
||||
protected override GreeterClient NewInstance(ClientBaseConfiguration configuration)
|
||||
{
|
||||
return new GreeterClient(configuration);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Creates service definition that can be registered with a server</summary>
|
||||
public static ServerServiceDefinition BindService(GreeterBase serviceImpl)
|
||||
{
|
||||
return ServerServiceDefinition.CreateBuilder()
|
||||
.AddMethod(__Method_SayHello, serviceImpl.SayHello).Build();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"title": "Greeter",
|
||||
"version": "1.0.0-*",
|
||||
"buildOptions": {
|
||||
"debugType": "portable",
|
||||
},
|
||||
"dependencies": {
|
||||
"Google.Protobuf": "3.0.0-beta3",
|
||||
"Grpc": "1.0.0-pre1",
|
||||
},
|
||||
"frameworks": {
|
||||
"net45": {
|
||||
"frameworkAssemblies": {
|
||||
"System.Runtime": "",
|
||||
"System.IO": ""
|
||||
},
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
// 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.
|
||||
|
||||
using System;
|
||||
using Grpc.Core;
|
||||
using Helloworld;
|
||||
|
||||
namespace GreeterClient
|
||||
{
|
||||
class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
Channel channel = new Channel("127.0.0.1:50051", ChannelCredentials.Insecure);
|
||||
|
||||
var client = new Greeter.GreeterClient(channel);
|
||||
String user = "you";
|
||||
|
||||
var reply = client.SayHello(new HelloRequest { Name = user });
|
||||
Console.WriteLine("Greeting: " + reply.Message);
|
||||
|
||||
channel.ShutdownAsync().Wait();
|
||||
Console.WriteLine("Press any key to exit...");
|
||||
Console.ReadKey();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"title": "GreeterClient",
|
||||
"version": "1.0.0-*",
|
||||
"buildOptions": {
|
||||
"debugType": "portable",
|
||||
"emitEntryPoint": "true"
|
||||
},
|
||||
"dependencies": {
|
||||
"Google.Protobuf": "3.0.0-beta3",
|
||||
"Grpc": "1.0.0-pre1",
|
||||
"Greeter": {
|
||||
"target": "project"
|
||||
}
|
||||
},
|
||||
"frameworks": {
|
||||
"net45": {
|
||||
"frameworkAssemblies": {
|
||||
"System.Runtime": "",
|
||||
"System.IO": ""
|
||||
},
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Grpc.Core;
|
||||
using Helloworld;
|
||||
|
||||
namespace GreeterServer
|
||||
{
|
||||
class GreeterImpl : Greeter.GreeterBase
|
||||
{
|
||||
// Server side handler of the SayHello RPC
|
||||
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
|
||||
{
|
||||
return Task.FromResult(new HelloReply { Message = "Hello " + request.Name });
|
||||
}
|
||||
}
|
||||
|
||||
class Program
|
||||
{
|
||||
const int Port = 50051;
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
Server server = new Server
|
||||
{
|
||||
Services = { Greeter.BindService(new GreeterImpl()) },
|
||||
Ports = { new ServerPort("localhost", Port, ServerCredentials.Insecure) }
|
||||
};
|
||||
server.Start();
|
||||
|
||||
Console.WriteLine("Greeter server listening on port " + Port);
|
||||
Console.WriteLine("Press any key to stop the server...");
|
||||
Console.ReadKey();
|
||||
|
||||
server.ShutdownAsync().Wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"title": "GreeterServer",
|
||||
"version": "1.0.0-*",
|
||||
"buildOptions": {
|
||||
"debugType": "portable",
|
||||
"emitEntryPoint": "true"
|
||||
},
|
||||
"dependencies": {
|
||||
"Google.Protobuf": "3.0.0-beta3",
|
||||
"Grpc": "1.0.0-pre1",
|
||||
"Greeter": {
|
||||
"target": "project"
|
||||
}
|
||||
},
|
||||
"frameworks": {
|
||||
"net45": {
|
||||
"frameworkAssemblies": {
|
||||
"System.Runtime": "",
|
||||
"System.IO": ""
|
||||
},
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
gRPC in 3 minutes (C#)
|
||||
========================
|
||||
|
||||
BACKGROUND
|
||||
-------------
|
||||
This is a different version of the helloworld example, using the dotnet sdk
|
||||
tools to build and run.
|
||||
|
||||
For this sample, we've already generated the server and client stubs from [helloworld.proto][].
|
||||
|
||||
Example projects in this directory depend on the [Grpc](https://www.nuget.org/packages/Grpc/)
|
||||
and [Google.Protobuf](https://www.nuget.org/packages/Google.Protobuf/) NuGet packages
|
||||
which have been already added to the project for you.
|
||||
|
||||
The examples in this directory target .NET 4.5 framework, as .NET Core support is
|
||||
currently experimental.
|
||||
|
||||
PREREQUISITES
|
||||
-------------
|
||||
|
||||
- The DotNetCore SDK cli.
|
||||
|
||||
- The .NET 4.5 framework.
|
||||
|
||||
Both are available to download at https://www.microsoft.com/net/download
|
||||
|
||||
BUILD
|
||||
-------
|
||||
|
||||
From the `examples/csharp/helloworld-from-cli` directory:
|
||||
|
||||
- `dotnet restore`
|
||||
|
||||
- `dotnet build **/project.json` (this will automatically download NuGet dependencies)
|
||||
|
||||
Try it!
|
||||
-------
|
||||
|
||||
- Run the server
|
||||
|
||||
```
|
||||
> cd GreeterServer
|
||||
> dotnet run
|
||||
```
|
||||
|
||||
- Run the client
|
||||
|
||||
```
|
||||
> cd GreeterClient
|
||||
> dotnet run
|
||||
```
|
||||
|
||||
Tutorial
|
||||
--------
|
||||
|
||||
You can find a more detailed tutorial about Grpc in [gRPC Basics: C#][]
|
||||
|
||||
[helloworld.proto]:../../protos/helloworld.proto
|
||||
[gRPC Basics: C#]:http://www.grpc.io/docs/tutorials/basic/csharp.html
|
||||
|
|
@ -13,7 +13,7 @@ PREREQUISITES
|
|||
-------------
|
||||
|
||||
- Windows: .NET Framework 4.5+, Visual Studio 2013 or 2015
|
||||
- Linux: Mono 4+, MonoDevelop 5.9+ (with NuGet add-in installed)
|
||||
- Linux: Mono 4+, MonoDevelop 5.9+
|
||||
- Mac OS X: Xamarin Studio 5.9+
|
||||
|
||||
BUILD
|
||||
|
|
@ -21,7 +21,20 @@ BUILD
|
|||
|
||||
- Open solution `Greeter.sln` with Visual Studio, Monodevelop (on Linux) or Xamarin Studio (on Mac OS X)
|
||||
|
||||
- Build the solution (this will automatically download NuGet dependencies)
|
||||
# Using Visual Studio
|
||||
|
||||
* Build the solution (this will automatically download NuGet dependencies)
|
||||
|
||||
# Using Monodevelop or Xamarin Studio
|
||||
|
||||
The nuget add-in available for Xamarin Studio and Monodevelop IDEs is too old to
|
||||
download all of the nuget dependencies of gRPC. One alternative to is to use the dotnet command line tools instead (see [helloworld-from-cli]).
|
||||
|
||||
Using these IDEs, a workaround is as follows:
|
||||
* Obtain a nuget executable for your platform and update it with
|
||||
`nuget update -self`.
|
||||
* Navigate to this directory and run `nuget restore`.
|
||||
* Now that packages have been restored into their proper package folder, build the solution from your IDE.
|
||||
|
||||
Try it!
|
||||
-------
|
||||
|
|
@ -49,5 +62,6 @@ Tutorial
|
|||
|
||||
You can find a more detailed tutorial in [gRPC Basics: C#][]
|
||||
|
||||
[helloworld-from-cli]:../helloworld-from-cli/README.md
|
||||
[helloworld.proto]:../../protos/helloworld.proto
|
||||
[gRPC Basics: C#]:http://www.grpc.io/docs/tutorials/basic/csharp.html
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"async": "^1.5.2",
|
||||
"google-protobuf": "^3.0.0-alpha.5",
|
||||
"grpc": "^0.14.0",
|
||||
"google-protobuf": "^3.0.0",
|
||||
"grpc": "^1.0.0",
|
||||
"lodash": "^4.6.1",
|
||||
"minimist": "^1.2.0"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ lib_dir = File.join(this_dir, 'lib')
|
|||
$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
|
||||
|
||||
require 'grpc'
|
||||
require 'helloworld_services'
|
||||
require 'helloworld_services_pb'
|
||||
|
||||
def main
|
||||
stub = Helloworld::Greeter::Stub.new('localhost:50051', :this_channel_is_insecure)
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ lib_dir = File.join(this_dir, 'lib')
|
|||
$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
|
||||
|
||||
require 'grpc'
|
||||
require 'helloworld_services'
|
||||
require 'helloworld_services_pb'
|
||||
|
||||
# GreeterServer is simple server that implements the Helloworld Greeter server.
|
||||
class GreeterServer < Helloworld::Greeter::Service
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
Gem::Specification.new do |s|
|
||||
s.name = 'grpc-demo'
|
||||
s.version = '0.11.0'
|
||||
s.version = '1.0.0'
|
||||
s.authors = ['gRPC Authors']
|
||||
s.email = 'temiola@google.com'
|
||||
s.homepage = 'https://github.com/grpc/grpc'
|
||||
|
|
@ -17,7 +17,7 @@ Gem::Specification.new do |s|
|
|||
s.require_paths = ['lib']
|
||||
s.platform = Gem::Platform::RUBY
|
||||
|
||||
s.add_dependency 'grpc', '~> 0.11'
|
||||
s.add_dependency 'grpc', '~> 1.0.0'
|
||||
|
||||
s.add_development_dependency 'bundler', '~> 1.7'
|
||||
end
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
#
|
||||
|
||||
require 'grpc'
|
||||
require 'helloworld'
|
||||
require 'helloworld_pb'
|
||||
|
||||
module Helloworld
|
||||
module Greeter
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
#
|
||||
|
||||
require 'grpc'
|
||||
require 'route_guide'
|
||||
require 'route_guide_pb'
|
||||
|
||||
module Routeguide
|
||||
module RouteGuide
|
||||
|
|
@ -39,7 +39,7 @@ $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
|
|||
|
||||
require 'grpc'
|
||||
require 'multi_json'
|
||||
require 'route_guide_services'
|
||||
require 'route_guide_services_pb'
|
||||
|
||||
include Routeguide
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
|
|||
|
||||
require 'grpc'
|
||||
require 'multi_json'
|
||||
require 'route_guide_services'
|
||||
require 'route_guide_services_pb'
|
||||
|
||||
include Routeguide
|
||||
COORD_FACTOR = 1e7
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ Gem::Specification.new do |s|
|
|||
s.require_paths = %w( src/ruby/bin src/ruby/lib src/ruby/pb )
|
||||
s.platform = Gem::Platform::RUBY
|
||||
|
||||
s.add_dependency 'google-protobuf', '~> 3.0.0.alpha.5.0.3'
|
||||
s.add_dependency 'google-protobuf', '~> 3.0'
|
||||
s.add_dependency 'googleauth', '~> 0.5.1'
|
||||
|
||||
s.add_development_dependency 'bundler', '~> 1.9'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2016, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_H
|
||||
#define GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_H
|
||||
|
||||
#include <grpc/impl/codegen/byte_buffer.h>
|
||||
#include <grpc/impl/codegen/byte_buffer_reader.h>
|
||||
#include <grpc/impl/codegen/slice.h>
|
||||
#include <grpc/impl/codegen/slice_buffer.h>
|
||||
#include <thrift/protocol/TBinaryProtocol.h>
|
||||
#include <thrift/protocol/TCompactProtocol.h>
|
||||
#include <thrift/protocol/TProtocolException.h>
|
||||
#include <thrift/transport/TBufferTransports.h>
|
||||
#include <thrift/transport/TTransportUtils.h>
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace util {
|
||||
|
||||
using apache::thrift::protocol::TBinaryProtocolT;
|
||||
using apache::thrift::protocol::TCompactProtocolT;
|
||||
using apache::thrift::protocol::TMessageType;
|
||||
using apache::thrift::protocol::TNetworkBigEndian;
|
||||
using apache::thrift::transport::TMemoryBuffer;
|
||||
using apache::thrift::transport::TBufferBase;
|
||||
using apache::thrift::transport::TTransport;
|
||||
|
||||
template <typename Dummy, typename Protocol>
|
||||
class ThriftSerializer {
|
||||
public:
|
||||
ThriftSerializer()
|
||||
: prepared_(false),
|
||||
last_deserialized_(false),
|
||||
serialize_version_(false) {}
|
||||
|
||||
virtual ~ThriftSerializer() {}
|
||||
|
||||
// Serialize the passed type into the internal buffer
|
||||
// and returns a pointer to internal buffer and its size
|
||||
template <typename T>
|
||||
void Serialize(const T& fields, const uint8_t** serialized_buffer,
|
||||
size_t* serialized_len) {
|
||||
// prepare or reset buffer
|
||||
if (!prepared_ || last_deserialized_) {
|
||||
prepare();
|
||||
} else {
|
||||
buffer_->resetBuffer();
|
||||
}
|
||||
last_deserialized_ = false;
|
||||
|
||||
// if required serialize protocol version
|
||||
if (serialize_version_) {
|
||||
protocol_->writeMessageBegin("", TMessageType(0), 0);
|
||||
}
|
||||
|
||||
// serialize fields into buffer
|
||||
fields.write(protocol_.get());
|
||||
|
||||
// write the end of message
|
||||
if (serialize_version_) {
|
||||
protocol_->writeMessageEnd();
|
||||
}
|
||||
|
||||
uint8_t* byte_buffer;
|
||||
uint32_t byte_buffer_size;
|
||||
buffer_->getBuffer(&byte_buffer, &byte_buffer_size);
|
||||
*serialized_buffer = byte_buffer;
|
||||
*serialized_len = byte_buffer_size;
|
||||
}
|
||||
|
||||
// Serialize the passed type into the byte buffer
|
||||
template <typename T>
|
||||
void Serialize(const T& fields, grpc_byte_buffer** bp) {
|
||||
const uint8_t* byte_buffer;
|
||||
size_t byte_buffer_size;
|
||||
|
||||
Serialize(fields, &byte_buffer, &byte_buffer_size);
|
||||
|
||||
gpr_slice slice = gpr_slice_from_copied_buffer(
|
||||
reinterpret_cast<const char*>(byte_buffer), byte_buffer_size);
|
||||
|
||||
*bp = grpc_raw_byte_buffer_create(&slice, 1);
|
||||
|
||||
gpr_slice_unref(slice);
|
||||
}
|
||||
|
||||
// Deserialize the passed char array into the passed type, returns the number
|
||||
// of bytes that have been consumed from the passed string.
|
||||
template <typename T>
|
||||
uint32_t Deserialize(uint8_t* serialized_buffer, size_t length, T* fields) {
|
||||
// prepare buffer if necessary
|
||||
if (!prepared_) {
|
||||
prepare();
|
||||
}
|
||||
last_deserialized_ = true;
|
||||
|
||||
// reset buffer transport
|
||||
buffer_->resetBuffer(serialized_buffer, length);
|
||||
|
||||
// read the protocol version if necessary
|
||||
if (serialize_version_) {
|
||||
std::string name = "";
|
||||
TMessageType mt = static_cast<TMessageType>(0);
|
||||
int32_t seq_id = 0;
|
||||
protocol_->readMessageBegin(name, mt, seq_id);
|
||||
}
|
||||
|
||||
// deserialize buffer into fields
|
||||
uint32_t len = fields->read(protocol_.get());
|
||||
|
||||
// read the end of message
|
||||
if (serialize_version_) {
|
||||
protocol_->readMessageEnd();
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
// Deserialize the passed byte buffer to passed type, returns the number
|
||||
// of bytes consumed from byte buffer
|
||||
template <typename T>
|
||||
uint32_t Deserialize(grpc_byte_buffer* buffer, T* msg) {
|
||||
grpc_byte_buffer_reader reader;
|
||||
grpc_byte_buffer_reader_init(&reader, buffer);
|
||||
|
||||
gpr_slice slice = grpc_byte_buffer_reader_readall(&reader);
|
||||
|
||||
uint32_t len =
|
||||
Deserialize(GPR_SLICE_START_PTR(slice), GPR_SLICE_LENGTH(slice), msg);
|
||||
|
||||
gpr_slice_unref(slice);
|
||||
|
||||
grpc_byte_buffer_reader_destroy(&reader);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
// set serialization version flag
|
||||
void SetSerializeVersion(bool value) { serialize_version_ = value; }
|
||||
|
||||
// Set the container size limit to deserialize
|
||||
// This function should be called after buffer_ is initialized
|
||||
void SetContainerSizeLimit(int32_t container_limit) {
|
||||
if (!prepared_) {
|
||||
prepare();
|
||||
}
|
||||
protocol_->setContainerSizeLimit(container_limit);
|
||||
}
|
||||
|
||||
// Set the string size limit to deserialize
|
||||
// This function should be called after buffer_ is initialized
|
||||
void SetStringSizeLimit(int32_t string_limit) {
|
||||
if (!prepared_) {
|
||||
prepare();
|
||||
}
|
||||
protocol_->setStringSizeLimit(string_limit);
|
||||
}
|
||||
|
||||
private:
|
||||
bool prepared_;
|
||||
bool last_deserialized_;
|
||||
boost::shared_ptr<TMemoryBuffer> buffer_;
|
||||
std::shared_ptr<Protocol> protocol_;
|
||||
bool serialize_version_;
|
||||
|
||||
void prepare() {
|
||||
buffer_ = boost::make_shared<TMemoryBuffer>();
|
||||
// create a protocol for the memory buffer transport
|
||||
protocol_ = std::make_shared<Protocol>(buffer_);
|
||||
prepared_ = true;
|
||||
}
|
||||
|
||||
}; // ThriftSerializer
|
||||
|
||||
typedef ThriftSerializer<void, TBinaryProtocolT<TBufferBase, TNetworkBigEndian>>
|
||||
ThriftSerializerBinary;
|
||||
typedef ThriftSerializer<void, TCompactProtocolT<TBufferBase>>
|
||||
ThriftSerializerCompact;
|
||||
|
||||
} // namespace util
|
||||
} // namespace thrift
|
||||
} // namespace apache
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2016, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GRPCXX_IMPL_CODEGEN_THRIFT_UTILS_H
|
||||
#define GRPCXX_IMPL_CODEGEN_THRIFT_UTILS_H
|
||||
|
||||
#include <grpc++/impl/codegen/config.h>
|
||||
#include <grpc++/impl/codegen/core_codegen_interface.h>
|
||||
#include <grpc++/impl/codegen/serialization_traits.h>
|
||||
#include <grpc++/impl/codegen/status.h>
|
||||
#include <grpc++/impl/codegen/status_code_enum.h>
|
||||
#include <grpc++/impl/codegen/thrift_serializer.h>
|
||||
#include <grpc/impl/codegen/byte_buffer.h>
|
||||
#include <grpc/impl/codegen/byte_buffer_reader.h>
|
||||
#include <grpc/impl/codegen/slice.h>
|
||||
#include <grpc/impl/codegen/slice_buffer.h>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace grpc {
|
||||
|
||||
using apache::thrift::util::ThriftSerializerCompact;
|
||||
|
||||
template <class T>
|
||||
class SerializationTraits<T, typename std::enable_if<std::is_base_of<
|
||||
apache::thrift::TBase, T>::value>::type> {
|
||||
public:
|
||||
static Status Serialize(const T& msg, grpc_byte_buffer** bp,
|
||||
bool* own_buffer) {
|
||||
*own_buffer = true;
|
||||
|
||||
ThriftSerializerCompact serializer;
|
||||
serializer.Serialize(msg, bp);
|
||||
|
||||
return Status(StatusCode::OK, "ok");
|
||||
}
|
||||
|
||||
static Status Deserialize(grpc_byte_buffer* buffer, T* msg,
|
||||
int max_message_size) {
|
||||
if (!buffer) {
|
||||
return Status(StatusCode::INTERNAL, "No payload");
|
||||
}
|
||||
|
||||
ThriftSerializerCompact deserializer;
|
||||
deserializer.Deserialize(buffer, msg);
|
||||
|
||||
grpc_byte_buffer_destroy(buffer);
|
||||
|
||||
return Status(StatusCode::OK, "ok");
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace grpc
|
||||
|
||||
#endif // GRPCXX_IMPL_CODEGEN_THRIFT_UTILS_H
|
||||
|
|
@ -72,6 +72,9 @@ class ByteBuffer GRPC_FINAL {
|
|||
/// Buffer size in bytes.
|
||||
size_t Length() const;
|
||||
|
||||
/// Swap the state of *this and *other.
|
||||
void Swap(ByteBuffer* other);
|
||||
|
||||
private:
|
||||
friend class SerializationTraits<ByteBuffer, void>;
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
"devDependencies": {
|
||||
"async": "^1.5.0",
|
||||
"google-auth-library": "^0.9.2",
|
||||
"google-protobuf": "^3.0.0-alpha.5",
|
||||
"google-protobuf": "^3.0.0",
|
||||
"istanbul": "^0.3.21",
|
||||
"jsdoc": "^3.3.2",
|
||||
"jshint": "^2.5.0",
|
||||
|
|
|
|||
19
package.xml
19
package.xml
|
|
@ -10,7 +10,7 @@
|
|||
<email>grpc-packages@google.com</email>
|
||||
<active>yes</active>
|
||||
</lead>
|
||||
<date>2016-07-28</date>
|
||||
<date>2016-08-09</date>
|
||||
<time>16:06:07</time>
|
||||
<version>
|
||||
<release>1.1.0</release>
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
</stability>
|
||||
<license>BSD</license>
|
||||
<notes>
|
||||
- PHP7 Support continued, reduce code duplication #7543
|
||||
- Fixed Ubuntu compile error #7571, #7642
|
||||
</notes>
|
||||
<contents>
|
||||
<dir baseinstalldir="/" name="/">
|
||||
|
|
@ -1143,5 +1143,20 @@ Update to wrap gRPC C Core version 0.10.0
|
|||
- PHP7 Support continued, reduce code duplication #7543
|
||||
</notes>
|
||||
</release>
|
||||
<release>
|
||||
<version>
|
||||
<release>1.0.0RC4</release>
|
||||
<api>1.0.0RC4</api>
|
||||
</version>
|
||||
<stability>
|
||||
<release>stable</release>
|
||||
<api>stable</api>
|
||||
</stability>
|
||||
<date>2016-08-09</date>
|
||||
<license>BSD</license>
|
||||
<notes>
|
||||
- Fixed Ubuntu compile error #7571, #7642
|
||||
</notes>
|
||||
</release>
|
||||
</changelog>
|
||||
</package>
|
||||
|
|
|
|||
|
|
@ -88,14 +88,21 @@ static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg,
|
|||
}
|
||||
|
||||
static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint,
|
||||
grpc_channel_args *args, void *user_data,
|
||||
grpc_channel_args *args,
|
||||
gpr_slice_buffer *read_buffer, void *user_data,
|
||||
grpc_error *error) {
|
||||
connector *c = user_data;
|
||||
c->result->transport =
|
||||
grpc_create_chttp2_transport(exec_ctx, args, endpoint, 1);
|
||||
GPR_ASSERT(c->result->transport);
|
||||
grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL, 0);
|
||||
c->result->channel_args = args;
|
||||
if (error != GRPC_ERROR_NONE) {
|
||||
grpc_channel_args_destroy(args);
|
||||
gpr_free(read_buffer);
|
||||
} else {
|
||||
c->result->transport =
|
||||
grpc_create_chttp2_transport(exec_ctx, args, endpoint, 1);
|
||||
GPR_ASSERT(c->result->transport);
|
||||
grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport,
|
||||
read_buffer);
|
||||
c->result->channel_args = args;
|
||||
}
|
||||
grpc_closure *notify = c->notify;
|
||||
c->notify = NULL;
|
||||
grpc_exec_ctx_sched(exec_ctx, notify, error, NULL);
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ grpc_channel *grpc_insecure_channel_create_from_fd(
|
|||
grpc_channel *channel = grpc_channel_create(
|
||||
&exec_ctx, target, final_args, GRPC_CLIENT_DIRECT_CHANNEL, transport);
|
||||
grpc_channel_args_destroy(final_args);
|
||||
grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0);
|
||||
grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL);
|
||||
|
||||
grpc_exec_ctx_finish(&exec_ctx);
|
||||
|
||||
|
|
|
|||
|
|
@ -114,8 +114,7 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
|
|||
gpr_mu_unlock(&c->mu);
|
||||
c->result->transport = grpc_create_chttp2_transport(
|
||||
exec_ctx, c->args.channel_args, secure_endpoint, 1);
|
||||
grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL,
|
||||
0);
|
||||
grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL);
|
||||
auth_context_arg = grpc_auth_context_to_arg(auth_context);
|
||||
c->result->channel_args =
|
||||
grpc_channel_args_copy_and_add(c->tmp_args, &auth_context_arg, 1);
|
||||
|
|
@ -126,10 +125,13 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
|
|||
}
|
||||
|
||||
static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint,
|
||||
grpc_channel_args *args, void *user_data,
|
||||
grpc_channel_args *args,
|
||||
gpr_slice_buffer *read_buffer, void *user_data,
|
||||
grpc_error *error) {
|
||||
connector *c = user_data;
|
||||
c->tmp_args = args;
|
||||
if (error != GRPC_ERROR_NONE) {
|
||||
gpr_free(read_buffer);
|
||||
grpc_closure *notify = c->notify;
|
||||
c->notify = NULL;
|
||||
grpc_exec_ctx_sched(exec_ctx, notify, error, NULL);
|
||||
|
|
@ -137,10 +139,9 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint,
|
|||
// TODO(roth, jboeuf): Convert security connector handshaking to use new
|
||||
// handshake API, and then move the code from on_secure_handshake_done()
|
||||
// into this function.
|
||||
c->tmp_args = args;
|
||||
grpc_channel_security_connector_do_handshake(
|
||||
exec_ctx, c->security_connector, endpoint, c->args.deadline,
|
||||
on_secure_handshake_done, c);
|
||||
exec_ctx, c->security_connector, endpoint, read_buffer,
|
||||
c->args.deadline, on_secure_handshake_done, c);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,8 @@ typedef struct server_connect_state {
|
|||
} server_connect_state;
|
||||
|
||||
static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint,
|
||||
grpc_channel_args *args, void *user_data,
|
||||
grpc_channel_args *args,
|
||||
gpr_slice_buffer *read_buffer, void *user_data,
|
||||
grpc_error *error) {
|
||||
server_connect_state *state = user_data;
|
||||
if (error != GRPC_ERROR_NONE) {
|
||||
|
|
@ -64,6 +65,7 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint,
|
|||
grpc_error_free_string(error_str);
|
||||
GRPC_ERROR_UNREF(error);
|
||||
grpc_handshake_manager_shutdown(exec_ctx, state->handshake_mgr);
|
||||
gpr_free(read_buffer);
|
||||
} else {
|
||||
// Beware that the call to grpc_create_chttp2_transport() has to happen
|
||||
// before grpc_tcp_server_destroy(). This is fine here, but similar code
|
||||
|
|
@ -75,7 +77,7 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint,
|
|||
grpc_server_setup_transport(exec_ctx, state->server, transport,
|
||||
state->accepting_pollset,
|
||||
grpc_server_get_channel_args(state->server));
|
||||
grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0);
|
||||
grpc_chttp2_transport_start_reading(exec_ctx, transport, read_buffer);
|
||||
}
|
||||
// Clean up.
|
||||
grpc_channel_args_destroy(args);
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ void grpc_server_add_insecure_channel_from_fd(grpc_server *server,
|
|||
&exec_ctx, server_args, server_endpoint, 0 /* is_client */);
|
||||
grpc_endpoint_add_to_pollset(&exec_ctx, server_endpoint, grpc_cq_pollset(cq));
|
||||
grpc_server_setup_transport(&exec_ctx, server, transport, NULL, server_args);
|
||||
grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0);
|
||||
grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL);
|
||||
grpc_exec_ctx_finish(&exec_ctx);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep,
|
|||
grpc_server_setup_transport(exec_ctx, state->state->server, transport,
|
||||
state->accepting_pollset, args_copy);
|
||||
grpc_channel_args_destroy(args_copy);
|
||||
grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0);
|
||||
grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL);
|
||||
} else {
|
||||
/* We need to consume this here, because the server may already have
|
||||
* gone away. */
|
||||
|
|
@ -128,7 +128,8 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep,
|
|||
}
|
||||
|
||||
static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint,
|
||||
grpc_channel_args *args, void *user_data,
|
||||
grpc_channel_args *args,
|
||||
gpr_slice_buffer *read_buffer, void *user_data,
|
||||
grpc_error *error) {
|
||||
server_secure_connect *state = user_data;
|
||||
if (error != GRPC_ERROR_NONE) {
|
||||
|
|
@ -136,9 +137,10 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint,
|
|||
gpr_log(GPR_ERROR, "Handshaking failed: %s", error_str);
|
||||
grpc_error_free_string(error_str);
|
||||
GRPC_ERROR_UNREF(error);
|
||||
grpc_channel_args_destroy(args);
|
||||
gpr_free(read_buffer);
|
||||
grpc_handshake_manager_shutdown(exec_ctx, state->handshake_mgr);
|
||||
grpc_handshake_manager_destroy(exec_ctx, state->handshake_mgr);
|
||||
grpc_channel_args_destroy(args);
|
||||
state_unref(state->state);
|
||||
gpr_free(state);
|
||||
return;
|
||||
|
|
@ -150,8 +152,8 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint,
|
|||
// into this function.
|
||||
state->args = args;
|
||||
grpc_server_security_connector_do_handshake(
|
||||
exec_ctx, state->state->sc, state->acceptor, endpoint, state->deadline,
|
||||
on_secure_handshake_done, state);
|
||||
exec_ctx, state->state->sc, state->acceptor, endpoint, read_buffer,
|
||||
state->deadline, on_secure_handshake_done, state);
|
||||
}
|
||||
|
||||
static void on_accept(grpc_exec_ctx *exec_ctx, void *statep, grpc_endpoint *tcp,
|
||||
|
|
|
|||
|
|
@ -2354,9 +2354,12 @@ grpc_transport *grpc_create_chttp2_transport(
|
|||
|
||||
void grpc_chttp2_transport_start_reading(grpc_exec_ctx *exec_ctx,
|
||||
grpc_transport *transport,
|
||||
gpr_slice *slices, size_t nslices) {
|
||||
gpr_slice_buffer *read_buffer) {
|
||||
grpc_chttp2_transport *t = (grpc_chttp2_transport *)transport;
|
||||
REF_TRANSPORT(t, "reading_action"); /* matches unref inside reading_action */
|
||||
gpr_slice_buffer_addn(&t->read_buffer, slices, nslices);
|
||||
if (read_buffer != NULL) {
|
||||
gpr_slice_buffer_move_into(read_buffer, &t->read_buffer);
|
||||
gpr_free(read_buffer);
|
||||
}
|
||||
reading_action(exec_ctx, t, GRPC_ERROR_NONE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,8 +44,10 @@ grpc_transport *grpc_create_chttp2_transport(
|
|||
grpc_exec_ctx *exec_ctx, const grpc_channel_args *channel_args,
|
||||
grpc_endpoint *ep, int is_client);
|
||||
|
||||
/// Takes ownership of \a read_buffer, which (if non-NULL) contains
|
||||
/// leftover bytes previously read from the endpoint (e.g., by handshakers).
|
||||
void grpc_chttp2_transport_start_reading(grpc_exec_ctx *exec_ctx,
|
||||
grpc_transport *transport,
|
||||
gpr_slice *slices, size_t nslices);
|
||||
gpr_slice_buffer *read_buffer);
|
||||
|
||||
#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_CHTTP2_TRANSPORT_H */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -62,11 +62,13 @@ void grpc_handshaker_do_handshake(grpc_exec_ctx* exec_ctx,
|
|||
grpc_handshaker* handshaker,
|
||||
grpc_endpoint* endpoint,
|
||||
grpc_channel_args* args,
|
||||
gpr_slice_buffer* read_buffer,
|
||||
gpr_timespec deadline,
|
||||
grpc_tcp_server_acceptor* acceptor,
|
||||
grpc_handshaker_done_cb cb, void* user_data) {
|
||||
handshaker->vtable->do_handshake(exec_ctx, handshaker, endpoint, args,
|
||||
deadline, acceptor, cb, user_data);
|
||||
read_buffer, deadline, acceptor, cb,
|
||||
user_data);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -143,7 +145,8 @@ void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx,
|
|||
// handshakers together.
|
||||
static void call_next_handshaker(grpc_exec_ctx* exec_ctx,
|
||||
grpc_endpoint* endpoint,
|
||||
grpc_channel_args* args, void* user_data,
|
||||
grpc_channel_args* args,
|
||||
gpr_slice_buffer* read_buffer, void* user_data,
|
||||
grpc_error* error) {
|
||||
grpc_handshake_manager* mgr = user_data;
|
||||
GPR_ASSERT(mgr->state != NULL);
|
||||
|
|
@ -151,8 +154,8 @@ static void call_next_handshaker(grpc_exec_ctx* exec_ctx,
|
|||
// If we got an error, skip all remaining handshakers and invoke the
|
||||
// caller-supplied callback immediately.
|
||||
if (error != GRPC_ERROR_NONE) {
|
||||
mgr->state->final_cb(exec_ctx, endpoint, args, mgr->state->final_user_data,
|
||||
error);
|
||||
mgr->state->final_cb(exec_ctx, endpoint, args, read_buffer,
|
||||
mgr->state->final_user_data, error);
|
||||
return;
|
||||
}
|
||||
grpc_handshaker_done_cb cb = call_next_handshaker;
|
||||
|
|
@ -163,9 +166,9 @@ static void call_next_handshaker(grpc_exec_ctx* exec_ctx,
|
|||
user_data = mgr->state->final_user_data;
|
||||
}
|
||||
// Invoke handshaker.
|
||||
grpc_handshaker_do_handshake(exec_ctx, mgr->handshakers[mgr->state->index],
|
||||
endpoint, args, mgr->state->deadline,
|
||||
mgr->state->acceptor, cb, user_data);
|
||||
grpc_handshaker_do_handshake(
|
||||
exec_ctx, mgr->handshakers[mgr->state->index], endpoint, args,
|
||||
read_buffer, mgr->state->deadline, mgr->state->acceptor, cb, user_data);
|
||||
++mgr->state->index;
|
||||
// If this is the last handshaker, clean up state.
|
||||
if (mgr->state->index == mgr->count) {
|
||||
|
|
@ -180,10 +183,12 @@ void grpc_handshake_manager_do_handshake(
|
|||
gpr_timespec deadline, grpc_tcp_server_acceptor* acceptor,
|
||||
grpc_handshaker_done_cb cb, void* user_data) {
|
||||
grpc_channel_args* args_copy = grpc_channel_args_copy(args);
|
||||
gpr_slice_buffer* read_buffer = malloc(sizeof(*read_buffer));
|
||||
gpr_slice_buffer_init(read_buffer);
|
||||
if (mgr->count == 0) {
|
||||
// No handshakers registered, so we just immediately call the done
|
||||
// callback with the passed-in endpoint.
|
||||
cb(exec_ctx, endpoint, args_copy, user_data, GRPC_ERROR_NONE);
|
||||
cb(exec_ctx, endpoint, args_copy, read_buffer, user_data, GRPC_ERROR_NONE);
|
||||
} else {
|
||||
GPR_ASSERT(mgr->state == NULL);
|
||||
mgr->state = gpr_malloc(sizeof(struct grpc_handshaker_state));
|
||||
|
|
@ -192,6 +197,7 @@ void grpc_handshake_manager_do_handshake(
|
|||
mgr->state->acceptor = acceptor;
|
||||
mgr->state->final_cb = cb;
|
||||
mgr->state->final_user_data = user_data;
|
||||
call_next_handshaker(exec_ctx, endpoint, args_copy, mgr, GRPC_ERROR_NONE);
|
||||
call_next_handshaker(exec_ctx, endpoint, args_copy, read_buffer, mgr,
|
||||
GRPC_ERROR_NONE);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
#include <grpc/impl/codegen/grpc_types.h>
|
||||
#include <grpc/impl/codegen/time.h>
|
||||
#include <grpc/support/slice_buffer.h>
|
||||
|
||||
#include "src/core/lib/iomgr/closure.h"
|
||||
#include "src/core/lib/iomgr/endpoint.h"
|
||||
|
|
@ -56,10 +57,11 @@
|
|||
typedef struct grpc_handshaker grpc_handshaker;
|
||||
|
||||
/// Callback type invoked when a handshaker is done.
|
||||
/// Takes ownership of \a args.
|
||||
/// Takes ownership of \a args and \a read_buffer.
|
||||
typedef void (*grpc_handshaker_done_cb)(grpc_exec_ctx* exec_ctx,
|
||||
grpc_endpoint* endpoint,
|
||||
grpc_channel_args* args,
|
||||
gpr_slice_buffer* read_buffer,
|
||||
void* user_data, grpc_error* error);
|
||||
|
||||
struct grpc_handshaker_vtable {
|
||||
|
|
@ -72,10 +74,12 @@ struct grpc_handshaker_vtable {
|
|||
|
||||
/// Performs handshaking. When finished, calls \a cb with \a user_data.
|
||||
/// Takes ownership of \a args.
|
||||
/// Takes ownership of \a read_buffer, which contains leftover bytes read
|
||||
/// from the endpoint by the previous handshaker.
|
||||
/// \a acceptor will be NULL for client-side handshakers.
|
||||
void (*do_handshake)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker,
|
||||
grpc_endpoint* endpoint, grpc_channel_args* args,
|
||||
gpr_timespec deadline,
|
||||
gpr_slice_buffer* read_buffer, gpr_timespec deadline,
|
||||
grpc_tcp_server_acceptor* acceptor,
|
||||
grpc_handshaker_done_cb cb, void* user_data);
|
||||
};
|
||||
|
|
@ -101,6 +105,7 @@ void grpc_handshaker_do_handshake(grpc_exec_ctx* exec_ctx,
|
|||
grpc_handshaker* handshaker,
|
||||
grpc_endpoint* endpoint,
|
||||
grpc_channel_args* args,
|
||||
gpr_slice_buffer* read_buffer,
|
||||
gpr_timespec deadline,
|
||||
grpc_tcp_server_acceptor* acceptor,
|
||||
grpc_handshaker_done_cb cb, void* user_data);
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ static void httpcli_ssl_destroy(grpc_security_connector *sc) {
|
|||
static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx,
|
||||
grpc_channel_security_connector *sc,
|
||||
grpc_endpoint *nonsecure_endpoint,
|
||||
gpr_slice_buffer *read_buffer,
|
||||
gpr_timespec deadline,
|
||||
grpc_security_handshake_done_cb cb,
|
||||
void *user_data) {
|
||||
|
|
@ -69,6 +70,7 @@ static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx,
|
|||
tsi_result result = TSI_OK;
|
||||
tsi_handshaker *handshaker;
|
||||
if (c->handshaker_factory == NULL) {
|
||||
gpr_free(read_buffer);
|
||||
cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
|
|
@ -77,10 +79,12 @@ static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx,
|
|||
if (result != TSI_OK) {
|
||||
gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
|
||||
tsi_result_to_string(result));
|
||||
gpr_free(read_buffer);
|
||||
cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL);
|
||||
} else {
|
||||
grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, true,
|
||||
nonsecure_endpoint, deadline, cb, user_data);
|
||||
nonsecure_endpoint, read_buffer, deadline, cb,
|
||||
user_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -183,7 +187,7 @@ static void ssl_handshake(grpc_exec_ctx *exec_ctx, void *arg,
|
|||
pem_root_certs, pem_root_certs_size, host, &sc) ==
|
||||
GRPC_SECURITY_OK);
|
||||
grpc_channel_security_connector_do_handshake(
|
||||
exec_ctx, sc, tcp, deadline, on_secure_transport_setup_done, c);
|
||||
exec_ctx, sc, tcp, NULL, deadline, on_secure_transport_setup_done, c);
|
||||
GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "httpcli");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <sys/epoll.h>
|
||||
|
|
|
|||
|
|
@ -325,8 +325,9 @@ static void on_timeout(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
|
|||
void grpc_do_security_handshake(
|
||||
grpc_exec_ctx *exec_ctx, tsi_handshaker *handshaker,
|
||||
grpc_security_connector *connector, bool is_client_side,
|
||||
grpc_endpoint *nonsecure_endpoint, gpr_timespec deadline,
|
||||
grpc_security_handshake_done_cb cb, void *user_data) {
|
||||
grpc_endpoint *nonsecure_endpoint, gpr_slice_buffer *read_buffer,
|
||||
gpr_timespec deadline, grpc_security_handshake_done_cb cb,
|
||||
void *user_data) {
|
||||
grpc_security_connector_handshake_list *handshake_node;
|
||||
grpc_security_handshake *h = gpr_malloc(sizeof(grpc_security_handshake));
|
||||
memset(h, 0, sizeof(grpc_security_handshake));
|
||||
|
|
@ -346,6 +347,10 @@ void grpc_do_security_handshake(
|
|||
gpr_slice_buffer_init(&h->left_overs);
|
||||
gpr_slice_buffer_init(&h->outgoing);
|
||||
gpr_slice_buffer_init(&h->incoming);
|
||||
if (read_buffer != NULL) {
|
||||
gpr_slice_buffer_move_into(read_buffer, &h->incoming);
|
||||
gpr_free(read_buffer);
|
||||
}
|
||||
if (!is_client_side) {
|
||||
grpc_server_security_connector *server_connector =
|
||||
(grpc_server_security_connector *)connector;
|
||||
|
|
|
|||
|
|
@ -37,12 +37,13 @@
|
|||
#include "src/core/lib/iomgr/endpoint.h"
|
||||
#include "src/core/lib/security/transport/security_connector.h"
|
||||
|
||||
/* Calls the callback upon completion. Takes owership of handshaker. */
|
||||
/* Calls the callback upon completion. Takes owership of handshaker and
|
||||
* read_buffer. */
|
||||
void grpc_do_security_handshake(
|
||||
grpc_exec_ctx *exec_ctx, tsi_handshaker *handshaker,
|
||||
grpc_security_connector *connector, bool is_client_side,
|
||||
grpc_endpoint *nonsecure_endpoint, gpr_timespec deadline,
|
||||
grpc_security_handshake_done_cb cb, void *user_data);
|
||||
grpc_endpoint *nonsecure_endpoint, gpr_slice_buffer *read_buffer,
|
||||
gpr_timespec deadline, grpc_security_handshake_done_cb cb, void *user_data);
|
||||
|
||||
void grpc_security_handshake_shutdown(grpc_exec_ctx *exec_ctx, void *handshake);
|
||||
|
||||
|
|
|
|||
|
|
@ -127,25 +127,29 @@ void grpc_server_security_connector_shutdown(
|
|||
|
||||
void grpc_channel_security_connector_do_handshake(
|
||||
grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc,
|
||||
grpc_endpoint *nonsecure_endpoint, gpr_timespec deadline,
|
||||
grpc_security_handshake_done_cb cb, void *user_data) {
|
||||
grpc_endpoint *nonsecure_endpoint, gpr_slice_buffer *read_buffer,
|
||||
gpr_timespec deadline, grpc_security_handshake_done_cb cb,
|
||||
void *user_data) {
|
||||
if (sc == NULL || nonsecure_endpoint == NULL) {
|
||||
gpr_free(read_buffer);
|
||||
cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL);
|
||||
} else {
|
||||
sc->do_handshake(exec_ctx, sc, nonsecure_endpoint, deadline, cb, user_data);
|
||||
sc->do_handshake(exec_ctx, sc, nonsecure_endpoint, read_buffer, deadline,
|
||||
cb, user_data);
|
||||
}
|
||||
}
|
||||
|
||||
void grpc_server_security_connector_do_handshake(
|
||||
grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc,
|
||||
grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint,
|
||||
gpr_timespec deadline, grpc_security_handshake_done_cb cb,
|
||||
void *user_data) {
|
||||
gpr_slice_buffer *read_buffer, gpr_timespec deadline,
|
||||
grpc_security_handshake_done_cb cb, void *user_data) {
|
||||
if (sc == NULL || nonsecure_endpoint == NULL) {
|
||||
gpr_free(read_buffer);
|
||||
cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL);
|
||||
} else {
|
||||
sc->do_handshake(exec_ctx, sc, acceptor, nonsecure_endpoint, deadline, cb,
|
||||
user_data);
|
||||
sc->do_handshake(exec_ctx, sc, acceptor, nonsecure_endpoint, read_buffer,
|
||||
deadline, cb, user_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -312,23 +316,23 @@ static void fake_channel_check_call_host(grpc_exec_ctx *exec_ctx,
|
|||
static void fake_channel_do_handshake(grpc_exec_ctx *exec_ctx,
|
||||
grpc_channel_security_connector *sc,
|
||||
grpc_endpoint *nonsecure_endpoint,
|
||||
gpr_slice_buffer *read_buffer,
|
||||
gpr_timespec deadline,
|
||||
grpc_security_handshake_done_cb cb,
|
||||
void *user_data) {
|
||||
grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(1), &sc->base,
|
||||
true, nonsecure_endpoint, deadline, cb, user_data);
|
||||
true, nonsecure_endpoint, read_buffer, deadline,
|
||||
cb, user_data);
|
||||
}
|
||||
|
||||
static void fake_server_do_handshake(grpc_exec_ctx *exec_ctx,
|
||||
grpc_server_security_connector *sc,
|
||||
grpc_tcp_server_acceptor *acceptor,
|
||||
grpc_endpoint *nonsecure_endpoint,
|
||||
gpr_timespec deadline,
|
||||
grpc_security_handshake_done_cb cb,
|
||||
void *user_data) {
|
||||
static void fake_server_do_handshake(
|
||||
grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc,
|
||||
grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint,
|
||||
gpr_slice_buffer *read_buffer, gpr_timespec deadline,
|
||||
grpc_security_handshake_done_cb cb, void *user_data) {
|
||||
grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(0), &sc->base,
|
||||
false, nonsecure_endpoint, deadline, cb,
|
||||
user_data);
|
||||
false, nonsecure_endpoint, read_buffer, deadline,
|
||||
cb, user_data);
|
||||
}
|
||||
|
||||
static grpc_security_connector_vtable fake_channel_vtable = {
|
||||
|
|
@ -418,6 +422,7 @@ static grpc_security_status ssl_create_handshaker(
|
|||
static void ssl_channel_do_handshake(grpc_exec_ctx *exec_ctx,
|
||||
grpc_channel_security_connector *sc,
|
||||
grpc_endpoint *nonsecure_endpoint,
|
||||
gpr_slice_buffer *read_buffer,
|
||||
gpr_timespec deadline,
|
||||
grpc_security_handshake_done_cb cb,
|
||||
void *user_data) {
|
||||
|
|
@ -430,30 +435,32 @@ static void ssl_channel_do_handshake(grpc_exec_ctx *exec_ctx,
|
|||
: c->target_name,
|
||||
&handshaker);
|
||||
if (status != GRPC_SECURITY_OK) {
|
||||
gpr_free(read_buffer);
|
||||
cb(exec_ctx, user_data, status, NULL, NULL);
|
||||
} else {
|
||||
grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, true,
|
||||
nonsecure_endpoint, deadline, cb, user_data);
|
||||
nonsecure_endpoint, read_buffer, deadline, cb,
|
||||
user_data);
|
||||
}
|
||||
}
|
||||
|
||||
static void ssl_server_do_handshake(grpc_exec_ctx *exec_ctx,
|
||||
grpc_server_security_connector *sc,
|
||||
grpc_tcp_server_acceptor *acceptor,
|
||||
grpc_endpoint *nonsecure_endpoint,
|
||||
gpr_timespec deadline,
|
||||
grpc_security_handshake_done_cb cb,
|
||||
void *user_data) {
|
||||
static void ssl_server_do_handshake(
|
||||
grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc,
|
||||
grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint,
|
||||
gpr_slice_buffer *read_buffer, gpr_timespec deadline,
|
||||
grpc_security_handshake_done_cb cb, void *user_data) {
|
||||
grpc_ssl_server_security_connector *c =
|
||||
(grpc_ssl_server_security_connector *)sc;
|
||||
tsi_handshaker *handshaker;
|
||||
grpc_security_status status =
|
||||
ssl_create_handshaker(c->handshaker_factory, false, NULL, &handshaker);
|
||||
if (status != GRPC_SECURITY_OK) {
|
||||
gpr_free(read_buffer);
|
||||
cb(exec_ctx, user_data, status, NULL, NULL);
|
||||
} else {
|
||||
grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, false,
|
||||
nonsecure_endpoint, deadline, cb, user_data);
|
||||
nonsecure_endpoint, read_buffer, deadline, cb,
|
||||
user_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -143,7 +143,8 @@ struct grpc_channel_security_connector {
|
|||
grpc_security_call_host_check_cb cb, void *user_data);
|
||||
void (*do_handshake)(grpc_exec_ctx *exec_ctx,
|
||||
grpc_channel_security_connector *sc,
|
||||
grpc_endpoint *nonsecure_endpoint, gpr_timespec deadline,
|
||||
grpc_endpoint *nonsecure_endpoint,
|
||||
gpr_slice_buffer *read_buffer, gpr_timespec deadline,
|
||||
grpc_security_handshake_done_cb cb, void *user_data);
|
||||
};
|
||||
|
||||
|
|
@ -156,8 +157,8 @@ void grpc_channel_security_connector_check_call_host(
|
|||
/* Handshake. */
|
||||
void grpc_channel_security_connector_do_handshake(
|
||||
grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *connector,
|
||||
grpc_endpoint *nonsecure_endpoint, gpr_timespec deadline,
|
||||
grpc_security_handshake_done_cb cb, void *user_data);
|
||||
grpc_endpoint *nonsecure_endpoint, gpr_slice_buffer *read_buffer,
|
||||
gpr_timespec deadline, grpc_security_handshake_done_cb cb, void *user_data);
|
||||
|
||||
/* --- server_security_connector object. ---
|
||||
|
||||
|
|
@ -174,14 +175,16 @@ struct grpc_server_security_connector {
|
|||
void (*do_handshake)(grpc_exec_ctx *exec_ctx,
|
||||
grpc_server_security_connector *sc,
|
||||
grpc_tcp_server_acceptor *acceptor,
|
||||
grpc_endpoint *nonsecure_endpoint, gpr_timespec deadline,
|
||||
grpc_endpoint *nonsecure_endpoint,
|
||||
gpr_slice_buffer *read_buffer, gpr_timespec deadline,
|
||||
grpc_security_handshake_done_cb cb, void *user_data);
|
||||
};
|
||||
|
||||
void grpc_server_security_connector_do_handshake(
|
||||
grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc,
|
||||
grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint,
|
||||
gpr_timespec deadline, grpc_security_handshake_done_cb cb, void *user_data);
|
||||
gpr_slice_buffer *read_buffer, gpr_timespec deadline,
|
||||
grpc_security_handshake_done_cb cb, void *user_data);
|
||||
|
||||
void grpc_server_security_connector_shutdown(
|
||||
grpc_exec_ctx *exec_ctx, grpc_server_security_connector *connector);
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@
|
|||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/string_util.h>
|
||||
#include <grpc/support/time.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
|
|
|||
|
|
@ -37,12 +37,19 @@
|
|||
namespace grpc {
|
||||
|
||||
ByteBuffer::ByteBuffer(const Slice* slices, size_t nslices) {
|
||||
// TODO(yangg) maybe expose some core API to simplify this
|
||||
std::vector<gpr_slice> c_slices(nslices);
|
||||
for (size_t i = 0; i < nslices; i++) {
|
||||
c_slices[i] = slices[i].slice_;
|
||||
}
|
||||
buffer_ = grpc_raw_byte_buffer_create(c_slices.data(), nslices);
|
||||
// The following assertions check that the representation of a grpc::Slice is
|
||||
// identical to that of a gpr_slice: it has a gpr_slice field, and nothing
|
||||
// else.
|
||||
static_assert(std::is_same<decltype(slices[0].slice_), gpr_slice>::value,
|
||||
"Slice must have same representation as gpr_slice");
|
||||
static_assert(sizeof(Slice) == sizeof(gpr_slice),
|
||||
"Slice must have same representation as gpr_slice");
|
||||
// The const_cast is legal if grpc_raw_byte_buffer_create() does no more
|
||||
// than its advertised side effect of increasing the reference count of the
|
||||
// slices it processes, and such an increase does not affect the semantics
|
||||
// seen by the caller of this constructor.
|
||||
buffer_ = grpc_raw_byte_buffer_create(
|
||||
reinterpret_cast<gpr_slice*>(const_cast<Slice*>(slices)), nslices);
|
||||
}
|
||||
|
||||
ByteBuffer::~ByteBuffer() {
|
||||
|
|
@ -95,4 +102,10 @@ ByteBuffer& ByteBuffer::operator=(const ByteBuffer& buf) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
void ByteBuffer::Swap(ByteBuffer* other) {
|
||||
grpc_byte_buffer* tmp = other->buffer_;
|
||||
other->buffer_ = this->buffer_;
|
||||
this->buffer_ = tmp;
|
||||
}
|
||||
|
||||
} // namespace grpc
|
||||
|
|
|
|||
|
|
@ -39,30 +39,25 @@
|
|||
<AssemblyOriginatorKeyFile>..\keys\Grpc.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="BouncyCastle.Crypto, Version=1.7.4137.9688, Culture=neutral, PublicKeyToken=a4292a325f69b123, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Auth, Version=1.11.1.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Auth.PlatformServices, Version=1.11.1.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Core, Version=1.11.1.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Google.Apis.Core.1.11.1\lib\net45\Google.Apis.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Net" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Net.Http.WebRequest" />
|
||||
<Reference Include="BouncyCastle.Crypto">
|
||||
<HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Core">
|
||||
<HintPath>..\packages\Google.Apis.Core.1.15.0\lib\net45\Google.Apis.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Auth">
|
||||
<HintPath>..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Auth.PlatformServices">
|
||||
<HintPath>..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Grpc.Core\Version.cs">
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
<copyright>Copyright 2015, Google Inc.</copyright>
|
||||
<tags>gRPC RPC Protocol HTTP/2 Auth OAuth2</tags>
|
||||
<dependencies>
|
||||
<dependency id="Google.Apis.Auth" version="1.11.1" />
|
||||
<dependency id="Google.Apis.Auth" version="1.15.0" />
|
||||
<dependency id="Grpc.Core" version="$version$" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
|
||||
<package id="Google.Apis.Auth" version="1.11.1" targetFramework="net45" />
|
||||
<package id="Google.Apis.Core" version="1.11.1" targetFramework="net45" />
|
||||
<package id="Google.Apis.Auth" version="1.15.0" targetFramework="net45" />
|
||||
<package id="Google.Apis.Core" version="1.15.0" targetFramework="net45" />
|
||||
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
|
||||
</packages>
|
||||
|
|
@ -23,13 +23,13 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"Grpc.Core": "1.1.0-dev",
|
||||
"Google.Apis.Auth": "1.11.1"
|
||||
"Google.Apis.Auth": "1.15.0"
|
||||
},
|
||||
"frameworks": {
|
||||
"net45": { },
|
||||
"netstandard1.5": {
|
||||
"imports": [
|
||||
"net45"
|
||||
"portable-net45"
|
||||
],
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Portable.Compatibility": "1.0.1",
|
||||
|
|
|
|||
|
|
@ -58,9 +58,9 @@ namespace Grpc.Core.Tests
|
|||
[Test]
|
||||
public void TestsJsonUpToDate()
|
||||
{
|
||||
Dictionary<string, List<string>> discoveredTests = DiscoverAllTestClasses();
|
||||
Dictionary<string, List<string>> testsFromFile
|
||||
= JsonConvert.DeserializeObject<Dictionary<string, List<string>>>(ReadTestsJson());
|
||||
var discoveredTests = DiscoverAllTestClasses();
|
||||
var testsFromFile
|
||||
= JsonConvert.DeserializeObject<Dictionary<string, List<string>>>(ReadTestsJson());
|
||||
|
||||
Assert.AreEqual(discoveredTests, testsFromFile);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"runtimes": {
|
||||
"win7-x64": { },
|
||||
"debian.8-x64": { },
|
||||
"osx.10.11-x64": { }
|
||||
},
|
||||
|
||||
"dependencies": {
|
||||
"Grpc.Examples": {
|
||||
|
|
|
|||
|
|
@ -42,6 +42,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"runtimes": {
|
||||
"win7-x64": { },
|
||||
"debian.8-x64": { },
|
||||
"osx.10.11-x64": { }
|
||||
},
|
||||
|
||||
"dependencies": {
|
||||
"Grpc.Examples": {
|
||||
|
|
|
|||
|
|
@ -20,11 +20,12 @@
|
|||
"System.IO": ""
|
||||
}
|
||||
},
|
||||
"netstandard1.5": {
|
||||
"netcoreapp1.0": {
|
||||
"imports": [
|
||||
"portable-net45"
|
||||
],
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.App": "1.0.0",
|
||||
"NETStandard.Library": "1.6.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,30 +39,25 @@
|
|||
<AssemblyOriginatorKeyFile>..\keys\Grpc.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="BouncyCastle.Crypto, Version=1.7.4137.9688, Culture=neutral, PublicKeyToken=a4292a325f69b123, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Auth, Version=1.11.1.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Auth.PlatformServices, Version=1.11.1.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Core, Version=1.11.1.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Google.Apis.Core.1.11.1\lib\net45\Google.Apis.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Net" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Net.Http.WebRequest" />
|
||||
<Reference Include="BouncyCastle.Crypto">
|
||||
<HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Core">
|
||||
<HintPath>..\packages\Google.Apis.Core.1.15.0\lib\net45\Google.Apis.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Auth">
|
||||
<HintPath>..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Auth.PlatformServices">
|
||||
<HintPath>..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Grpc.Core\Version.cs">
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
|
||||
<package id="Google.Apis.Auth" version="1.11.1" targetFramework="net45" />
|
||||
<package id="Google.Apis.Core" version="1.11.1" targetFramework="net45" />
|
||||
<package id="Google.Apis.Auth" version="1.15.0" targetFramework="net45" />
|
||||
<package id="Google.Apis.Core" version="1.15.0" targetFramework="net45" />
|
||||
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
|
||||
</packages>
|
||||
|
|
@ -58,7 +58,6 @@
|
|||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="Grpc.IntegrationTesting.QpsWorker.project.json" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Net.Http.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.2.29.0" newVersion="4.2.29.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Google.Apis.Core" publicKeyToken="4b01fa6e34db77ab" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.11.1.0" newVersion="1.11.1.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
||||
|
|
@ -44,6 +44,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"runtimes": {
|
||||
"win7-x64": { },
|
||||
"debian.8-x64": { },
|
||||
"osx.10.11-x64": { }
|
||||
},
|
||||
|
||||
"dependencies": {
|
||||
"Grpc.IntegrationTesting": {
|
||||
|
|
|
|||
|
|
@ -39,30 +39,25 @@
|
|||
<AssemblyOriginatorKeyFile>..\keys\Grpc.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="BouncyCastle.Crypto, Version=1.7.4137.9688, Culture=neutral, PublicKeyToken=a4292a325f69b123, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Auth, Version=1.11.1.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Auth.PlatformServices, Version=1.11.1.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Core, Version=1.11.1.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Google.Apis.Core.1.11.1\lib\net45\Google.Apis.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Net" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Net.Http.WebRequest" />
|
||||
<Reference Include="BouncyCastle.Crypto">
|
||||
<HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Core">
|
||||
<HintPath>..\packages\Google.Apis.Core.1.15.0\lib\net45\Google.Apis.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Auth">
|
||||
<HintPath>..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Auth.PlatformServices">
|
||||
<HintPath>..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Grpc.Core\Version.cs">
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
|
||||
<package id="Google.Apis.Auth" version="1.11.1" targetFramework="net45" />
|
||||
<package id="Google.Apis.Core" version="1.11.1" targetFramework="net45" />
|
||||
<package id="Google.Apis.Auth" version="1.15.0" targetFramework="net45" />
|
||||
<package id="Google.Apis.Core" version="1.15.0" targetFramework="net45" />
|
||||
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
|
||||
</packages>
|
||||
|
|
@ -44,6 +44,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"runtimes": {
|
||||
"win7-x64": { },
|
||||
"debian.8-x64": { },
|
||||
"osx.10.11-x64": { }
|
||||
},
|
||||
|
||||
"dependencies": {
|
||||
"Grpc.IntegrationTesting": {
|
||||
|
|
|
|||
|
|
@ -38,9 +38,6 @@
|
|||
<AssemblyOriginatorKeyFile>..\keys\Grpc.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="CommandLine">
|
||||
<HintPath>..\packages\CommandLineParser.1.9.71\lib\net45\CommandLine.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Moq">
|
||||
<HintPath>..\packages\Moq.4.2.1510.2205\lib\net40\Moq.dll</HintPath>
|
||||
</Reference>
|
||||
|
|
@ -51,15 +48,6 @@
|
|||
<Reference Include="BouncyCastle.Crypto">
|
||||
<HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Auth">
|
||||
<HintPath>..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Auth.PlatformServices">
|
||||
<HintPath>..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Core">
|
||||
<HintPath>..\packages\Google.Apis.Core.1.11.1\lib\net45\Google.Apis.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Protobuf">
|
||||
<HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
|
||||
</Reference>
|
||||
|
|
@ -75,6 +63,18 @@
|
|||
<Reference Include="nunitlite">
|
||||
<HintPath>..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Core">
|
||||
<HintPath>..\packages\Google.Apis.Core.1.15.0\lib\net45\Google.Apis.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Auth">
|
||||
<HintPath>..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Auth.PlatformServices">
|
||||
<HintPath>..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="CommandLineParser.Unofficial">
|
||||
<HintPath>..\packages\CommandLineParser.Unofficial.2.0.275\lib\net45\CommandLineParser.Unofficial.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Grpc.Core\Version.cs">
|
||||
|
|
|
|||
|
|
@ -56,24 +56,24 @@ namespace Grpc.IntegrationTesting
|
|||
{
|
||||
private class ClientOptions
|
||||
{
|
||||
[Option("server_host", DefaultValue = "127.0.0.1")]
|
||||
[Option("server_host", Default = "127.0.0.1")]
|
||||
public string ServerHost { get; set; }
|
||||
|
||||
[Option("server_host_override", DefaultValue = TestCredentials.DefaultHostOverride)]
|
||||
[Option("server_host_override", Default = TestCredentials.DefaultHostOverride)]
|
||||
public string ServerHostOverride { get; set; }
|
||||
|
||||
[Option("server_port", Required = true)]
|
||||
public int ServerPort { get; set; }
|
||||
|
||||
[Option("test_case", DefaultValue = "large_unary")]
|
||||
[Option("test_case", Default = "large_unary")]
|
||||
public string TestCase { get; set; }
|
||||
|
||||
// Deliberately using nullable bool type to allow --use_tls=true syntax (as opposed to --use_tls)
|
||||
[Option("use_tls", DefaultValue = false)]
|
||||
[Option("use_tls", Default = false)]
|
||||
public bool? UseTls { get; set; }
|
||||
|
||||
// Deliberately using nullable bool type to allow --use_test_ca=true syntax (as opposed to --use_test_ca)
|
||||
[Option("use_test_ca", DefaultValue = false)]
|
||||
[Option("use_test_ca", Default = false)]
|
||||
public bool? UseTestCa { get; set; }
|
||||
|
||||
[Option("default_service_account", Required = false)]
|
||||
|
|
@ -84,19 +84,6 @@ namespace Grpc.IntegrationTesting
|
|||
|
||||
[Option("service_account_key_file", Required = false)]
|
||||
public string ServiceAccountKeyFile { get; set; }
|
||||
|
||||
[HelpOption]
|
||||
public string GetUsage()
|
||||
{
|
||||
var help = new HelpText
|
||||
{
|
||||
Heading = "gRPC C# interop testing client",
|
||||
AddDashesToOption = true
|
||||
};
|
||||
help.AddPreOptionsLine("Usage:");
|
||||
help.AddOptions(this);
|
||||
return help;
|
||||
}
|
||||
}
|
||||
|
||||
ClientOptions options;
|
||||
|
|
@ -108,14 +95,13 @@ namespace Grpc.IntegrationTesting
|
|||
|
||||
public static void Run(string[] args)
|
||||
{
|
||||
var options = new ClientOptions();
|
||||
if (!Parser.Default.ParseArguments(args, options))
|
||||
{
|
||||
Environment.Exit(1);
|
||||
}
|
||||
|
||||
var interopClient = new InteropClient(options);
|
||||
interopClient.Run().Wait();
|
||||
var parserResult = Parser.Default.ParseArguments<ClientOptions>(args)
|
||||
.WithNotParsed(errors => Environment.Exit(1))
|
||||
.WithParsed(options =>
|
||||
{
|
||||
var interopClient = new InteropClient(options);
|
||||
interopClient.Run().Wait();
|
||||
});
|
||||
}
|
||||
|
||||
private async Task Run()
|
||||
|
|
@ -145,26 +131,16 @@ namespace Grpc.IntegrationTesting
|
|||
|
||||
if (options.TestCase == "jwt_token_creds")
|
||||
{
|
||||
#if !NETCOREAPP1_0
|
||||
var googleCredential = await GoogleCredential.GetApplicationDefaultAsync();
|
||||
Assert.IsTrue(googleCredential.IsCreateScopedRequired);
|
||||
credentials = ChannelCredentials.Create(credentials, googleCredential.ToCallCredentials());
|
||||
#else
|
||||
// TODO(jtattermusch): implement this
|
||||
throw new NotImplementedException("Not supported on CoreCLR yet");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (options.TestCase == "compute_engine_creds")
|
||||
{
|
||||
#if !NETCOREAPP1_0
|
||||
var googleCredential = await GoogleCredential.GetApplicationDefaultAsync();
|
||||
Assert.IsFalse(googleCredential.IsCreateScopedRequired);
|
||||
credentials = ChannelCredentials.Create(credentials, googleCredential.ToCallCredentials());
|
||||
#else
|
||||
// TODO(jtattermusch): implement this
|
||||
throw new NotImplementedException("Not supported on CoreCLR yet");
|
||||
#endif
|
||||
}
|
||||
return credentials;
|
||||
}
|
||||
|
|
@ -395,7 +371,6 @@ namespace Grpc.IntegrationTesting
|
|||
|
||||
public static async Task RunOAuth2AuthTokenAsync(TestService.TestServiceClient client, string oauthScope)
|
||||
{
|
||||
#if !NETCOREAPP1_0
|
||||
Console.WriteLine("running oauth2_auth_token");
|
||||
ITokenAccess credential = (await GoogleCredential.GetApplicationDefaultAsync()).CreateScoped(new[] { oauthScope });
|
||||
string oauth2Token = await credential.GetAccessTokenForRequestAsync();
|
||||
|
|
@ -413,15 +388,10 @@ namespace Grpc.IntegrationTesting
|
|||
Assert.True(oauthScope.Contains(response.OauthScope));
|
||||
Assert.AreEqual(GetEmailFromServiceAccountFile(), response.Username);
|
||||
Console.WriteLine("Passed!");
|
||||
#else
|
||||
// TODO(jtattermusch): implement this
|
||||
throw new NotImplementedException("Not supported on CoreCLR yet");
|
||||
#endif
|
||||
}
|
||||
|
||||
public static async Task RunPerRpcCredsAsync(TestService.TestServiceClient client, string oauthScope)
|
||||
{
|
||||
#if !NETCOREAPP1_0
|
||||
Console.WriteLine("running per_rpc_creds");
|
||||
ITokenAccess googleCredential = await GoogleCredential.GetApplicationDefaultAsync();
|
||||
|
||||
|
|
@ -435,10 +405,6 @@ namespace Grpc.IntegrationTesting
|
|||
|
||||
Assert.AreEqual(GetEmailFromServiceAccountFile(), response.Username);
|
||||
Console.WriteLine("Passed!");
|
||||
#else
|
||||
// TODO(jtattermusch): implement this
|
||||
throw new NotImplementedException("Not supported on CoreCLR yet");
|
||||
#endif
|
||||
}
|
||||
|
||||
public static async Task RunCancelAfterBeginAsync(TestService.TestServiceClient client)
|
||||
|
|
@ -731,17 +697,12 @@ namespace Grpc.IntegrationTesting
|
|||
// extracts the client_email field from service account file used for auth test cases
|
||||
private static string GetEmailFromServiceAccountFile()
|
||||
{
|
||||
#if !NETCOREAPP1_0
|
||||
string keyFile = Environment.GetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS");
|
||||
Assert.IsNotNull(keyFile);
|
||||
var jobject = JObject.Parse(File.ReadAllText(keyFile));
|
||||
string email = jobject.GetValue("client_email").Value<string>();
|
||||
Assert.IsTrue(email.Length > 0); // spec requires nonempty client email.
|
||||
return email;
|
||||
#else
|
||||
// TODO(jtattermusch): implement this
|
||||
throw new NotImplementedException("Not supported on CoreCLR yet");
|
||||
#endif
|
||||
}
|
||||
|
||||
private static Metadata CreateTestMetadata()
|
||||
|
|
|
|||
|
|
@ -51,25 +51,12 @@ namespace Grpc.IntegrationTesting
|
|||
{
|
||||
private class ServerOptions
|
||||
{
|
||||
[Option("port", DefaultValue = 8070)]
|
||||
[Option("port", Default = 8070)]
|
||||
public int Port { get; set; }
|
||||
|
||||
// Deliberately using nullable bool type to allow --use_tls=true syntax (as opposed to --use_tls)
|
||||
[Option("use_tls", DefaultValue = false)]
|
||||
[Option("use_tls", Default = false)]
|
||||
public bool? UseTls { get; set; }
|
||||
|
||||
[HelpOption]
|
||||
public string GetUsage()
|
||||
{
|
||||
var help = new HelpText
|
||||
{
|
||||
Heading = "gRPC C# interop testing server",
|
||||
AddDashesToOption = true
|
||||
};
|
||||
help.AddPreOptionsLine("Usage:");
|
||||
help.AddOptions(this);
|
||||
return help;
|
||||
}
|
||||
}
|
||||
|
||||
ServerOptions options;
|
||||
|
|
@ -81,14 +68,13 @@ namespace Grpc.IntegrationTesting
|
|||
|
||||
public static void Run(string[] args)
|
||||
{
|
||||
var options = new ServerOptions();
|
||||
if (!Parser.Default.ParseArguments(args, options))
|
||||
{
|
||||
Environment.Exit(1);
|
||||
}
|
||||
|
||||
var interopServer = new InteropServer(options);
|
||||
interopServer.Run();
|
||||
var parserResult = Parser.Default.ParseArguments<ServerOptions>(args)
|
||||
.WithNotParsed(errors => Environment.Exit(1))
|
||||
.WithParsed(options =>
|
||||
{
|
||||
var interopServer = new InteropServer(options);
|
||||
interopServer.Run();
|
||||
});
|
||||
}
|
||||
|
||||
private void Run()
|
||||
|
|
|
|||
|
|
@ -52,21 +52,8 @@ namespace Grpc.IntegrationTesting
|
|||
{
|
||||
private class ServerOptions
|
||||
{
|
||||
[Option("driver_port", DefaultValue = 0)]
|
||||
[Option("driver_port", Default = 0)]
|
||||
public int DriverPort { get; set; }
|
||||
|
||||
[HelpOption]
|
||||
public string GetUsage()
|
||||
{
|
||||
var help = new HelpText
|
||||
{
|
||||
Heading = "gRPC C# performance testing worker",
|
||||
AddDashesToOption = true
|
||||
};
|
||||
help.AddPreOptionsLine("Usage:");
|
||||
help.AddOptions(this);
|
||||
return help;
|
||||
}
|
||||
}
|
||||
|
||||
ServerOptions options;
|
||||
|
|
@ -78,14 +65,13 @@ namespace Grpc.IntegrationTesting
|
|||
|
||||
public static void Run(string[] args)
|
||||
{
|
||||
var options = new ServerOptions();
|
||||
if (!Parser.Default.ParseArguments(args, options))
|
||||
{
|
||||
Environment.Exit(1);
|
||||
}
|
||||
|
||||
var workerServer = new QpsWorker(options);
|
||||
workerServer.RunAsync().Wait();
|
||||
var parserResult = Parser.Default.ParseArguments<ServerOptions>(args)
|
||||
.WithNotParsed((x) => Environment.Exit(1))
|
||||
.WithParsed(options =>
|
||||
{
|
||||
var workerServer = new QpsWorker(options);
|
||||
workerServer.RunAsync().Wait();
|
||||
});
|
||||
}
|
||||
|
||||
private async Task RunAsync()
|
||||
|
|
|
|||
|
|
@ -54,36 +54,23 @@ namespace Grpc.IntegrationTesting
|
|||
|
||||
private class ClientOptions
|
||||
{
|
||||
[Option("server_addresses", DefaultValue = "localhost:8080")]
|
||||
[Option("server_addresses", Default = "localhost:8080")]
|
||||
public string ServerAddresses { get; set; }
|
||||
|
||||
[Option("test_cases", DefaultValue = "large_unary:100")]
|
||||
[Option("test_cases", Default = "large_unary:100")]
|
||||
public string TestCases { get; set; }
|
||||
|
||||
[Option("test_duration_secs", DefaultValue = -1)]
|
||||
[Option("test_duration_secs", Default = -1)]
|
||||
public int TestDurationSecs { get; set; }
|
||||
|
||||
[Option("num_channels_per_server", DefaultValue = 1)]
|
||||
[Option("num_channels_per_server", Default = 1)]
|
||||
public int NumChannelsPerServer { get; set; }
|
||||
|
||||
[Option("num_stubs_per_channel", DefaultValue = 1)]
|
||||
[Option("num_stubs_per_channel", Default = 1)]
|
||||
public int NumStubsPerChannel { get; set; }
|
||||
|
||||
[Option("metrics_port", DefaultValue = 8081)]
|
||||
[Option("metrics_port", Default = 8081)]
|
||||
public int MetricsPort { get; set; }
|
||||
|
||||
[HelpOption]
|
||||
public string GetUsage()
|
||||
{
|
||||
var help = new HelpText
|
||||
{
|
||||
Heading = "gRPC C# stress test client",
|
||||
AddDashesToOption = true
|
||||
};
|
||||
help.AddPreOptionsLine("Usage:");
|
||||
help.AddOptions(this);
|
||||
return help;
|
||||
}
|
||||
}
|
||||
|
||||
ClientOptions options;
|
||||
|
|
@ -105,23 +92,21 @@ namespace Grpc.IntegrationTesting
|
|||
|
||||
public static void Run(string[] args)
|
||||
{
|
||||
var options = new ClientOptions();
|
||||
if (!Parser.Default.ParseArguments(args, options))
|
||||
{
|
||||
Environment.Exit(1);
|
||||
}
|
||||
var parserResult = Parser.Default.ParseArguments<ClientOptions>(args)
|
||||
.WithNotParsed((x) => Environment.Exit(1))
|
||||
.WithParsed(options => {
|
||||
GrpcPreconditions.CheckArgument(options.NumChannelsPerServer > 0);
|
||||
GrpcPreconditions.CheckArgument(options.NumStubsPerChannel > 0);
|
||||
|
||||
GrpcPreconditions.CheckArgument(options.NumChannelsPerServer > 0);
|
||||
GrpcPreconditions.CheckArgument(options.NumStubsPerChannel > 0);
|
||||
var serverAddresses = options.ServerAddresses.Split(',');
|
||||
GrpcPreconditions.CheckArgument(serverAddresses.Length > 0, "You need to provide at least one server address");
|
||||
|
||||
var serverAddresses = options.ServerAddresses.Split(',');
|
||||
GrpcPreconditions.CheckArgument(serverAddresses.Length > 0, "You need to provide at least one server address");
|
||||
var testCases = ParseWeightedTestCases(options.TestCases);
|
||||
GrpcPreconditions.CheckArgument(testCases.Count > 0, "You need to provide at least one test case");
|
||||
|
||||
var testCases = ParseWeightedTestCases(options.TestCases);
|
||||
GrpcPreconditions.CheckArgument(testCases.Count > 0, "You need to provide at least one test case");
|
||||
|
||||
var interopClient = new StressTestClient(options, serverAddresses.ToList(), testCases);
|
||||
interopClient.Run().Wait();
|
||||
var interopClient = new StressTestClient(options, serverAddresses.ToList(), testCases);
|
||||
interopClient.Run().Wait();
|
||||
});
|
||||
}
|
||||
|
||||
async Task Run()
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
|
||||
<package id="CommandLineParser" version="1.9.71" targetFramework="net45" />
|
||||
<package id="Google.Apis.Auth" version="1.11.1" targetFramework="net45" />
|
||||
<package id="Google.Apis.Core" version="1.11.1" targetFramework="net45" />
|
||||
<package id="CommandLineParser.Unofficial" version="2.0.275" targetFramework="net45" />
|
||||
<package id="Google.Apis.Auth" version="1.15.0" targetFramework="net45" />
|
||||
<package id="Google.Apis.Core" version="1.15.0" targetFramework="net45" />
|
||||
<package id="Google.Protobuf" version="3.0.0-beta3" targetFramework="net45" />
|
||||
<package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
|
||||
<package id="Moq" version="4.2.1510.2205" targetFramework="net45" />
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@
|
|||
"target": "project"
|
||||
},
|
||||
"Google.Protobuf": "3.0.0-beta3",
|
||||
"CommandLineParser": "1.9.71",
|
||||
"CommandLineParser.Unofficial": "2.0.275",
|
||||
"NUnit": "3.2.0",
|
||||
"NUnitLite": "3.2.0-*"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -31,10 +31,7 @@
|
|||
|
||||
@rem Current package versions
|
||||
set VERSION=1.1.0-dev
|
||||
set PROTOBUF_VERSION=3.0.0-beta3
|
||||
|
||||
@rem Packages that depend on prerelease packages (like Google.Protobuf) need to have prerelease suffix as well.
|
||||
set VERSION_WITH_BETA=%VERSION%-beta
|
||||
set PROTOBUF_VERSION=3.0.0
|
||||
|
||||
@rem Adjust the location of nuget.exe
|
||||
set NUGET=C:\nuget\nuget.exe
|
||||
|
|
@ -58,7 +55,6 @@ xcopy /Y /I ..\..\architecture=x64,language=protoc,platform=macos\artifacts\* pr
|
|||
|
||||
@rem Fetch all dependencies
|
||||
%NUGET% restore ..\..\vsprojects\grpc_csharp_ext.sln || goto :error
|
||||
%NUGET% restore Grpc.sln || goto :error
|
||||
|
||||
setlocal
|
||||
|
||||
|
|
@ -73,7 +69,7 @@ endlocal
|
|||
|
||||
%NUGET% pack Grpc.Auth\Grpc.Auth.nuspec -Symbols -Version %VERSION% || goto :error
|
||||
%NUGET% pack Grpc.Core\Grpc.Core.nuspec -Symbols -Version %VERSION% || goto :error
|
||||
%NUGET% pack Grpc.HealthCheck\Grpc.HealthCheck.nuspec -Symbols -Version %VERSION_WITH_BETA% -Properties ProtobufVersion=%PROTOBUF_VERSION% || goto :error
|
||||
%NUGET% pack Grpc.HealthCheck\Grpc.HealthCheck.nuspec -Symbols -Version %VERSION% -Properties ProtobufVersion=%PROTOBUF_VERSION% || goto :error
|
||||
%NUGET% pack Grpc.nuspec -Version %VERSION% || goto :error
|
||||
%NUGET% pack Grpc.Tools.nuspec -Version %VERSION% || goto :error
|
||||
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@
|
|||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"grpc": "^0.15.0",
|
||||
"grpc": "^1.1.0-dev",
|
||||
"lodash": "^3.9.3",
|
||||
"google-protobuf": "^3.0.0-alpha.5"
|
||||
"google-protobuf": "^3.0.0"
|
||||
},
|
||||
"files": [
|
||||
"LICENSE",
|
||||
|
|
|
|||
|
|
@ -47,7 +47,11 @@ var exe_ext = process.platform === 'win32' ? '.exe' : '';
|
|||
|
||||
var protoc = path.resolve(__dirname, 'protoc' + exe_ext);
|
||||
|
||||
var child_process = execFile(protoc, process.argv.slice(2), function(error, stdout, stderr) {
|
||||
var plugin = path.resolve(__dirname, 'grpc_node_plugin' + exe_ext);
|
||||
|
||||
var args = ['--plugin=protoc-gen-grpc=' + plugin].concat(process.argv.slice(2));
|
||||
|
||||
var child_process = execFile(protoc, args, function(error, stdout, stderr) {
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,394 +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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This test file is derived from fixture h2_ssl.c in core end2end test
|
||||
* (test/core/end2end/fixture/h2_ssl.c). The structure of the fixture is
|
||||
* preserved as much as possible
|
||||
*
|
||||
* This fixture creates a server full stack using chttp2 and a client
|
||||
* full stack using Cronet. End-to-end tests are run against this
|
||||
* configuration
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <grpc/support/alloc.h>
|
||||
#include <grpc/support/host_port.h>
|
||||
#include <grpc/support/log.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/security/credentials/credentials.h"
|
||||
#include "src/core/lib/support/env.h"
|
||||
#include "src/core/lib/support/string.h"
|
||||
#include "src/core/lib/support/tmpfile.h"
|
||||
#include "test/core/end2end/data/ssl_test_data.h"
|
||||
#include "test/core/util/port.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
#include <grpc/grpc_cronet.h>
|
||||
#import <Cronet/Cronet.h>
|
||||
|
||||
typedef struct fullstack_secure_fixture_data {
|
||||
char *localaddr;
|
||||
} fullstack_secure_fixture_data;
|
||||
|
||||
static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack(
|
||||
grpc_channel_args *client_args, grpc_channel_args *server_args) {
|
||||
grpc_end2end_test_fixture f;
|
||||
int port = grpc_pick_unused_port_or_die();
|
||||
fullstack_secure_fixture_data *ffd =
|
||||
gpr_malloc(sizeof(fullstack_secure_fixture_data));
|
||||
memset(&f, 0, sizeof(f));
|
||||
|
||||
gpr_join_host_port(&ffd->localaddr, "localhost", port);
|
||||
|
||||
f.fixture_data = ffd;
|
||||
f.cq = grpc_completion_queue_create(NULL);
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
static void process_auth_failure(void *state, grpc_auth_context *ctx,
|
||||
const grpc_metadata *md, size_t md_count,
|
||||
grpc_process_auth_metadata_done_cb cb,
|
||||
void *user_data) {
|
||||
GPR_ASSERT(state == NULL);
|
||||
cb(user_data, NULL, 0, NULL, 0, GRPC_STATUS_UNAUTHENTICATED, NULL);
|
||||
}
|
||||
|
||||
static void cronet_init_client_secure_fullstack(
|
||||
grpc_end2end_test_fixture *f, grpc_channel_args *client_args,
|
||||
cronet_engine *cronetEngine) {
|
||||
fullstack_secure_fixture_data *ffd = f->fixture_data;
|
||||
f->client =
|
||||
grpc_cronet_secure_channel_create(cronetEngine, ffd->localaddr, client_args, NULL);
|
||||
GPR_ASSERT(f->client != NULL);
|
||||
}
|
||||
|
||||
static void chttp2_init_server_secure_fullstack(
|
||||
grpc_end2end_test_fixture *f, grpc_channel_args *server_args,
|
||||
grpc_server_credentials *server_creds) {
|
||||
fullstack_secure_fixture_data *ffd = f->fixture_data;
|
||||
if (f->server) {
|
||||
grpc_server_destroy(f->server);
|
||||
}
|
||||
f->server = grpc_server_create(server_args, NULL);
|
||||
grpc_server_register_completion_queue(f->server, f->cq, NULL);
|
||||
GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr,
|
||||
server_creds));
|
||||
grpc_server_credentials_release(server_creds);
|
||||
grpc_server_start(f->server);
|
||||
}
|
||||
|
||||
static void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture *f) {
|
||||
fullstack_secure_fixture_data *ffd = f->fixture_data;
|
||||
gpr_free(ffd->localaddr);
|
||||
gpr_free(ffd);
|
||||
}
|
||||
|
||||
static void cronet_init_client_simple_ssl_secure_fullstack(
|
||||
grpc_end2end_test_fixture *f, grpc_channel_args *client_args) {
|
||||
grpc_arg ssl_name_override = {GRPC_ARG_STRING,
|
||||
GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
|
||||
{"foo.test.google.fr"}};
|
||||
|
||||
grpc_channel_args *new_client_args =
|
||||
grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1);
|
||||
[Cronet setHttp2Enabled:YES];
|
||||
[Cronet start];
|
||||
cronet_engine *cronetEngine = [Cronet getGlobalEngine];
|
||||
|
||||
cronet_init_client_secure_fullstack(f, new_client_args, cronetEngine);
|
||||
grpc_channel_args_destroy(new_client_args);
|
||||
}
|
||||
|
||||
static int fail_server_auth_check(grpc_channel_args *server_args) {
|
||||
size_t i;
|
||||
if (server_args == NULL) return 0;
|
||||
for (i = 0; i < server_args->num_args; i++) {
|
||||
if (strcmp(server_args->args[i].key, FAIL_AUTH_CHECK_SERVER_ARG_NAME) ==
|
||||
0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void chttp2_init_server_simple_ssl_secure_fullstack(
|
||||
grpc_end2end_test_fixture *f, grpc_channel_args *server_args) {
|
||||
grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key,
|
||||
test_server1_cert};
|
||||
grpc_server_credentials *ssl_creds =
|
||||
grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0, NULL);
|
||||
if (fail_server_auth_check(server_args)) {
|
||||
grpc_auth_metadata_processor processor = {process_auth_failure, NULL, NULL};
|
||||
grpc_server_credentials_set_auth_metadata_processor(ssl_creds, processor);
|
||||
}
|
||||
chttp2_init_server_secure_fullstack(f, server_args, ssl_creds);
|
||||
}
|
||||
|
||||
/* All test configurations */
|
||||
|
||||
static grpc_end2end_test_config configs[] = {
|
||||
{"chttp2/simple_ssl_fullstack",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS,
|
||||
chttp2_create_fixture_secure_fullstack,
|
||||
cronet_init_client_simple_ssl_secure_fullstack,
|
||||
chttp2_init_server_simple_ssl_secure_fullstack,
|
||||
chttp2_tear_down_secure_fullstack},
|
||||
};
|
||||
|
||||
|
||||
|
||||
static char *roots_filename;
|
||||
|
||||
@interface CoreCronetEnd2EndTests : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation CoreCronetEnd2EndTests
|
||||
|
||||
|
||||
// The setUp() function is run before the test cases run and only run once
|
||||
+ (void)setUp {
|
||||
[super setUp];
|
||||
|
||||
FILE *roots_file;
|
||||
size_t roots_size = strlen(test_root_cert);
|
||||
|
||||
char *argv[] = {"CoreCronetEnd2EndTests"};
|
||||
grpc_test_init(1, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
|
||||
/* Set the SSL roots env var. */
|
||||
roots_file = gpr_tmpfile("chttp2_simple_ssl_fullstack_test", &roots_filename);
|
||||
GPR_ASSERT(roots_filename != NULL);
|
||||
GPR_ASSERT(roots_file != NULL);
|
||||
GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size);
|
||||
fclose(roots_file);
|
||||
gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename);
|
||||
|
||||
grpc_init();
|
||||
|
||||
}
|
||||
|
||||
// The tearDown() function is run after all test cases finish running
|
||||
+ (void)tearDown {
|
||||
grpc_shutdown();
|
||||
|
||||
/* Cleanup. */
|
||||
remove(roots_filename);
|
||||
gpr_free(roots_filename);
|
||||
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void)testIndividualCase:(char*)test_case {
|
||||
char *argv[] = {"h2_ssl", test_case};
|
||||
|
||||
for (int i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(sizeof(argv) / sizeof(argv[0]), argv, configs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(mxyan): Use NSStringFromSelector(_cmd) to acquire test name from the
|
||||
// test case method name, so that bodies of test cases can stay identical
|
||||
- (void)testBadHostname {
|
||||
[self testIndividualCase:"bad_hostname"];
|
||||
}
|
||||
|
||||
- (void)testBinaryMetadata {
|
||||
[self testIndividualCase:"binary_metadata"];
|
||||
}
|
||||
|
||||
- (void)testCallCreds {
|
||||
[self testIndividualCase:"call_creds"];
|
||||
}
|
||||
|
||||
- (void)testCancelAfterAccept {
|
||||
[self testIndividualCase:"cancel_after_accept"];
|
||||
}
|
||||
|
||||
- (void)testCancelAfterClientDone {
|
||||
[self testIndividualCase:"cancel_after_client_done"];
|
||||
}
|
||||
|
||||
- (void)testCancelAfterInvoke {
|
||||
[self testIndividualCase:"cancel_after_invoke"];
|
||||
}
|
||||
|
||||
- (void)testCancelBeforeInvoke {
|
||||
[self testIndividualCase:"cancel_before_invoke"];
|
||||
}
|
||||
|
||||
- (void)testCancelInAVacuum {
|
||||
[self testIndividualCase:"cancel_in_a_vacuum"];
|
||||
}
|
||||
|
||||
- (void)testCancelWithStatus {
|
||||
[self testIndividualCase:"cancel_with_status"];
|
||||
}
|
||||
|
||||
- (void)testCompressedPayload {
|
||||
[self testIndividualCase:"compressed_payload"];
|
||||
}
|
||||
|
||||
- (void)testConnectivity {
|
||||
[self testIndividualCase:"connectivity"];
|
||||
}
|
||||
|
||||
- (void)testDefaultHost {
|
||||
[self testIndividualCase:"default_host"];
|
||||
}
|
||||
|
||||
- (void)testDisappearingServer {
|
||||
[self testIndividualCase:"disappearing_server"];
|
||||
}
|
||||
|
||||
- (void)testEmptyBatch {
|
||||
[self testIndividualCase:"empty_batch"];
|
||||
}
|
||||
|
||||
- (void)testFilterCausesClose {
|
||||
[self testIndividualCase:"filter_causes_close"];
|
||||
}
|
||||
|
||||
- (void)testGracefulServerShutdown {
|
||||
[self testIndividualCase:"graceful_server_shutdown"];
|
||||
}
|
||||
|
||||
- (void)testHighInitialSeqno {
|
||||
[self testIndividualCase:"high_initial_seqno"];
|
||||
}
|
||||
|
||||
- (void)testHpackSize {
|
||||
[self testIndividualCase:"hpack_size"];
|
||||
}
|
||||
|
||||
- (void)testIdempotentRequest {
|
||||
[self testIndividualCase:"idempotent_request"];
|
||||
}
|
||||
|
||||
- (void)testInvokeLargeRequest {
|
||||
[self testIndividualCase:"invoke_large_request"];
|
||||
}
|
||||
|
||||
- (void)testLargeMetadata {
|
||||
[self testIndividualCase:"large_metadata"];
|
||||
}
|
||||
|
||||
- (void)testMaxConcurrentStreams {
|
||||
[self testIndividualCase:"max_concurrent_streams"];
|
||||
}
|
||||
|
||||
- (void)testMaxMessageLength {
|
||||
[self testIndividualCase:"max_message_length"];
|
||||
}
|
||||
|
||||
- (void)testNegativeDeadline {
|
||||
[self testIndividualCase:"negative_deadline"];
|
||||
}
|
||||
|
||||
- (void)testNetworkStatusChange {
|
||||
[self testIndividualCase:"network_status_change"];
|
||||
}
|
||||
|
||||
- (void)testNoOp {
|
||||
[self testIndividualCase:"no_op"];
|
||||
}
|
||||
|
||||
- (void)testPayload {
|
||||
[self testIndividualCase:"payload"];
|
||||
}
|
||||
|
||||
- (void)testPing {
|
||||
[self testIndividualCase:"ping"];
|
||||
}
|
||||
|
||||
- (void)testPingPongStreaming {
|
||||
[self testIndividualCase:"ping_pong_streaming"];
|
||||
}
|
||||
|
||||
- (void)testRegisteredCall {
|
||||
[self testIndividualCase:"registered_call"];
|
||||
}
|
||||
|
||||
- (void)testRequestWithFlags {
|
||||
[self testIndividualCase:"request_with_flags"];
|
||||
}
|
||||
|
||||
- (void)testRequestWithPayload {
|
||||
[self testIndividualCase:"request_with_payload"];
|
||||
}
|
||||
|
||||
- (void)testServerFinishesRequest {
|
||||
[self testIndividualCase:"server_finishes_request"];
|
||||
}
|
||||
|
||||
- (void)testShutdownFinishesCalls {
|
||||
[self testIndividualCase:"shutdown_finishes_calls"];
|
||||
}
|
||||
|
||||
- (void)testShutdownFinishesTags {
|
||||
[self testIndividualCase:"shutdown_finishes_tags"];
|
||||
}
|
||||
|
||||
- (void)testSimpleDelayedRequest {
|
||||
[self testIndividualCase:"simple_delayed_request"];
|
||||
}
|
||||
|
||||
- (void)testSimpleMetadata {
|
||||
[self testIndividualCase:"simple_metadata"];
|
||||
}
|
||||
|
||||
- (void)testSimpleRequest {
|
||||
[self testIndividualCase:"simple_request"];
|
||||
}
|
||||
|
||||
- (void)testStreamingErrorResponse {
|
||||
[self testIndividualCase:"streaming_error_response"];
|
||||
}
|
||||
|
||||
- (void)testTrailingMetadata {
|
||||
[self testIndividualCase:"trailing_metadata"];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -143,8 +143,7 @@ static inline int php_grpc_zend_hash_find(HashTable *ht, char *key, int len,
|
|||
|
||||
#define PHP_GRPC_RETURN_STRING(val, dup) RETURN_STRING(val)
|
||||
#define PHP_GRPC_MAKE_STD_ZVAL(pzv) \
|
||||
zval _stack_zval_##pzv; \
|
||||
pzv = &(_stack_zval_##pzv)
|
||||
pzv = (zval *)emalloc(sizeof(zval));
|
||||
#define PHP_GRPC_DELREF(zv)
|
||||
|
||||
#define PHP_GRPC_WRAP_OBJECT_START(name) \
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ cdef class Call:
|
|||
|
||||
def __cinit__(self):
|
||||
# Create an *empty* call
|
||||
grpc_init()
|
||||
self.c_call = NULL
|
||||
self.references = []
|
||||
|
||||
|
|
@ -106,6 +107,7 @@ cdef class Call:
|
|||
def __dealloc__(self):
|
||||
if self.c_call != NULL:
|
||||
grpc_call_destroy(self.c_call)
|
||||
grpc_shutdown()
|
||||
|
||||
# The object *should* always be valid from Python. Used for debugging.
|
||||
@property
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ cdef class Channel:
|
|||
|
||||
def __cinit__(self, bytes target, ChannelArgs arguments=None,
|
||||
ChannelCredentials channel_credentials=None):
|
||||
grpc_init()
|
||||
cdef grpc_channel_args *c_arguments = NULL
|
||||
cdef char *c_target = NULL
|
||||
self.c_channel = NULL
|
||||
|
|
@ -103,3 +104,4 @@ cdef class Channel:
|
|||
def __dealloc__(self):
|
||||
if self.c_channel != NULL:
|
||||
grpc_channel_destroy(self.c_channel)
|
||||
grpc_shutdown()
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ cdef int _INTERRUPT_CHECK_PERIOD_MS = 200
|
|||
cdef class CompletionQueue:
|
||||
|
||||
def __cinit__(self):
|
||||
grpc_init()
|
||||
with nogil:
|
||||
self.c_completion_queue = grpc_completion_queue_create(NULL)
|
||||
self.is_shutting_down = False
|
||||
|
|
@ -129,3 +130,4 @@ cdef class CompletionQueue:
|
|||
self.c_completion_queue, c_deadline, NULL)
|
||||
self._interpret_event(event)
|
||||
grpc_completion_queue_destroy(self.c_completion_queue)
|
||||
grpc_shutdown()
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ cimport cpython
|
|||
cdef class ChannelCredentials:
|
||||
|
||||
def __cinit__(self):
|
||||
grpc_init()
|
||||
self.c_credentials = NULL
|
||||
self.c_ssl_pem_key_cert_pair.private_key = NULL
|
||||
self.c_ssl_pem_key_cert_pair.certificate_chain = NULL
|
||||
|
|
@ -47,11 +48,13 @@ cdef class ChannelCredentials:
|
|||
def __dealloc__(self):
|
||||
if self.c_credentials != NULL:
|
||||
grpc_channel_credentials_release(self.c_credentials)
|
||||
grpc_shutdown()
|
||||
|
||||
|
||||
cdef class CallCredentials:
|
||||
|
||||
def __cinit__(self):
|
||||
grpc_init()
|
||||
self.c_credentials = NULL
|
||||
self.references = []
|
||||
|
||||
|
|
@ -64,17 +67,20 @@ cdef class CallCredentials:
|
|||
def __dealloc__(self):
|
||||
if self.c_credentials != NULL:
|
||||
grpc_call_credentials_release(self.c_credentials)
|
||||
grpc_shutdown()
|
||||
|
||||
|
||||
cdef class ServerCredentials:
|
||||
|
||||
def __cinit__(self):
|
||||
grpc_init()
|
||||
self.c_credentials = NULL
|
||||
self.references = []
|
||||
|
||||
def __dealloc__(self):
|
||||
if self.c_credentials != NULL:
|
||||
grpc_server_credentials_release(self.c_credentials)
|
||||
grpc_shutdown()
|
||||
|
||||
|
||||
cdef class CredentialsMetadataPlugin:
|
||||
|
|
@ -90,6 +96,7 @@ cdef class CredentialsMetadataPlugin:
|
|||
successful).
|
||||
name (bytes): Plugin name.
|
||||
"""
|
||||
grpc_init()
|
||||
if not callable(plugin_callback):
|
||||
raise ValueError('expected callable plugin_callback')
|
||||
self.plugin_callback = plugin_callback
|
||||
|
|
@ -105,10 +112,14 @@ cdef class CredentialsMetadataPlugin:
|
|||
cpython.Py_INCREF(self)
|
||||
return result
|
||||
|
||||
def __dealloc__(self):
|
||||
grpc_shutdown()
|
||||
|
||||
|
||||
cdef class AuthMetadataContext:
|
||||
|
||||
def __cinit__(self):
|
||||
grpc_init()
|
||||
self.context.service_url = NULL
|
||||
self.context.method_name = NULL
|
||||
|
||||
|
|
@ -120,6 +131,9 @@ cdef class AuthMetadataContext:
|
|||
def method_name(self):
|
||||
return self.context.method_name
|
||||
|
||||
def __dealloc__(self):
|
||||
grpc_shutdown()
|
||||
|
||||
|
||||
cdef void plugin_get_metadata(
|
||||
void *state, grpc_auth_metadata_context context,
|
||||
|
|
|
|||
|
|
@ -176,12 +176,14 @@ cdef class Timespec:
|
|||
cdef class CallDetails:
|
||||
|
||||
def __cinit__(self):
|
||||
grpc_init()
|
||||
with nogil:
|
||||
grpc_call_details_init(&self.c_details)
|
||||
|
||||
def __dealloc__(self):
|
||||
with nogil:
|
||||
grpc_call_details_destroy(&self.c_details)
|
||||
grpc_shutdown()
|
||||
|
||||
@property
|
||||
def method(self):
|
||||
|
|
@ -232,6 +234,7 @@ cdef class Event:
|
|||
cdef class ByteBuffer:
|
||||
|
||||
def __cinit__(self, bytes data):
|
||||
grpc_init()
|
||||
if data is None:
|
||||
self.c_byte_buffer = NULL
|
||||
return
|
||||
|
|
@ -288,6 +291,7 @@ cdef class ByteBuffer:
|
|||
def __dealloc__(self):
|
||||
if self.c_byte_buffer != NULL:
|
||||
grpc_byte_buffer_destroy(self.c_byte_buffer)
|
||||
grpc_shutdown()
|
||||
|
||||
|
||||
cdef class SslPemKeyCertPair:
|
||||
|
|
@ -319,6 +323,7 @@ cdef class ChannelArg:
|
|||
cdef class ChannelArgs:
|
||||
|
||||
def __cinit__(self, args):
|
||||
grpc_init()
|
||||
self.args = list(args)
|
||||
for arg in self.args:
|
||||
if not isinstance(arg, ChannelArg):
|
||||
|
|
@ -333,6 +338,7 @@ cdef class ChannelArgs:
|
|||
def __dealloc__(self):
|
||||
with nogil:
|
||||
gpr_free(self.c_args.arguments)
|
||||
grpc_shutdown()
|
||||
|
||||
def __len__(self):
|
||||
# self.args is never stale; it's only updated from this file
|
||||
|
|
@ -399,6 +405,7 @@ cdef class _MetadataIterator:
|
|||
cdef class Metadata:
|
||||
|
||||
def __cinit__(self, metadata):
|
||||
grpc_init()
|
||||
self.metadata = list(metadata)
|
||||
for metadatum in metadata:
|
||||
if not isinstance(metadatum, Metadatum):
|
||||
|
|
@ -420,6 +427,7 @@ cdef class Metadata:
|
|||
# it'd be nice if that were documented somewhere...)
|
||||
# TODO(atash): document this in the C core
|
||||
grpc_metadata_array_destroy(&self.c_metadata_array)
|
||||
grpc_shutdown()
|
||||
|
||||
def __len__(self):
|
||||
return self.c_metadata_array.count
|
||||
|
|
@ -437,6 +445,7 @@ cdef class Metadata:
|
|||
cdef class Operation:
|
||||
|
||||
def __cinit__(self):
|
||||
grpc_init()
|
||||
self.references = []
|
||||
self._received_status_details = NULL
|
||||
self._received_status_details_capacity = 0
|
||||
|
|
@ -529,6 +538,7 @@ cdef class Operation:
|
|||
# This means that we need to clean up after receive_status_on_client.
|
||||
if self.c_op.type == GRPC_OP_RECV_STATUS_ON_CLIENT:
|
||||
gpr_free(self._received_status_details)
|
||||
grpc_shutdown()
|
||||
|
||||
def operation_send_initial_metadata(Metadata metadata, int flags):
|
||||
cdef Operation op = Operation()
|
||||
|
|
@ -645,6 +655,7 @@ cdef class _OperationsIterator:
|
|||
cdef class Operations:
|
||||
|
||||
def __cinit__(self, operations):
|
||||
grpc_init()
|
||||
self.operations = list(operations) # normalize iterable
|
||||
self.c_ops = NULL
|
||||
self.c_nops = 0
|
||||
|
|
@ -667,6 +678,7 @@ cdef class Operations:
|
|||
def __dealloc__(self):
|
||||
with nogil:
|
||||
gpr_free(self.c_ops)
|
||||
grpc_shutdown()
|
||||
|
||||
def __iter__(self):
|
||||
return _OperationsIterator(self)
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import time
|
|||
cdef class Server:
|
||||
|
||||
def __cinit__(self, ChannelArgs arguments=None):
|
||||
grpc_init()
|
||||
cdef grpc_channel_args *c_arguments = NULL
|
||||
self.references = []
|
||||
self.registered_completion_queues = []
|
||||
|
|
@ -172,3 +173,4 @@ cdef class Server:
|
|||
while not self.is_shutdown:
|
||||
time.sleep(0)
|
||||
grpc_server_destroy(self.c_server)
|
||||
grpc_shutdown()
|
||||
|
|
|
|||
|
|
@ -55,12 +55,8 @@ cdef extern from "Python.h":
|
|||
|
||||
|
||||
def _initialize():
|
||||
grpc_init()
|
||||
grpc_set_ssl_roots_override_callback(
|
||||
<grpc_ssl_roots_override_callback>ssl_roots_override_callback)
|
||||
|
||||
if Py_AtExit(grpc_shutdown) != 0:
|
||||
raise ImportError('failed to register gRPC library shutdown callbacks')
|
||||
|
||||
|
||||
_initialize()
|
||||
|
|
|
|||
|
|
@ -29,9 +29,10 @@
|
|||
|
||||
"""Insecure client-server interoperability as a unit test."""
|
||||
|
||||
from concurrent import futures
|
||||
import unittest
|
||||
|
||||
from grpc.beta import implementations
|
||||
import grpc
|
||||
from src.proto.grpc.testing import test_pb2
|
||||
|
||||
from tests.interop import _interop_test_case
|
||||
|
|
@ -44,14 +45,13 @@ class InsecureInteropTest(
|
|||
unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.server = test_pb2.beta_create_TestService_server(methods.TestService())
|
||||
self.server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
|
||||
test_pb2.add_TestServiceServicer_to_server(
|
||||
methods.TestService(), self.server)
|
||||
port = self.server.add_insecure_port('[::]:0')
|
||||
self.server.start()
|
||||
self.stub = test_pb2.beta_create_TestService_stub(
|
||||
implementations.insecure_channel('localhost', port))
|
||||
|
||||
def tearDown(self):
|
||||
self.server.stop(0)
|
||||
self.stub = test_pb2.TestServiceStub(
|
||||
grpc.insecure_channel('localhost:{}'.format(port)))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
|||
|
|
@ -29,17 +29,16 @@
|
|||
|
||||
"""Secure client-server interoperability as a unit test."""
|
||||
|
||||
from concurrent import futures
|
||||
import unittest
|
||||
|
||||
from grpc.beta import implementations
|
||||
import grpc
|
||||
from src.proto.grpc.testing import test_pb2
|
||||
|
||||
from tests.interop import _interop_test_case
|
||||
from tests.interop import methods
|
||||
from tests.interop import resources
|
||||
|
||||
from tests.unit.beta import test_utilities
|
||||
|
||||
_SERVER_HOST_OVERRIDE = 'foo.test.google.fr'
|
||||
|
||||
|
||||
|
|
@ -48,19 +47,18 @@ class SecureInteropTest(
|
|||
unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.server = test_pb2.beta_create_TestService_server(methods.TestService())
|
||||
self.server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
|
||||
test_pb2.add_TestServiceServicer_to_server(
|
||||
methods.TestService(), self.server)
|
||||
port = self.server.add_secure_port(
|
||||
'[::]:0', implementations.ssl_server_credentials(
|
||||
'[::]:0', grpc.ssl_server_credentials(
|
||||
[(resources.private_key(), resources.certificate_chain())]))
|
||||
self.server.start()
|
||||
self.stub = test_pb2.beta_create_TestService_stub(
|
||||
test_utilities.not_really_secure_channel(
|
||||
'localhost', port, implementations.ssl_channel_credentials(
|
||||
resources.test_root_certificates()),
|
||||
_SERVER_HOST_OVERRIDE))
|
||||
|
||||
def tearDown(self):
|
||||
self.server.stop(0)
|
||||
self.stub = test_pb2.TestServiceStub(
|
||||
grpc.secure_channel(
|
||||
'localhost:{}'.format(port),
|
||||
grpc.ssl_channel_credentials(resources.test_root_certificates()),
|
||||
(('grpc.ssl_target_name_override', _SERVER_HOST_OVERRIDE,),)))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
|||
|
|
@ -32,14 +32,12 @@
|
|||
import argparse
|
||||
from oauth2client import client as oauth2client_client
|
||||
|
||||
import grpc
|
||||
from grpc.beta import implementations
|
||||
from src.proto.grpc.testing import test_pb2
|
||||
|
||||
from tests.interop import methods
|
||||
from tests.interop import resources
|
||||
from tests.unit.beta import test_utilities
|
||||
|
||||
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
|
||||
|
||||
|
||||
def _args():
|
||||
|
|
@ -66,41 +64,49 @@ def _args():
|
|||
return parser.parse_args()
|
||||
|
||||
|
||||
def _application_default_credentials():
|
||||
return oauth2client_client.GoogleCredentials.get_application_default()
|
||||
|
||||
|
||||
def _stub(args):
|
||||
target = '{}:{}'.format(args.server_host, args.server_port)
|
||||
if args.test_case == 'oauth2_auth_token':
|
||||
creds = oauth2client_client.GoogleCredentials.get_application_default()
|
||||
scoped_creds = creds.create_scoped([args.oauth_scope])
|
||||
access_token = scoped_creds.get_access_token().access_token
|
||||
call_creds = implementations.access_token_call_credentials(access_token)
|
||||
google_credentials = _application_default_credentials()
|
||||
scoped_credentials = google_credentials.create_scoped([args.oauth_scope])
|
||||
access_token = scoped_credentials.get_access_token().access_token
|
||||
call_credentials = grpc.access_token_call_credentials(access_token)
|
||||
elif args.test_case == 'compute_engine_creds':
|
||||
creds = oauth2client_client.GoogleCredentials.get_application_default()
|
||||
scoped_creds = creds.create_scoped([args.oauth_scope])
|
||||
call_creds = implementations.google_call_credentials(scoped_creds)
|
||||
google_credentials = _application_default_credentials()
|
||||
scoped_credentials = google_credentials.create_scoped([args.oauth_scope])
|
||||
# TODO(https://github.com/grpc/grpc/issues/6799): Eliminate this last
|
||||
# remaining use of the Beta API.
|
||||
call_credentials = implementations.google_call_credentials(
|
||||
scoped_credentials)
|
||||
elif args.test_case == 'jwt_token_creds':
|
||||
creds = oauth2client_client.GoogleCredentials.get_application_default()
|
||||
call_creds = implementations.google_call_credentials(creds)
|
||||
google_credentials = _application_default_credentials()
|
||||
# TODO(https://github.com/grpc/grpc/issues/6799): Eliminate this last
|
||||
# remaining use of the Beta API.
|
||||
call_credentials = implementations.google_call_credentials(
|
||||
google_credentials)
|
||||
else:
|
||||
call_creds = None
|
||||
call_credentials = None
|
||||
if args.use_tls:
|
||||
if args.use_test_ca:
|
||||
root_certificates = resources.test_root_certificates()
|
||||
else:
|
||||
root_certificates = None # will load default roots.
|
||||
|
||||
channel_creds = implementations.ssl_channel_credentials(root_certificates)
|
||||
if call_creds is not None:
|
||||
channel_creds = implementations.composite_channel_credentials(
|
||||
channel_creds, call_creds)
|
||||
channel_credentials = grpc.ssl_channel_credentials(root_certificates)
|
||||
if call_credentials is not None:
|
||||
channel_credentials = grpc.composite_channel_credentials(
|
||||
channel_credentials, call_credentials)
|
||||
|
||||
channel = test_utilities.not_really_secure_channel(
|
||||
args.server_host, args.server_port, channel_creds,
|
||||
args.server_host_override)
|
||||
stub = test_pb2.beta_create_TestService_stub(channel)
|
||||
channel = grpc.secure_channel(
|
||||
target, channel_credentials,
|
||||
(('grpc.ssl_target_name_override', args.server_host_override,),))
|
||||
else:
|
||||
channel = implementations.insecure_channel(
|
||||
args.server_host, args.server_port)
|
||||
stub = test_pb2.beta_create_TestService_stub(channel)
|
||||
return stub
|
||||
channel = grpc.insecure_channel(target)
|
||||
return test_pb2.TestServiceStub(channel)
|
||||
|
||||
|
||||
def _test_case_from_arg(test_case_arg):
|
||||
|
|
|
|||
|
|
@ -29,8 +29,6 @@
|
|||
|
||||
"""Implementations of interoperability test methods."""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import enum
|
||||
import json
|
||||
import os
|
||||
|
|
@ -41,26 +39,21 @@ from oauth2client import client as oauth2client_client
|
|||
|
||||
import grpc
|
||||
from grpc.beta import implementations
|
||||
from grpc.beta import interfaces
|
||||
from grpc.framework.common import cardinality
|
||||
from grpc.framework.interfaces.face import face
|
||||
|
||||
from src.proto.grpc.testing import empty_pb2
|
||||
from src.proto.grpc.testing import messages_pb2
|
||||
from src.proto.grpc.testing import test_pb2
|
||||
|
||||
_TIMEOUT = 7
|
||||
|
||||
|
||||
class TestService(test_pb2.BetaTestServiceServicer):
|
||||
class TestService(test_pb2.TestServiceServicer):
|
||||
|
||||
def EmptyCall(self, request, context):
|
||||
return empty_pb2.Empty()
|
||||
|
||||
def UnaryCall(self, request, context):
|
||||
if request.HasField('response_status'):
|
||||
context.code(request.response_status.code)
|
||||
context.details(request.response_status.message)
|
||||
context.set_code(request.response_status.code)
|
||||
context.set_details(request.response_status.message)
|
||||
return messages_pb2.SimpleResponse(
|
||||
payload=messages_pb2.Payload(
|
||||
type=messages_pb2.COMPRESSABLE,
|
||||
|
|
@ -68,8 +61,8 @@ class TestService(test_pb2.BetaTestServiceServicer):
|
|||
|
||||
def StreamingOutputCall(self, request, context):
|
||||
if request.HasField('response_status'):
|
||||
context.code(request.response_status.code)
|
||||
context.details(request.response_status.message)
|
||||
context.set_code(request.response_status.code)
|
||||
context.set_details(request.response_status.message)
|
||||
for response_parameters in request.response_parameters:
|
||||
yield messages_pb2.StreamingOutputCallResponse(
|
||||
payload=messages_pb2.Payload(
|
||||
|
|
@ -79,7 +72,7 @@ class TestService(test_pb2.BetaTestServiceServicer):
|
|||
def StreamingInputCall(self, request_iterator, context):
|
||||
aggregate_size = 0
|
||||
for request in request_iterator:
|
||||
if request.payload and request.payload.body:
|
||||
if request.payload is not None and request.payload.body:
|
||||
aggregate_size += len(request.payload.body)
|
||||
return messages_pb2.StreamingInputCallResponse(
|
||||
aggregated_payload_size=aggregate_size)
|
||||
|
|
@ -87,8 +80,8 @@ class TestService(test_pb2.BetaTestServiceServicer):
|
|||
def FullDuplexCall(self, request_iterator, context):
|
||||
for request in request_iterator:
|
||||
if request.HasField('response_status'):
|
||||
context.code(request.response_status.code)
|
||||
context.details(request.response_status.message)
|
||||
context.set_code(request.response_status.code)
|
||||
context.set_details(request.response_status.message)
|
||||
for response_parameters in request.response_parameters:
|
||||
yield messages_pb2.StreamingOutputCallResponse(
|
||||
payload=messages_pb2.Payload(
|
||||
|
|
@ -101,83 +94,80 @@ class TestService(test_pb2.BetaTestServiceServicer):
|
|||
return self.FullDuplexCall(request_iterator, context)
|
||||
|
||||
|
||||
def _large_unary_common_behavior(stub, fill_username, fill_oauth_scope,
|
||||
protocol_options=None):
|
||||
with stub:
|
||||
request = messages_pb2.SimpleRequest(
|
||||
response_type=messages_pb2.COMPRESSABLE, response_size=314159,
|
||||
payload=messages_pb2.Payload(body=b'\x00' * 271828),
|
||||
fill_username=fill_username, fill_oauth_scope=fill_oauth_scope)
|
||||
response_future = stub.UnaryCall.future(request, _TIMEOUT,
|
||||
protocol_options=protocol_options)
|
||||
response = response_future.result()
|
||||
if response.payload.type is not messages_pb2.COMPRESSABLE:
|
||||
raise ValueError(
|
||||
'response payload type is "%s"!' % type(response.payload.type))
|
||||
if len(response.payload.body) != 314159:
|
||||
raise ValueError(
|
||||
'response body of incorrect size %d!' % len(response.payload.body))
|
||||
def _large_unary_common_behavior(
|
||||
stub, fill_username, fill_oauth_scope, call_credentials):
|
||||
request = messages_pb2.SimpleRequest(
|
||||
response_type=messages_pb2.COMPRESSABLE, response_size=314159,
|
||||
payload=messages_pb2.Payload(body=b'\x00' * 271828),
|
||||
fill_username=fill_username, fill_oauth_scope=fill_oauth_scope)
|
||||
response_future = stub.UnaryCall.future(
|
||||
request, credentials=call_credentials)
|
||||
response = response_future.result()
|
||||
if response.payload.type is not messages_pb2.COMPRESSABLE:
|
||||
raise ValueError(
|
||||
'response payload type is "%s"!' % type(response.payload.type))
|
||||
elif len(response.payload.body) != 314159:
|
||||
raise ValueError(
|
||||
'response body of incorrect size %d!' % len(response.payload.body))
|
||||
else:
|
||||
return response
|
||||
|
||||
|
||||
def _empty_unary(stub):
|
||||
with stub:
|
||||
response = stub.EmptyCall(empty_pb2.Empty(), _TIMEOUT)
|
||||
if not isinstance(response, empty_pb2.Empty):
|
||||
raise TypeError(
|
||||
'response is of type "%s", not empty_pb2.Empty!', type(response))
|
||||
response = stub.EmptyCall(empty_pb2.Empty())
|
||||
if not isinstance(response, empty_pb2.Empty):
|
||||
raise TypeError(
|
||||
'response is of type "%s", not empty_pb2.Empty!', type(response))
|
||||
|
||||
|
||||
def _large_unary(stub):
|
||||
_large_unary_common_behavior(stub, False, False)
|
||||
_large_unary_common_behavior(stub, False, False, None)
|
||||
|
||||
|
||||
def _client_streaming(stub):
|
||||
with stub:
|
||||
payload_body_sizes = (27182, 8, 1828, 45904)
|
||||
payloads = (
|
||||
messages_pb2.Payload(body=b'\x00' * size)
|
||||
for size in payload_body_sizes)
|
||||
requests = (
|
||||
messages_pb2.StreamingInputCallRequest(payload=payload)
|
||||
for payload in payloads)
|
||||
response = stub.StreamingInputCall(requests, _TIMEOUT)
|
||||
if response.aggregated_payload_size != 74922:
|
||||
raise ValueError(
|
||||
'incorrect size %d!' % response.aggregated_payload_size)
|
||||
payload_body_sizes = (27182, 8, 1828, 45904,)
|
||||
payloads = (
|
||||
messages_pb2.Payload(body=b'\x00' * size)
|
||||
for size in payload_body_sizes)
|
||||
requests = (
|
||||
messages_pb2.StreamingInputCallRequest(payload=payload)
|
||||
for payload in payloads)
|
||||
response = stub.StreamingInputCall(requests)
|
||||
if response.aggregated_payload_size != 74922:
|
||||
raise ValueError(
|
||||
'incorrect size %d!' % response.aggregated_payload_size)
|
||||
|
||||
|
||||
def _server_streaming(stub):
|
||||
sizes = (31415, 9, 2653, 58979)
|
||||
sizes = (31415, 9, 2653, 58979,)
|
||||
|
||||
with stub:
|
||||
request = messages_pb2.StreamingOutputCallRequest(
|
||||
response_type=messages_pb2.COMPRESSABLE,
|
||||
response_parameters=(
|
||||
messages_pb2.ResponseParameters(size=sizes[0]),
|
||||
messages_pb2.ResponseParameters(size=sizes[1]),
|
||||
messages_pb2.ResponseParameters(size=sizes[2]),
|
||||
messages_pb2.ResponseParameters(size=sizes[3]),
|
||||
))
|
||||
response_iterator = stub.StreamingOutputCall(request, _TIMEOUT)
|
||||
for index, response in enumerate(response_iterator):
|
||||
if response.payload.type != messages_pb2.COMPRESSABLE:
|
||||
raise ValueError(
|
||||
'response body of invalid type %s!' % response.payload.type)
|
||||
if len(response.payload.body) != sizes[index]:
|
||||
raise ValueError(
|
||||
'response body of invalid size %d!' % len(response.payload.body))
|
||||
request = messages_pb2.StreamingOutputCallRequest(
|
||||
response_type=messages_pb2.COMPRESSABLE,
|
||||
response_parameters=(
|
||||
messages_pb2.ResponseParameters(size=sizes[0]),
|
||||
messages_pb2.ResponseParameters(size=sizes[1]),
|
||||
messages_pb2.ResponseParameters(size=sizes[2]),
|
||||
messages_pb2.ResponseParameters(size=sizes[3]),
|
||||
)
|
||||
)
|
||||
response_iterator = stub.StreamingOutputCall(request)
|
||||
for index, response in enumerate(response_iterator):
|
||||
if response.payload.type != messages_pb2.COMPRESSABLE:
|
||||
raise ValueError(
|
||||
'response body of invalid type %s!' % response.payload.type)
|
||||
elif len(response.payload.body) != sizes[index]:
|
||||
raise ValueError(
|
||||
'response body of invalid size %d!' % len(response.payload.body))
|
||||
|
||||
def _cancel_after_begin(stub):
|
||||
with stub:
|
||||
sizes = (27182, 8, 1828, 45904)
|
||||
payloads = [messages_pb2.Payload(body=b'\x00' * size) for size in sizes]
|
||||
requests = [messages_pb2.StreamingInputCallRequest(payload=payload)
|
||||
for payload in payloads]
|
||||
responses = stub.StreamingInputCall.future(requests, _TIMEOUT)
|
||||
responses.cancel()
|
||||
if not responses.cancelled():
|
||||
raise ValueError('expected call to be cancelled')
|
||||
sizes = (27182, 8, 1828, 45904,)
|
||||
payloads = (messages_pb2.Payload(body=b'\x00' * size) for size in sizes)
|
||||
requests = (messages_pb2.StreamingInputCallRequest(payload=payload)
|
||||
for payload in payloads)
|
||||
response_future = stub.StreamingInputCall.future(requests)
|
||||
response_future.cancel()
|
||||
if not response_future.cancelled():
|
||||
raise ValueError('expected call to be cancelled')
|
||||
|
||||
|
||||
class _Pipe(object):
|
||||
|
|
@ -220,18 +210,17 @@ class _Pipe(object):
|
|||
|
||||
|
||||
def _ping_pong(stub):
|
||||
request_response_sizes = (31415, 9, 2653, 58979)
|
||||
request_payload_sizes = (27182, 8, 1828, 45904)
|
||||
request_response_sizes = (31415, 9, 2653, 58979,)
|
||||
request_payload_sizes = (27182, 8, 1828, 45904,)
|
||||
|
||||
with stub, _Pipe() as pipe:
|
||||
response_iterator = stub.FullDuplexCall(pipe, _TIMEOUT)
|
||||
print('Starting ping-pong with response iterator %s' % response_iterator)
|
||||
with _Pipe() as pipe:
|
||||
response_iterator = stub.FullDuplexCall(pipe)
|
||||
for response_size, payload_size in zip(
|
||||
request_response_sizes, request_payload_sizes):
|
||||
request = messages_pb2.StreamingOutputCallRequest(
|
||||
response_type=messages_pb2.COMPRESSABLE,
|
||||
response_parameters=(messages_pb2.ResponseParameters(
|
||||
size=response_size),),
|
||||
response_parameters=(
|
||||
messages_pb2.ResponseParameters(size=response_size),),
|
||||
payload=messages_pb2.Payload(body=b'\x00' * payload_size))
|
||||
pipe.add(request)
|
||||
response = next(response_iterator)
|
||||
|
|
@ -244,17 +233,17 @@ def _ping_pong(stub):
|
|||
|
||||
|
||||
def _cancel_after_first_response(stub):
|
||||
request_response_sizes = (31415, 9, 2653, 58979)
|
||||
request_payload_sizes = (27182, 8, 1828, 45904)
|
||||
with stub, _Pipe() as pipe:
|
||||
response_iterator = stub.FullDuplexCall(pipe, _TIMEOUT)
|
||||
request_response_sizes = (31415, 9, 2653, 58979,)
|
||||
request_payload_sizes = (27182, 8, 1828, 45904,)
|
||||
with _Pipe() as pipe:
|
||||
response_iterator = stub.FullDuplexCall(pipe)
|
||||
|
||||
response_size = request_response_sizes[0]
|
||||
payload_size = request_payload_sizes[0]
|
||||
request = messages_pb2.StreamingOutputCallRequest(
|
||||
response_type=messages_pb2.COMPRESSABLE,
|
||||
response_parameters=(messages_pb2.ResponseParameters(
|
||||
size=response_size),),
|
||||
response_parameters=(
|
||||
messages_pb2.ResponseParameters(size=response_size),),
|
||||
payload=messages_pb2.Payload(body=b'\x00' * payload_size))
|
||||
pipe.add(request)
|
||||
response = next(response_iterator)
|
||||
|
|
@ -264,16 +253,17 @@ def _cancel_after_first_response(stub):
|
|||
|
||||
try:
|
||||
next(response_iterator)
|
||||
except Exception:
|
||||
pass
|
||||
except grpc.RpcError as rpc_error:
|
||||
if rpc_error.code() is not grpc.StatusCode.CANCELLED:
|
||||
raise
|
||||
else:
|
||||
raise ValueError('expected call to be cancelled')
|
||||
|
||||
|
||||
def _timeout_on_sleeping_server(stub):
|
||||
request_payload_size = 27182
|
||||
with stub, _Pipe() as pipe:
|
||||
response_iterator = stub.FullDuplexCall(pipe, 0.001)
|
||||
with _Pipe() as pipe:
|
||||
response_iterator = stub.FullDuplexCall(pipe, timeout=0.001)
|
||||
|
||||
request = messages_pb2.StreamingOutputCallRequest(
|
||||
response_type=messages_pb2.COMPRESSABLE,
|
||||
|
|
@ -282,15 +272,16 @@ def _timeout_on_sleeping_server(stub):
|
|||
time.sleep(0.1)
|
||||
try:
|
||||
next(response_iterator)
|
||||
except face.ExpirationError:
|
||||
pass
|
||||
except grpc.RpcError as rpc_error:
|
||||
if rpc_error.code() is not grpc.StatusCode.DEADLINE_EXCEEDED:
|
||||
raise
|
||||
else:
|
||||
raise ValueError('expected call to exceed deadline')
|
||||
|
||||
|
||||
def _empty_stream(stub):
|
||||
with stub, _Pipe() as pipe:
|
||||
response_iterator = stub.FullDuplexCall(pipe, _TIMEOUT)
|
||||
with _Pipe() as pipe:
|
||||
response_iterator = stub.FullDuplexCall(pipe)
|
||||
pipe.close()
|
||||
try:
|
||||
next(response_iterator)
|
||||
|
|
@ -300,65 +291,64 @@ def _empty_stream(stub):
|
|||
|
||||
|
||||
def _status_code_and_message(stub):
|
||||
with stub:
|
||||
message = 'test status message'
|
||||
code = 2
|
||||
status = grpc.StatusCode.UNKNOWN # code = 2
|
||||
request = messages_pb2.SimpleRequest(
|
||||
response_type=messages_pb2.COMPRESSABLE,
|
||||
response_size=1,
|
||||
payload=messages_pb2.Payload(body=b'\x00'),
|
||||
response_status=messages_pb2.EchoStatus(code=code, message=message)
|
||||
)
|
||||
response_future = stub.UnaryCall.future(request, _TIMEOUT)
|
||||
if response_future.code() != status:
|
||||
raise ValueError(
|
||||
'expected code %s, got %s' % (status, response_future.code()))
|
||||
if response_future.details() != message:
|
||||
raise ValueError(
|
||||
'expected message %s, got %s' % (message, response_future.details()))
|
||||
message = 'test status message'
|
||||
code = 2
|
||||
status = grpc.StatusCode.UNKNOWN # code = 2
|
||||
request = messages_pb2.SimpleRequest(
|
||||
response_type=messages_pb2.COMPRESSABLE,
|
||||
response_size=1,
|
||||
payload=messages_pb2.Payload(body=b'\x00'),
|
||||
response_status=messages_pb2.EchoStatus(code=code, message=message)
|
||||
)
|
||||
response_future = stub.UnaryCall.future(request)
|
||||
if response_future.code() != status:
|
||||
raise ValueError(
|
||||
'expected code %s, got %s' % (status, response_future.code()))
|
||||
elif response_future.details() != message:
|
||||
raise ValueError(
|
||||
'expected message %s, got %s' % (message, response_future.details()))
|
||||
|
||||
request = messages_pb2.StreamingOutputCallRequest(
|
||||
response_type=messages_pb2.COMPRESSABLE,
|
||||
response_parameters=(
|
||||
messages_pb2.ResponseParameters(size=1),),
|
||||
response_status=messages_pb2.EchoStatus(code=code, message=message))
|
||||
response_iterator = stub.StreamingOutputCall(request, _TIMEOUT)
|
||||
if response_future.code() != status:
|
||||
raise ValueError(
|
||||
'expected code %s, got %s' % (status, response_iterator.code()))
|
||||
if response_future.details() != message:
|
||||
raise ValueError(
|
||||
'expected message %s, got %s' % (message, response_iterator.details()))
|
||||
request = messages_pb2.StreamingOutputCallRequest(
|
||||
response_type=messages_pb2.COMPRESSABLE,
|
||||
response_parameters=(
|
||||
messages_pb2.ResponseParameters(size=1),),
|
||||
response_status=messages_pb2.EchoStatus(code=code, message=message))
|
||||
response_iterator = stub.StreamingOutputCall(request)
|
||||
if response_future.code() != status:
|
||||
raise ValueError(
|
||||
'expected code %s, got %s' % (status, response_iterator.code()))
|
||||
elif response_future.details() != message:
|
||||
raise ValueError(
|
||||
'expected message %s, got %s' % (message, response_iterator.details()))
|
||||
|
||||
|
||||
def _compute_engine_creds(stub, args):
|
||||
response = _large_unary_common_behavior(stub, True, True)
|
||||
response = _large_unary_common_behavior(stub, True, True, None)
|
||||
if args.default_service_account != response.username:
|
||||
raise ValueError(
|
||||
'expected username %s, got %s' % (args.default_service_account,
|
||||
response.username))
|
||||
'expected username %s, got %s' % (
|
||||
args.default_service_account, response.username))
|
||||
|
||||
|
||||
def _oauth2_auth_token(stub, args):
|
||||
json_key_filename = os.environ[
|
||||
oauth2client_client.GOOGLE_APPLICATION_CREDENTIALS]
|
||||
wanted_email = json.load(open(json_key_filename, 'rb'))['client_email']
|
||||
response = _large_unary_common_behavior(stub, True, True)
|
||||
response = _large_unary_common_behavior(stub, True, True, None)
|
||||
if wanted_email != response.username:
|
||||
raise ValueError(
|
||||
'expected username %s, got %s' % (wanted_email, response.username))
|
||||
if args.oauth_scope.find(response.oauth_scope) == -1:
|
||||
raise ValueError(
|
||||
'expected to find oauth scope "%s" in received "%s"' %
|
||||
(response.oauth_scope, args.oauth_scope))
|
||||
'expected to find oauth scope "{}" in received "{}"'.format(
|
||||
response.oauth_scope, args.oauth_scope))
|
||||
|
||||
|
||||
def _jwt_token_creds(stub, args):
|
||||
json_key_filename = os.environ[
|
||||
oauth2client_client.GOOGLE_APPLICATION_CREDENTIALS]
|
||||
wanted_email = json.load(open(json_key_filename, 'rb'))['client_email']
|
||||
response = _large_unary_common_behavior(stub, True, False)
|
||||
response = _large_unary_common_behavior(stub, True, False, None)
|
||||
if wanted_email != response.username:
|
||||
raise ValueError(
|
||||
'expected username %s, got %s' % (wanted_email, response.username))
|
||||
|
|
@ -370,11 +360,11 @@ def _per_rpc_creds(stub, args):
|
|||
wanted_email = json.load(open(json_key_filename, 'rb'))['client_email']
|
||||
credentials = oauth2client_client.GoogleCredentials.get_application_default()
|
||||
scoped_credentials = credentials.create_scoped([args.oauth_scope])
|
||||
call_creds = implementations.google_call_credentials(scoped_credentials)
|
||||
options = interfaces.grpc_call_options(disable_compression=False,
|
||||
credentials=call_creds)
|
||||
response = _large_unary_common_behavior(stub, True, False,
|
||||
protocol_options=options)
|
||||
# TODO(https://github.com/grpc/grpc/issues/6799): Eliminate this last
|
||||
# remaining use of the Beta API.
|
||||
call_credentials = implementations.google_call_credentials(
|
||||
scoped_credentials)
|
||||
response = _large_unary_common_behavior(stub, True, False, call_credentials)
|
||||
if wanted_email != response.username:
|
||||
raise ValueError(
|
||||
'expected username %s, got %s' % (wanted_email, response.username))
|
||||
|
|
|
|||
|
|
@ -30,10 +30,11 @@
|
|||
"""The Python implementation of the GRPC interoperability test server."""
|
||||
|
||||
import argparse
|
||||
from concurrent import futures
|
||||
import logging
|
||||
import time
|
||||
|
||||
from grpc.beta import implementations
|
||||
import grpc
|
||||
from src.proto.grpc.testing import test_pb2
|
||||
|
||||
from tests.interop import methods
|
||||
|
|
@ -51,12 +52,13 @@ def serve():
|
|||
default=False, type=resources.parse_bool)
|
||||
args = parser.parse_args()
|
||||
|
||||
server = test_pb2.beta_create_TestService_server(methods.TestService())
|
||||
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
|
||||
test_pb2.add_TestServiceServicer_to_server(methods.TestService(), server)
|
||||
if args.use_tls:
|
||||
private_key = resources.private_key()
|
||||
certificate_chain = resources.certificate_chain()
|
||||
credentials = implementations.ssl_server_credentials(
|
||||
[(private_key, certificate_chain)])
|
||||
credentials = grpc.ssl_server_credentials(
|
||||
((private_key, certificate_chain),))
|
||||
server.add_secure_port('[::]:{}'.format(args.port), credentials)
|
||||
else:
|
||||
server.add_insecure_port('[::]:{}'.format(args.port))
|
||||
|
|
@ -68,7 +70,7 @@ def serve():
|
|||
time.sleep(_ONE_DAY_IN_SECONDS)
|
||||
except BaseException as e:
|
||||
logging.info('Caught exception "%s"; stopping server...', e)
|
||||
server.stop(0)
|
||||
server.stop(None)
|
||||
logging.info('Server stopped; exiting.')
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
|||
|
|
@ -30,9 +30,10 @@
|
|||
"""Entry point for running stress tests."""
|
||||
|
||||
import argparse
|
||||
from concurrent import futures
|
||||
import threading
|
||||
|
||||
from grpc.beta import implementations
|
||||
import grpc
|
||||
from six.moves import queue
|
||||
from src.proto.grpc.testing import metrics_pb2
|
||||
from src.proto.grpc.testing import test_pb2
|
||||
|
|
@ -92,24 +93,24 @@ def _parse_weighted_test_cases(test_case_args):
|
|||
|
||||
def run_test(args):
|
||||
test_cases = _parse_weighted_test_cases(args.test_cases)
|
||||
test_servers = args.server_addresses.split(',')
|
||||
test_server_targets = args.server_addresses.split(',')
|
||||
# Propagate any client exceptions with a queue
|
||||
exception_queue = queue.Queue()
|
||||
stop_event = threading.Event()
|
||||
hist = histogram.Histogram(1, 1)
|
||||
runners = []
|
||||
|
||||
server = metrics_pb2.beta_create_MetricsService_server(
|
||||
metrics_server.MetricsServer(hist))
|
||||
server = grpc.server(futures.ThreadPoolExecutor(max_workers=25))
|
||||
metrics_pb2.add_MetricsServiceServicer_to_server(
|
||||
metrics_server.MetricsServer(hist), server)
|
||||
server.add_insecure_port('[::]:{}'.format(args.metrics_port))
|
||||
server.start()
|
||||
|
||||
for test_server in test_servers:
|
||||
host, port = test_server.split(':', 1)
|
||||
for test_server_target in test_server_targets:
|
||||
for _ in xrange(args.num_channels_per_server):
|
||||
channel = implementations.insecure_channel(host, int(port))
|
||||
channel = grpc.insecure_channel(test_server_target)
|
||||
for _ in xrange(args.num_stubs_per_channel):
|
||||
stub = test_pb2.beta_create_TestService_stub(channel)
|
||||
stub = test_pb2.TestServiceStub(channel)
|
||||
runner = test_runner.TestRunner(stub, test_cases, hist,
|
||||
exception_queue, stop_event)
|
||||
runners.append(runner)
|
||||
|
|
@ -128,8 +129,8 @@ def run_test(args):
|
|||
stop_event.set()
|
||||
for runner in runners:
|
||||
runner.join()
|
||||
runner = None
|
||||
server.stop(0)
|
||||
runner = None
|
||||
server.stop(None)
|
||||
|
||||
if __name__ == '__main__':
|
||||
run_test(_args())
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ from src.proto.grpc.testing import metrics_pb2
|
|||
GAUGE_NAME = 'python_overall_qps'
|
||||
|
||||
|
||||
class MetricsServer(metrics_pb2.BetaMetricsServiceServicer):
|
||||
class MetricsServer(metrics_pb2.MetricsServiceServicer):
|
||||
|
||||
def __init__(self, histogram):
|
||||
self._start_time = time.time()
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
import time
|
||||
import threading
|
||||
import unittest
|
||||
import platform
|
||||
|
||||
from grpc._cython import cygrpc
|
||||
from tests.unit._cython import test_utilities
|
||||
|
|
@ -113,6 +114,9 @@ class TypeSmokeTest(unittest.TestCase):
|
|||
lambda ignored_a, ignored_b: None, b'')
|
||||
del plugin
|
||||
|
||||
@unittest.skipIf(
|
||||
platform.python_implementation() == "PyPy",
|
||||
'TODO(issue 7672): figure out why this fails on PyPy')
|
||||
def testCallCredentialsFromPluginUpDown(self):
|
||||
plugin = cygrpc.CredentialsMetadataPlugin(_metadata_plugin_callback, b'')
|
||||
call_credentials = cygrpc.call_credentials_metadata_plugin(plugin)
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ module GRPC
|
|||
include Core::TimeConsts
|
||||
include Core::CallOps
|
||||
extend Forwardable
|
||||
attr_reader(:deadline)
|
||||
attr_reader :deadline, :metadata_sent, :metadata_to_send
|
||||
def_delegators :@call, :cancel, :metadata, :write_flag, :write_flag=,
|
||||
:peer, :peer_cert, :trailing_metadata
|
||||
|
||||
|
|
@ -101,7 +101,7 @@ module GRPC
|
|||
# @param metadata_received [true|false] indicates if metadata has already
|
||||
# been received. Should always be true for server calls
|
||||
def initialize(call, marshal, unmarshal, deadline, started: true,
|
||||
metadata_received: false)
|
||||
metadata_received: false, metadata_to_send: nil)
|
||||
fail(TypeError, '!Core::Call') unless call.is_a? Core::Call
|
||||
@call = call
|
||||
@deadline = deadline
|
||||
|
|
@ -110,6 +110,20 @@ module GRPC
|
|||
@metadata_received = metadata_received
|
||||
@metadata_sent = started
|
||||
@op_notifier = nil
|
||||
|
||||
fail(ArgumentError, 'Already sent md') if started && metadata_to_send
|
||||
@metadata_to_send = metadata_to_send || {} unless started
|
||||
@send_initial_md_mutex = Mutex.new
|
||||
end
|
||||
|
||||
# Sends the initial metadata that has yet to be sent.
|
||||
# Does nothing if metadata has already been sent for this call.
|
||||
def send_initial_metadata
|
||||
@send_initial_md_mutex.synchronize do
|
||||
return if @metadata_sent
|
||||
@metadata_tag = ActiveCall.client_invoke(@call, @metadata_to_send)
|
||||
@metadata_sent = true
|
||||
end
|
||||
end
|
||||
|
||||
# output_metadata are provides access to hash that can be used to
|
||||
|
|
@ -187,7 +201,7 @@ module GRPC
|
|||
# @param marshalled [false, true] indicates if the object is already
|
||||
# marshalled.
|
||||
def remote_send(req, marshalled = false)
|
||||
# TODO(murgatroid99): ensure metadata was sent
|
||||
send_initial_metadata
|
||||
GRPC.logger.debug("sending #{req}, marshalled? #{marshalled}")
|
||||
payload = marshalled ? req : @marshal.call(req)
|
||||
@call.run_batch(SEND_MESSAGE => payload)
|
||||
|
|
@ -203,6 +217,7 @@ module GRPC
|
|||
# list, mulitple metadata for its key are sent
|
||||
def send_status(code = OK, details = '', assert_finished = false,
|
||||
metadata: {})
|
||||
send_initial_metadata
|
||||
ops = {
|
||||
SEND_STATUS_FROM_SERVER => Struct::Status.new(code, details, metadata)
|
||||
}
|
||||
|
|
@ -303,7 +318,7 @@ module GRPC
|
|||
# a list, multiple metadata for its key are sent
|
||||
# @return [Object] the response received from the server
|
||||
def request_response(req, metadata: {})
|
||||
start_call(metadata)
|
||||
merge_metadata_to_send(metadata) && send_initial_metadata
|
||||
remote_send(req)
|
||||
writes_done(false)
|
||||
response = remote_read
|
||||
|
|
@ -327,7 +342,7 @@ module GRPC
|
|||
# a list, multiple metadata for its key are sent
|
||||
# @return [Object] the response received from the server
|
||||
def client_streamer(requests, metadata: {})
|
||||
start_call(metadata)
|
||||
merge_metadata_to_send(metadata) && send_initial_metadata
|
||||
requests.each { |r| remote_send(r) }
|
||||
writes_done(false)
|
||||
response = remote_read
|
||||
|
|
@ -353,7 +368,7 @@ module GRPC
|
|||
# a list, multiple metadata for its key are sent
|
||||
# @return [Enumerator|nil] a response Enumerator
|
||||
def server_streamer(req, metadata: {})
|
||||
start_call(metadata)
|
||||
merge_metadata_to_send(metadata) && send_initial_metadata
|
||||
remote_send(req)
|
||||
writes_done(false)
|
||||
replies = enum_for(:each_remote_read_then_finish)
|
||||
|
|
@ -392,9 +407,12 @@ module GRPC
|
|||
# a list, multiple metadata for its key are sent
|
||||
# @return [Enumerator, nil] a response Enumerator
|
||||
def bidi_streamer(requests, metadata: {}, &blk)
|
||||
start_call(metadata)
|
||||
bd = BidiCall.new(@call, @marshal, @unmarshal,
|
||||
merge_metadata_to_send(metadata) && send_initial_metadata
|
||||
bd = BidiCall.new(@call,
|
||||
@marshal,
|
||||
@unmarshal,
|
||||
metadata_received: @metadata_received)
|
||||
|
||||
bd.run_on_client(requests, @op_notifier, &blk)
|
||||
end
|
||||
|
||||
|
|
@ -410,8 +428,12 @@ module GRPC
|
|||
#
|
||||
# @param gen_each_reply [Proc] generates the BiDi stream replies
|
||||
def run_server_bidi(gen_each_reply)
|
||||
bd = BidiCall.new(@call, @marshal, @unmarshal,
|
||||
metadata_received: @metadata_received)
|
||||
bd = BidiCall.new(@call,
|
||||
@marshal,
|
||||
@unmarshal,
|
||||
metadata_received: @metadata_received,
|
||||
req_view: MultiReqView.new(self))
|
||||
|
||||
bd.run_on_server(gen_each_reply)
|
||||
end
|
||||
|
||||
|
|
@ -428,15 +450,23 @@ module GRPC
|
|||
@op_notifier.notify(self)
|
||||
end
|
||||
|
||||
# Add to the metadata that will be sent from the server.
|
||||
# Fails if metadata has already been sent.
|
||||
# Unused by client calls.
|
||||
def merge_metadata_to_send(new_metadata = {})
|
||||
@send_initial_md_mutex.synchronize do
|
||||
fail('cant change metadata after already sent') if @metadata_sent
|
||||
@metadata_to_send.merge!(new_metadata)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Starts the call if not already started
|
||||
# @param metadata [Hash] metadata to be sent to the server. If a value is
|
||||
# a list, multiple metadata for its key are sent
|
||||
def start_call(metadata = {})
|
||||
return if @metadata_sent
|
||||
@metadata_tag = ActiveCall.client_invoke(@call, metadata)
|
||||
@metadata_sent = true
|
||||
merge_metadata_to_send(metadata) && send_initial_metadata
|
||||
end
|
||||
|
||||
def self.view_class(*visible_methods)
|
||||
|
|
@ -454,12 +484,20 @@ module GRPC
|
|||
# SingleReqView limits access to an ActiveCall's methods for use in server
|
||||
# handlers that receive just one request.
|
||||
SingleReqView = view_class(:cancelled?, :deadline, :metadata,
|
||||
:output_metadata, :peer, :peer_cert)
|
||||
:output_metadata, :peer, :peer_cert,
|
||||
:send_initial_metadata,
|
||||
:metadata_to_send,
|
||||
:merge_metadata_to_send,
|
||||
:metadata_sent)
|
||||
|
||||
# MultiReqView limits access to an ActiveCall's methods for use in
|
||||
# server client_streamer handlers.
|
||||
MultiReqView = view_class(:cancelled?, :deadline, :each_queued_msg,
|
||||
:each_remote_read, :metadata, :output_metadata)
|
||||
:each_remote_read, :metadata, :output_metadata,
|
||||
:send_initial_metadata,
|
||||
:metadata_to_send,
|
||||
:merge_metadata_to_send,
|
||||
:metadata_sent)
|
||||
|
||||
# Operation limits access to an ActiveCall's methods for use as
|
||||
# a Operation on the client.
|
||||
|
|
|
|||
|
|
@ -56,18 +56,19 @@ module GRPC
|
|||
# @param unmarshal [Function] f(string)->obj that unmarshals responses
|
||||
# @param metadata_received [true|false] indicates if metadata has already
|
||||
# been received. Should always be true for server calls
|
||||
def initialize(call, marshal, unmarshal, metadata_received: false)
|
||||
def initialize(call, marshal, unmarshal, metadata_received: false,
|
||||
req_view: nil)
|
||||
fail(ArgumentError, 'not a call') unless call.is_a? Core::Call
|
||||
@call = call
|
||||
@marshal = marshal
|
||||
@op_notifier = nil # signals completion on clients
|
||||
@readq = Queue.new
|
||||
@unmarshal = unmarshal
|
||||
@metadata_received = metadata_received
|
||||
@reads_complete = false
|
||||
@writes_complete = false
|
||||
@complete = false
|
||||
@done_mutex = Mutex.new
|
||||
@req_view = req_view
|
||||
end
|
||||
|
||||
# Begins orchestration of the Bidi stream for a client sending requests.
|
||||
|
|
@ -81,8 +82,7 @@ module GRPC
|
|||
def run_on_client(requests, op_notifier, &blk)
|
||||
@op_notifier = op_notifier
|
||||
@enq_th = Thread.new { write_loop(requests) }
|
||||
@loop_th = start_read_loop
|
||||
each_queued_msg(&blk)
|
||||
read_loop(&blk)
|
||||
end
|
||||
|
||||
# Begins orchestration of the Bidi stream for a server generating replies.
|
||||
|
|
@ -97,8 +97,15 @@ module GRPC
|
|||
#
|
||||
# @param gen_each_reply [Proc] generates the BiDi stream replies.
|
||||
def run_on_server(gen_each_reply)
|
||||
replys = gen_each_reply.call(each_queued_msg)
|
||||
@loop_th = start_read_loop(is_client: false)
|
||||
# Pass in the optional call object parameter if possible
|
||||
if gen_each_reply.arity == 1
|
||||
replys = gen_each_reply.call(read_loop(is_client: false))
|
||||
elsif gen_each_reply.arity == 2
|
||||
replys = gen_each_reply.call(read_loop(is_client: false), @req_view)
|
||||
else
|
||||
fail 'Illegal arity of reply generator'
|
||||
end
|
||||
|
||||
write_loop(replys, is_client: false)
|
||||
end
|
||||
|
||||
|
|
@ -135,24 +142,6 @@ module GRPC
|
|||
batch_result
|
||||
end
|
||||
|
||||
# each_queued_msg yields each message on this instances readq
|
||||
#
|
||||
# - messages are added to the readq by #read_loop
|
||||
# - iteration ends when the instance itself is added
|
||||
def each_queued_msg
|
||||
return enum_for(:each_queued_msg) unless block_given?
|
||||
count = 0
|
||||
loop do
|
||||
GRPC.logger.debug("each_queued_msg: waiting##{count}")
|
||||
count += 1
|
||||
req = @readq.pop
|
||||
GRPC.logger.debug("each_queued_msg: req = #{req}")
|
||||
fail req if req.is_a? StandardError
|
||||
break if req.equal?(END_OF_READS)
|
||||
yield req
|
||||
end
|
||||
end
|
||||
|
||||
def write_loop(requests, is_client: true)
|
||||
GRPC.logger.debug('bidi-write-loop: starting')
|
||||
count = 0
|
||||
|
|
@ -162,6 +151,7 @@ module GRPC
|
|||
payload = @marshal.call(req)
|
||||
# Fails if status already received
|
||||
begin
|
||||
@req_view.send_initial_metadata unless @req_view.nil?
|
||||
@call.run_batch(SEND_MESSAGE => payload)
|
||||
rescue GRPC::Core::CallError => e
|
||||
# This is almost definitely caused by a status arriving while still
|
||||
|
|
@ -190,47 +180,45 @@ module GRPC
|
|||
raise e
|
||||
end
|
||||
|
||||
# starts the read loop
|
||||
def start_read_loop(is_client: true)
|
||||
Thread.new do
|
||||
GRPC.logger.debug('bidi-read-loop: starting')
|
||||
begin
|
||||
count = 0
|
||||
# queue the initial read before beginning the loop
|
||||
loop do
|
||||
GRPC.logger.debug("bidi-read-loop: #{count}")
|
||||
count += 1
|
||||
batch_result = read_using_run_batch
|
||||
# Provides an enumerator that yields results of remote reads
|
||||
def read_loop(is_client: true)
|
||||
return enum_for(:read_loop,
|
||||
is_client: is_client) unless block_given?
|
||||
GRPC.logger.debug('bidi-read-loop: starting')
|
||||
begin
|
||||
count = 0
|
||||
# queue the initial read before beginning the loop
|
||||
loop do
|
||||
GRPC.logger.debug("bidi-read-loop: #{count}")
|
||||
count += 1
|
||||
batch_result = read_using_run_batch
|
||||
|
||||
# handle the next message
|
||||
if batch_result.message.nil?
|
||||
GRPC.logger.debug("bidi-read-loop: null batch #{batch_result}")
|
||||
# handle the next message
|
||||
if batch_result.message.nil?
|
||||
GRPC.logger.debug("bidi-read-loop: null batch #{batch_result}")
|
||||
|
||||
if is_client
|
||||
batch_result = @call.run_batch(RECV_STATUS_ON_CLIENT => nil)
|
||||
@call.status = batch_result.status
|
||||
batch_result.check_status
|
||||
GRPC.logger.debug("bidi-read-loop: done status #{@call.status}")
|
||||
end
|
||||
|
||||
@readq.push(END_OF_READS)
|
||||
GRPC.logger.debug('bidi-read-loop: done reading!')
|
||||
break
|
||||
if is_client
|
||||
batch_result = @call.run_batch(RECV_STATUS_ON_CLIENT => nil)
|
||||
@call.status = batch_result.status
|
||||
batch_result.check_status
|
||||
GRPC.logger.debug("bidi-read-loop: done status #{@call.status}")
|
||||
end
|
||||
|
||||
# push the latest read onto the queue and continue reading
|
||||
res = @unmarshal.call(batch_result.message)
|
||||
@readq.push(res)
|
||||
GRPC.logger.debug('bidi-read-loop: done reading!')
|
||||
break
|
||||
end
|
||||
rescue StandardError => e
|
||||
GRPC.logger.warn('bidi: read-loop failed')
|
||||
GRPC.logger.warn(e)
|
||||
@readq.push(e) # let each_queued_msg terminate with this error
|
||||
|
||||
res = @unmarshal.call(batch_result.message)
|
||||
yield res
|
||||
end
|
||||
GRPC.logger.debug('bidi-read-loop: finished')
|
||||
@reads_complete = true
|
||||
finished
|
||||
rescue StandardError => e
|
||||
GRPC.logger.warn('bidi: read-loop failed')
|
||||
GRPC.logger.warn(e)
|
||||
raise e
|
||||
end
|
||||
GRPC.logger.debug('bidi-read-loop: finished')
|
||||
@reads_complete = true
|
||||
finished
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -104,7 +104,14 @@ module GRPC
|
|||
end
|
||||
|
||||
def assert_arity_matches(mth)
|
||||
if request_response? || server_streamer?
|
||||
# A bidi handler function can optionally be passed a second
|
||||
# call object parameter for access to metadata, cancelling, etc.
|
||||
if bidi_streamer?
|
||||
if mth.arity != 2 && mth.arity != 1
|
||||
fail arity_error(mth, 2, "should be #{mth.name}(req, call) or " \
|
||||
"#{mth.name}(req)")
|
||||
end
|
||||
elsif request_response? || server_streamer?
|
||||
if mth.arity != 2
|
||||
fail arity_error(mth, 2, "should be #{mth.name}(req, call)")
|
||||
end
|
||||
|
|
|
|||
|
|
@ -335,8 +335,11 @@ module GRPC
|
|||
return an_rpc if @pool.jobs_waiting <= @max_waiting_requests
|
||||
GRPC.logger.warn("NOT AVAILABLE: too many jobs_waiting: #{an_rpc}")
|
||||
noop = proc { |x| x }
|
||||
|
||||
# Create a new active call that knows that metadata hasn't been
|
||||
# sent yet
|
||||
c = ActiveCall.new(an_rpc.call, noop, noop, an_rpc.deadline,
|
||||
metadata_received: true)
|
||||
metadata_received: true, started: false)
|
||||
c.send_status(GRPC::Core::StatusCodes::RESOURCE_EXHAUSTED, '')
|
||||
nil
|
||||
end
|
||||
|
|
@ -347,8 +350,11 @@ module GRPC
|
|||
return an_rpc if rpc_descs.key?(mth)
|
||||
GRPC.logger.warn("UNIMPLEMENTED: #{an_rpc}")
|
||||
noop = proc { |x| x }
|
||||
|
||||
# Create a new active call that knows that
|
||||
# metadata hasn't been sent yet
|
||||
c = ActiveCall.new(an_rpc.call, noop, noop, an_rpc.deadline,
|
||||
metadata_received: true)
|
||||
metadata_received: true, started: false)
|
||||
c.send_status(GRPC::Core::StatusCodes::UNIMPLEMENTED, '')
|
||||
nil
|
||||
end
|
||||
|
|
@ -396,17 +402,20 @@ module GRPC
|
|||
unless @connect_md_proc.nil?
|
||||
connect_md = @connect_md_proc.call(an_rpc.method, an_rpc.metadata)
|
||||
end
|
||||
an_rpc.call.run_batch(SEND_INITIAL_METADATA => connect_md)
|
||||
|
||||
return nil unless available?(an_rpc)
|
||||
return nil unless implemented?(an_rpc)
|
||||
|
||||
# Create the ActiveCall
|
||||
# Create the ActiveCall. Indicate that metadata hasnt been sent yet.
|
||||
GRPC.logger.info("deadline is #{an_rpc.deadline}; (now=#{Time.now})")
|
||||
rpc_desc = rpc_descs[an_rpc.method.to_sym]
|
||||
c = ActiveCall.new(an_rpc.call, rpc_desc.marshal_proc,
|
||||
rpc_desc.unmarshal_proc(:input), an_rpc.deadline,
|
||||
metadata_received: true)
|
||||
c = ActiveCall.new(an_rpc.call,
|
||||
rpc_desc.marshal_proc,
|
||||
rpc_desc.unmarshal_proc(:input),
|
||||
an_rpc.deadline,
|
||||
metadata_received: true,
|
||||
started: false,
|
||||
metadata_to_send: connect_md)
|
||||
mth = an_rpc.method.to_sym
|
||||
[c, mth]
|
||||
end
|
||||
|
|
|
|||
|
|
@ -60,8 +60,10 @@ describe GRPC::ActiveCall do
|
|||
end
|
||||
|
||||
describe '#multi_req_view' do
|
||||
it 'exposes a fixed subset of the ActiveCall methods' do
|
||||
want = %w(cancelled?, deadline, each_remote_read, metadata, shutdown)
|
||||
it 'exposes a fixed subset of the ActiveCall.methods' do
|
||||
want = %w(cancelled?, deadline, each_remote_read, metadata, \
|
||||
shutdown, peer, peer_cert, send_initial_metadata, \
|
||||
initial_metadata_sent)
|
||||
v = @client_call.multi_req_view
|
||||
want.each do |w|
|
||||
expect(v.methods.include?(w))
|
||||
|
|
@ -70,8 +72,10 @@ describe GRPC::ActiveCall do
|
|||
end
|
||||
|
||||
describe '#single_req_view' do
|
||||
it 'exposes a fixed subset of the ActiveCall methods' do
|
||||
want = %w(cancelled?, deadline, metadata, shutdown)
|
||||
it 'exposes a fixed subset of the ActiveCall.methods' do
|
||||
want = %w(cancelled?, deadline, metadata, shutdown, \
|
||||
send_initial_metadata, metadata_to_send, \
|
||||
merge_metadata_to_send, initial_metadata_sent)
|
||||
v = @client_call.single_req_view
|
||||
want.each do |w|
|
||||
expect(v.methods.include?(w))
|
||||
|
|
@ -149,6 +153,146 @@ describe GRPC::ActiveCall do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'sending initial metadata', send_initial_metadata: true do
|
||||
it 'sends metadata before sending a message if it hasnt been sent yet' do
|
||||
call = make_test_call
|
||||
@client_call = ActiveCall.new(
|
||||
call,
|
||||
@pass_through,
|
||||
@pass_through,
|
||||
deadline,
|
||||
started: false)
|
||||
|
||||
metadata = { key: 'dummy_val', other: 'other_val' }
|
||||
expect(@client_call.metadata_sent).to eq(false)
|
||||
@client_call.merge_metadata_to_send(metadata)
|
||||
|
||||
message = 'dummy message'
|
||||
|
||||
expect(call).to(
|
||||
receive(:run_batch)
|
||||
.with(
|
||||
hash_including(
|
||||
CallOps::SEND_INITIAL_METADATA => metadata)).once)
|
||||
|
||||
expect(call).to(
|
||||
receive(:run_batch).with(hash_including(
|
||||
CallOps::SEND_MESSAGE => message)).once)
|
||||
@client_call.remote_send(message)
|
||||
|
||||
expect(@client_call.metadata_sent).to eq(true)
|
||||
end
|
||||
|
||||
it 'doesnt send metadata if it thinks its already been sent' do
|
||||
call = make_test_call
|
||||
|
||||
@client_call = ActiveCall.new(call,
|
||||
@pass_through,
|
||||
@pass_through,
|
||||
deadline)
|
||||
|
||||
expect(@client_call.metadata_sent).to eql(true)
|
||||
expect(call).to(
|
||||
receive(:run_batch).with(hash_including(
|
||||
CallOps::SEND_INITIAL_METADATA)).never)
|
||||
|
||||
@client_call.remote_send('test message')
|
||||
end
|
||||
|
||||
it 'sends metadata if it is explicitly sent and ok to do so' do
|
||||
call = make_test_call
|
||||
|
||||
@client_call = ActiveCall.new(call,
|
||||
@pass_through,
|
||||
@pass_through,
|
||||
deadline,
|
||||
started: false)
|
||||
|
||||
expect(@client_call.metadata_sent).to eql(false)
|
||||
|
||||
metadata = { test_key: 'val' }
|
||||
@client_call.merge_metadata_to_send(metadata)
|
||||
expect(@client_call.metadata_to_send).to eq(metadata)
|
||||
|
||||
expect(call).to(
|
||||
receive(:run_batch).with(hash_including(
|
||||
CallOps::SEND_INITIAL_METADATA =>
|
||||
metadata)).once)
|
||||
@client_call.send_initial_metadata
|
||||
end
|
||||
|
||||
it 'explicit sending does nothing if metadata has already been sent' do
|
||||
call = make_test_call
|
||||
|
||||
@client_call = ActiveCall.new(call,
|
||||
@pass_through,
|
||||
@pass_through,
|
||||
deadline)
|
||||
|
||||
expect(@client_call.metadata_sent).to eql(true)
|
||||
|
||||
blk = proc do
|
||||
@client_call.send_initial_metadata
|
||||
end
|
||||
|
||||
expect { blk.call }.to_not raise_error
|
||||
end
|
||||
end
|
||||
|
||||
describe '#merge_metadata_to_send', merge_metadata_to_send: true do
|
||||
it 'adds to existing metadata when there is existing metadata to send' do
|
||||
call = make_test_call
|
||||
starting_metadata = {
|
||||
k1: 'key1_val',
|
||||
k2: 'key2_val',
|
||||
k3: 'key3_val'
|
||||
}
|
||||
|
||||
@client_call = ActiveCall.new(
|
||||
call,
|
||||
@pass_through, @pass_through,
|
||||
deadline,
|
||||
started: false,
|
||||
metadata_to_send: starting_metadata)
|
||||
|
||||
expect(@client_call.metadata_to_send).to eq(starting_metadata)
|
||||
|
||||
@client_call.merge_metadata_to_send(
|
||||
k3: 'key3_new_val',
|
||||
k4: 'key4_val')
|
||||
|
||||
expected_md_to_send = {
|
||||
k1: 'key1_val',
|
||||
k2: 'key2_val',
|
||||
k3: 'key3_new_val',
|
||||
k4: 'key4_val' }
|
||||
|
||||
expect(@client_call.metadata_to_send).to eq(expected_md_to_send)
|
||||
|
||||
@client_call.merge_metadata_to_send(k5: 'key5_val')
|
||||
expected_md_to_send.merge!(k5: 'key5_val')
|
||||
expect(@client_call.metadata_to_send).to eq(expected_md_to_send)
|
||||
end
|
||||
|
||||
it 'fails when initial metadata has already been sent' do
|
||||
call = make_test_call
|
||||
@client_call = ActiveCall.new(
|
||||
call,
|
||||
@pass_through,
|
||||
@pass_through,
|
||||
deadline,
|
||||
started: true)
|
||||
|
||||
expect(@client_call.metadata_sent).to eq(true)
|
||||
|
||||
blk = proc do
|
||||
@client_call.merge_metadata_to_send(k1: 'key1_val')
|
||||
end
|
||||
|
||||
expect { blk.call }.to raise_error
|
||||
end
|
||||
end
|
||||
|
||||
describe '#client_invoke' do
|
||||
it 'sends metadata to the server when present' do
|
||||
call = make_test_call
|
||||
|
|
@ -163,7 +307,26 @@ describe GRPC::ActiveCall do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#remote_read' do
|
||||
describe '#send_status', send_status: true do
|
||||
it 'works when no metadata or messages have been sent yet' do
|
||||
call = make_test_call
|
||||
ActiveCall.client_invoke(call)
|
||||
|
||||
recvd_rpc = @server.request_call
|
||||
server_call = ActiveCall.new(
|
||||
recvd_rpc.call,
|
||||
@pass_through,
|
||||
@pass_through,
|
||||
deadline,
|
||||
started: false)
|
||||
|
||||
expect(server_call.metadata_sent).to eq(false)
|
||||
blk = proc { server_call.send_status(OK) }
|
||||
expect { blk.call }.to_not raise_error
|
||||
end
|
||||
end
|
||||
|
||||
describe '#remote_read', remote_read: true do
|
||||
it 'reads the response sent by a server' do
|
||||
call = make_test_call
|
||||
ActiveCall.client_invoke(call)
|
||||
|
|
@ -205,6 +368,31 @@ describe GRPC::ActiveCall do
|
|||
expect(client_call.metadata).to eq(expected)
|
||||
end
|
||||
|
||||
it 'get a status from server when nothing else sent from server' do
|
||||
client_call = make_test_call
|
||||
ActiveCall.client_invoke(client_call)
|
||||
|
||||
recvd_rpc = @server.request_call
|
||||
recvd_call = recvd_rpc.call
|
||||
|
||||
server_call = ActiveCall.new(
|
||||
recvd_call,
|
||||
@pass_through,
|
||||
@pass_through,
|
||||
deadline,
|
||||
started: false)
|
||||
|
||||
server_call.send_status(OK, 'OK')
|
||||
|
||||
# Check that we can receive initial metadata and a status
|
||||
client_call.run_batch(
|
||||
CallOps::RECV_INITIAL_METADATA => nil)
|
||||
batch_result = client_call.run_batch(
|
||||
CallOps::RECV_STATUS_ON_CLIENT => nil)
|
||||
|
||||
expect(batch_result.status.code).to eq(OK)
|
||||
end
|
||||
|
||||
it 'get a nil msg before a status when an OK status is sent' do
|
||||
call = make_test_call
|
||||
ActiveCall.client_invoke(call)
|
||||
|
|
@ -329,6 +517,86 @@ describe GRPC::ActiveCall do
|
|||
end
|
||||
end
|
||||
|
||||
# Test sending of the initial metadata in #run_server_bidi
|
||||
# from the server handler both implicitly and explicitly.
|
||||
describe '#run_server_bidi metadata sending tests', run_server_bidi: true do
|
||||
before(:each) do
|
||||
@requests = ['first message', 'second message']
|
||||
@server_to_client_metadata = { 'test_key' => 'test_val' }
|
||||
@server_status = OK
|
||||
|
||||
@client_call = make_test_call
|
||||
@client_call.run_batch(CallOps::SEND_INITIAL_METADATA => {})
|
||||
|
||||
recvd_rpc = @server.request_call
|
||||
recvd_call = recvd_rpc.call
|
||||
@server_call = ActiveCall.new(
|
||||
recvd_call,
|
||||
@pass_through,
|
||||
@pass_through,
|
||||
deadline,
|
||||
metadata_received: true,
|
||||
started: false,
|
||||
metadata_to_send: @server_to_client_metadata)
|
||||
end
|
||||
|
||||
after(:each) do
|
||||
# Send the requests and send a close so the server can send a status
|
||||
@requests.each do |message|
|
||||
@client_call.run_batch(CallOps::SEND_MESSAGE => message)
|
||||
end
|
||||
@client_call.run_batch(CallOps::SEND_CLOSE_FROM_CLIENT => nil)
|
||||
|
||||
@server_thread.join
|
||||
|
||||
# Expect that initial metadata was sent,
|
||||
# the requests were echoed, and a status was sent
|
||||
batch_result = @client_call.run_batch(
|
||||
CallOps::RECV_INITIAL_METADATA => nil)
|
||||
expect(batch_result.metadata).to eq(@server_to_client_metadata)
|
||||
|
||||
@requests.each do |message|
|
||||
batch_result = @client_call.run_batch(
|
||||
CallOps::RECV_MESSAGE => nil)
|
||||
expect(batch_result.message).to eq(message)
|
||||
end
|
||||
|
||||
batch_result = @client_call.run_batch(
|
||||
CallOps::RECV_STATUS_ON_CLIENT => nil)
|
||||
expect(batch_result.status.code).to eq(@server_status)
|
||||
end
|
||||
|
||||
it 'sends the initial metadata implicitly if not already sent' do
|
||||
# Server handler that doesn't have access to a "call"
|
||||
# It echoes the requests
|
||||
fake_gen_each_reply_with_no_call_param = proc do |msgs|
|
||||
msgs
|
||||
end
|
||||
|
||||
@server_thread = Thread.new do
|
||||
@server_call.run_server_bidi(
|
||||
fake_gen_each_reply_with_no_call_param)
|
||||
@server_call.send_status(@server_status)
|
||||
end
|
||||
end
|
||||
|
||||
it 'sends the metadata when sent explicitly and not already sent' do
|
||||
# Fake server handler that has access to a "call" object and
|
||||
# uses it to explicitly update and send the initial metadata
|
||||
fake_gen_each_reply_with_call_param = proc do |msgs, call_param|
|
||||
call_param.merge_metadata_to_send(@server_to_client_metadata)
|
||||
call_param.send_initial_metadata
|
||||
msgs
|
||||
end
|
||||
|
||||
@server_thread = Thread.new do
|
||||
@server_call.run_server_bidi(
|
||||
fake_gen_each_reply_with_call_param)
|
||||
@server_call.send_status(@server_status)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def expect_server_to_receive(sent_text, **kw)
|
||||
c = expect_server_to_be_invoked(**kw)
|
||||
expect(c.remote_read).to eq(sent_text)
|
||||
|
|
|
|||
|
|
@ -196,6 +196,9 @@ describe GRPC::RpcDesc do
|
|||
def fake_svstream(_arg1, _arg2)
|
||||
end
|
||||
|
||||
def fake_three_args(_arg1, _arg2, _arg3)
|
||||
end
|
||||
|
||||
it 'raises when a request_response does not have 2 args' do
|
||||
[:fake_clstream, :no_arg].each do |mth|
|
||||
blk = proc do
|
||||
|
|
@ -244,8 +247,8 @@ describe GRPC::RpcDesc do
|
|||
expect(&blk).to_not raise_error
|
||||
end
|
||||
|
||||
it 'raises when a bidi streamer does not have 1 arg' do
|
||||
[:fake_svstream, :no_arg].each do |mth|
|
||||
it 'raises when a bidi streamer does not have 1 or 2 args' do
|
||||
[:fake_three_args, :no_arg].each do |mth|
|
||||
blk = proc do
|
||||
@bidi_streamer.assert_arity_matches(method(mth))
|
||||
end
|
||||
|
|
@ -259,6 +262,13 @@ describe GRPC::RpcDesc do
|
|||
end
|
||||
expect(&blk).to_not raise_error
|
||||
end
|
||||
|
||||
it 'passes when a bidi streamer has 2 args' do
|
||||
blk = proc do
|
||||
@bidi_streamer.assert_arity_matches(method(:fake_svstream))
|
||||
end
|
||||
expect(&blk).to_not raise_error
|
||||
end
|
||||
end
|
||||
|
||||
describe '#request_response?' do
|
||||
|
|
|
|||
|
|
@ -694,13 +694,6 @@
|
|||
NO_DEPS = true
|
||||
endif
|
||||
|
||||
INSTALL_OK = false
|
||||
ifeq ($(HAS_VALID_PROTOC),true)
|
||||
ifeq ($(HAS_SYSTEM_PROTOBUF_VERIFY),true)
|
||||
INSTALL_OK = true
|
||||
endif
|
||||
endif
|
||||
|
||||
.SECONDARY = %.pb.h %.pb.cc
|
||||
|
||||
ifeq ($(DEP_MISSING),)
|
||||
|
|
@ -1193,7 +1186,7 @@
|
|||
$(Q) mkdir -p `dirname $@`
|
||||
$(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
|
||||
|
||||
install: install_c install_cxx install-plugins install-certs verify-install
|
||||
install: install_c install_cxx install-plugins install-certs
|
||||
|
||||
install_c: install-headers_c install-static_c install-shared_c
|
||||
|
||||
|
|
@ -1311,28 +1304,6 @@
|
|||
$(Q) $(INSTALL) -d $(prefix)/share/grpc
|
||||
$(Q) $(INSTALL) etc/roots.pem $(prefix)/share/grpc/roots.pem
|
||||
|
||||
verify-install:
|
||||
ifeq ($(INSTALL_OK),true)
|
||||
@echo "Your system looks ready to go."
|
||||
@echo
|
||||
else
|
||||
@echo "Warning: it looks like protoc 3.0.0+ isn't installed on your system,"
|
||||
@echo "which means that you won't be able to compile .proto files for use"
|
||||
@echo "with gRPC."
|
||||
@echo
|
||||
@echo "If you are just using pre-compiled protocol buffers, or you otherwise"
|
||||
@echo "have no need to compile .proto files, you can ignore this."
|
||||
@echo
|
||||
@echo "If you do need protobuf for some reason, you can download and install"
|
||||
@echo "it from:"
|
||||
@echo
|
||||
@echo " https://github.com/google/protobuf/releases"
|
||||
@echo
|
||||
@echo "Once you've done so, you can re-run this check by doing:"
|
||||
@echo
|
||||
@echo " make verify-install"
|
||||
endif
|
||||
|
||||
clean:
|
||||
$(E) "[CLEAN] Cleaning build directories."
|
||||
$(Q) $(RM) -rf $(OBJDIR) $(LIBDIR) $(BINDIR) $(GENDIR) cache.mk
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
s.require_paths = %w( src/ruby/bin src/ruby/lib src/ruby/pb )
|
||||
s.platform = Gem::Platform::RUBY
|
||||
|
||||
s.add_dependency 'google-protobuf', '~> 3.0.0.alpha.5.0.3'
|
||||
s.add_dependency 'google-protobuf', '~> 3.0'
|
||||
s.add_dependency 'googleauth', '~> 0.5.1'
|
||||
|
||||
s.add_development_dependency 'bundler', '~> 1.9'
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
"devDependencies": {
|
||||
"async": "^1.5.0",
|
||||
"google-auth-library": "^0.9.2",
|
||||
"google-protobuf": "^3.0.0-alpha.5",
|
||||
"google-protobuf": "^3.0.0",
|
||||
"istanbul": "^0.3.21",
|
||||
"jsdoc": "^3.3.2",
|
||||
"jshint": "^2.5.0",
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue