Merge pull request #1034 from sunxiaoguang/fix_duplicated_symbols
Fix duplicated symbols
diff --git a/Makefile b/Makefile
index 8c6fc32..3e1efc7 100644
--- a/Makefile
+++ b/Makefile
@@ -159,9 +159,14 @@
$(error Invalid CONFIG value '$(CONFIG)')
endif
+ifeq ($(SYSTEM),Linux)
+TMPOUT = /dev/null
+else
+TMPOUT = `mktemp /tmp/test-out-XXXXXX`
+endif
# Detect if we can use C++11
-CXX11_CHECK_CMD = $(CXX) -std=c++11 -o /dev/null -c test/build/c++11.cc
+CXX11_CHECK_CMD = $(CXX) -std=c++11 -o $(TMPOUT) -c test/build/c++11.cc
HAS_CXX11 = $(shell $(CXX11_CHECK_CMD) 2> /dev/null && echo true || echo false)
# The HOST compiler settings are used to compile the protoc plugins.
@@ -194,9 +199,25 @@
INCLUDES = . include $(GENDIR)
ifeq ($(SYSTEM),Darwin)
-INCLUDES += /usr/local/ssl/include /opt/local/include
+ifneq ($(wildcard /usr/local/ssl/include),)
+INCLUDES += /usr/local/ssl/include
+endif
+ifneq ($(wildcard /opt/local/include),)
+INCLUDES += /opt/local/include
+endif
+ifneq ($(wildcard /usr/local/include),)
+INCLUDES += /usr/local/include
+endif
LIBS = m z
-LDFLAGS += -L/usr/local/ssl/lib -L/opt/local/lib
+ifneq ($(wildcard /usr/local/ssl/lib),)
+LDFLAGS += -L/usr/local/ssl/lib
+endif
+ifneq ($(wildcard /opt/local/lib),)
+LDFLAGS += -L/opt/local/lib
+endif
+ifneq ($(wildcard /usr/local/lib),)
+LDFLAGS += -L/usr/local/lib
+endif
else
LIBS = rt m z pthread
LDFLAGS += -pthread
@@ -251,10 +272,10 @@
IS_GIT_FOLDER = true
endif
-OPENSSL_ALPN_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o /dev/null test/build/openssl-alpn.c -lssl -lcrypto -ldl $(LDFLAGS)
-ZLIB_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o /dev/null test/build/zlib.c -lz $(LDFLAGS)
-PERFTOOLS_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o /dev/null test/build/perftools.c -lprofiler $(LDFLAGS)
-PROTOBUF_CHECK_CMD = $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o /dev/null test/build/protobuf.cc -lprotobuf $(LDFLAGS)
+OPENSSL_ALPN_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o $(TMPOUT) test/build/openssl-alpn.c -lssl -lcrypto -ldl $(LDFLAGS)
+ZLIB_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o $(TMPOUT) test/build/zlib.c -lz $(LDFLAGS)
+PERFTOOLS_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o $(TMPOUT) test/build/perftools.c -lprofiler $(LDFLAGS)
+PROTOBUF_CHECK_CMD = $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $(TMPOUT) test/build/protobuf.cc -lprotobuf $(LDFLAGS)
PROTOC_CMD = which protoc
PROTOC_CHECK_CMD = protoc --version | grep -q libprotoc.3
@@ -2036,10 +2057,10 @@
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/gpr.$(SHARED_EXT) $(prefix)/lib/gpr.$(SHARED_EXT)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgpr-imp.a $(prefix)/lib/libgpr-imp.a
else
+ifneq ($(SYSTEM),Darwin)
$(E) "[INSTALL] Installing libgpr.$(SHARED_EXT)"
$(Q) $(INSTALL) -d $(prefix)/lib
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(prefix)/lib/libgpr.$(SHARED_EXT)
-ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf libgpr.$(SHARED_EXT) $(prefix)/lib/libgpr.so
endif
endif
@@ -2049,10 +2070,10 @@
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc.$(SHARED_EXT) $(prefix)/lib/grpc.$(SHARED_EXT)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc-imp.a $(prefix)/lib/libgrpc-imp.a
else
+ifneq ($(SYSTEM),Darwin)
$(E) "[INSTALL] Installing libgrpc.$(SHARED_EXT)"
$(Q) $(INSTALL) -d $(prefix)/lib
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(prefix)/lib/libgrpc.$(SHARED_EXT)
-ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf libgrpc.$(SHARED_EXT) $(prefix)/lib/libgrpc.so
endif
endif
@@ -2062,10 +2083,10 @@
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc_unsecure.$(SHARED_EXT) $(prefix)/lib/grpc_unsecure.$(SHARED_EXT)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure-imp.a $(prefix)/lib/libgrpc_unsecure-imp.a
else
+ifneq ($(SYSTEM),Darwin)
$(E) "[INSTALL] Installing libgrpc_unsecure.$(SHARED_EXT)"
$(Q) $(INSTALL) -d $(prefix)/lib
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc_unsecure.$(SHARED_EXT)
-ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf libgrpc_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc_unsecure.so
endif
endif
@@ -2083,10 +2104,10 @@
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc++.$(SHARED_EXT) $(prefix)/lib/grpc++.$(SHARED_EXT)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++-imp.a $(prefix)/lib/libgrpc++-imp.a
else
+ifneq ($(SYSTEM),Darwin)
$(E) "[INSTALL] Installing libgrpc++.$(SHARED_EXT)"
$(Q) $(INSTALL) -d $(prefix)/lib
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(prefix)/lib/libgrpc++.$(SHARED_EXT)
-ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf libgrpc++.$(SHARED_EXT) $(prefix)/lib/libgrpc++.so
endif
endif
@@ -2096,10 +2117,10 @@
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/grpc++_unsecure.$(SHARED_EXT)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure-imp.a $(prefix)/lib/libgrpc++_unsecure-imp.a
else
+ifneq ($(SYSTEM),Darwin)
$(E) "[INSTALL] Installing libgrpc++_unsecure.$(SHARED_EXT)"
$(Q) $(INSTALL) -d $(prefix)/lib
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc++_unsecure.$(SHARED_EXT)
-ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf libgrpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc++_unsecure.so
endif
endif
@@ -2117,10 +2138,10 @@
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/grpc_csharp_ext.$(SHARED_EXT)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext-imp.a $(prefix)/lib/libgrpc_csharp_ext-imp.a
else
+ifneq ($(SYSTEM),Darwin)
$(E) "[INSTALL] Installing libgrpc_csharp_ext.$(SHARED_EXT)"
$(Q) $(INSTALL) -d $(prefix)/lib
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/libgrpc_csharp_ext.$(SHARED_EXT)
-ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf libgrpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/libgrpc_csharp_ext.so
endif
endif
diff --git a/include/grpc++/channel_arguments.h b/include/grpc++/channel_arguments.h
index b649ba2..8d338c6 100644
--- a/include/grpc++/channel_arguments.h
+++ b/include/grpc++/channel_arguments.h
@@ -66,7 +66,7 @@
void SetChannelArgs(grpc_channel_args* channel_args) const;
private:
- friend class Channel;
+ friend class SecureCredentials;
friend class testing::ChannelArgumentsTest;
// TODO(yangg) implement copy and assign
diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h
index ab2cc08..586cfcf 100644
--- a/include/grpc/grpc_security.h
+++ b/include/grpc/grpc_security.h
@@ -117,6 +117,15 @@
grpc_credentials *grpc_jwt_credentials_create(const char *json_key,
gpr_timespec token_lifetime);
+/* Creates an Oauth2 Refresh Token crednetials object. May return NULL if the
+ input is invalid.
+ WARNING: Do NOT use this credentials to connect to a non-google service as
+ this could result in an oauth2 token leak.
+ - json_refresh_token is the JSON string containing the refresh token itself
+ along with a client_id and client_secret. */
+grpc_credentials *grpc_refresh_token_credentials_create(
+ const char *json_refresh_token);
+
/* Creates a fake transport security credentials object for testing. */
grpc_credentials *grpc_fake_transport_security_credentials_create(void);
@@ -167,10 +176,9 @@
grpc_server_credentials *grpc_fake_transport_security_server_credentials_create(
void);
-/* --- Secure server creation. --- */
+/* --- Server-side secure ports. --- */
/* Add a HTTP2 over an encrypted link over tcp listener.
- Server must have been created with grpc_secure_server_create.
Returns bound port number on success, 0 on failure.
REQUIRES: server not started */
int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
diff --git a/include/grpc/support/slice_buffer.h b/include/grpc/support/slice_buffer.h
index 56f71ef..c7e5dbc 100644
--- a/include/grpc/support/slice_buffer.h
+++ b/include/grpc/support/slice_buffer.h
@@ -74,6 +74,8 @@
/* add a very small (less than 8 bytes) amount of data to the end of a slice
buffer: returns a pointer into which to add the data */
gpr_uint8 *gpr_slice_buffer_tiny_add(gpr_slice_buffer *sb, unsigned len);
+/* pop the last buffer, but don't unref it */
+void gpr_slice_buffer_pop(gpr_slice_buffer *sb);
/* clear a slice buffer, unref all elements */
void gpr_slice_buffer_reset_and_unref(gpr_slice_buffer *sb);
diff --git a/src/compiler/python_generator.cc b/src/compiler/python_generator.cc
index b217c0d..b5022d5 100644
--- a/src/compiler/python_generator.cc
+++ b/src/compiler/python_generator.cc
@@ -60,8 +60,6 @@
using std::map;
using std::pair;
using std::replace;
-using std::string;
-using std::strlen;
using std::vector;
namespace grpc_python_generator {
@@ -72,14 +70,14 @@
// Converts an initializer list of the form { key0, value0, key1, value1, ... }
// into a map of key* to value*. Is merely a readability helper for later code.
-map<string, string> ListToDict(const initializer_list<string>& values) {
+map<std::string, std::string> ListToDict(const initializer_list<std::string>& values) {
assert(values.size() % 2 == 0);
- map<string, string> value_map;
+ map<std::string, std::string> value_map;
auto value_iter = values.begin();
for (unsigned i = 0; i < values.size()/2; ++i) {
- string key = *value_iter;
+ std::string key = *value_iter;
++value_iter;
- string value = *value_iter;
+ std::string value = *value_iter;
value_map[key] = value;
++value_iter;
}
@@ -113,8 +111,8 @@
bool PrintServicer(const ServiceDescriptor* service,
Printer* out) {
- string doc = "<fill me in later!>";
- map<string, string> dict = ListToDict({
+ std::string doc = "<fill me in later!>";
+ map<std::string, std::string> dict = ListToDict({
"Service", service->name(),
"Documentation", doc,
});
@@ -125,7 +123,7 @@
out->Print("__metaclass__ = abc.ABCMeta\n");
for (int i = 0; i < service->method_count(); ++i) {
auto meth = service->method(i);
- string arg_name = meth->client_streaming() ?
+ std::string arg_name = meth->client_streaming() ?
"request_iterator" : "request";
out->Print("@abc.abstractmethod\n");
out->Print("def $Method$(self, $ArgName$, context):\n",
@@ -140,8 +138,8 @@
}
bool PrintServer(const ServiceDescriptor* service, Printer* out) {
- string doc = "<fill me in later!>";
- map<string, string> dict = ListToDict({
+ std::string doc = "<fill me in later!>";
+ map<std::string, std::string> dict = ListToDict({
"Service", service->name(),
"Documentation", doc,
});
@@ -169,8 +167,8 @@
bool PrintStub(const ServiceDescriptor* service,
Printer* out) {
- string doc = "<fill me in later!>";
- map<string, string> dict = ListToDict({
+ std::string doc = "<fill me in later!>";
+ map<std::string, std::string> dict = ListToDict({
"Service", service->name(),
"Documentation", doc,
});
@@ -181,7 +179,7 @@
out->Print("__metaclass__ = abc.ABCMeta\n");
for (int i = 0; i < service->method_count(); ++i) {
const MethodDescriptor* meth = service->method(i);
- string arg_name = meth->client_streaming() ?
+ std::string arg_name = meth->client_streaming() ?
"request_iterator" : "request";
auto methdict = ListToDict({"Method", meth->name(), "ArgName", arg_name});
out->Print("@abc.abstractmethod\n");
@@ -198,29 +196,29 @@
// TODO(protobuf team): Export `ModuleName` from protobuf's
// `src/google/protobuf/compiler/python/python_generator.cc` file.
-string ModuleName(const string& filename) {
- string basename = StripProto(filename);
+std::string ModuleName(const std::string& filename) {
+ std::string basename = StripProto(filename);
basename = StringReplace(basename, "-", "_");
basename = StringReplace(basename, "/", ".");
return basename + "_pb2";
}
bool GetModuleAndMessagePath(const Descriptor* type,
- pair<string, string>* out) {
+ pair<std::string, std::string>* out) {
const Descriptor* path_elem_type = type;
vector<const Descriptor*> message_path;
do {
message_path.push_back(path_elem_type);
path_elem_type = path_elem_type->containing_type();
} while (path_elem_type != nullptr);
- string file_name = type->file()->name();
+ std::string file_name = type->file()->name();
static const int proto_suffix_length = strlen(".proto");
if (!(file_name.size() > static_cast<size_t>(proto_suffix_length) &&
file_name.find_last_of(".proto") == file_name.size() - 1)) {
return false;
}
- string module = ModuleName(file_name);
- string message_type;
+ std::string module = ModuleName(file_name);
+ std::string message_type;
for (auto path_iter = message_path.rbegin();
path_iter != message_path.rend(); ++path_iter) {
message_type += (*path_iter)->name() + ".";
@@ -237,21 +235,21 @@
"Service", service->name());
{
IndentScope raii_create_server_indent(out);
- map<string, string> method_description_constructors;
- map<string, pair<string, string>> input_message_modules_and_classes;
- map<string, pair<string, string>> output_message_modules_and_classes;
+ map<std::string, std::string> method_description_constructors;
+ map<std::string, pair<std::string, std::string>> input_message_modules_and_classes;
+ map<std::string, pair<std::string, std::string>> output_message_modules_and_classes;
for (int i = 0; i < service->method_count(); ++i) {
const MethodDescriptor* method = service->method(i);
- const string method_description_constructor =
- string(method->client_streaming() ? "stream_" : "unary_") +
- string(method->server_streaming() ? "stream_" : "unary_") +
+ const std::string method_description_constructor =
+ std::string(method->client_streaming() ? "stream_" : "unary_") +
+ std::string(method->server_streaming() ? "stream_" : "unary_") +
"service_description";
- pair<string, string> input_message_module_and_class;
+ pair<std::string, std::string> input_message_module_and_class;
if (!GetModuleAndMessagePath(method->input_type(),
&input_message_module_and_class)) {
return false;
}
- pair<string, string> output_message_module_and_class;
+ pair<std::string, std::string> output_message_module_and_class;
if (!GetModuleAndMessagePath(method->output_type(),
&output_message_module_and_class)) {
return false;
@@ -272,7 +270,7 @@
for (auto& name_and_description_constructor :
method_description_constructors) {
IndentScope raii_descriptions_indent(out);
- const string method_name = name_and_description_constructor.first;
+ const std::string method_name = name_and_description_constructor.first;
auto input_message_module_and_class =
input_message_modules_and_classes.find(method_name);
auto output_message_module_and_class =
@@ -306,27 +304,27 @@
}
bool PrintStubFactory(const ServiceDescriptor* service, Printer* out) {
- map<string, string> dict = ListToDict({
+ map<std::string, std::string> dict = ListToDict({
"Service", service->name(),
});
out->Print(dict, "def early_adopter_create_$Service$_stub(host, port):\n");
{
IndentScope raii_create_server_indent(out);
- map<string, string> method_description_constructors;
- map<string, pair<string, string>> input_message_modules_and_classes;
- map<string, pair<string, string>> output_message_modules_and_classes;
+ map<std::string, std::string> method_description_constructors;
+ map<std::string, pair<std::string, std::string>> input_message_modules_and_classes;
+ map<std::string, pair<std::string, std::string>> output_message_modules_and_classes;
for (int i = 0; i < service->method_count(); ++i) {
const MethodDescriptor* method = service->method(i);
- const string method_description_constructor =
- string(method->client_streaming() ? "stream_" : "unary_") +
- string(method->server_streaming() ? "stream_" : "unary_") +
+ const std::string method_description_constructor =
+ std::string(method->client_streaming() ? "stream_" : "unary_") +
+ std::string(method->server_streaming() ? "stream_" : "unary_") +
"invocation_description";
- pair<string, string> input_message_module_and_class;
+ pair<std::string, std::string> input_message_module_and_class;
if (!GetModuleAndMessagePath(method->input_type(),
&input_message_module_and_class)) {
return false;
}
- pair<string, string> output_message_module_and_class;
+ pair<std::string, std::string> output_message_module_and_class;
if (!GetModuleAndMessagePath(method->output_type(),
&output_message_module_and_class)) {
return false;
@@ -347,7 +345,7 @@
for (auto& name_and_description_constructor :
method_description_constructors) {
IndentScope raii_descriptions_indent(out);
- const string method_name = name_and_description_constructor.first;
+ const std::string method_name = name_and_description_constructor.first;
auto input_message_module_and_class =
input_message_modules_and_classes.find(method_name);
auto output_message_module_and_class =
@@ -385,8 +383,8 @@
} // namespace
-pair<bool, string> GetServices(const FileDescriptor* file) {
- string output;
+pair<bool, std::string> GetServices(const FileDescriptor* file) {
+ std::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
StringOutputStream output_stream(&output);
diff --git a/src/compiler/python_plugin.cc b/src/compiler/python_plugin.cc
index 825f15a..e7d172f 100644
--- a/src/compiler/python_plugin.cc
+++ b/src/compiler/python_plugin.cc
@@ -51,18 +51,16 @@
using google::protobuf::compiler::PluginMain;
using google::protobuf::io::CodedOutputStream;
using google::protobuf::io::ZeroCopyOutputStream;
-using std::string;
-using std::strlen;
class PythonGrpcGenerator : public CodeGenerator {
public:
PythonGrpcGenerator() {}
~PythonGrpcGenerator() {}
- bool Generate(const FileDescriptor* file, const string& parameter,
- GeneratorContext* context, string* error) const {
+ bool Generate(const FileDescriptor* file, const std::string& parameter,
+ GeneratorContext* context, std::string* error) const {
// Get output file name.
- string file_name;
+ std::string file_name;
static const int proto_suffix_length = strlen(".proto");
if (file->name().size() > static_cast<size_t>(proto_suffix_length) &&
file->name().find_last_of(".proto") == file->name().size() - 1) {
@@ -77,7 +75,7 @@
context->OpenForInsert(file_name, "module_scope"));
CodedOutputStream coded_out(output.get());
bool success = false;
- string code = "";
+ std::string code = "";
tie(success, code) = grpc_python_generator::GetServices(file);
if (success) {
coded_out.WriteRaw(code.data(), code.size());
diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c
index 3ad1e7e..698e099 100644
--- a/src/core/security/credentials.c
+++ b/src/core/security/credentials.c
@@ -46,20 +46,6 @@
#include <grpc/support/sync.h>
#include <grpc/support/time.h>
-/* -- Constants. -- */
-
-#define GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS 60
-
-#define GRPC_COMPUTE_ENGINE_METADATA_HOST "metadata"
-#define GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH \
- "/computeMetadata/v1/instance/service-accounts/default/token"
-
-#define GRPC_SERVICE_ACCOUNT_HOST "www.googleapis.com"
-#define GRPC_SERVICE_ACCOUNT_TOKEN_PATH "/oauth2/v3/token"
-#define GRPC_SERVICE_ACCOUNT_POST_BODY_PREFIX \
- "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&" \
- "assertion="
-
/* -- Common. -- */
typedef struct {
@@ -671,8 +657,8 @@
}
gpr_asprintf(&body, "%s%s", GRPC_SERVICE_ACCOUNT_POST_BODY_PREFIX, jwt);
memset(&request, 0, sizeof(grpc_httpcli_request));
- request.host = GRPC_SERVICE_ACCOUNT_HOST;
- request.path = GRPC_SERVICE_ACCOUNT_TOKEN_PATH;
+ request.host = GRPC_GOOGLE_OAUTH2_SERVICE_HOST;
+ request.path = GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH;
request.hdr_count = 1;
request.hdrs = &header;
request.use_ssl = 1;
@@ -703,6 +689,67 @@
return &c->base.base;
}
+/* -- RefreshToken credentials. -- */
+
+typedef struct {
+ grpc_oauth2_token_fetcher_credentials base;
+ grpc_auth_refresh_token refresh_token;
+} grpc_refresh_token_credentials;
+
+static void refresh_token_destroy(grpc_credentials *creds) {
+ grpc_refresh_token_credentials *c =
+ (grpc_refresh_token_credentials *)creds;
+ grpc_auth_refresh_token_destruct(&c->refresh_token);
+ oauth2_token_fetcher_destroy(&c->base.base);
+}
+
+static grpc_credentials_vtable refresh_token_vtable = {
+ refresh_token_destroy, oauth2_token_fetcher_has_request_metadata,
+ oauth2_token_fetcher_has_request_metadata_only,
+ oauth2_token_fetcher_get_request_metadata};
+
+static void refresh_token_fetch_oauth2(
+ grpc_credentials_metadata_request *metadata_req,
+ grpc_httpcli_response_cb response_cb, gpr_timespec deadline) {
+ grpc_refresh_token_credentials *c =
+ (grpc_refresh_token_credentials *)metadata_req->creds;
+ grpc_httpcli_header header = {"Content-Type",
+ "application/x-www-form-urlencoded"};
+ grpc_httpcli_request request;
+ char *body = NULL;
+ gpr_asprintf(&body, GRPC_REFRESH_TOKEN_POST_BODY_FORMAT_STRING,
+ c->refresh_token.client_id, c->refresh_token.client_secret,
+ c->refresh_token.refresh_token);
+ memset(&request, 0, sizeof(grpc_httpcli_request));
+ request.host = GRPC_GOOGLE_OAUTH2_SERVICE_HOST;
+ request.path = GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH;
+ request.hdr_count = 1;
+ request.hdrs = &header;
+ request.use_ssl = 1;
+ grpc_httpcli_post(&request, body, strlen(body), deadline, response_cb,
+ metadata_req);
+ gpr_free(body);
+}
+
+grpc_credentials *grpc_refresh_token_credentials_create(
+ const char *json_refresh_token) {
+ grpc_refresh_token_credentials *c;
+ grpc_auth_refresh_token refresh_token =
+ grpc_auth_refresh_token_create_from_string(json_refresh_token);
+
+ if (!grpc_auth_refresh_token_is_valid(&refresh_token)) {
+ gpr_log(GPR_ERROR,
+ "Invalid input for refresh token credentials creation");
+ return NULL;
+ }
+ c = gpr_malloc(sizeof(grpc_refresh_token_credentials));
+ memset(c, 0, sizeof(grpc_refresh_token_credentials));
+ init_oauth2_token_fetcher(&c->base, refresh_token_fetch_oauth2);
+ c->base.base.vtable = &refresh_token_vtable;
+ c->refresh_token = refresh_token;
+ return &c->base.base;
+}
+
/* -- Fake Oauth2 credentials. -- */
typedef struct {
diff --git a/src/core/security/credentials.h b/src/core/security/credentials.h
index 454e668..0f70670 100644
--- a/src/core/security/credentials.h
+++ b/src/core/security/credentials.h
@@ -64,6 +64,22 @@
#define GRPC_GOOGLE_WELL_KNOWN_CREDENTIALS_FILE \
"application_default_credentials.json"
+#define GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS 60
+
+#define GRPC_COMPUTE_ENGINE_METADATA_HOST "metadata"
+#define GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH \
+ "/computeMetadata/v1/instance/service-accounts/default/token"
+
+#define GRPC_GOOGLE_OAUTH2_SERVICE_HOST "www.googleapis.com"
+#define GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH "/oauth2/v3/token"
+
+#define GRPC_SERVICE_ACCOUNT_POST_BODY_PREFIX \
+ "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&" \
+ "assertion="
+
+#define GRPC_REFRESH_TOKEN_POST_BODY_FORMAT_STRING \
+ "client_id=%s&client_secret=%s&refresh_token=%s&grant_type=refresh_token"
+
/* --- grpc_credentials. --- */
/* It is the caller's responsibility to gpr_free the result if not NULL. */
diff --git a/src/core/security/google_default_credentials.c b/src/core/security/google_default_credentials.c
index bdc907e..ebea70d 100644
--- a/src/core/security/google_default_credentials.c
+++ b/src/core/security/google_default_credentials.c
@@ -138,6 +138,23 @@
return result;
}
+/* Takes ownership of creds_path if not NULL. */
+static grpc_credentials *create_refresh_token_creds_from_path(
+ char *creds_path) {
+ grpc_credentials *result = NULL;
+ gpr_slice creds_data;
+ int file_ok = 0;
+ if (creds_path == NULL) return NULL;
+ creds_data = gpr_load_file(creds_path, &file_ok);
+ gpr_free(creds_path);
+ if (file_ok) {
+ result = grpc_refresh_token_credentials_create(
+ (const char *)GPR_SLICE_START_PTR(creds_data));
+ gpr_slice_unref(creds_data);
+ }
+ return result;
+}
+
grpc_credentials *grpc_google_default_credentials_create(void) {
grpc_credentials *result = NULL;
int serving_cached_credentials = 0;
@@ -157,7 +174,7 @@
if (result != NULL) goto end;
/* Then the well-known file. */
- result = create_jwt_creds_from_path(
+ result = create_refresh_token_creds_from_path(
grpc_get_well_known_google_credentials_file_path());
if (result != NULL) goto end;
diff --git a/src/core/security/json_token.c b/src/core/security/json_token.c
index 40b612b..eadae33 100644
--- a/src/core/security/json_token.c
+++ b/src/core/security/json_token.c
@@ -52,8 +52,9 @@
/* 1 hour max. */
const gpr_timespec grpc_max_auth_token_lifetime = {3600, 0};
-#define GRPC_AUTH_JSON_KEY_TYPE_INVALID "invalid"
-#define GRPC_AUTH_JSON_KEY_TYPE_SERVICE_ACCOUNT "service_account"
+#define GRPC_AUTH_JSON_TYPE_INVALID "invalid"
+#define GRPC_AUTH_JSON_TYPE_SERVICE_ACCOUNT "service_account"
+#define GRPC_AUTH_JSON_TYPE_AUTHORIZED_USER "authorized_user"
#define GRPC_JWT_RSA_SHA256_ALGORITHM "RS256"
#define GRPC_JWT_TYPE "JWT"
@@ -87,7 +88,7 @@
int grpc_auth_json_key_is_valid(const grpc_auth_json_key *json_key) {
return (json_key != NULL) &&
- strcmp(json_key->type, GRPC_AUTH_JSON_KEY_TYPE_INVALID);
+ strcmp(json_key->type, GRPC_AUTH_JSON_TYPE_INVALID);
}
grpc_auth_json_key grpc_auth_json_key_create_from_string(
@@ -100,7 +101,7 @@
int success = 0;
memset(&result, 0, sizeof(grpc_auth_json_key));
- result.type = GRPC_AUTH_JSON_KEY_TYPE_INVALID;
+ result.type = GRPC_AUTH_JSON_TYPE_INVALID;
if (json == NULL) {
gpr_log(GPR_ERROR, "Invalid json string %s", json_string);
goto end;
@@ -108,10 +109,10 @@
prop_value = json_get_string_property(json, "type");
if (prop_value == NULL ||
- strcmp(prop_value, GRPC_AUTH_JSON_KEY_TYPE_SERVICE_ACCOUNT)) {
+ strcmp(prop_value, GRPC_AUTH_JSON_TYPE_SERVICE_ACCOUNT)) {
goto end;
}
- result.type = GRPC_AUTH_JSON_KEY_TYPE_SERVICE_ACCOUNT;
+ result.type = GRPC_AUTH_JSON_TYPE_SERVICE_ACCOUNT;
if (!set_json_key_string_property(json, "private_key_id",
&result.private_key_id) ||
@@ -148,7 +149,7 @@
void grpc_auth_json_key_destruct(grpc_auth_json_key *json_key) {
if (json_key == NULL) return;
- json_key->type = GRPC_AUTH_JSON_KEY_TYPE_INVALID;
+ json_key->type = GRPC_AUTH_JSON_TYPE_INVALID;
if (json_key->client_id != NULL) {
gpr_free(json_key->client_id);
json_key->client_id = NULL;
@@ -331,3 +332,67 @@
grpc_jwt_encode_and_sign_override func) {
g_jwt_encode_and_sign_override = func;
}
+
+/* --- grpc_auth_refresh_token --- */
+
+int grpc_auth_refresh_token_is_valid(
+ const grpc_auth_refresh_token *refresh_token) {
+ return (refresh_token != NULL) &&
+ strcmp(refresh_token->type, GRPC_AUTH_JSON_TYPE_INVALID);
+}
+
+grpc_auth_refresh_token grpc_auth_refresh_token_create_from_string(
+ const char *json_string) {
+ grpc_auth_refresh_token result;
+ char *scratchpad = gpr_strdup(json_string);
+ grpc_json *json = grpc_json_parse_string(scratchpad);
+ const char *prop_value;
+ int success = 0;
+
+ memset(&result, 0, sizeof(grpc_auth_refresh_token));
+ result.type = GRPC_AUTH_JSON_TYPE_INVALID;
+ if (json == NULL) {
+ gpr_log(GPR_ERROR, "Invalid json string %s", json_string);
+ goto end;
+ }
+
+ prop_value = json_get_string_property(json, "type");
+ if (prop_value == NULL ||
+ strcmp(prop_value, GRPC_AUTH_JSON_TYPE_AUTHORIZED_USER)) {
+ goto end;
+ }
+ result.type = GRPC_AUTH_JSON_TYPE_AUTHORIZED_USER;
+
+ if (!set_json_key_string_property(json, "client_secret",
+ &result.client_secret) ||
+ !set_json_key_string_property(json, "client_id", &result.client_id) ||
+ !set_json_key_string_property(json, "refresh_token",
+ &result.refresh_token)) {
+ goto end;
+ }
+ success = 1;
+
+end:
+ if (json != NULL) grpc_json_destroy(json);
+ if (!success) grpc_auth_refresh_token_destruct(&result);
+ gpr_free(scratchpad);
+ return result;
+}
+
+void grpc_auth_refresh_token_destruct(grpc_auth_refresh_token *refresh_token) {
+ if (refresh_token == NULL) return;
+ refresh_token->type = GRPC_AUTH_JSON_TYPE_INVALID;
+ if (refresh_token->client_id != NULL) {
+ gpr_free(refresh_token->client_id);
+ refresh_token->client_id = NULL;
+ }
+ if (refresh_token->client_secret != NULL) {
+ gpr_free(refresh_token->client_secret);
+ refresh_token->client_secret = NULL;
+ }
+ if (refresh_token->refresh_token != NULL) {
+ gpr_free(refresh_token->refresh_token);
+ refresh_token->refresh_token = NULL;
+ }
+}
+
diff --git a/src/core/security/json_token.h b/src/core/security/json_token.h
index 029ede3..197796a 100644
--- a/src/core/security/json_token.h
+++ b/src/core/security/json_token.h
@@ -44,7 +44,7 @@
/* --- auth_json_key parsing. --- */
typedef struct {
- char *type;
+ const char *type;
char *private_key_id;
char *client_id;
char *client_email;
@@ -79,4 +79,25 @@
void grpc_jwt_encode_and_sign_set_override(
grpc_jwt_encode_and_sign_override func);
+/* --- auth_refresh_token parsing. --- */
+
+typedef struct {
+ const char *type;
+ char *client_id;
+ char *client_secret;
+ char *refresh_token;
+} grpc_auth_refresh_token;
+
+/* Returns 1 if the object is valid, 0 otherwise. */
+int grpc_auth_refresh_token_is_valid(
+ const grpc_auth_refresh_token *refresh_token);
+
+/* Creates a refresh token object from string. Returns an invalid object if a
+ parsing error has been encountered. */
+grpc_auth_refresh_token grpc_auth_refresh_token_create_from_string(
+ const char *json_string);
+
+/* Destructs the object. */
+void grpc_auth_refresh_token_destruct(grpc_auth_refresh_token *refresh_token);
+
#endif /* GRPC_INTERNAL_CORE_SECURITY_JSON_TOKEN_H */
diff --git a/src/core/support/slice_buffer.c b/src/core/support/slice_buffer.c
index 6cd51f9..b280e4b 100644
--- a/src/core/support/slice_buffer.c
+++ b/src/core/support/slice_buffer.c
@@ -143,6 +143,13 @@
}
}
+void gpr_slice_buffer_pop(gpr_slice_buffer *sb) {
+ if (sb->count != 0) {
+ size_t count = --sb->count;
+ sb->length -= GPR_SLICE_LENGTH(sb->slices[count]);
+ }
+}
+
void gpr_slice_buffer_reset_and_unref(gpr_slice_buffer *sb) {
size_t i;
diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c
index 0d01a37..2b15b2a 100644
--- a/src/core/transport/chttp2_transport.c
+++ b/src/core/transport/chttp2_transport.c
@@ -1655,7 +1655,15 @@
if (!init_frame_parser(t)) {
return 0;
}
- t->last_incoming_stream_id = t->incoming_stream_id;
+ /* t->last_incoming_stream_id is used as last-stream-id when
+ sending GOAWAY frame.
+ https://tools.ietf.org/html/draft-ietf-httpbis-http2-17#section-6.8
+ says that last-stream-id is peer-initiated stream ID. So,
+ since we don't have server pushed streams, client should send
+ GOAWAY last-stream-id=0 in this case. */
+ if (!t->is_client) {
+ t->last_incoming_stream_id = t->incoming_stream_id;
+ }
if (t->incoming_frame_size == 0) {
if (!parse_frame_slice(t, gpr_empty_slice(), 1)) {
return 0;
diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc
index 2dcfe69..f3ca430 100644
--- a/src/cpp/client/insecure_credentials.cc
+++ b/src/cpp/client/insecure_credentials.cc
@@ -54,7 +54,7 @@
target, grpc_channel_create(target.c_str(), &channel_args)));
}
- SecureCredentials* AsSecureCredentials() { return nullptr; }
+ SecureCredentials* AsSecureCredentials() GRPC_OVERRIDE { return nullptr; }
};
} // namespace
diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc
index 5eb5c54..6ca702e 100644
--- a/src/cpp/client/secure_credentials.cc
+++ b/src/cpp/client/secure_credentials.cc
@@ -54,11 +54,12 @@
grpc_channel_args channel_args;
args.SetChannelArgs(&channel_args);
return std::shared_ptr<ChannelInterface>(new Channel(
- target,
+ args.GetSslTargetNameOverride().empty()
+ ? target : args.GetSslTargetNameOverride(),
grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args)));
}
- SecureCredentials* AsSecureCredentials() { return this; }
+ SecureCredentials* AsSecureCredentials() GRPC_OVERRIDE { return this; }
private:
grpc_credentials* const c_creds_;
diff --git a/src/cpp/proto/proto_utils.cc b/src/cpp/proto/proto_utils.cc
index 72f1bf7..e4e51bf 100644
--- a/src/cpp/proto/proto_utils.cc
+++ b/src/cpp/proto/proto_utils.cc
@@ -35,38 +35,135 @@
#include <grpc++/config.h>
#include <grpc/grpc.h>
+#include <grpc/byte_buffer.h>
#include <grpc/support/slice.h>
+#include <grpc/support/slice_buffer.h>
+#include <grpc/support/port_platform.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+
+const int kMaxBufferLength = 8192;
+
+class GrpcBufferWriter GRPC_FINAL
+ : public ::google::protobuf::io::ZeroCopyOutputStream {
+ public:
+ explicit GrpcBufferWriter(grpc_byte_buffer **bp,
+ int block_size = kMaxBufferLength)
+ : block_size_(block_size), byte_count_(0), have_backup_(false) {
+ *bp = grpc_byte_buffer_create(NULL, 0);
+ slice_buffer_ = &(*bp)->data.slice_buffer;
+ }
+
+ ~GrpcBufferWriter() GRPC_OVERRIDE {
+ if (have_backup_) {
+ gpr_slice_unref(backup_slice_);
+ }
+ }
+
+ bool Next(void **data, int *size) GRPC_OVERRIDE {
+ if (have_backup_) {
+ slice_ = backup_slice_;
+ have_backup_ = false;
+ } else {
+ slice_ = gpr_slice_malloc(block_size_);
+ }
+ *data = GPR_SLICE_START_PTR(slice_);
+ byte_count_ += *size = GPR_SLICE_LENGTH(slice_);
+ gpr_slice_buffer_add(slice_buffer_, slice_);
+ return true;
+ }
+
+ void BackUp(int count) GRPC_OVERRIDE {
+ gpr_slice_buffer_pop(slice_buffer_);
+ if (count == block_size_) {
+ backup_slice_ = slice_;
+ } else {
+ backup_slice_ =
+ gpr_slice_split_tail(&slice_, GPR_SLICE_LENGTH(slice_) - count);
+ gpr_slice_buffer_add(slice_buffer_, slice_);
+ }
+ have_backup_ = true;
+ byte_count_ -= count;
+ }
+
+ gpr_int64 ByteCount() const GRPC_OVERRIDE { return byte_count_; }
+
+ private:
+ const int block_size_;
+ gpr_int64 byte_count_;
+ gpr_slice_buffer *slice_buffer_;
+ bool have_backup_;
+ gpr_slice backup_slice_;
+ gpr_slice slice_;
+};
+
+class GrpcBufferReader GRPC_FINAL
+ : public ::google::protobuf::io::ZeroCopyInputStream {
+ public:
+ explicit GrpcBufferReader(grpc_byte_buffer *buffer)
+ : byte_count_(0), backup_count_(0) {
+ reader_ = grpc_byte_buffer_reader_create(buffer);
+ }
+ ~GrpcBufferReader() GRPC_OVERRIDE {
+ grpc_byte_buffer_reader_destroy(reader_);
+ }
+
+ bool Next(const void **data, int *size) GRPC_OVERRIDE {
+ if (backup_count_ > 0) {
+ *data = GPR_SLICE_START_PTR(slice_) + GPR_SLICE_LENGTH(slice_) -
+ backup_count_;
+ *size = backup_count_;
+ backup_count_ = 0;
+ return true;
+ }
+ if (!grpc_byte_buffer_reader_next(reader_, &slice_)) {
+ return false;
+ }
+ gpr_slice_unref(slice_);
+ *data = GPR_SLICE_START_PTR(slice_);
+ byte_count_ += *size = GPR_SLICE_LENGTH(slice_);
+ return true;
+ }
+
+ void BackUp(int count) GRPC_OVERRIDE {
+ backup_count_ = count;
+ }
+
+ bool Skip(int count) GRPC_OVERRIDE {
+ const void *data;
+ int size;
+ while (Next(&data, &size)) {
+ if (size >= count) {
+ BackUp(size - count);
+ return true;
+ }
+ // size < count;
+ count -= size;
+ }
+ // error or we have too large count;
+ return false;
+ }
+
+ gpr_int64 ByteCount() const GRPC_OVERRIDE {
+ return byte_count_ - backup_count_;
+ }
+
+ private:
+ gpr_int64 byte_count_;
+ gpr_int64 backup_count_;
+ grpc_byte_buffer_reader *reader_;
+ gpr_slice slice_;
+};
namespace grpc {
-bool SerializeProto(const grpc::protobuf::Message &msg,
- grpc_byte_buffer **bp) {
- grpc::string msg_str;
- bool success = msg.SerializeToString(&msg_str);
- if (success) {
- gpr_slice slice =
- gpr_slice_from_copied_buffer(msg_str.data(), msg_str.length());
- *bp = grpc_byte_buffer_create(&slice, 1);
- gpr_slice_unref(slice);
- }
- return success;
+bool SerializeProto(const grpc::protobuf::Message &msg, grpc_byte_buffer **bp) {
+ GrpcBufferWriter writer(bp);
+ return msg.SerializeToZeroCopyStream(&writer);
}
-bool DeserializeProto(grpc_byte_buffer *buffer,
- grpc::protobuf::Message *msg) {
- grpc::string msg_string;
- grpc_byte_buffer_reader *reader = grpc_byte_buffer_reader_create(buffer);
- gpr_slice slice;
- while (grpc_byte_buffer_reader_next(reader, &slice)) {
- const char *data = reinterpret_cast<const char *>(
- slice.refcount ? slice.data.refcounted.bytes
- : slice.data.inlined.bytes);
- msg_string.append(data, slice.refcount ? slice.data.refcounted.length
- : slice.data.inlined.length);
- gpr_slice_unref(slice);
- }
- grpc_byte_buffer_reader_destroy(reader);
- return msg->ParseFromString(msg_string);
+bool DeserializeProto(grpc_byte_buffer *buffer, grpc::protobuf::Message *msg) {
+ GrpcBufferReader reader(buffer);
+ return msg->ParseFromZeroCopyStream(&reader);
}
} // namespace grpc
diff --git a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs
index 39be35c..e73159b 100644
--- a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs
+++ b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs
@@ -122,10 +122,13 @@
{
var call = new Call<string, string>(unaryEchoStringMethod, channel);
- try {
+ try
+ {
Calls.BlockingUnaryCall(call, "ABC", default(CancellationToken));
Assert.Fail();
- } catch(RpcException e) {
+ }
+ catch (RpcException e)
+ {
Assert.AreEqual(StatusCode.Unimplemented, e.Status.StatusCode);
}
}
@@ -140,4 +143,3 @@
}
}
}
-
diff --git a/src/csharp/Grpc.Core.Tests/GrpcEnvironmentTest.cs b/src/csharp/Grpc.Core.Tests/GrpcEnvironmentTest.cs
index 596918c..6a132a5 100644
--- a/src/csharp/Grpc.Core.Tests/GrpcEnvironmentTest.cs
+++ b/src/csharp/Grpc.Core.Tests/GrpcEnvironmentTest.cs
@@ -68,7 +68,7 @@
var tp2 = GrpcEnvironment.ThreadPool;
GrpcEnvironment.Shutdown();
- Assert.IsFalse(Object.ReferenceEquals(tp1, tp2));
+ Assert.IsFalse(object.ReferenceEquals(tp1, tp2));
}
}
}
diff --git a/src/csharp/Grpc.Core.Tests/PInvokeTest.cs b/src/csharp/Grpc.Core.Tests/PInvokeTest.cs
index 9db08d2..3beffc3 100644
--- a/src/csharp/Grpc.Core.Tests/PInvokeTest.cs
+++ b/src/csharp/Grpc.Core.Tests/PInvokeTest.cs
@@ -33,13 +33,13 @@
using System;
using System.Diagnostics;
+using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Grpc.Core;
using Grpc.Core.Internal;
using Grpc.Core.Utils;
using NUnit.Framework;
-using System.Runtime.InteropServices;
namespace Grpc.Core.Tests
{
@@ -73,14 +73,13 @@
{
BenchmarkUtil.RunBenchmark(
100000, 1000000,
- () => {
+ () =>
+ {
CompletionQueueSafeHandle cq = CompletionQueueSafeHandle.Create();
cq.Dispose();
- }
- );
+ });
}
-
/// <summary>
/// Approximate results:
/// (~80ns Mono Linux)
@@ -94,10 +93,10 @@
counter = 0;
BenchmarkUtil.RunBenchmark(
1000000, 10000000,
- () => {
+ () =>
+ {
grpcsharp_test_callback(handler);
- }
- );
+ });
Assert.AreNotEqual(0, counter);
}
@@ -113,10 +112,10 @@
counter = 0;
BenchmarkUtil.RunBenchmark(
10000, 10000,
- () => {
- grpcsharp_test_callback(new CompletionCallbackDelegate(Handler));
- }
- );
+ () =>
+ {
+ grpcsharp_test_callback(new CompletionCallbackDelegate(Handler));
+ });
Assert.AreNotEqual(0, counter);
}
@@ -129,15 +128,15 @@
{
BenchmarkUtil.RunBenchmark(
1000000, 100000000,
- () => {
+ () =>
+ {
grpcsharp_test_nop(IntPtr.Zero);
- }
- );
+ });
}
- private void Handler(GRPCOpError op, IntPtr ptr) {
- counter ++;
+ private void Handler(GRPCOpError op, IntPtr ptr)
+ {
+ counter++;
}
}
}
-
diff --git a/src/csharp/Grpc.Core.Tests/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Core.Tests/Properties/AssemblyInfo.cs
index 499d931..e432880 100644
--- a/src/csharp/Grpc.Core.Tests/Properties/AssemblyInfo.cs
+++ b/src/csharp/Grpc.Core.Tests/Properties/AssemblyInfo.cs
@@ -1,8 +1,6 @@
using System.Reflection;
using System.Runtime.CompilerServices;
-// Information about this assembly is defined by the following attributes.
-// Change them to the values specific to your project.
[assembly: AssemblyTitle("Grpc.Core.Tests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
@@ -11,12 +9,4 @@
[assembly: AssemblyCopyright("Google Inc. All rights reserved.")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
-// The form "{Major}.{Minor}.*" will automatically update the build and revision,
-// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("0.1.*")]
-// The following attributes are used to specify the signing key for the assembly,
-// if desired. See the Mono documentation for more information about signing.
-//[assembly: AssemblyDelaySign(false)]
-//[assembly: AssemblyKeyFile("")]
-
diff --git a/src/csharp/Grpc.Core.Tests/ServerTest.cs b/src/csharp/Grpc.Core.Tests/ServerTest.cs
index dd30366..12f914b 100644
--- a/src/csharp/Grpc.Core.Tests/ServerTest.cs
+++ b/src/csharp/Grpc.Core.Tests/ServerTest.cs
@@ -53,6 +53,5 @@
GrpcEnvironment.Shutdown();
}
-
}
}
diff --git a/src/csharp/Grpc.Core.Tests/TimespecTest.cs b/src/csharp/Grpc.Core.Tests/TimespecTest.cs
index 0ca84ec..f5bae6d 100644
--- a/src/csharp/Grpc.Core.Tests/TimespecTest.cs
+++ b/src/csharp/Grpc.Core.Tests/TimespecTest.cs
@@ -86,4 +86,3 @@
}
}
}
-
diff --git a/src/csharp/Grpc.Core/Call.cs b/src/csharp/Grpc.Core/Call.cs
index 72dca68..d84d594 100644
--- a/src/csharp/Grpc.Core/Call.cs
+++ b/src/csharp/Grpc.Core/Call.cs
@@ -47,7 +47,8 @@
Func<TRequest, byte[]> requestSerializer,
Func<byte[], TResponse> responseDeserializer,
TimeSpan timeout,
- Channel channel) {
+ Channel channel)
+ {
this.methodName = methodName;
this.requestSerializer = requestSerializer;
this.responseDeserializer = responseDeserializer;
@@ -95,4 +96,3 @@
}
}
}
-
diff --git a/src/csharp/Grpc.Core/Calls.cs b/src/csharp/Grpc.Core/Calls.cs
index ee2208e..cc1d67a 100644
--- a/src/csharp/Grpc.Core/Calls.cs
+++ b/src/csharp/Grpc.Core/Calls.cs
@@ -38,8 +38,6 @@
namespace Grpc.Core
{
- // NOTE: this class is work-in-progress
-
/// <summary>
/// Helper methods for generated stubs to make RPC calls.
/// </summary>
@@ -89,9 +87,9 @@
return new ClientStreamingInputObserver<TRequest, TResponse>(asyncCall);
}
- private static CompletionQueueSafeHandle GetCompletionQueue() {
+ private static CompletionQueueSafeHandle GetCompletionQueue()
+ {
return GrpcEnvironment.ThreadPool.CompletionQueue;
}
}
}
-
diff --git a/src/csharp/Grpc.Core/Channel.cs b/src/csharp/Grpc.Core/Channel.cs
index 83d965d..3a42dac 100644
--- a/src/csharp/Grpc.Core/Channel.cs
+++ b/src/csharp/Grpc.Core/Channel.cs
@@ -36,10 +36,13 @@
namespace Grpc.Core
{
+ /// <summary>
+ /// gRPC Channel
+ /// </summary>
public class Channel : IDisposable
{
readonly ChannelSafeHandle handle;
- readonly String target;
+ readonly string target;
/// <summary>
/// Creates a channel.
diff --git a/src/csharp/Grpc.Core/ChannelArgs.cs b/src/csharp/Grpc.Core/ChannelArgs.cs
index 298b6ed..74ab310 100644
--- a/src/csharp/Grpc.Core/ChannelArgs.cs
+++ b/src/csharp/Grpc.Core/ChannelArgs.cs
@@ -30,6 +30,7 @@
#endregion
using System;
using System.Collections.Generic;
+using System.Collections.Immutable;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
@@ -37,33 +38,18 @@
namespace Grpc.Core
{
- // TODO: should we be using the builder pattern?
+ /// <summary>
+ /// gRPC channel options.
+ /// </summary>
public class ChannelArgs
{
public const string SslTargetNameOverrideKey = "grpc.ssl_target_name_override";
- public class Builder
+ readonly ImmutableDictionary<string, string> stringArgs;
+
+ private ChannelArgs(ImmutableDictionary<string, string> stringArgs)
{
- Dictionary<string,string> stringArgs = new Dictionary<string,string>();
- // TODO: AddInteger not supported yet.
- public Builder AddString(string key, string value)
- {
- stringArgs.Add(key, value);
- return this;
- }
-
- public ChannelArgs Build()
- {
- return new ChannelArgs(stringArgs);
- }
- }
-
- Dictionary<string,string> stringArgs;
-
- private ChannelArgs(Dictionary<string, string> stringArgs)
- {
- // TODO: use immutable dict?
- this.stringArgs = new Dictionary<string, string>(stringArgs);
+ this.stringArgs = stringArgs;
}
public string GetSslTargetNameOverride()
@@ -76,11 +62,28 @@
return null;
}
- public static Builder NewBuilder()
+ public static Builder CreateBuilder()
{
return new Builder();
}
+ public class Builder
+ {
+ readonly Dictionary<string, string> stringArgs = new Dictionary<string, string>();
+
+ // TODO: AddInteger not supported yet.
+ public Builder AddString(string key, string value)
+ {
+ stringArgs.Add(key, value);
+ return this;
+ }
+
+ public ChannelArgs Build()
+ {
+ return new ChannelArgs(stringArgs.ToImmutableDictionary());
+ }
+ }
+
/// <summary>
/// Creates native object for the channel arguments.
/// </summary>
diff --git a/src/csharp/Grpc.Core/ClientStreamingAsyncResult.cs b/src/csharp/Grpc.Core/ClientStreamingAsyncResult.cs
index 44580a1..65bedb0 100644
--- a/src/csharp/Grpc.Core/ClientStreamingAsyncResult.cs
+++ b/src/csharp/Grpc.Core/ClientStreamingAsyncResult.cs
@@ -67,4 +67,3 @@
}
}
}
-
diff --git a/src/csharp/Grpc.Core/Credentials.cs b/src/csharp/Grpc.Core/Credentials.cs
index 5116c27..15dd3ef 100644
--- a/src/csharp/Grpc.Core/Credentials.cs
+++ b/src/csharp/Grpc.Core/Credentials.cs
@@ -36,6 +36,9 @@
namespace Grpc.Core
{
+ /// <summary>
+ /// Client-side credentials.
+ /// </summary>
public abstract class Credentials
{
/// <summary>
@@ -74,4 +77,3 @@
}
}
}
-
diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj
index 78b6cdde..29f1a06 100644
--- a/src/csharp/Grpc.Core/Grpc.Core.csproj
+++ b/src/csharp/Grpc.Core/Grpc.Core.csproj
@@ -31,6 +31,9 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
+ <Reference Include="System.Collections.Immutable">
+ <HintPath>..\packages\System.Collections.Immutable.1.1.34-rc\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
+ </Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Internal\GrpcLog.cs" />
@@ -54,7 +57,7 @@
<Compile Include="Internal\ServerSafeHandle.cs" />
<Compile Include="Method.cs" />
<Compile Include="ServerCalls.cs" />
- <Compile Include="ServerCallHandler.cs" />
+ <Compile Include="Internal\ServerCallHandler.cs" />
<Compile Include="Marshaller.cs" />
<Compile Include="ServerServiceDefinition.cs" />
<Compile Include="Utils\RecordingObserver.cs" />
@@ -74,6 +77,11 @@
<Compile Include="OperationFailedException.cs" />
<Compile Include="Internal\AsyncCall.cs" />
<Compile Include="Utils\Preconditions.cs" />
+ <Compile Include="Internal\ServerCredentialsSafeHandle.cs" />
+ <Compile Include="ServerCredentials.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
</ItemGroup>
<Choose>
<!-- Under older versions of Monodevelop, Choose is not supported and is just
diff --git a/src/csharp/Grpc.Core/GrpcEnvironment.cs b/src/csharp/Grpc.Core/GrpcEnvironment.cs
index d3a8da4..9c10a42 100644
--- a/src/csharp/Grpc.Core/GrpcEnvironment.cs
+++ b/src/csharp/Grpc.Core/GrpcEnvironment.cs
@@ -63,8 +63,9 @@
/// lifetime (and call Shutdown once you're done), for the sake of easier testing it's
/// allowed to initialize the environment again after it has been successfully shutdown.
/// </summary>
- public static void Initialize() {
- lock(staticLock)
+ public static void Initialize()
+ {
+ lock (staticLock)
{
if (instance == null)
{
@@ -79,7 +80,7 @@
/// </summary>
public static void Shutdown()
{
- lock(staticLock)
+ lock (staticLock)
{
if (instance != null)
{
@@ -133,4 +134,3 @@
}
}
}
-
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
index 5ae0362..04fc28d 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
@@ -54,7 +54,7 @@
TaskCompletionSource<TResponse> unaryResponseTcs;
// Set after status is received. Only used for streaming response calls.
- Nullable<Status> finishedStatus;
+ Status? finishedStatus;
bool readObserverCompleted; // True if readObserver has already been completed.
@@ -64,7 +64,7 @@
this.finishedHandler = CreateBatchCompletionCallback(HandleFinished);
}
- public void Initialize(Channel channel, CompletionQueueSafeHandle cq, String methodName)
+ public void Initialize(Channel channel, CompletionQueueSafeHandle cq, string methodName)
{
var call = CallSafeHandle.Create(channel.Handle, cq, methodName, channel.Target, Timespec.InfFuture);
InitializeInternal(call);
@@ -77,9 +77,9 @@
/// <summary>
/// Blocking unary request - unary response call.
/// </summary>
- public TResponse UnaryCall(Channel channel, String methodName, TRequest msg)
+ public TResponse UnaryCall(Channel channel, string methodName, TRequest msg)
{
- using(CompletionQueueSafeHandle cq = CompletionQueueSafeHandle.Create())
+ using (CompletionQueueSafeHandle cq = CompletionQueueSafeHandle.Create())
{
byte[] payload = UnsafeSerialize(msg);
@@ -254,7 +254,7 @@
/// </summary>
private void HandleUnaryResponse(bool wasError, BatchContextSafeHandleNotOwned ctx)
{
- lock(myLock)
+ lock (myLock)
{
finished = true;
halfclosed = true;
@@ -264,9 +264,7 @@
if (wasError)
{
- unaryResponseTcs.SetException(new RpcException(
- new Status(StatusCode.Internal, "Internal error occured.")
- ));
+ unaryResponseTcs.SetException(new RpcException(new Status(StatusCode.Internal, "Internal error occured.")));
return;
}
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
index 44d66b3..15b0cfe 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
@@ -225,7 +225,7 @@
payload = serializer(msg);
return true;
}
- catch(Exception)
+ catch (Exception)
{
Console.WriteLine("Exception occured while trying to serialize message");
payload = null;
@@ -240,7 +240,7 @@
msg = deserializer(payload);
return true;
}
- catch(Exception)
+ catch (Exception)
{
Console.WriteLine("Exception occured while trying to deserialize message");
msg = default(TRead);
@@ -254,7 +254,7 @@
{
readObserver.OnNext(value);
}
- catch(Exception e)
+ catch (Exception e)
{
Console.WriteLine("Exception occured while invoking readObserver.OnNext: " + e);
}
@@ -266,7 +266,7 @@
{
readObserver.OnCompleted();
}
- catch(Exception e)
+ catch (Exception e)
{
Console.WriteLine("Exception occured while invoking readObserver.OnCompleted: " + e);
}
@@ -278,7 +278,7 @@
{
readObserver.OnError(error);
}
- catch(Exception e)
+ catch (Exception e)
{
Console.WriteLine("Exception occured while invoking readObserver.OnError: " + e);
}
@@ -290,7 +290,7 @@
{
completionDelegate(error);
}
- catch(Exception e)
+ catch (Exception e)
{
Console.WriteLine("Exception occured while invoking completion delegate: " + e);
}
@@ -302,14 +302,15 @@
/// </summary>
protected CompletionCallbackDelegate CreateBatchCompletionCallback(Action<bool, BatchContextSafeHandleNotOwned> handler)
{
- return new CompletionCallbackDelegate( (error, batchContextPtr) => {
+ return new CompletionCallbackDelegate((error, batchContextPtr) =>
+ {
try
{
var ctx = new BatchContextSafeHandleNotOwned(batchContextPtr);
bool wasError = (error != GRPCOpError.GRPC_OP_OK);
handler(wasError, ctx);
}
- catch(Exception e)
+ catch (Exception e)
{
Console.WriteLine("Caught exception in a native handler: " + e);
}
@@ -363,7 +364,6 @@
{
FireCompletion(origCompletionDelegate, null);
}
-
}
/// <summary>
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCompletion.cs b/src/csharp/Grpc.Core/Internal/AsyncCompletion.cs
index b78bb49..673b527 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCompletion.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCompletion.cs
@@ -91,5 +91,4 @@
tcs.SetException(error);
}
}
-
}
\ No newline at end of file
diff --git a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandleNotOwned.cs b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandleNotOwned.cs
index 75cd30e..3c54753 100644
--- a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandleNotOwned.cs
+++ b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandleNotOwned.cs
@@ -80,16 +80,18 @@
{
return null;
}
- byte[] data = new byte[(int) len];
+ byte[] data = new byte[(int)len];
grpcsharp_batch_context_recv_message_to_buffer(this, data, new UIntPtr((ulong)data.Length));
return data;
}
- public CallSafeHandle GetServerRpcNewCall() {
+ public CallSafeHandle GetServerRpcNewCall()
+ {
return grpcsharp_batch_context_server_rpc_new_call(this);
}
- public string GetServerRpcNewMethod() {
+ public string GetServerRpcNewMethod()
+ {
return Marshal.PtrToStringAnsi(grpcsharp_batch_context_server_rpc_new_method(this));
}
}
diff --git a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
index 61566b5..a8cef4a 100644
--- a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
@@ -36,13 +36,14 @@
namespace Grpc.Core.Internal
{
- internal delegate void CompletionCallbackDelegate(GRPCOpError error,IntPtr batchContextPtr);
+ internal delegate void CompletionCallbackDelegate(GRPCOpError error, IntPtr batchContextPtr);
+
/// <summary>
/// grpc_call from <grpc/grpc.h>
/// </summary>
internal class CallSafeHandle : SafeHandleZeroIsInvalid
{
- const UInt32 GRPC_WRITE_BUFFER_HINT = 1;
+ const uint GRPC_WRITE_BUFFER_HINT = 1;
[DllImport("grpc_csharp_ext.dll")]
static extern CallSafeHandle grpcsharp_channel_create_call(ChannelSafeHandle channel, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline);
@@ -179,7 +180,7 @@
Trace.Assert(callError == GRPCCallError.GRPC_CALL_OK, "Status not GRPC_CALL_OK");
}
- private static UInt32 GetFlags(bool buffered)
+ private static uint GetFlags(bool buffered)
{
return buffered ? 0 : GRPC_WRITE_BUFFER_HINT;
}
diff --git a/src/csharp/Grpc.Core/Internal/ChannelArgsSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ChannelArgsSafeHandle.cs
index ca3c21d..c69f1a0 100644
--- a/src/csharp/Grpc.Core/Internal/ChannelArgsSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/ChannelArgsSafeHandle.cs
@@ -74,4 +74,3 @@
}
}
}
-
diff --git a/src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs
index 6bff923..600d1fc 100644
--- a/src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs
@@ -77,4 +77,3 @@
}
}
}
-
diff --git a/src/csharp/Grpc.Core/Internal/Enums.cs b/src/csharp/Grpc.Core/Internal/Enums.cs
index f363050..94a2fd1 100644
--- a/src/csharp/Grpc.Core/Internal/Enums.cs
+++ b/src/csharp/Grpc.Core/Internal/Enums.cs
@@ -112,4 +112,3 @@
GRPC_OP_ERROR
}
}
-
diff --git a/src/csharp/Grpc.Core/Internal/GrpcLog.cs b/src/csharp/Grpc.Core/Internal/GrpcLog.cs
index 98768d0..2f3c8ad 100644
--- a/src/csharp/Grpc.Core/Internal/GrpcLog.cs
+++ b/src/csharp/Grpc.Core/Internal/GrpcLog.cs
@@ -40,7 +40,7 @@
namespace Grpc.Core.Internal
{
- internal delegate void GprLogDelegate(IntPtr fileStringPtr, Int32 line, UInt64 threadId, IntPtr severityStringPtr, IntPtr msgPtr);
+ internal delegate void GprLogDelegate(IntPtr fileStringPtr, int line, ulong threadId, IntPtr severityStringPtr, IntPtr msgPtr);
/// <summary>
/// Logs from gRPC C core library can get lost if your application is not a console app.
@@ -73,7 +73,7 @@
}
}
- private static void HandleWrite(IntPtr fileStringPtr, Int32 line, UInt64 threadId, IntPtr severityStringPtr, IntPtr msgPtr)
+ private static void HandleWrite(IntPtr fileStringPtr, int line, ulong threadId, IntPtr severityStringPtr, IntPtr msgPtr)
{
try
{
diff --git a/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs b/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs
index 9e69fe2..f422466 100644
--- a/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs
+++ b/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs
@@ -51,12 +51,13 @@
CompletionQueueSafeHandle cq;
- public GrpcThreadPool(int poolSize) {
+ public GrpcThreadPool(int poolSize)
+ {
this.poolSize = poolSize;
}
- public void Start() {
-
+ public void Start()
+ {
lock (myLock)
{
if (cq != null)
@@ -73,8 +74,8 @@
}
}
- public void Stop() {
-
+ public void Stop()
+ {
lock (myLock)
{
cq.Shutdown();
@@ -86,7 +87,6 @@
}
cq.Dispose();
-
}
}
@@ -116,10 +116,9 @@
do
{
completionType = cq.NextWithCallback();
- } while(completionType != GRPCCompletionType.GRPC_QUEUE_SHUTDOWN);
+ }
+ while (completionType != GRPCCompletionType.GRPC_QUEUE_SHUTDOWN);
Console.WriteLine("Completion queue has shutdown successfully, thread " + Thread.CurrentThread.Name + " exiting.");
}
}
-
}
-
diff --git a/src/csharp/Grpc.Core/Internal/SafeHandleZeroIsInvalid.cs b/src/csharp/Grpc.Core/Internal/SafeHandleZeroIsInvalid.cs
index aa6fce2..702aea2 100644
--- a/src/csharp/Grpc.Core/Internal/SafeHandleZeroIsInvalid.cs
+++ b/src/csharp/Grpc.Core/Internal/SafeHandleZeroIsInvalid.cs
@@ -64,4 +64,3 @@
}
}
}
-
diff --git a/src/csharp/Grpc.Core/ServerCallHandler.cs b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
similarity index 97%
rename from src/csharp/Grpc.Core/ServerCallHandler.cs
rename to src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
index 3eb8422..25fd4fa 100644
--- a/src/csharp/Grpc.Core/ServerCallHandler.cs
+++ b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
@@ -36,7 +36,7 @@
using Grpc.Core.Internal;
using Grpc.Core.Utils;
-namespace Grpc.Core
+namespace Grpc.Core.Internal
{
internal interface IServerCallHandler
{
@@ -70,7 +70,6 @@
handler(request, responseObserver);
finishedTask.Wait();
-
}
}
@@ -93,7 +92,7 @@
asyncCall.Initialize(call);
- var responseObserver = new ServerStreamingOutputObserver<TRequest,TResponse>(asyncCall);
+ var responseObserver = new ServerStreamingOutputObserver<TRequest, TResponse>(asyncCall);
var requestObserver = handler(responseObserver);
var finishedTask = asyncCall.ServerSideCallAsync(requestObserver);
finishedTask.Wait();
@@ -113,7 +112,7 @@
var finishedTask = asyncCall.ServerSideCallAsync(new NullObserver<byte[]>());
// TODO: check result of the completion status.
- asyncCall.StartSendStatusFromServer(new Status(StatusCode.Unimplemented, "No such method."), new AsyncCompletionDelegate((error) => {}));
+ asyncCall.StartSendStatusFromServer(new Status(StatusCode.Unimplemented, "No such method."), new AsyncCompletionDelegate((error) => { }));
finishedTask.Wait();
}
@@ -132,7 +131,5 @@
public void OnNext(T value)
{
}
-
}
}
-
diff --git a/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs
new file mode 100644
index 0000000..9611807
--- /dev/null
+++ b/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs
@@ -0,0 +1,68 @@
+#region Copyright notice and license
+// 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.
+#endregion
+using System;
+using System.Runtime.InteropServices;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core.Utils;
+
+namespace Grpc.Core.Internal
+{
+ /// <summary>
+ /// grpc_server_credentials from <grpc/grpc_security.h>
+ /// </summary>
+ internal class ServerCredentialsSafeHandle : SafeHandleZeroIsInvalid
+ {
+ [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
+ static extern ServerCredentialsSafeHandle grpcsharp_ssl_server_credentials_create(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, UIntPtr numKeyCertPairs);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ static extern void grpcsharp_server_credentials_release(IntPtr credentials);
+
+ private ServerCredentialsSafeHandle()
+ {
+ }
+
+ public static ServerCredentialsSafeHandle CreateSslCredentials(string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray)
+ {
+ Preconditions.CheckArgument(keyCertPairCertChainArray.Length == keyCertPairPrivateKeyArray.Length);
+ return grpcsharp_ssl_server_credentials_create(null,
+ keyCertPairCertChainArray, keyCertPairPrivateKeyArray,
+ new UIntPtr((ulong)keyCertPairCertChainArray.Length));
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ grpcsharp_server_credentials_release(handle);
+ return true;
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs
index de9bbaf..dc4781e 100644
--- a/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs
@@ -53,7 +53,10 @@
static extern ServerSafeHandle grpcsharp_server_create(CompletionQueueSafeHandle cq, IntPtr args);
[DllImport("grpc_csharp_ext.dll")]
- static extern Int32 grpcsharp_server_add_http2_port(ServerSafeHandle server, string addr);
+ static extern int grpcsharp_server_add_http2_port(ServerSafeHandle server, string addr);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ static extern int grpcsharp_server_add_secure_http2_port(ServerSafeHandle server, string addr, ServerCredentialsSafeHandle creds);
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_server_start(ServerSafeHandle server);
@@ -74,7 +77,6 @@
public static ServerSafeHandle NewServer(CompletionQueueSafeHandle cq, IntPtr args)
{
- // TODO: also grpc_secure_server_create...
return grpcsharp_server_create(cq, args);
}
@@ -83,6 +85,11 @@
return grpcsharp_server_add_http2_port(this, addr);
}
+ public int AddPort(string addr, ServerCredentialsSafeHandle credentials)
+ {
+ return grpcsharp_server_add_secure_http2_port(this, addr, credentials);
+ }
+
public void Start()
{
grpcsharp_server_start(this);
diff --git a/src/csharp/Grpc.Core/Internal/ServerStreamingOutputObserver.cs b/src/csharp/Grpc.Core/Internal/ServerStreamingOutputObserver.cs
index 9873dc9..97b62d0 100644
--- a/src/csharp/Grpc.Core/Internal/ServerStreamingOutputObserver.cs
+++ b/src/csharp/Grpc.Core/Internal/ServerStreamingOutputObserver.cs
@@ -69,4 +69,3 @@
}
}
}
-
diff --git a/src/csharp/Grpc.Core/Internal/Timespec.cs b/src/csharp/Grpc.Core/Internal/Timespec.cs
index e6efd66..94d48c2 100644
--- a/src/csharp/Grpc.Core/Internal/Timespec.cs
+++ b/src/csharp/Grpc.Core/Internal/Timespec.cs
@@ -40,8 +40,8 @@
[StructLayout(LayoutKind.Sequential)]
internal struct Timespec
{
- const int nanosPerSecond = 1000 * 1000 * 1000;
- const int nanosPerTick = 100;
+ const int NanosPerSecond = 1000 * 1000 * 1000;
+ const int NanosPerTick = 100;
[DllImport("grpc_csharp_ext.dll")]
static extern Timespec gprsharp_now();
@@ -99,14 +99,13 @@
public Timespec Add(TimeSpan timeSpan)
{
- long nanos = tv_nsec.ToInt64() + (timeSpan.Ticks % TimeSpan.TicksPerSecond) * nanosPerTick;
- long overflow_sec = (nanos > nanosPerSecond) ? 1 : 0;
+ long nanos = tv_nsec.ToInt64() + (timeSpan.Ticks % TimeSpan.TicksPerSecond) * NanosPerTick;
+ long overflow_sec = (nanos > NanosPerSecond) ? 1 : 0;
Timespec result;
- result.tv_nsec = new IntPtr(nanos % nanosPerSecond);
+ result.tv_nsec = new IntPtr(nanos % NanosPerSecond);
result.tv_sec = new IntPtr(tv_sec.ToInt64() + (timeSpan.Ticks / TimeSpan.TicksPerSecond) + overflow_sec);
return result;
}
}
}
-
diff --git a/src/csharp/Grpc.Core/Marshaller.cs b/src/csharp/Grpc.Core/Marshaller.cs
index 602e0eb..e73e7b7 100644
--- a/src/csharp/Grpc.Core/Marshaller.cs
+++ b/src/csharp/Grpc.Core/Marshaller.cs
@@ -40,8 +40,8 @@
/// </summary>
public struct Marshaller<T>
{
- readonly Func<T,byte[]> serializer;
- readonly Func<byte[],T> deserializer;
+ readonly Func<T, byte[]> serializer;
+ readonly Func<byte[], T> deserializer;
public Marshaller(Func<T, byte[]> serializer, Func<byte[], T> deserializer)
{
@@ -66,9 +66,12 @@
}
}
- public static class Marshallers {
-
- public static Marshaller<T> Create<T>(Func<T,byte[]> serializer, Func<byte[],T> deserializer)
+ /// <summary>
+ /// Utilities for creating marshallers.
+ /// </summary>
+ public static class Marshallers
+ {
+ public static Marshaller<T> Create<T>(Func<T, byte[]> serializer, Func<byte[], T> deserializer)
{
return new Marshaller<T>(serializer, deserializer);
}
@@ -81,7 +84,5 @@
System.Text.Encoding.UTF8.GetString);
}
}
-
}
}
-
diff --git a/src/csharp/Grpc.Core/Method.cs b/src/csharp/Grpc.Core/Method.cs
index c94aa81..4f97eee 100644
--- a/src/csharp/Grpc.Core/Method.cs
+++ b/src/csharp/Grpc.Core/Method.cs
@@ -94,4 +94,3 @@
}
}
}
-
diff --git a/src/csharp/Grpc.Core/OperationFailedException.cs b/src/csharp/Grpc.Core/OperationFailedException.cs
index 34a8c95..9b1c24d 100644
--- a/src/csharp/Grpc.Core/OperationFailedException.cs
+++ b/src/csharp/Grpc.Core/OperationFailedException.cs
@@ -45,4 +45,3 @@
}
}
}
-
diff --git a/src/csharp/Grpc.Core/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Core/Properties/AssemblyInfo.cs
index 37ba1e2..168939c 100644
--- a/src/csharp/Grpc.Core/Properties/AssemblyInfo.cs
+++ b/src/csharp/Grpc.Core/Properties/AssemblyInfo.cs
@@ -1,24 +1,14 @@
using System.Reflection;
using System.Runtime.CompilerServices;
-// Information about this assembly is defined by the following attributes.
-// Change them to the values specific to your project.
-[assembly: AssemblyTitle ("Grpc.Core")]
-[assembly: AssemblyDescription ("")]
-[assembly: AssemblyConfiguration ("")]
-[assembly: AssemblyCompany ("")]
-[assembly: AssemblyProduct ("")]
-[assembly: AssemblyCopyright ("Google Inc. All rights reserved.")]
-[assembly: AssemblyTrademark ("")]
-[assembly: AssemblyCulture ("")]
-// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
-// The form "{Major}.{Minor}.*" will automatically update the build and revision,
-// and "{Major}.{Minor}.{Build}.*" will update just the revision.
-[assembly: AssemblyVersion ("0.1.*")]
-// The following attributes are used to specify the signing key for the assembly,
-// if desired. See the Mono documentation for more information about signing.
-//[assembly: AssemblyDelaySign(false)]
-//[assembly: AssemblyKeyFile("")]
+[assembly: AssemblyTitle("Grpc.Core")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("Google Inc. All rights reserved.")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+[assembly: AssemblyVersion("0.1.*")]
[assembly: InternalsVisibleTo("Grpc.Core.Tests")]
-
diff --git a/src/csharp/Grpc.Core/RpcException.cs b/src/csharp/Grpc.Core/RpcException.cs
index e1cf64c..433d872 100644
--- a/src/csharp/Grpc.Core/RpcException.cs
+++ b/src/csharp/Grpc.Core/RpcException.cs
@@ -35,6 +35,9 @@
namespace Grpc.Core
{
+ /// <summary>
+ /// Thrown when remote procedure call fails.
+ /// </summary>
public class RpcException : Exception
{
private readonly Status status;
@@ -58,4 +61,3 @@
}
}
}
-
diff --git a/src/csharp/Grpc.Core/Server.cs b/src/csharp/Grpc.Core/Server.cs
index 152cc21..2439cdb 100644
--- a/src/csharp/Grpc.Core/Server.cs
+++ b/src/csharp/Grpc.Core/Server.cs
@@ -67,18 +67,29 @@
}
// only call this before Start()
- public void AddServiceDefinition(ServerServiceDefinition serviceDefinition) {
- foreach(var entry in serviceDefinition.CallHandlers)
+ public void AddServiceDefinition(ServerServiceDefinition serviceDefinition)
+ {
+ foreach (var entry in serviceDefinition.CallHandlers)
{
callHandlers.Add(entry.Key, entry.Value);
}
}
// only call before Start()
- public int AddPort(string addr) {
+ public int AddPort(string addr)
+ {
return handle.AddPort(addr);
}
+ // only call before Start()
+ public int AddPort(string addr, ServerCredentials credentials)
+ {
+ using (var nativeCredentials = credentials.ToNativeCredentials())
+ {
+ return handle.AddPort(addr, nativeCredentials);
+ }
+ }
+
public void Start()
{
handle.Start();
@@ -98,7 +109,7 @@
{
var rpcInfo = newRpcQueue.Take();
- //Console.WriteLine("Server received RPC " + rpcInfo.Method);
+ // Console.WriteLine("Server received RPC " + rpcInfo.Method);
IServerCallHandler callHandler;
if (!callHandlers.TryGetValue(rpcInfo.Method, out callHandler))
@@ -107,7 +118,7 @@
}
callHandler.StartCall(rpcInfo.Method, rpcInfo.Call, GetCompletionQueue());
}
- catch(Exception e)
+ catch (Exception e)
{
Console.WriteLine("Exception while handling RPC: " + e);
}
@@ -118,7 +129,8 @@
/// cleans up used resources.
/// </summary>
/// <returns>The async.</returns>
- public async Task ShutdownAsync() {
+ public async Task ShutdownAsync()
+ {
handle.ShutdownAndNotify(serverShutdownHandler);
await shutdownTcs.Task;
handle.Dispose();
@@ -135,11 +147,13 @@
}
}
- public void Kill() {
+ public void Kill()
+ {
handle.Dispose();
}
- private async Task StartHandlingRpcs() {
+ private async Task StartHandlingRpcs()
+ {
while (true)
{
await Task.Factory.StartNew(RunRpc);
@@ -151,22 +165,27 @@
AssertCallOk(handle.RequestCall(GetCompletionQueue(), newServerRpcHandler));
}
- private void HandleNewServerRpc(GRPCOpError error, IntPtr batchContextPtr) {
- try {
+ private void HandleNewServerRpc(GRPCOpError error, IntPtr batchContextPtr)
+ {
+ try
+ {
var ctx = new BatchContextSafeHandleNotOwned(batchContextPtr);
- if (error != GRPCOpError.GRPC_OP_OK) {
+ if (error != GRPCOpError.GRPC_OP_OK)
+ {
// TODO: handle error
}
var rpcInfo = new NewRpcInfo(ctx.GetServerRpcNewCall(), ctx.GetServerRpcNewMethod());
// after server shutdown, the callback returns with null call
- if (!rpcInfo.Call.IsInvalid) {
+ if (!rpcInfo.Call.IsInvalid)
+ {
newRpcQueue.Add(rpcInfo);
}
-
- } catch(Exception e) {
+ }
+ catch (Exception e)
+ {
Console.WriteLine("Caught exception in a native handler: " + e);
}
}
diff --git a/src/csharp/Grpc.Core/ServerCalls.cs b/src/csharp/Grpc.Core/ServerCalls.cs
index bed7779..dcae994 100644
--- a/src/csharp/Grpc.Core/ServerCalls.cs
+++ b/src/csharp/Grpc.Core/ServerCalls.cs
@@ -32,17 +32,18 @@
#endregion
using System;
+using Grpc.Core.Internal;
namespace Grpc.Core
{
// TODO: perhaps add also serverSideStreaming and clientSideStreaming
- public delegate void UnaryRequestServerMethod<TRequest, TResponse> (TRequest request, IObserver<TResponse> responseObserver);
+ public delegate void UnaryRequestServerMethod<TRequest, TResponse>(TRequest request, IObserver<TResponse> responseObserver);
- public delegate IObserver<TRequest> StreamingRequestServerMethod<TRequest, TResponse> (IObserver<TResponse> responseObserver);
+ public delegate IObserver<TRequest> StreamingRequestServerMethod<TRequest, TResponse>(IObserver<TResponse> responseObserver);
- internal static class ServerCalls {
-
+ internal static class ServerCalls
+ {
public static IServerCallHandler UnaryRequestCall<TRequest, TResponse>(Method<TRequest, TResponse> method, UnaryRequestServerMethod<TRequest, TResponse> handler)
{
return new UnaryRequestServerCallHandler<TRequest, TResponse>(method, handler);
@@ -52,7 +53,5 @@
{
return new StreamingRequestServerCallHandler<TRequest, TResponse>(method, handler);
}
-
}
}
-
diff --git a/src/csharp/Grpc.Core/ServerCredentials.cs b/src/csharp/Grpc.Core/ServerCredentials.cs
new file mode 100644
index 0000000..ab7d0b4
--- /dev/null
+++ b/src/csharp/Grpc.Core/ServerCredentials.cs
@@ -0,0 +1,109 @@
+#region Copyright notice and license
+
+// 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.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using Grpc.Core.Internal;
+
+namespace Grpc.Core
+{
+ /// <summary>
+ /// Server side credentials.
+ /// </summary>
+ public abstract class ServerCredentials
+ {
+ /// <summary>
+ /// Creates native object for the credentials.
+ /// </summary>
+ /// <returns>The native credentials.</returns>
+ internal abstract ServerCredentialsSafeHandle ToNativeCredentials();
+ }
+
+ /// <summary>
+ /// Key certificate pair (in PEM encoding).
+ /// </summary>
+ public class KeyCertificatePair
+ {
+ readonly string certChain;
+ readonly string privateKey;
+
+ public KeyCertificatePair(string certChain, string privateKey)
+ {
+ this.certChain = certChain;
+ this.privateKey = privateKey;
+ }
+
+ public string CertChain
+ {
+ get
+ {
+ return certChain;
+ }
+ }
+
+ public string PrivateKey
+ {
+ get
+ {
+ return privateKey;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Server-side SSL credentials.
+ /// </summary>
+ public class SslServerCredentials : ServerCredentials
+ {
+ ImmutableList<KeyCertificatePair> keyCertPairs;
+
+ public SslServerCredentials(ImmutableList<KeyCertificatePair> keyCertPairs)
+ {
+ this.keyCertPairs = keyCertPairs;
+ }
+
+ internal override ServerCredentialsSafeHandle ToNativeCredentials()
+ {
+ int count = keyCertPairs.Count;
+ string[] certChains = new string[count];
+ string[] keys = new string[count];
+ for (int i = 0; i < count; i++)
+ {
+ certChains[i] = keyCertPairs[i].CertChain;
+ keys[i] = keyCertPairs[i].PrivateKey;
+ }
+ return ServerCredentialsSafeHandle.CreateSslCredentials(certChains, keys);
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/ServerServiceDefinition.cs b/src/csharp/Grpc.Core/ServerServiceDefinition.cs
index 231c376..0044154 100644
--- a/src/csharp/Grpc.Core/ServerServiceDefinition.cs
+++ b/src/csharp/Grpc.Core/ServerServiceDefinition.cs
@@ -33,22 +33,26 @@
using System;
using System.Collections.Generic;
+using System.Collections.Immutable;
+using Grpc.Core.Internal;
namespace Grpc.Core
{
+ /// <summary>
+ /// Mapping of method names to server call handlers.
+ /// </summary>
public class ServerServiceDefinition
{
readonly string serviceName;
- // TODO: we would need an immutable dictionary here...
- readonly Dictionary<string, IServerCallHandler> callHandlers;
+ readonly ImmutableDictionary<string, IServerCallHandler> callHandlers;
- private ServerServiceDefinition(string serviceName, Dictionary<string, IServerCallHandler> callHandlers)
+ private ServerServiceDefinition(string serviceName, ImmutableDictionary<string, IServerCallHandler> callHandlers)
{
this.serviceName = serviceName;
- this.callHandlers = new Dictionary<string, IServerCallHandler>(callHandlers);
+ this.callHandlers = callHandlers;
}
- internal Dictionary<string, IServerCallHandler> CallHandlers
+ internal ImmutableDictionary<string, IServerCallHandler> CallHandlers
{
get
{
@@ -56,8 +60,7 @@
}
}
-
- public static Builder CreateBuilder(String serviceName)
+ public static Builder CreateBuilder(string serviceName)
{
return new Builder(serviceName);
}
@@ -65,7 +68,7 @@
public class Builder
{
readonly string serviceName;
- readonly Dictionary<string, IServerCallHandler> callHandlers = new Dictionary<String, IServerCallHandler>();
+ readonly Dictionary<string, IServerCallHandler> callHandlers = new Dictionary<string, IServerCallHandler>();
public Builder(string serviceName)
{
@@ -90,9 +93,8 @@
public ServerServiceDefinition Build()
{
- return new ServerServiceDefinition(serviceName, callHandlers);
+ return new ServerServiceDefinition(serviceName, callHandlers.ToImmutableDictionary());
}
}
}
}
-
diff --git a/src/csharp/Grpc.Core/StatusCode.cs b/src/csharp/Grpc.Core/StatusCode.cs
index 1987e52..a9696fa 100644
--- a/src/csharp/Grpc.Core/StatusCode.cs
+++ b/src/csharp/Grpc.Core/StatusCode.cs
@@ -35,9 +35,9 @@
namespace Grpc.Core
{
- // TODO: element names should changed to comply with C# naming conventions.
/// <summary>
- /// based on grpc_status_code from grpc/status.h
+ /// Result of a remote procedure call.
+ /// Based on grpc_status_code from grpc/status.h
/// </summary>
public enum StatusCode
{
@@ -139,4 +139,3 @@
DataLoss = 15
}
}
-
diff --git a/src/csharp/Grpc.Core/Utils/BenchmarkUtil.cs b/src/csharp/Grpc.Core/Utils/BenchmarkUtil.cs
index 3f0dae8..4180d98 100644
--- a/src/csharp/Grpc.Core/Utils/BenchmarkUtil.cs
+++ b/src/csharp/Grpc.Core/Utils/BenchmarkUtil.cs
@@ -32,10 +32,10 @@
#endregion
using System;
-using System.Threading.Tasks;
-using System.Collections.Generic;
using System.Collections.Concurrent;
+using System.Collections.Generic;
using System.Diagnostics;
+using System.Threading.Tasks;
namespace Grpc.Core.Utils
{
@@ -61,8 +61,7 @@
}
stopwatch.Stop();
Console.WriteLine("Elapsed time: " + stopwatch.ElapsedMilliseconds + "ms");
- Console.WriteLine("Ops per second: " + (int) ((double) benchmarkIterations * 1000 / stopwatch.ElapsedMilliseconds));
+ Console.WriteLine("Ops per second: " + (int)((double)benchmarkIterations * 1000 / stopwatch.ElapsedMilliseconds));
}
}
}
-
diff --git a/src/csharp/Grpc.Core/Utils/ExceptionHelper.cs b/src/csharp/Grpc.Core/Utils/ExceptionHelper.cs
index 18702e1..c4d6bee 100644
--- a/src/csharp/Grpc.Core/Utils/ExceptionHelper.cs
+++ b/src/csharp/Grpc.Core/Utils/ExceptionHelper.cs
@@ -42,7 +42,8 @@
/// Otherwise, rethrows the original aggregate exception.
/// Always throws, the exception return type is here only to make the.
/// </summary>
- public static Exception UnwrapRpcException(AggregateException ae) {
+ public static Exception UnwrapRpcException(AggregateException ae)
+ {
foreach (var e in ae.InnerExceptions)
{
if (e is RpcException)
@@ -54,4 +55,3 @@
}
}
}
-
diff --git a/src/csharp/Grpc.Core/Utils/Preconditions.cs b/src/csharp/Grpc.Core/Utils/Preconditions.cs
index b17ce42..aeb5d21 100644
--- a/src/csharp/Grpc.Core/Utils/Preconditions.cs
+++ b/src/csharp/Grpc.Core/Utils/Preconditions.cs
@@ -32,10 +32,10 @@
#endregion
using System;
-using System.Threading.Tasks;
-using System.Collections.Generic;
using System.Collections.Concurrent;
+using System.Collections.Generic;
using System.Diagnostics;
+using System.Threading.Tasks;
namespace Grpc.Core.Utils
{
@@ -66,7 +66,7 @@
/// <summary>
/// Throws NullReferenceException if reference is null.
/// </summary>
- public static T CheckNotNull<T> (T reference)
+ public static T CheckNotNull<T>(T reference)
{
if (reference == null)
{
@@ -78,7 +78,7 @@
/// <summary>
/// Throws NullReferenceException with given message if reference is null.
/// </summary>
- public static T CheckNotNull<T> (T reference, string errorMessage)
+ public static T CheckNotNull<T>(T reference, string errorMessage)
{
if (reference == null)
{
@@ -110,4 +110,3 @@
}
}
}
-
diff --git a/src/csharp/Grpc.Core/Utils/RecordingObserver.cs b/src/csharp/Grpc.Core/Utils/RecordingObserver.cs
index 99d2725..7b43ab8 100644
--- a/src/csharp/Grpc.Core/Utils/RecordingObserver.cs
+++ b/src/csharp/Grpc.Core/Utils/RecordingObserver.cs
@@ -57,9 +57,9 @@
data.Add(value);
}
- public Task<List<T>> ToList() {
+ public Task<List<T>> ToList()
+ {
return tcs.Task;
}
}
}
-
diff --git a/src/csharp/Grpc.Core/Utils/RecordingQueue.cs b/src/csharp/Grpc.Core/Utils/RecordingQueue.cs
index 63992da..9749168 100644
--- a/src/csharp/Grpc.Core/Utils/RecordingQueue.cs
+++ b/src/csharp/Grpc.Core/Utils/RecordingQueue.cs
@@ -32,9 +32,9 @@
#endregion
using System;
-using System.Threading.Tasks;
-using System.Collections.Generic;
using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Threading.Tasks;
namespace Grpc.Core.Utils
{
@@ -81,4 +81,3 @@
}
}
}
-
diff --git a/src/csharp/Grpc.Core/packages.config b/src/csharp/Grpc.Core/packages.config
new file mode 100644
index 0000000..cf711ac
--- /dev/null
+++ b/src/csharp/Grpc.Core/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="System.Collections.Immutable" version="1.1.34-rc" targetFramework="net45" />
+</packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Examples.MathClient/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Examples.MathClient/Properties/AssemblyInfo.cs
index bdd7189..11fc099 100644
--- a/src/csharp/Grpc.Examples.MathClient/Properties/AssemblyInfo.cs
+++ b/src/csharp/Grpc.Examples.MathClient/Properties/AssemblyInfo.cs
@@ -1,22 +1,12 @@
using System.Reflection;
using System.Runtime.CompilerServices;
-// Information about this assembly is defined by the following attributes.
-// Change them to the values specific to your project.
-[assembly: AssemblyTitle ("Grpc.Examples.MathClient")]
-[assembly: AssemblyDescription ("")]
-[assembly: AssemblyConfiguration ("")]
-[assembly: AssemblyCompany ("")]
-[assembly: AssemblyProduct ("")]
-[assembly: AssemblyCopyright ("Google Inc. All rights reserved.")]
-[assembly: AssemblyTrademark ("")]
-[assembly: AssemblyCulture ("")]
-// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
-// The form "{Major}.{Minor}.*" will automatically update the build and revision,
-// and "{Major}.{Minor}.{Build}.*" will update just the revision.
-[assembly: AssemblyVersion ("0.1.*")]
-// The following attributes are used to specify the signing key for the assembly,
-// if desired. See the Mono documentation for more information about signing.
-//[assembly: AssemblyDelaySign(false)]
-//[assembly: AssemblyKeyFile("")]
-
+[assembly: AssemblyTitle("Grpc.Examples.MathClient")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("Google Inc. All rights reserved.")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+[assembly: AssemblyVersion("0.1.*")]
diff --git a/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs b/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs
index 767340d..c86da65 100644
--- a/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs
+++ b/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs
@@ -105,7 +105,7 @@
var recorder = new RecordingObserver<Num>();
client.Fib(new FibArgs.Builder { Limit = 6 }.Build(), recorder);
- CollectionAssert.AreEqual(new List<long>{1, 1, 2, 3, 5, 8},
+ CollectionAssert.AreEqual(new List<long> { 1, 1, 2, 3, 5, 8 },
recorder.ToList().Result.ConvertAll((n) => n.Num_));
}
@@ -114,7 +114,8 @@
public void Sum()
{
var res = client.Sum();
- foreach (var num in new long[] { 10, 20, 30 }) {
+ foreach (var num in new long[] { 10, 20, 30 })
+ {
res.Inputs.OnNext(Num.CreateBuilder().SetNum_(num).Build());
}
res.Inputs.OnCompleted();
@@ -125,7 +126,8 @@
[Test]
public void DivMany()
{
- List<DivArgs> divArgsList = new List<DivArgs>{
+ List<DivArgs> divArgsList = new List<DivArgs>
+ {
new DivArgs.Builder { Dividend = 10, Divisor = 3 }.Build(),
new DivArgs.Builder { Dividend = 100, Divisor = 21 }.Build(),
new DivArgs.Builder { Dividend = 7, Divisor = 2 }.Build()
@@ -142,9 +144,8 @@
var result = recorder.ToList().Result;
- CollectionAssert.AreEqual(new long[] {3, 4, 3}, result.ConvertAll((divReply) => divReply.Quotient));
- CollectionAssert.AreEqual(new long[] {1, 16, 1}, result.ConvertAll((divReply) => divReply.Remainder));
+ CollectionAssert.AreEqual(new long[] { 3, 4, 3 }, result.ConvertAll((divReply) => divReply.Quotient));
+ CollectionAssert.AreEqual(new long[] { 1, 16, 1 }, result.ConvertAll((divReply) => divReply.Remainder));
}
}
}
-
diff --git a/src/csharp/Grpc.Examples.Tests/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Examples.Tests/Properties/AssemblyInfo.cs
index 44b075a..43c7616 100644
--- a/src/csharp/Grpc.Examples.Tests/Properties/AssemblyInfo.cs
+++ b/src/csharp/Grpc.Examples.Tests/Properties/AssemblyInfo.cs
@@ -1,8 +1,6 @@
using System.Reflection;
using System.Runtime.CompilerServices;
-// Information about this assembly is defined by the following attributes.
-// Change them to the values specific to your project.
[assembly: AssemblyTitle("Grpc.Examples.Tests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
@@ -11,12 +9,4 @@
[assembly: AssemblyCopyright("Google Inc. All rights reserved.")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
-// The form "{Major}.{Minor}.*" will automatically update the build and revision,
-// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("0.1.*")]
-// The following attributes are used to specify the signing key for the assembly,
-// if desired. See the Mono documentation for more information about signing.
-//[assembly: AssemblyDelaySign(false)]
-//[assembly: AssemblyKeyFile("")]
-
diff --git a/src/csharp/Grpc.Examples/MathExamples.cs b/src/csharp/Grpc.Examples/MathExamples.cs
index 134270f..b8bb7ea 100644
--- a/src/csharp/Grpc.Examples/MathExamples.cs
+++ b/src/csharp/Grpc.Examples/MathExamples.cs
@@ -71,7 +71,8 @@
public static void SumExample(MathGrpc.IMathServiceClient stub)
{
List<Num> numbers = new List<Num>
- {new Num.Builder { Num_ = 1 }.Build(),
+ {
+ new Num.Builder { Num_ = 1 }.Build(),
new Num.Builder { Num_ = 2 }.Build(),
new Num.Builder { Num_ = 3 }.Build()
};
@@ -110,24 +111,12 @@
public static void DependendRequestsExample(MathGrpc.IMathServiceClient stub)
{
var numberList = new List<Num>
- { new Num.Builder{ Num_ = 1 }.Build(),
- new Num.Builder{ Num_ = 2 }.Build(), new Num.Builder{ Num_ = 3 }.Build()
+ {
+ new Num.Builder { Num_ = 1 }.Build(),
+ new Num.Builder { Num_ = 2 }.Build(), new Num.Builder { Num_ = 3 }.Build()
};
numberList.ToObservable();
-
- //IObserver<Num> numbers;
- //Task<Num> call = stub.Sum(out numbers);
- //foreach (var num in numberList)
- //{
- // numbers.OnNext(num);
- //}
- //numbers.OnCompleted();
-
- //Num sum = call.Result;
-
- //DivReply result = stub.Div(new DivArgs.Builder { Dividend = sum.Num_, Divisor = numberList.Count }.Build());
}
}
}
-
diff --git a/src/csharp/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs
index f938a24..33a9ca9 100644
--- a/src/csharp/Grpc.Examples/MathGrpc.cs
+++ b/src/csharp/Grpc.Examples/MathGrpc.cs
@@ -45,35 +45,34 @@
/// </summary>
public class MathGrpc
{
- readonly static Marshaller<DivArgs> divArgsMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), DivArgs.ParseFrom);
- readonly static Marshaller<DivReply> divReplyMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), DivReply.ParseFrom);
- readonly static Marshaller<Num> numMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), Num.ParseFrom);
- readonly static Marshaller<FibArgs> fibArgsMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), FibArgs.ParseFrom);
+ static readonly Marshaller<DivArgs> DivArgsMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), DivArgs.ParseFrom);
+ static readonly Marshaller<DivReply> DivReplyMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), DivReply.ParseFrom);
+ static readonly Marshaller<Num> NumMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), Num.ParseFrom);
+ static readonly Marshaller<FibArgs> FibArgsMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), FibArgs.ParseFrom);
- readonly static Method<DivArgs, DivReply> divMethod = new Method<DivArgs, DivReply>(
+ static readonly Method<DivArgs, DivReply> DivMethod = new Method<DivArgs, DivReply>(
MethodType.Unary,
"/math.Math/Div",
- divArgsMarshaller,
- divReplyMarshaller
- );
- readonly static Method<FibArgs, Num> fibMethod = new Method<FibArgs, Num>(
+ DivArgsMarshaller,
+ DivReplyMarshaller);
+
+ static readonly Method<FibArgs, Num> FibMethod = new Method<FibArgs, Num>(
MethodType.ServerStreaming,
"/math.Math/Fib",
- fibArgsMarshaller,
- numMarshaller
- );
- readonly static Method<Num, Num> sumMethod = new Method<Num, Num>(
+ FibArgsMarshaller,
+ NumMarshaller);
+
+ static readonly Method<Num, Num> SumMethod = new Method<Num, Num>(
MethodType.ClientStreaming,
"/math.Math/Sum",
- numMarshaller,
- numMarshaller
- );
- readonly static Method<DivArgs, DivReply> divManyMethod = new Method<DivArgs, DivReply>(
+ NumMarshaller,
+ NumMarshaller);
+
+ static readonly Method<DivArgs, DivReply> DivManyMethod = new Method<DivArgs, DivReply>(
MethodType.DuplexStreaming,
"/math.Math/DivMany",
- divArgsMarshaller,
- divReplyMarshaller
- );
+ DivArgsMarshaller,
+ DivReplyMarshaller);
public interface IMathServiceClient
{
@@ -99,31 +98,31 @@
public DivReply Div(DivArgs request, CancellationToken token = default(CancellationToken))
{
- var call = new Grpc.Core.Call<DivArgs, DivReply>(divMethod, channel);
+ var call = new Grpc.Core.Call<DivArgs, DivReply>(DivMethod, channel);
return Calls.BlockingUnaryCall(call, request, token);
}
public Task<DivReply> DivAsync(DivArgs request, CancellationToken token = default(CancellationToken))
{
- var call = new Grpc.Core.Call<DivArgs, DivReply>(divMethod, channel);
+ var call = new Grpc.Core.Call<DivArgs, DivReply>(DivMethod, channel);
return Calls.AsyncUnaryCall(call, request, token);
}
public void Fib(FibArgs request, IObserver<Num> responseObserver, CancellationToken token = default(CancellationToken))
{
- var call = new Grpc.Core.Call<FibArgs, Num>(fibMethod, channel);
+ var call = new Grpc.Core.Call<FibArgs, Num>(FibMethod, channel);
Calls.AsyncServerStreamingCall(call, request, responseObserver, token);
}
public ClientStreamingAsyncResult<Num, Num> Sum(CancellationToken token = default(CancellationToken))
{
- var call = new Grpc.Core.Call<Num, Num>(sumMethod, channel);
+ var call = new Grpc.Core.Call<Num, Num>(SumMethod, channel);
return Calls.AsyncClientStreamingCall(call, token);
}
public IObserver<DivArgs> DivMany(IObserver<DivReply> responseObserver, CancellationToken token = default(CancellationToken))
{
- var call = new Grpc.Core.Call<DivArgs, DivReply>(divManyMethod, channel);
+ var call = new Grpc.Core.Call<DivArgs, DivReply>(DivManyMethod, channel);
return Calls.DuplexStreamingCall(call, responseObserver, token);
}
}
@@ -143,10 +142,10 @@
public static ServerServiceDefinition BindService(IMathService serviceImpl)
{
return ServerServiceDefinition.CreateBuilder("/math.Math/")
- .AddMethod(divMethod, serviceImpl.Div)
- .AddMethod(fibMethod, serviceImpl.Fib)
- .AddMethod(sumMethod, serviceImpl.Sum)
- .AddMethod(divManyMethod, serviceImpl.DivMany).Build();
+ .AddMethod(DivMethod, serviceImpl.Div)
+ .AddMethod(FibMethod, serviceImpl.Fib)
+ .AddMethod(SumMethod, serviceImpl.Sum)
+ .AddMethod(DivManyMethod, serviceImpl.DivMany).Build();
}
public static IMathServiceClient NewStub(Channel channel)
diff --git a/src/csharp/Grpc.Examples/MathServiceImpl.cs b/src/csharp/Grpc.Examples/MathServiceImpl.cs
index 76a08ce..0b2357e 100644
--- a/src/csharp/Grpc.Examples/MathServiceImpl.cs
+++ b/src/csharp/Grpc.Examples/MathServiceImpl.cs
@@ -73,8 +73,8 @@
public IObserver<Num> Sum(IObserver<Num> responseObserver)
{
var recorder = new RecordingObserver<Num>();
- Task.Factory.StartNew(() => {
-
+ Task.Factory.StartNew(() =>
+ {
List<Num> inputs = recorder.ToList().Result;
long sum = 0;
@@ -104,7 +104,7 @@
static IEnumerable<Num> FibInternal(long n)
{
long a = 1;
- yield return new Num.Builder { Num_=a }.Build();
+ yield return new Num.Builder { Num_ = a }.Build();
long b = 1;
for (long i = 0; i < n - 1; i++)
@@ -112,12 +112,12 @@
long temp = a;
a = b;
b = temp + b;
- yield return new Num.Builder { Num_=a }.Build();
+ yield return new Num.Builder { Num_ = a }.Build();
}
}
- private class DivObserver : IObserver<DivArgs> {
-
+ private class DivObserver : IObserver<DivArgs>
+ {
readonly IObserver<DivReply> responseObserver;
public DivObserver(IObserver<DivReply> responseObserver)
@@ -142,4 +142,3 @@
}
}
}
-
diff --git a/src/csharp/Grpc.Examples/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Examples/Properties/AssemblyInfo.cs
index 7603db7..b55d241 100644
--- a/src/csharp/Grpc.Examples/Properties/AssemblyInfo.cs
+++ b/src/csharp/Grpc.Examples/Properties/AssemblyInfo.cs
@@ -1,22 +1,12 @@
using System.Reflection;
using System.Runtime.CompilerServices;
-// Information about this assembly is defined by the following attributes.
-// Change them to the values specific to your project.
-[assembly: AssemblyTitle ("Grpc.Examples")]
-[assembly: AssemblyDescription ("")]
-[assembly: AssemblyConfiguration ("")]
-[assembly: AssemblyCompany ("")]
-[assembly: AssemblyProduct ("")]
-[assembly: AssemblyCopyright ("Google Inc. All rights reserved.")]
-[assembly: AssemblyTrademark ("")]
-[assembly: AssemblyCulture ("")]
-// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
-// The form "{Major}.{Minor}.*" will automatically update the build and revision,
-// and "{Major}.{Minor}.{Build}.*" will update just the revision.
-[assembly: AssemblyVersion ("0.1.*")]
-// The following attributes are used to specify the signing key for the assembly,
-// if desired. See the Mono documentation for more information about signing.
-//[assembly: AssemblyDelaySign(false)]
-//[assembly: AssemblyKeyFile("")]
-
+[assembly: AssemblyTitle("Grpc.Examples")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("Google Inc. All rights reserved.")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+[assembly: AssemblyVersion("0.1.*")]
diff --git a/src/csharp/Grpc.Examples/Settings.StyleCop b/src/csharp/Grpc.Examples/Settings.StyleCop
new file mode 100644
index 0000000..e9b6e71
--- /dev/null
+++ b/src/csharp/Grpc.Examples/Settings.StyleCop
@@ -0,0 +1,10 @@
+<StyleCopSettings Version="105">
+ <SourceFileList>
+ <SourceFile>Math.cs</SourceFile>
+ <Settings>
+ <GlobalSettings>
+ <BooleanProperty Name="RulesEnabledByDefault">False</BooleanProperty>
+ </GlobalSettings>
+ </Settings>
+ </SourceFileList>
+</StyleCopSettings>
\ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting.Client/Properties/AssemblyInfo.cs b/src/csharp/Grpc.IntegrationTesting.Client/Properties/AssemblyInfo.cs
index d1f9e85..c93dd1e 100644
--- a/src/csharp/Grpc.IntegrationTesting.Client/Properties/AssemblyInfo.cs
+++ b/src/csharp/Grpc.IntegrationTesting.Client/Properties/AssemblyInfo.cs
@@ -1,8 +1,6 @@
using System.Reflection;
using System.Runtime.CompilerServices;
-// Information about this assembly is defined by the following attributes.
-// Change them to the values specific to your project.
[assembly: AssemblyTitle("Grpc.IntegrationTesting.Client")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
@@ -11,12 +9,4 @@
[assembly: AssemblyCopyright("Google Inc. All rights reserved.")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
-// The form "{Major}.{Minor}.*" will automatically update the build and revision,
-// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("0.1.*")]
-// The following attributes are used to specify the signing key for the assembly,
-// if desired. See the Mono documentation for more information about signing.
-//[assembly: AssemblyDelaySign(false)]
-//[assembly: AssemblyKeyFile("")]
-
diff --git a/src/csharp/Grpc.IntegrationTesting.Server/Properties/AssemblyInfo.cs b/src/csharp/Grpc.IntegrationTesting.Server/Properties/AssemblyInfo.cs
index 4ef93f3..f3def1a 100644
--- a/src/csharp/Grpc.IntegrationTesting.Server/Properties/AssemblyInfo.cs
+++ b/src/csharp/Grpc.IntegrationTesting.Server/Properties/AssemblyInfo.cs
@@ -1,8 +1,6 @@
using System.Reflection;
using System.Runtime.CompilerServices;
-// Information about this assembly is defined by the following attributes.
-// Change them to the values specific to your project.
[assembly: AssemblyTitle("Grpc.IntegrationTesting.Server")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
@@ -11,12 +9,4 @@
[assembly: AssemblyCopyright("Google Inc. All rights reserved.")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
-// The form "{Major}.{Minor}.*" will automatically update the build and revision,
-// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("0.1.*")]
-// The following attributes are used to specify the signing key for the assembly,
-// if desired. See the Mono documentation for more information about signing.
-//[assembly: AssemblyDelaySign(false)]
-//[assembly: AssemblyKeyFile("")]
-
diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
index 8f7a17e..cfb2587 100644
--- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
+++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
@@ -39,6 +39,10 @@
<Reference Include="Google.ProtocolBuffers">
<HintPath>..\packages\Google.ProtocolBuffers.2.4.1.521\lib\net40\Google.ProtocolBuffers.dll</HintPath>
</Reference>
+ <Reference Include="System.Collections.Immutable, Version=1.1.34.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\packages\System.Collections.Immutable.1.1.34-rc\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
+ </Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
@@ -49,6 +53,7 @@
<Compile Include="TestServiceImpl.cs" />
<Compile Include="InteropServer.cs" />
<Compile Include="InteropClient.cs" />
+ <Compile Include="TestCredentials.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
@@ -75,8 +80,5 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
- <ItemGroup>
- <Folder Include="proto\" />
- <Folder Include="data\" />
- </ItemGroup>
-</Project>
+ <ItemGroup />
+</Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
index 30301f1..6b92d3c 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
@@ -38,10 +38,10 @@
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Google.ProtocolBuffers;
+using grpc.testing;
using Grpc.Core;
using Grpc.Core.Utils;
using NUnit.Framework;
-using grpc.testing;
namespace Grpc.IntegrationTesting
{
@@ -50,8 +50,8 @@
private class ClientOptions
{
public bool help;
- public string serverHost= "127.0.0.1";
- public string serverHostOverride = "foo.test.google.fr";
+ public string serverHost = "127.0.0.1";
+ public string serverHostOverride = TestCredentials.DefaultHostOverride;
public int? serverPort;
public string testCase = "large_unary";
public bool useTls;
@@ -103,22 +103,13 @@
Credentials credentials = null;
if (options.useTls)
{
- string caPath = "data/ca.pem"; // Default testing CA
- if (!options.useTestCa)
- {
- caPath = Environment.GetEnvironmentVariable("SSL_CERT_FILE");
- if (string.IsNullOrEmpty(caPath))
- {
- throw new ArgumentException("CA path environment variable is not set.");
- }
- }
- credentials = new SslCredentials(File.ReadAllText(caPath));
+ credentials = TestCredentials.CreateTestClientCredentials(options.useTestCa);
}
ChannelArgs channelArgs = null;
if (!string.IsNullOrEmpty(options.serverHostOverride))
{
- channelArgs = ChannelArgs.NewBuilder()
+ channelArgs = ChannelArgs.CreateBuilder()
.AddString(ChannelArgs.SslTargetNameOverrideKey, options.serverHostOverride).Build();
}
@@ -189,7 +180,7 @@
{
Console.WriteLine("running client_streaming");
- var bodySizes = new List<int>{27182, 8, 1828, 45904};
+ var bodySizes = new List<int> { 27182, 8, 1828, 45904 };
var context = client.StreamingInputCall();
foreach (var size in bodySizes)
@@ -208,7 +199,7 @@
{
Console.WriteLine("running server_streaming");
- var bodySizes = new List<int>{31415, 9, 2653, 58979};
+ var bodySizes = new List<int> { 31415, 9, 2653, 58979 };
var request = StreamingOutputCallRequest.CreateBuilder()
.SetResponseType(PayloadType.COMPRESSABLE)
@@ -265,7 +256,6 @@
Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type);
Assert.AreEqual(2653, response.Payload.Body.Length);
-
inputs.OnNext(StreamingOutputCallRequest.CreateBuilder()
.SetResponseType(PayloadType.COMPRESSABLE)
.AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(58979))
@@ -301,17 +291,18 @@
public static void RunBenchmarkEmptyUnary(TestServiceGrpc.ITestServiceClient client)
{
BenchmarkUtil.RunBenchmark(10000, 10000,
- () => { client.EmptyCall(Empty.DefaultInstance);});
+ () => { client.EmptyCall(Empty.DefaultInstance); });
}
- private static Payload CreateZerosPayload(int size) {
+ private static Payload CreateZerosPayload(int size)
+ {
return Payload.CreateBuilder().SetBody(ByteString.CopyFrom(new byte[size])).Build();
}
private static ClientOptions ParseArguments(string[] args)
{
var options = new ClientOptions();
- foreach(string arg in args)
+ foreach (string arg in args)
{
ParseArgument(arg, options);
if (options.help)
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs b/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
index 4bb0b9e..814f631 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
@@ -35,10 +35,10 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
+using grpc.testing;
using Grpc.Core;
using Grpc.Core.Utils;
using NUnit.Framework;
-using grpc.testing;
namespace Grpc.IntegrationTesting
{
@@ -59,9 +59,13 @@
server = new Server();
server.AddServiceDefinition(TestServiceGrpc.BindService(new TestServiceImpl()));
- int port = server.AddPort(host + ":0");
+ int port = server.AddPort(host + ":0", TestCredentials.CreateTestServerCredentials());
server.Start();
- channel = new Channel(host + ":" + port);
+
+ var channelArgs = ChannelArgs.CreateBuilder()
+ .AddString(ChannelArgs.SslTargetNameOverrideKey, TestCredentials.DefaultHostOverride).Build();
+
+ channel = new Channel(host + ":" + port, TestCredentials.CreateTestClientCredentials(true), channelArgs);
client = TestServiceGrpc.NewStub(channel);
}
@@ -113,7 +117,5 @@
// TODO: add cancel_after_begin
// TODO: add cancel_after_first_response
-
}
}
-
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropServer.cs b/src/csharp/Grpc.IntegrationTesting/InteropServer.cs
index a25d3b3..5e58028 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropServer.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropServer.cs
@@ -34,13 +34,14 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.IO;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Google.ProtocolBuffers;
+using grpc.testing;
using Grpc.Core;
using Grpc.Core.Utils;
using NUnit.Framework;
-using grpc.testing;
namespace Grpc.IntegrationTesting
{
@@ -49,7 +50,7 @@
private class ServerOptions
{
public bool help;
- public int? port;
+ public int? port = 8070;
public bool useTls;
}
@@ -93,7 +94,14 @@
server.AddServiceDefinition(TestServiceGrpc.BindService(new TestServiceImpl()));
string addr = "0.0.0.0:" + options.port;
- server.AddPort(addr);
+ if (options.useTls)
+ {
+ server.AddPort(addr, TestCredentials.CreateTestServerCredentials());
+ }
+ else
+ {
+ server.AddPort(addr);
+ }
Console.WriteLine("Running server on " + addr);
server.Start();
@@ -105,7 +113,7 @@
private static ServerOptions ParseArguments(string[] args)
{
var options = new ServerOptions();
- foreach(string arg in args)
+ foreach (string arg in args)
{
ParseArgument(arg, options);
if (options.help)
diff --git a/src/csharp/Grpc.IntegrationTesting/Properties/AssemblyInfo.cs b/src/csharp/Grpc.IntegrationTesting/Properties/AssemblyInfo.cs
index f633c19..f09a448 100644
--- a/src/csharp/Grpc.IntegrationTesting/Properties/AssemblyInfo.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Properties/AssemblyInfo.cs
@@ -1,8 +1,6 @@
using System.Reflection;
using System.Runtime.CompilerServices;
-// Information about this assembly is defined by the following attributes.
-// Change them to the values specific to your project.
[assembly: AssemblyTitle("Grpc.IntegrationTesting")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
@@ -11,12 +9,4 @@
[assembly: AssemblyCopyright("Google Inc. All rights reserved.")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
-// The form "{Major}.{Minor}.*" will automatically update the build and revision,
-// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("0.1.*")]
-// The following attributes are used to specify the signing key for the assembly,
-// if desired. See the Mono documentation for more information about signing.
-//[assembly: AssemblyDelaySign(false)]
-//[assembly: AssemblyKeyFile("")]
-
diff --git a/src/csharp/Grpc.IntegrationTesting/Settings.StyleCop b/src/csharp/Grpc.IntegrationTesting/Settings.StyleCop
new file mode 100644
index 0000000..fb99cd4
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/Settings.StyleCop
@@ -0,0 +1,11 @@
+<StyleCopSettings Version="105">
+ <SourceFileList>
+ <SourceFile>Messages.cs</SourceFile>
+ <SourceFile>Empty.cs</SourceFile>
+ <Settings>
+ <GlobalSettings>
+ <BooleanProperty Name="RulesEnabledByDefault">False</BooleanProperty>
+ </GlobalSettings>
+ </Settings>
+ </SourceFileList>
+</StyleCopSettings>
\ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting/TestCredentials.cs b/src/csharp/Grpc.IntegrationTesting/TestCredentials.cs
new file mode 100644
index 0000000..401c50b
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/TestCredentials.cs
@@ -0,0 +1,84 @@
+#region Copyright notice and license
+
+// 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.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Diagnostics;
+using System.IO;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using Google.ProtocolBuffers;
+using grpc.testing;
+using Grpc.Core;
+using Grpc.Core.Utils;
+using NUnit.Framework;
+
+namespace Grpc.IntegrationTesting
+{
+ /// <summary>
+ /// SSL Credentials for testing.
+ /// </summary>
+ public static class TestCredentials
+ {
+ public const string DefaultHostOverride = "foo.test.google.fr";
+
+ public const string ClientCertAuthorityPath = "data/ca.pem";
+ public const string ClientCertAuthorityEnvName = "SSL_CERT_FILE";
+
+ public const string ServerCertChainPath = "data/server1.pem";
+ public const string ServerPrivateKeyPath = "data/server1.key";
+
+ public static SslCredentials CreateTestClientCredentials(bool useTestCa)
+ {
+ string caPath = ClientCertAuthorityPath;
+ if (!useTestCa)
+ {
+ caPath = Environment.GetEnvironmentVariable(ClientCertAuthorityEnvName);
+ if (string.IsNullOrEmpty(caPath))
+ {
+ throw new ArgumentException("CA path environment variable is not set.");
+ }
+ }
+ return new SslCredentials(File.ReadAllText(caPath));
+ }
+
+ public static SslServerCredentials CreateTestServerCredentials()
+ {
+ var keyCertPair = new KeyCertificatePair(
+ File.ReadAllText(ServerCertChainPath),
+ File.ReadAllText(ServerPrivateKeyPath));
+ return new SslServerCredentials(ImmutableList.Create(keyCertPair));
+ }
+ }
+}
diff --git a/src/csharp/Grpc.IntegrationTesting/TestServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestServiceGrpc.cs
index b71704b..9b0251c 100644
--- a/src/csharp/Grpc.IntegrationTesting/TestServiceGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/TestServiceGrpc.cs
@@ -44,50 +44,49 @@
/// </summary>
public class TestServiceGrpc
{
- readonly static Marshaller<Empty> emptyMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), Empty.ParseFrom);
- readonly static Marshaller<SimpleRequest> simpleRequestMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), SimpleRequest.ParseFrom);
- readonly static Marshaller<SimpleResponse> simpleResponseMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), SimpleResponse.ParseFrom);
- readonly static Marshaller<StreamingOutputCallRequest> streamingOutputCallRequestMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), StreamingOutputCallRequest.ParseFrom);
- readonly static Marshaller<StreamingOutputCallResponse> streamingOutputCallResponseMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), StreamingOutputCallResponse.ParseFrom);
- readonly static Marshaller<StreamingInputCallRequest> streamingInputCallRequestMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), StreamingInputCallRequest.ParseFrom);
- readonly static Marshaller<StreamingInputCallResponse> streamingInputCallResponseMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), StreamingInputCallResponse.ParseFrom);
+ static readonly Marshaller<Empty> EmptyMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), Empty.ParseFrom);
+ static readonly Marshaller<SimpleRequest> SimpleRequestMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), SimpleRequest.ParseFrom);
+ static readonly Marshaller<SimpleResponse> SimpleResponseMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), SimpleResponse.ParseFrom);
+ static readonly Marshaller<StreamingOutputCallRequest> StreamingOutputCallRequestMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), StreamingOutputCallRequest.ParseFrom);
+ static readonly Marshaller<StreamingOutputCallResponse> StreamingOutputCallResponseMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), StreamingOutputCallResponse.ParseFrom);
+ static readonly Marshaller<StreamingInputCallRequest> StreamingInputCallRequestMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), StreamingInputCallRequest.ParseFrom);
+ static readonly Marshaller<StreamingInputCallResponse> StreamingInputCallResponseMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), StreamingInputCallResponse.ParseFrom);
- readonly static Method<Empty, Empty> emptyCallMethod = new Method<Empty, Empty>(
+ static readonly Method<Empty, Empty> EmptyCallMethod = new Method<Empty, Empty>(
MethodType.Unary,
"/grpc.testing.TestService/EmptyCall",
- emptyMarshaller,
- emptyMarshaller
- );
- readonly static Method<SimpleRequest, SimpleResponse> unaryCallMethod = new Method<SimpleRequest, SimpleResponse>(
+ EmptyMarshaller,
+ EmptyMarshaller);
+
+ static readonly Method<SimpleRequest, SimpleResponse> UnaryCallMethod = new Method<SimpleRequest, SimpleResponse>(
MethodType.Unary,
"/grpc.testing.TestService/UnaryCall",
- simpleRequestMarshaller,
- simpleResponseMarshaller
- );
- readonly static Method<StreamingOutputCallRequest, StreamingOutputCallResponse> streamingOutputCallMethod = new Method<StreamingOutputCallRequest, StreamingOutputCallResponse>(
+ SimpleRequestMarshaller,
+ SimpleResponseMarshaller);
+
+ static readonly Method<StreamingOutputCallRequest, StreamingOutputCallResponse> StreamingOutputCallMethod = new Method<StreamingOutputCallRequest, StreamingOutputCallResponse>(
MethodType.ServerStreaming,
"/grpc.testing.TestService/StreamingOutputCall",
- streamingOutputCallRequestMarshaller,
- streamingOutputCallResponseMarshaller
- );
- readonly static Method<StreamingInputCallRequest, StreamingInputCallResponse> streamingInputCallMethod = new Method<StreamingInputCallRequest, StreamingInputCallResponse>(
+ StreamingOutputCallRequestMarshaller,
+ StreamingOutputCallResponseMarshaller);
+
+ static readonly Method<StreamingInputCallRequest, StreamingInputCallResponse> StreamingInputCallMethod = new Method<StreamingInputCallRequest, StreamingInputCallResponse>(
MethodType.ClientStreaming,
"/grpc.testing.TestService/StreamingInputCall",
- streamingInputCallRequestMarshaller,
- streamingInputCallResponseMarshaller
- );
- readonly static Method<StreamingOutputCallRequest, StreamingOutputCallResponse> fullDuplexCallMethod = new Method<StreamingOutputCallRequest, StreamingOutputCallResponse>(
+ StreamingInputCallRequestMarshaller,
+ StreamingInputCallResponseMarshaller);
+
+ static readonly Method<StreamingOutputCallRequest, StreamingOutputCallResponse> FullDuplexCallMethod = new Method<StreamingOutputCallRequest, StreamingOutputCallResponse>(
MethodType.DuplexStreaming,
"/grpc.testing.TestService/FullDuplexCall",
- streamingOutputCallRequestMarshaller,
- streamingOutputCallResponseMarshaller
- );
- readonly static Method<StreamingOutputCallRequest, StreamingOutputCallResponse> halfDuplexCallMethod = new Method<StreamingOutputCallRequest, StreamingOutputCallResponse>(
+ StreamingOutputCallRequestMarshaller,
+ StreamingOutputCallResponseMarshaller);
+
+ static readonly Method<StreamingOutputCallRequest, StreamingOutputCallResponse> HalfDuplexCallMethod = new Method<StreamingOutputCallRequest, StreamingOutputCallResponse>(
MethodType.DuplexStreaming,
"/grpc.testing.TestService/HalfDuplexCall",
- streamingOutputCallRequestMarshaller,
- streamingOutputCallResponseMarshaller
- );
+ StreamingOutputCallRequestMarshaller,
+ StreamingOutputCallResponseMarshaller);
public interface ITestServiceClient
{
@@ -119,49 +118,49 @@
public Empty EmptyCall(Empty request, CancellationToken token = default(CancellationToken))
{
- var call = new Grpc.Core.Call<Empty, Empty>(emptyCallMethod, channel);
+ var call = new Grpc.Core.Call<Empty, Empty>(EmptyCallMethod, channel);
return Calls.BlockingUnaryCall(call, request, token);
}
public Task<Empty> EmptyCallAsync(Empty request, CancellationToken token = default(CancellationToken))
{
- var call = new Grpc.Core.Call<Empty, Empty>(emptyCallMethod, channel);
+ var call = new Grpc.Core.Call<Empty, Empty>(EmptyCallMethod, channel);
return Calls.AsyncUnaryCall(call, request, token);
}
public SimpleResponse UnaryCall(SimpleRequest request, CancellationToken token = default(CancellationToken))
{
- var call = new Grpc.Core.Call<SimpleRequest, SimpleResponse>(unaryCallMethod, channel);
+ var call = new Grpc.Core.Call<SimpleRequest, SimpleResponse>(UnaryCallMethod, channel);
return Calls.BlockingUnaryCall(call, request, token);
}
public Task<SimpleResponse> UnaryCallAsync(SimpleRequest request, CancellationToken token = default(CancellationToken))
{
- var call = new Grpc.Core.Call<SimpleRequest, SimpleResponse>(unaryCallMethod, channel);
+ var call = new Grpc.Core.Call<SimpleRequest, SimpleResponse>(UnaryCallMethod, channel);
return Calls.AsyncUnaryCall(call, request, token);
}
- public void StreamingOutputCall(StreamingOutputCallRequest request, IObserver<StreamingOutputCallResponse> responseObserver, CancellationToken token = default(CancellationToken)) {
- var call = new Grpc.Core.Call<StreamingOutputCallRequest, StreamingOutputCallResponse>(streamingOutputCallMethod, channel);
+ public void StreamingOutputCall(StreamingOutputCallRequest request, IObserver<StreamingOutputCallResponse> responseObserver, CancellationToken token = default(CancellationToken))
+ {
+ var call = new Grpc.Core.Call<StreamingOutputCallRequest, StreamingOutputCallResponse>(StreamingOutputCallMethod, channel);
Calls.AsyncServerStreamingCall(call, request, responseObserver, token);
}
public ClientStreamingAsyncResult<StreamingInputCallRequest, StreamingInputCallResponse> StreamingInputCall(CancellationToken token = default(CancellationToken))
{
- var call = new Grpc.Core.Call<StreamingInputCallRequest, StreamingInputCallResponse>(streamingInputCallMethod, channel);
+ var call = new Grpc.Core.Call<StreamingInputCallRequest, StreamingInputCallResponse>(StreamingInputCallMethod, channel);
return Calls.AsyncClientStreamingCall(call, token);
}
public IObserver<StreamingOutputCallRequest> FullDuplexCall(IObserver<StreamingOutputCallResponse> responseObserver, CancellationToken token = default(CancellationToken))
{
- var call = new Grpc.Core.Call<StreamingOutputCallRequest, StreamingOutputCallResponse>(fullDuplexCallMethod, channel);
+ var call = new Grpc.Core.Call<StreamingOutputCallRequest, StreamingOutputCallResponse>(FullDuplexCallMethod, channel);
return Calls.DuplexStreamingCall(call, responseObserver, token);
}
-
public IObserver<StreamingOutputCallRequest> HalfDuplexCall(IObserver<StreamingOutputCallResponse> responseObserver, CancellationToken token = default(CancellationToken))
{
- var call = new Grpc.Core.Call<StreamingOutputCallRequest, StreamingOutputCallResponse>(halfDuplexCallMethod, channel);
+ var call = new Grpc.Core.Call<StreamingOutputCallRequest, StreamingOutputCallResponse>(HalfDuplexCallMethod, channel);
return Calls.DuplexStreamingCall(call, responseObserver, token);
}
}
@@ -185,12 +184,12 @@
public static ServerServiceDefinition BindService(ITestService serviceImpl)
{
return ServerServiceDefinition.CreateBuilder("/grpc.testing.TestService/")
- .AddMethod(emptyCallMethod, serviceImpl.EmptyCall)
- .AddMethod(unaryCallMethod, serviceImpl.UnaryCall)
- .AddMethod(streamingOutputCallMethod, serviceImpl.StreamingOutputCall)
- .AddMethod(streamingInputCallMethod, serviceImpl.StreamingInputCall)
- .AddMethod(fullDuplexCallMethod, serviceImpl.FullDuplexCall)
- .AddMethod(halfDuplexCallMethod, serviceImpl.HalfDuplexCall)
+ .AddMethod(EmptyCallMethod, serviceImpl.EmptyCall)
+ .AddMethod(UnaryCallMethod, serviceImpl.UnaryCall)
+ .AddMethod(StreamingOutputCallMethod, serviceImpl.StreamingOutputCall)
+ .AddMethod(StreamingInputCallMethod, serviceImpl.StreamingInputCall)
+ .AddMethod(FullDuplexCallMethod, serviceImpl.FullDuplexCall)
+ .AddMethod(HalfDuplexCallMethod, serviceImpl.HalfDuplexCall)
.Build();
}
diff --git a/src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs b/src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs
index 176843b..661b31b 100644
--- a/src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs
+++ b/src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs
@@ -55,14 +55,14 @@
{
var response = SimpleResponse.CreateBuilder()
.SetPayload(CreateZerosPayload(request.ResponseSize)).Build();
- //TODO: check we support ReponseType
+ // TODO: check we support ReponseType
responseObserver.OnNext(response);
responseObserver.OnCompleted();
}
public void StreamingOutputCall(StreamingOutputCallRequest request, IObserver<StreamingOutputCallResponse> responseObserver)
{
- foreach(var responseParam in request.ResponseParametersList)
+ foreach (var responseParam in request.ResponseParametersList)
{
var response = StreamingOutputCallResponse.CreateBuilder()
.SetPayload(CreateZerosPayload(responseParam.Size)).Build();
@@ -74,9 +74,10 @@
public IObserver<StreamingInputCallRequest> StreamingInputCall(IObserver<StreamingInputCallResponse> responseObserver)
{
var recorder = new RecordingObserver<StreamingInputCallRequest>();
- Task.Run(() => {
+ Task.Run(() =>
+ {
int sum = 0;
- foreach(var req in recorder.ToList().Result)
+ foreach (var req in recorder.ToList().Result)
{
sum += req.Payload.Body.Length;
}
@@ -98,8 +99,8 @@
throw new NotImplementedException();
}
- private class FullDuplexObserver : IObserver<StreamingOutputCallRequest> {
-
+ private class FullDuplexObserver : IObserver<StreamingOutputCallRequest>
+ {
readonly IObserver<StreamingOutputCallResponse> responseObserver;
public FullDuplexObserver(IObserver<StreamingOutputCallResponse> responseObserver)
@@ -119,22 +120,18 @@
public void OnNext(StreamingOutputCallRequest value)
{
- // TODO: this is not in order!!!
- //Task.Factory.StartNew(() => {
-
- foreach(var responseParam in value.ResponseParametersList)
- {
- var response = StreamingOutputCallResponse.CreateBuilder()
- .SetPayload(CreateZerosPayload(responseParam.Size)).Build();
- responseObserver.OnNext(response);
- }
- //});
+ foreach (var responseParam in value.ResponseParametersList)
+ {
+ var response = StreamingOutputCallResponse.CreateBuilder()
+ .SetPayload(CreateZerosPayload(responseParam.Size)).Build();
+ responseObserver.OnNext(response);
+ }
}
}
- private static Payload CreateZerosPayload(int size) {
+ private static Payload CreateZerosPayload(int size)
+ {
return Payload.CreateBuilder().SetBody(ByteString.CopyFrom(new byte[size])).Build();
}
}
}
-
diff --git a/src/csharp/Grpc.IntegrationTesting/packages.config b/src/csharp/Grpc.IntegrationTesting/packages.config
index 51c17bc..157c264 100644
--- a/src/csharp/Grpc.IntegrationTesting/packages.config
+++ b/src/csharp/Grpc.IntegrationTesting/packages.config
@@ -2,4 +2,5 @@
<packages>
<package id="Google.ProtocolBuffers" version="2.4.1.521" targetFramework="net45" />
<package id="NUnit" version="2.6.4" targetFramework="net45" />
+ <package id="System.Collections.Immutable" version="1.1.34-rc" targetFramework="net45" />
</packages>
\ No newline at end of file
diff --git a/src/csharp/Settings.StyleCop b/src/csharp/Settings.StyleCop
new file mode 100644
index 0000000..2ecf22f
--- /dev/null
+++ b/src/csharp/Settings.StyleCop
@@ -0,0 +1,509 @@
+<StyleCopSettings Version="105">
+ <Analyzers>
+ <Analyzer AnalyzerId="StyleCop.CSharp.DocumentationRules">
+ <Rules>
+ <Rule Name="ElementsMustBeDocumented">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="PartialElementsMustBeDocumented">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="EnumerationItemsMustBeDocumented">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="DocumentationMustContainValidXml">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="ElementDocumentationMustHaveSummary">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="PartialElementDocumentationMustHaveSummary">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="ElementDocumentationMustHaveSummaryText">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="PartialElementDocumentationMustHaveSummaryText">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="ElementDocumentationMustNotHaveDefaultSummary">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="ElementParametersMustBeDocumented">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="ElementParameterDocumentationMustMatchElementParameters">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="ElementParameterDocumentationMustDeclareParameterName">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="ElementParameterDocumentationMustHaveText">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="ElementReturnValueMustBeDocumented">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="ElementReturnValueDocumentationMustHaveText">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="VoidReturnValueMustNotBeDocumented">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="GenericTypeParametersMustBeDocumented">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="GenericTypeParametersMustBeDocumentedPartialClass">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="GenericTypeParameterDocumentationMustMatchTypeParameters">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="GenericTypeParameterDocumentationMustDeclareParameterName">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="GenericTypeParameterDocumentationMustHaveText">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="PropertySummaryDocumentationMustMatchAccessors">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="PropertySummaryDocumentationMustOmitSetAccessorWithRestrictedAccess">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="ElementDocumentationMustNotBeCopiedAndPasted">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="SingleLineCommentsMustNotUseDocumentationStyleSlashes">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="DocumentationTextMustNotBeEmpty">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="DocumentationTextMustContainWhitespace">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="DocumentationMustMeetCharacterPercentage">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="ConstructorSummaryDocumentationMustBeginWithStandardText">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="DestructorSummaryDocumentationMustBeginWithStandardText">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="DocumentationHeadersMustNotContainBlankLines">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="IncludedDocumentationXPathDoesNotExist">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="IncludeNodeDoesNotContainValidFileAndPath">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="InheritDocMustBeUsedWithInheritingClass">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="ElementDocumentationMustBeSpelledCorrectly">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="FileMustHaveHeader">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="FileHeaderMustShowCopyright">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="FileHeaderMustHaveCopyrightText">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="FileHeaderMustContainFileName">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="FileHeaderFileNameDocumentationMustMatchFileName">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="FileHeaderMustHaveValidCompanyText">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="FileHeaderFileNameDocumentationMustMatchTypeName">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ </Rules>
+ <AnalyzerSettings />
+ </Analyzer>
+ <Analyzer AnalyzerId="StyleCop.CSharp.MaintainabilityRules">
+ <Rules>
+ <Rule Name="AccessModifierMustBeDeclared">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="FieldsMustBePrivate">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="CodeAnalysisSuppressionMustHaveJustification">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="DebugAssertMustProvideMessageText">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="DebugFailMustProvideMessageText">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="FileMayOnlyContainASingleClass">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="StatementMustNotUseUnnecessaryParenthesis">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="ArithmeticExpressionsMustDeclarePrecedence">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="ConditionalExpressionsMustDeclarePrecedence">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="RemoveDelegateParenthesisWhenPossible">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="AttributeConstructorMustNotUseUnnecessaryParenthesis">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="RemoveUnnecessaryCode">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ </Rules>
+ <AnalyzerSettings />
+ </Analyzer>
+ <Analyzer AnalyzerId="StyleCop.CSharp.NamingRules">
+ <Rules>
+ <Rule Name="NonPrivateReadonlyFieldsMustBeginWithUpperCaseLetter">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="FieldNamesMustNotUseHungarianNotation">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="FieldNamesMustBeginWithLowerCaseLetter">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="AccessibleFieldsMustBeginWithUpperCaseLetter">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="VariableNamesMustNotBePrefixed">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="FieldNamesMustNotBeginWithUnderscore">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="FieldNamesMustNotContainUnderscore">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="ElementMustBeginWithUpperCaseLetter">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ </Rules>
+ <AnalyzerSettings />
+ </Analyzer>
+ <Analyzer AnalyzerId="StyleCop.CSharp.OrderingRules">
+ <Rules>
+ <Rule Name="UsingDirectivesMustBePlacedWithinNamespace">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="ElementsMustAppearInTheCorrectOrder">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="ElementsMustBeOrderedByAccess">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="StaticElementsMustAppearBeforeInstanceElements">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="PropertyAccessorsMustFollowOrder">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="EventAccessorsMustFollowOrder">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="UsingAliasDirectivesMustBePlacedAfterOtherUsingDirectives">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="UsingAliasDirectivesMustBeOrderedAlphabeticallyByAliasName">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ </Rules>
+ <AnalyzerSettings />
+ </Analyzer>
+ <Analyzer AnalyzerId="StyleCop.CSharp.ReadabilityRules">
+ <Rules>
+ <Rule Name="DoNotPrefixCallsWithBaseUnlessLocalImplementationExists">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="PrefixLocalCallsWithThis">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="PrefixCallsCorrectly">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="OpeningParenthesisMustBeOnDeclarationLine">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="ClosingParenthesisMustBeOnLineOfLastParameter">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="ClosingParenthesisMustBeOnLineOfOpeningParenthesis">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="CommaMustBeOnSameLineAsPreviousParameter">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="ParameterListMustFollowDeclaration">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="ParameterMustFollowComma">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="SplitParametersMustStartOnLineAfterDeclaration">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="ParametersMustBeOnSameLineOrSeparateLines">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="ParameterMustNotSpanMultipleLines">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="QueryClauseMustFollowPreviousClause">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="QueryClausesMustBeOnSeparateLinesOrAllOnOneLine">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="QueryClauseMustBeginOnNewLineWhenPreviousClauseSpansMultipleLines">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="QueryClausesSpanningMultipleLinesMustBeginOnOwnLine">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="CodeMustNotContainEmptyStatements">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="CodeMustNotContainMultipleStatementsOnOneLine">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="BlockStatementsMustNotContainEmbeddedComments">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="BlockStatementsMustNotContainEmbeddedRegions">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="UseStringEmptyForEmptyStrings">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ </Rules>
+ <AnalyzerSettings />
+ </Analyzer>
+ <Analyzer AnalyzerId="StyleCop.CSharp.LayoutRules">
+ <Rules>
+ <Rule Name="SingleLineCommentsMustNotBeFollowedByBlankLine">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="ClosingCurlyBracketMustBeFollowedByBlankLine">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="ElementDocumentationHeaderMustBePrecededByBlankLine">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="SingleLineCommentMustBePrecededByBlankLine">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ </Rules>
+ <AnalyzerSettings />
+ </Analyzer>
+ </Analyzers>
+</StyleCopSettings>
\ No newline at end of file
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
index e244387..51abb63 100644
--- a/src/csharp/ext/grpc_csharp_ext.c
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -653,6 +653,41 @@
return grpc_secure_channel_create(creds, target, args);
}
+GPR_EXPORT grpc_server_credentials *GPR_CALLTYPE
+grpcsharp_ssl_server_credentials_create(
+ const char *pem_root_certs, const char **key_cert_pair_cert_chain_array,
+ const char **key_cert_pair_private_key_array, size_t num_key_cert_pairs) {
+ size_t i;
+ grpc_server_credentials *creds;
+ grpc_ssl_pem_key_cert_pair *key_cert_pairs =
+ gpr_malloc(sizeof(grpc_ssl_pem_key_cert_pair) * num_key_cert_pairs);
+ memset(key_cert_pairs, 0,
+ sizeof(grpc_ssl_pem_key_cert_pair) * num_key_cert_pairs);
+
+ for (i = 0; i < num_key_cert_pairs; i++) {
+ if (key_cert_pair_cert_chain_array[i] ||
+ key_cert_pair_private_key_array[i]) {
+ key_cert_pairs[i].cert_chain = key_cert_pair_cert_chain_array[i];
+ key_cert_pairs[i].private_key = key_cert_pair_private_key_array[i];
+ }
+ }
+ creds = grpc_ssl_server_credentials_create(pem_root_certs, key_cert_pairs,
+ num_key_cert_pairs);
+ gpr_free(key_cert_pairs);
+ return creds;
+}
+
+GPR_EXPORT void grpcsharp_server_credentials_release(
+ grpc_server_credentials *creds) {
+ grpc_server_credentials_release(creds);
+}
+
+GPR_EXPORT gpr_int32 GPR_CALLTYPE
+grpcsharp_server_add_secure_http2_port(grpc_server *server, const char *addr,
+ grpc_server_credentials *creds) {
+ return grpc_server_add_secure_http2_port(server, addr, creds);
+}
+
/* Logging */
typedef void(GPR_CALLTYPE *grpcsharp_log_func)(const char *file, gpr_int32 line,
diff --git a/src/node/README.md b/src/node/README.md
index 5b3de6b..b1d2310 100644
--- a/src/node/README.md
+++ b/src/node/README.md
@@ -10,9 +10,9 @@
## Installation
-First, clone this repository (NPM package coming soon). Then follow the instructions in the `INSTALL` file in the root of the repository to install the C core library that this package depends on.
-
-Then, simply run `npm install` in or referencing this directory.
+ 1. Clone [the grpc repository](https://github.com/grpc/grpc).
+ 2. Follow the instructions in the `INSTALL` file in the root of that repository to install the C core library that this package depends on.
+ 3. Run `npm install`.
## Tests
diff --git a/src/node/ext/byte_buffer.cc b/src/node/ext/byte_buffer.cc
index 5235c8e..82b54b5 100644
--- a/src/node/ext/byte_buffer.cc
+++ b/src/node/ext/byte_buffer.cc
@@ -65,7 +65,7 @@
Handle<Value> ByteBufferToBuffer(grpc_byte_buffer *buffer) {
NanEscapableScope();
if (buffer == NULL) {
- return NanNull();
+ return NanEscapeScope(NanNull());
}
size_t length = grpc_byte_buffer_length(buffer);
char *result = reinterpret_cast<char *>(calloc(length, sizeof(char)));
diff --git a/src/node/ext/completion_queue_async_worker.cc b/src/node/ext/completion_queue_async_worker.cc
index ca22527..cd7acd1 100644
--- a/src/node/ext/completion_queue_async_worker.cc
+++ b/src/node/ext/completion_queue_async_worker.cc
@@ -80,7 +80,6 @@
NanScope();
NanCallback *callback = GetTagCallback(result->tag);
Handle<Value> argv[] = {NanNull(), GetTagNodeValue(result->tag)};
-
callback->Call(2, argv);
DestroyTag(result->tag);
diff --git a/src/node/package.json b/src/node/package.json
index 20eb21f..29cbab9 100644
--- a/src/node/package.json
+++ b/src/node/package.json
@@ -1,6 +1,6 @@
{
"name": "grpc",
- "version": "0.5.2",
+ "version": "0.5.4",
"author": "Google Inc.",
"description": "gRPC Library for Node",
"homepage": "http://www.grpc.io/",
diff --git a/src/node/test/end_to_end_test.js b/src/node/test/end_to_end_test.js
index 1cc1928..c39364d 100644
--- a/src/node/test/end_to_end_test.js
+++ b/src/node/test/end_to_end_test.js
@@ -235,4 +235,73 @@
});
});
});
+ it('should send multiple messages', function(complete) {
+ var done = multiDone(complete, 2);
+ var requests = ['req1', 'req2'];
+ var deadline = new Date();
+ deadline.setSeconds(deadline.getSeconds() + 3);
+ var status_text = 'xyz';
+ var call = new grpc.Call(channel,
+ 'dummy_method',
+ Infinity);
+ var client_batch = {};
+ client_batch[grpc.opType.SEND_INITIAL_METADATA] = {};
+ client_batch[grpc.opType.SEND_MESSAGE] = new Buffer(requests[0]);
+ client_batch[grpc.opType.RECV_INITIAL_METADATA] = true;
+ call.startBatch(client_batch, function(err, response) {
+ assert.ifError(err);
+ assert.deepEqual(response, {
+ 'send metadata': true,
+ 'send message': true,
+ 'metadata': {}
+ });
+ var req2_batch = {};
+ req2_batch[grpc.opType.SEND_MESSAGE] = new Buffer(requests[1]);
+ req2_batch[grpc.opType.SEND_CLOSE_FROM_CLIENT] = true;
+ req2_batch[grpc.opType.RECV_STATUS_ON_CLIENT] = true;
+ call.startBatch(req2_batch, function(err, resp) {
+ assert.ifError(err);
+ assert.deepEqual(resp, {
+ 'send message': true,
+ 'client close': true,
+ 'status': {
+ 'code': grpc.status.OK,
+ 'details': status_text,
+ 'metadata': {}
+ }
+ });
+ done();
+ });
+ });
+
+ server.requestCall(function(err, call_details) {
+ var new_call = call_details['new call'];
+ assert.notEqual(new_call, null);
+ var server_call = new_call.call;
+ assert.notEqual(server_call, null);
+ var server_batch = {};
+ server_batch[grpc.opType.SEND_INITIAL_METADATA] = {};
+ server_batch[grpc.opType.RECV_MESSAGE] = true;
+ server_call.startBatch(server_batch, function(err, response) {
+ assert.ifError(err);
+ assert(response['send metadata']);
+ assert.strictEqual(response.read.toString(), requests[0]);
+ var end_batch = {};
+ end_batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true;
+ end_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = {
+ 'metadata': {},
+ 'code': grpc.status.OK,
+ 'details': status_text
+ };
+ end_batch[grpc.opType.RECV_MESSAGE] = true;
+ server_call.startBatch(end_batch, function(err, response) {
+ assert.ifError(err);
+ assert(response['send status']);
+ assert(!response.cancelled);
+ assert.strictEqual(response.read.toString(), requests[1]);
+ done();
+ });
+ });
+ });
+ });
});
diff --git a/src/node/test/server_test.js b/src/node/test/server_test.js
new file mode 100644
index 0000000..7cb34fa
--- /dev/null
+++ b/src/node/test/server_test.js
@@ -0,0 +1,94 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+'use strict';
+
+var assert = require('assert');
+var grpc = require('bindings')('grpc.node');
+
+describe('server', function() {
+ describe('constructor', function() {
+ it('should work with no arguments', function() {
+ assert.doesNotThrow(function() {
+ new grpc.Server();
+ });
+ });
+ it('should work with an empty list argument', function() {
+ assert.doesNotThrow(function() {
+ new grpc.Server([]);
+ });
+ });
+ });
+ describe('addHttp2Port', function() {
+ var server;
+ before(function() {
+ server = new grpc.Server();
+ });
+ it('should bind to an unused port', function() {
+ var port;
+ assert.doesNotThrow(function() {
+ port = server.addHttp2Port('0.0.0.0:0');
+ });
+ assert(port > 0);
+ });
+ });
+ describe('addSecureHttp2Port', function() {
+ var server;
+ before(function() {
+ server = new grpc.Server();
+ });
+ it('should bind to an unused port with fake credentials', function() {
+ var port;
+ var creds = grpc.ServerCredentials.createFake();
+ assert.doesNotThrow(function() {
+ port = server.addSecureHttp2Port('0.0.0.0:0', creds);
+ });
+ assert(port > 0);
+ });
+ });
+ describe('listen', function() {
+ var server;
+ before(function() {
+ server = new grpc.Server();
+ server.addHttp2Port('0.0.0.0:0');
+ });
+ after(function() {
+ server.shutdown();
+ });
+ it('should listen without error', function() {
+ assert.doesNotThrow(function() {
+ server.start();
+ });
+ });
+ });
+});
diff --git a/src/python/src/grpc/_adapter/_call.c b/src/python/src/grpc/_adapter/_call.c
index dca2e49..d8806e5 100644
--- a/src/python/src/grpc/_adapter/_call.c
+++ b/src/python/src/grpc/_adapter/_call.c
@@ -45,7 +45,7 @@
const PyObject *channel;
const char *method;
const char *host;
- const double deadline;
+ double deadline;
static char *kwlist[] = {"channel", "method", "host", "deadline", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!ssd:Call", kwlist,
diff --git a/src/python/src/grpc/_adapter/fore.py b/src/python/src/grpc/_adapter/fore.py
index 6ef9e60..339c0ef 100644
--- a/src/python/src/grpc/_adapter/fore.py
+++ b/src/python/src/grpc/_adapter/fore.py
@@ -357,90 +357,3 @@
self._complete(ticket.operation_id, ticket.payload)
else:
self._cancel(ticket.operation_id)
-
-
-class _ActivatedForeLink(ticket_interfaces.ForeLink, activated.Activated):
-
- def __init__(
- self, port, request_deserializers, response_serializers,
- root_certificates, key_chain_pairs):
- self._port = port
- self._request_deserializers = request_deserializers
- self._response_serializers = response_serializers
- self._root_certificates = root_certificates
- self._key_chain_pairs = key_chain_pairs
-
- self._lock = threading.Lock()
- self._pool = None
- self._fore_link = None
- self._rear_link = null.NULL_REAR_LINK
-
- def join_rear_link(self, rear_link):
- with self._lock:
- self._rear_link = null.NULL_REAR_LINK if rear_link is None else rear_link
- if self._fore_link is not None:
- self._fore_link.join_rear_link(rear_link)
-
- def _start(self):
- with self._lock:
- self._pool = logging_pool.pool(_THREAD_POOL_SIZE)
- self._fore_link = ForeLink(
- self._pool, self._request_deserializers, self._response_serializers,
- self._root_certificates, self._key_chain_pairs, port=self._port)
- self._fore_link.join_rear_link(self._rear_link)
- self._fore_link.start()
- return self
-
- def _stop(self):
- with self._lock:
- self._fore_link.stop()
- self._fore_link = None
- self._pool.shutdown(wait=True)
- self._pool = None
-
- def __enter__(self):
- return self._start()
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- self._stop()
- return False
-
- def start(self):
- return self._start()
-
- def stop(self):
- self._stop()
-
- def port(self):
- with self._lock:
- return None if self._fore_link is None else self._fore_link.port()
-
- def accept_back_to_front_ticket(self, ticket):
- with self._lock:
- if self._fore_link is not None:
- self._fore_link.accept_back_to_front_ticket(ticket)
-
-
-def activated_fore_link(
- port, request_deserializers, response_serializers, root_certificates,
- key_chain_pairs):
- """Creates a ForeLink that is also an activated.Activated.
-
- The returned object is only valid for use between calls to its start and stop
- methods (or in context when used as a context manager).
-
- Args:
- port: The port on which to serve RPCs, or None for a port to be
- automatically selected.
- request_deserializers: A dictionary from RPC method names to request object
- deserializer behaviors.
- response_serializers: A dictionary from RPC method names to response object
- serializer behaviors.
- root_certificates: The PEM-encoded client root certificates as a bytestring
- or None.
- key_chain_pairs: A sequence of PEM-encoded private key-certificate chain
- pairs.
- """
- return _ActivatedForeLink(
- port, request_deserializers, response_serializers, root_certificates,
- key_chain_pairs)
diff --git a/src/python/src/grpc/_adapter/rear.py b/src/python/src/grpc/_adapter/rear.py
index fc71bf0..62703fa 100644
--- a/src/python/src/grpc/_adapter/rear.py
+++ b/src/python/src/grpc/_adapter/rear.py
@@ -387,127 +387,3 @@
else:
# NOTE(nathaniel): All other categories are treated as cancellation.
self._cancel(ticket.operation_id)
-
-
-class _ActivatedRearLink(ticket_interfaces.RearLink, activated.Activated):
-
- def __init__(
- self, host, port, request_serializers, response_deserializers, secure,
- root_certificates, private_key, certificate_chain,
- server_host_override=None):
- self._host = host
- self._port = port
- self._request_serializers = request_serializers
- self._response_deserializers = response_deserializers
- self._secure = secure
- self._root_certificates = root_certificates
- self._private_key = private_key
- self._certificate_chain = certificate_chain
- self._server_host_override = server_host_override
-
- self._lock = threading.Lock()
- self._pool = None
- self._rear_link = None
- self._fore_link = null.NULL_FORE_LINK
-
- def join_fore_link(self, fore_link):
- with self._lock:
- self._fore_link = null.NULL_FORE_LINK if fore_link is None else fore_link
- if self._rear_link is not None:
- self._rear_link.join_fore_link(self._fore_link)
-
- def _start(self):
- with self._lock:
- self._pool = logging_pool.pool(_THREAD_POOL_SIZE)
- self._rear_link = RearLink(
- self._host, self._port, self._pool, self._request_serializers,
- self._response_deserializers, self._secure, self._root_certificates,
- self._private_key, self._certificate_chain,
- server_host_override=self._server_host_override)
- self._rear_link.join_fore_link(self._fore_link)
- self._rear_link.start()
- return self
-
- def _stop(self):
- with self._lock:
- self._rear_link.stop()
- self._rear_link = None
- self._pool.shutdown(wait=True)
- self._pool = None
-
- def __enter__(self):
- return self._start()
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- self._stop()
- return False
-
- def start(self):
- return self._start()
-
- def stop(self):
- self._stop()
-
- def accept_front_to_back_ticket(self, ticket):
- with self._lock:
- if self._rear_link is not None:
- self._rear_link.accept_front_to_back_ticket(ticket)
-
-
-# TODO(issue 726): reconcile these two creation functions.
-def activated_rear_link(
- host, port, request_serializers, response_deserializers):
- """Creates a RearLink that is also an activated.Activated.
-
- The returned object is only valid for use between calls to its start and stop
- methods (or in context when used as a context manager).
-
- Args:
- host: The host to which to connect for RPC service.
- port: The port to which to connect for RPC service.
- request_serializers: A dictionary from RPC method name to request object
- serializer behavior.
- response_deserializers: A dictionary from RPC method name to response
- object deserializer behavior.
- secure: A boolean indicating whether or not to use a secure connection.
- root_certificates: The PEM-encoded root certificates or None to ask for
- them to be retrieved from a default location.
- private_key: The PEM-encoded private key to use or None if no private key
- should be used.
- certificate_chain: The PEM-encoded certificate chain to use or None if no
- certificate chain should be used.
- """
- return _ActivatedRearLink(
- host, port, request_serializers, response_deserializers, False, None,
- None, None)
-
-
-
-def secure_activated_rear_link(
- host, port, request_serializers, response_deserializers, root_certificates,
- private_key, certificate_chain, server_host_override=None):
- """Creates a RearLink that is also an activated.Activated.
-
- The returned object is only valid for use between calls to its start and stop
- methods (or in context when used as a context manager).
-
- Args:
- host: The host to which to connect for RPC service.
- port: The port to which to connect for RPC service.
- request_serializers: A dictionary from RPC method name to request object
- serializer behavior.
- response_deserializers: A dictionary from RPC method name to response
- object deserializer behavior.
- root_certificates: The PEM-encoded root certificates or None to ask for
- them to be retrieved from a default location.
- private_key: The PEM-encoded private key to use or None if no private key
- should be used.
- certificate_chain: The PEM-encoded certificate chain to use or None if no
- certificate chain should be used.
- server_host_override: (For testing only) the target name used for SSL
- host name checking.
- """
- return _ActivatedRearLink(
- host, port, request_serializers, response_deserializers, True,
- root_certificates, private_key, certificate_chain,
- server_host_override=server_host_override)
diff --git a/src/python/src/grpc/early_adopter/_reexport.py b/src/python/src/grpc/early_adopter/_reexport.py
index 3fed809..f341602 100644
--- a/src/python/src/grpc/early_adopter/_reexport.py
+++ b/src/python/src/grpc/early_adopter/_reexport.py
@@ -174,45 +174,6 @@
return _ReexportedFuture(self._underlying.future(request_iterator, timeout))
-class _Stub(interfaces.Stub):
-
- def __init__(self, assembly_stub, cardinalities):
- self._assembly_stub = assembly_stub
- self._cardinalities = cardinalities
-
- def __enter__(self):
- self._assembly_stub.__enter__()
- return self
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- self._assembly_stub.__exit__(exc_type, exc_val, exc_tb)
- return False
-
- def __getattr__(self, attr):
- underlying_attr = self._assembly_stub.__getattr__(attr)
- method_cardinality = self._cardinalities.get(attr)
- # TODO(nathaniel): unify this trick with its other occurrence in the code.
- if method_cardinality is None:
- for name, method_cardinality in self._cardinalities.iteritems():
- last_slash_index = name.rfind('/')
- if 0 <= last_slash_index and name[last_slash_index + 1:] == attr:
- break
- else:
- raise AttributeError(attr)
- if method_cardinality is interfaces.Cardinality.UNARY_UNARY:
- return _UnaryUnarySyncAsync(underlying_attr)
- elif method_cardinality is interfaces.Cardinality.UNARY_STREAM:
- return lambda request, timeout: _CancellableIterator(
- underlying_attr(request, timeout))
- elif method_cardinality is interfaces.Cardinality.STREAM_UNARY:
- return _StreamUnarySyncAsync(underlying_attr)
- elif method_cardinality is interfaces.Cardinality.STREAM_STREAM:
- return lambda request_iterator, timeout: _CancellableIterator(
- underlying_attr(request_iterator, timeout))
- else:
- raise AttributeError(attr)
-
-
def common_cardinalities(early_adopter_cardinalities):
common_cardinalities = {}
for name, early_adopter_cardinality in early_adopter_cardinalities.iteritems():
@@ -225,5 +186,13 @@
return _RpcContext(face_rpc_context)
-def stub(face_stub, cardinalities):
- return _Stub(face_stub, cardinalities)
+def cancellable_iterator(face_cancellable_iterator):
+ return _CancellableIterator(face_cancellable_iterator)
+
+
+def unary_unary_sync_async(face_unary_unary_multi_callable):
+ return _UnaryUnarySyncAsync(face_unary_unary_multi_callable)
+
+
+def stream_unary_sync_async(face_stream_unary_multi_callable):
+ return _StreamUnarySyncAsync(face_stream_unary_multi_callable)
diff --git a/src/python/src/grpc/early_adopter/implementations.py b/src/python/src/grpc/early_adopter/implementations.py
index b46f94e..6fe9059 100644
--- a/src/python/src/grpc/early_adopter/implementations.py
+++ b/src/python/src/grpc/early_adopter/implementations.py
@@ -36,7 +36,13 @@
from grpc.early_adopter import _face_utilities
from grpc.early_adopter import _reexport
from grpc.early_adopter import interfaces
-from grpc.framework.assembly import implementations as _assembly_implementations
+from grpc.framework.base import util as _base_utilities
+from grpc.framework.base.packets import implementations as _tickets_implementations
+from grpc.framework.face import implementations as _face_implementations
+from grpc.framework.foundation import logging_pool
+
+_THREAD_POOL_SIZE = 80
+_ONE_DAY_IN_SECONDS = 24 * 60 * 60
class _Server(interfaces.Server):
@@ -50,30 +56,40 @@
else:
self._key_chain_pairs = ((private_key, certificate_chain),)
+ self._pool = None
+ self._back = None
self._fore_link = None
- self._server = None
def _start(self):
with self._lock:
- if self._server is None:
- self._fore_link = _fore.activated_fore_link(
- self._port, self._breakdown.request_deserializers,
- self._breakdown.response_serializers, None, self._key_chain_pairs)
-
- self._server = _assembly_implementations.assemble_service(
- self._breakdown.implementations, self._fore_link)
- self._server.start()
+ if self._pool is None:
+ self._pool = logging_pool.pool(_THREAD_POOL_SIZE)
+ servicer = _face_implementations.servicer(
+ self._pool, self._breakdown.implementations, None)
+ self._back = _tickets_implementations.back(
+ servicer, self._pool, self._pool, self._pool, _ONE_DAY_IN_SECONDS,
+ _ONE_DAY_IN_SECONDS)
+ self._fore_link = _fore.ForeLink(
+ self._pool, self._breakdown.request_deserializers,
+ self._breakdown.response_serializers, None, self._key_chain_pairs,
+ port=self._port)
+ self._back.join_fore_link(self._fore_link)
+ self._fore_link.join_rear_link(self._back)
+ self._fore_link.start()
else:
raise ValueError('Server currently running!')
def _stop(self):
with self._lock:
- if self._server is None:
+ if self._pool is None:
raise ValueError('Server not running!')
else:
- self._server.stop()
- self._server = None
+ self._fore_link.stop()
+ _base_utilities.wait_for_idle(self._back)
+ self._pool.shutdown(wait=True)
self._fore_link = None
+ self._back = None
+ self._pool = None
def __enter__(self):
self._start()
@@ -93,11 +109,101 @@
with self._lock:
return self._fore_link.port()
-def _build_stub(breakdown, activated_rear_link):
- assembly_stub = _assembly_implementations.assemble_dynamic_inline_stub(
- _reexport.common_cardinalities(breakdown.cardinalities),
- activated_rear_link)
- return _reexport.stub(assembly_stub, breakdown.cardinalities)
+
+class _Stub(interfaces.Stub):
+
+ def __init__(
+ self, breakdown, host, port, secure, root_certificates, private_key,
+ certificate_chain, server_host_override=None):
+ self._lock = threading.Lock()
+ self._breakdown = breakdown
+ self._host = host
+ self._port = port
+ self._secure = secure
+ self._root_certificates = root_certificates
+ self._private_key = private_key
+ self._certificate_chain = certificate_chain
+ self._server_host_override = server_host_override
+
+ self._pool = None
+ self._front = None
+ self._rear_link = None
+ self._understub = None
+
+ def __enter__(self):
+ with self._lock:
+ if self._pool is None:
+ self._pool = logging_pool.pool(_THREAD_POOL_SIZE)
+ self._front = _tickets_implementations.front(
+ self._pool, self._pool, self._pool)
+ self._rear_link = _rear.RearLink(
+ self._host, self._port, self._pool,
+ self._breakdown.request_serializers,
+ self._breakdown.response_deserializers, self._secure,
+ self._root_certificates, self._private_key, self._certificate_chain,
+ server_host_override=self._server_host_override)
+ self._front.join_rear_link(self._rear_link)
+ self._rear_link.join_fore_link(self._front)
+ self._rear_link.start()
+ self._understub = _face_implementations.dynamic_stub(
+ _reexport.common_cardinalities(self._breakdown.cardinalities),
+ self._front, self._pool, '')
+ else:
+ raise ValueError('Tried to __enter__ already-__enter__ed Stub!')
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ with self._lock:
+ if self._pool is None:
+ raise ValueError('Tried to __exit__ non-__enter__ed Stub!')
+ else:
+ self._rear_link.stop()
+ _base_utilities.wait_for_idle(self._front)
+ self._pool.shutdown(wait=True)
+ self._rear_link = None
+ self._front = None
+ self._pool = None
+ self._understub = None
+ return False
+
+ def __getattr__(self, attr):
+ with self._lock:
+ if self._pool is None:
+ raise ValueError('Tried to __getattr__ non-__enter__ed Stub!')
+ else:
+ underlying_attr = getattr(self._understub, attr, None)
+ method_cardinality = self._breakdown.cardinalities.get(attr)
+ # TODO(nathaniel): Eliminate this trick.
+ if underlying_attr is None:
+ for method_name, method_cardinality in self._breakdown.cardinalities.iteritems():
+ last_slash_index = method_name.rfind('/')
+ if 0 <= last_slash_index and method_name[last_slash_index + 1:] == attr:
+ underlying_attr = getattr(self._understub, method_name)
+ break
+ else:
+ raise AttributeError(attr)
+ if method_cardinality is interfaces.Cardinality.UNARY_UNARY:
+ return _reexport.unary_unary_sync_async(underlying_attr)
+ elif method_cardinality is interfaces.Cardinality.UNARY_STREAM:
+ return lambda request, timeout: _reexport.cancellable_iterator(
+ underlying_attr(request, timeout))
+ elif method_cardinality is interfaces.Cardinality.STREAM_UNARY:
+ return _reexport.stream_unary_sync_async(underlying_attr)
+ elif method_cardinality is interfaces.Cardinality.STREAM_STREAM:
+ return lambda request_iterator, timeout: (
+ _reexport.cancellable_iterator(underlying_attr(
+ request_iterator, timeout)))
+ else:
+ raise AttributeError(attr)
+
+
+def _build_stub(
+ methods, host, port, secure, root_certificates, private_key,
+ certificate_chain, server_host_override=None):
+ breakdown = _face_utilities.break_down_invocation(methods)
+ return _Stub(
+ breakdown, host, port, secure, root_certificates, private_key,
+ certificate_chain, server_host_override=server_host_override)
def _build_server(methods, port, private_key, certificate_chain):
@@ -118,11 +224,7 @@
Returns:
An interfaces.Stub affording RPC invocation.
"""
- breakdown = _face_utilities.break_down_invocation(methods)
- activated_rear_link = _rear.activated_rear_link(
- host, port, breakdown.request_serializers,
- breakdown.response_deserializers)
- return _build_stub(breakdown, activated_rear_link)
+ return _build_stub(methods, host, port, False, None, None, None)
def secure_stub(
@@ -148,12 +250,9 @@
Returns:
An interfaces.Stub affording RPC invocation.
"""
- breakdown = _face_utilities.break_down_invocation(methods)
- activated_rear_link = _rear.secure_activated_rear_link(
- host, port, breakdown.request_serializers,
- breakdown.response_deserializers, root_certificates, private_key,
+ return _build_stub(
+ methods, host, port, True, root_certificates, private_key,
certificate_chain, server_host_override=server_host_override)
- return _build_stub(breakdown, activated_rear_link)
def insecure_server(methods, port):
diff --git a/src/python/src/grpc/framework/assembly/__init__.py b/src/python/src/grpc/framework/assembly/__init__.py
deleted file mode 100644
index 7086519..0000000
--- a/src/python/src/grpc/framework/assembly/__init__.py
+++ /dev/null
@@ -1,30 +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.
-
-
diff --git a/src/python/src/grpc/framework/assembly/implementations.py b/src/python/src/grpc/framework/assembly/implementations.py
deleted file mode 100644
index 24afcbe..0000000
--- a/src/python/src/grpc/framework/assembly/implementations.py
+++ /dev/null
@@ -1,264 +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.
-
-"""Implementations for assembling RPC framework values."""
-
-import threading
-
-# tickets_interfaces, face_interfaces, and activated are referenced from
-# specification in this module.
-from grpc.framework.assembly import interfaces
-from grpc.framework.base import util as base_utilities
-from grpc.framework.base.packets import implementations as tickets_implementations
-from grpc.framework.base.packets import interfaces as tickets_interfaces # pylint: disable=unused-import
-from grpc.framework.common import cardinality
-from grpc.framework.common import style
-from grpc.framework.face import implementations as face_implementations
-from grpc.framework.face import interfaces as face_interfaces # pylint: disable=unused-import
-from grpc.framework.face import utilities as face_utilities
-from grpc.framework.foundation import activated # pylint: disable=unused-import
-from grpc.framework.foundation import logging_pool
-
-_ONE_DAY_IN_SECONDS = 60 * 60 * 24
-_THREAD_POOL_SIZE = 100
-
-
-class _FaceStub(object):
-
- def __init__(self, rear_link):
- self._rear_link = rear_link
- self._lock = threading.Lock()
- self._pool = None
- self._front = None
- self._under_stub = None
-
- def __enter__(self):
- with self._lock:
- self._pool = logging_pool.pool(_THREAD_POOL_SIZE)
- self._front = tickets_implementations.front(
- self._pool, self._pool, self._pool)
- self._rear_link.start()
- self._rear_link.join_fore_link(self._front)
- self._front.join_rear_link(self._rear_link)
- self._under_stub = face_implementations.generic_stub(self._front, self._pool)
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- with self._lock:
- self._under_stub = None
- self._rear_link.stop()
- base_utilities.wait_for_idle(self._front)
- self._front = None
- self._pool.shutdown(wait=True)
- self._pool = None
- return False
-
- def __getattr__(self, attr):
- with self._lock:
- if self._under_stub is None:
- raise ValueError('Called out of context!')
- else:
- return getattr(self._under_stub, attr)
-
-
-def _behaviors(method_cardinalities, front, pool):
- behaviors = {}
- stub = face_implementations.generic_stub(front, pool)
- for name, method_cardinality in method_cardinalities.iteritems():
- if method_cardinality is cardinality.Cardinality.UNARY_UNARY:
- behaviors[name] = stub.unary_unary_multi_callable(name)
- elif method_cardinality is cardinality.Cardinality.UNARY_STREAM:
- behaviors[name] = lambda request, context, bound_name=name: (
- stub.inline_value_in_stream_out(bound_name, request, context))
- elif method_cardinality is cardinality.Cardinality.STREAM_UNARY:
- behaviors[name] = stub.stream_unary_multi_callable(name)
- elif method_cardinality is cardinality.Cardinality.STREAM_STREAM:
- behaviors[name] = lambda request_iterator, context, bound_name=name: (
- stub.inline_stream_in_stream_out(
- bound_name, request_iterator, context))
- return behaviors
-
-
-class _DynamicInlineStub(object):
-
- def __init__(self, cardinalities, rear_link):
- self._cardinalities = cardinalities
- self._rear_link = rear_link
- self._lock = threading.Lock()
- self._pool = None
- self._front = None
- self._behaviors = None
-
- def __enter__(self):
- with self._lock:
- self._pool = logging_pool.pool(_THREAD_POOL_SIZE)
- self._front = tickets_implementations.front(
- self._pool, self._pool, self._pool)
- self._rear_link.start()
- self._rear_link.join_fore_link(self._front)
- self._front.join_rear_link(self._rear_link)
- self._behaviors = _behaviors(
- self._cardinalities, self._front, self._pool)
- return self
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- with self._lock:
- self._behaviors = None
- self._rear_link.stop()
- base_utilities.wait_for_idle(self._front)
- self._front = None
- self._pool.shutdown(wait=True)
- self._pool = None
- return False
-
- def __getattr__(self, attr):
- with self._lock:
- behavior = self._behaviors.get(attr)
- if behavior is None:
- for name, behavior in self._behaviors.iteritems():
- last_slash_index = name.rfind('/')
- if 0 <= last_slash_index and name[last_slash_index + 1:] == attr:
- return behavior
- else:
- raise AttributeError(
- '_DynamicInlineStub instance has no attribute "%s"!' % attr)
- else:
- return behavior
-
-
-class _ServiceAssembly(interfaces.Server):
-
- def __init__(self, implementations, fore_link):
- self._implementations = implementations
- self._fore_link = fore_link
- self._lock = threading.Lock()
- self._pool = None
- self._back = None
-
- def _start(self):
- with self._lock:
- self._pool = logging_pool.pool(_THREAD_POOL_SIZE)
- servicer = face_implementations.servicer(
- self._pool, self._implementations, None)
- self._back = tickets_implementations.back(
- servicer, self._pool, self._pool, self._pool, _ONE_DAY_IN_SECONDS,
- _ONE_DAY_IN_SECONDS)
- self._fore_link.start()
- self._fore_link.join_rear_link(self._back)
- self._back.join_fore_link(self._fore_link)
-
- def _stop(self):
- with self._lock:
- self._fore_link.stop()
- base_utilities.wait_for_idle(self._back)
- self._back = None
- self._pool.shutdown(wait=True)
- self._pool = None
-
- def __enter__(self):
- self._start()
- return self
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- self._stop()
- return False
-
- def start(self):
- return self._start()
-
- def stop(self):
- self._stop()
-
- def port(self):
- with self._lock:
- return self._fore_link.port()
-
-
-def assemble_face_stub(activated_rear_link):
- """Assembles a face_interfaces.GenericStub.
-
- The returned object is a context manager and may only be used in context to
- invoke RPCs.
-
- Args:
- activated_rear_link: An object that is both a tickets_interfaces.RearLink
- and an activated.Activated. The object should be in the inactive state
- when passed to this method.
-
- Returns:
- A face_interfaces.GenericStub on which, in context, RPCs can be invoked.
- """
- return _FaceStub(activated_rear_link)
-
-
-def assemble_dynamic_inline_stub(cardinalities, activated_rear_link):
- """Assembles a stub with method names for attributes.
-
- The returned object is a context manager and may only be used in context to
- invoke RPCs.
-
- The returned object, when used in context, will respond to attribute access
- as follows: if the requested attribute is the name of a unary-unary RPC
- method, the value of the attribute will be a
- face_interfaces.UnaryUnaryMultiCallable with which to invoke the RPC method.
- If the requested attribute is the name of a unary-stream RPC method, the
- value of the attribute will be a face_interfaces.UnaryStreamMultiCallable
- with which to invoke the RPC method. If the requested attribute is the name
- of a stream-unary RPC method, the value of the attribute will be a
- face_interfaces.StreamUnaryMultiCallable with which to invoke the RPC method.
- If the requested attribute is the name of a stream-stream RPC method, the
- value of the attribute will be a face_interfaces.StreamStreamMultiCallable
- with which to invoke the RPC method.
-
- Args:
- cardinalities: A dictionary from RPC method name to cardinality.Cardinality
- value identifying the cardinality of the named RPC method.
- activated_rear_link: An object that is both a tickets_interfaces.RearLink
- and an activated.Activated. The object should be in the inactive state
- when passed to this method.
-
- Returns:
- A face_interfaces.DynamicStub on which, in context, RPCs can be invoked.
- """
- return _DynamicInlineStub(cardinalities, activated_rear_link)
-
-
-def assemble_service(implementations, activated_fore_link):
- """Assembles the service-side of the RPC Framework stack.
-
- Args:
- implementations: A dictionary from RPC method name to
- face_interfaces.MethodImplementation.
- activated_fore_link: An object that is both a tickets_interfaces.ForeLink
- and an activated.Activated. The object should be in the inactive state
- when passed to this method.
-
- Returns:
- An interfaces.Server encapsulating RPC service.
- """
- return _ServiceAssembly(implementations, activated_fore_link)
diff --git a/src/python/src/grpc/framework/assembly/implementations_test.py b/src/python/src/grpc/framework/assembly/implementations_test.py
deleted file mode 100644
index 5540edf..0000000
--- a/src/python/src/grpc/framework/assembly/implementations_test.py
+++ /dev/null
@@ -1,288 +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.
-
-# TODO(nathaniel): Expand this test coverage.
-
-"""Test of the GRPC-backed ForeLink and RearLink."""
-
-import threading
-import unittest
-
-from grpc.framework.assembly import implementations
-from grpc.framework.base import interfaces
-from grpc.framework.base.packets import packets as tickets
-from grpc.framework.base.packets import interfaces as tickets_interfaces
-from grpc.framework.base.packets import null
-from grpc.framework.face import utilities as face_utilities
-from grpc.framework.foundation import logging_pool
-from grpc._junkdrawer import math_pb2
-
-DIV = 'Div'
-DIV_MANY = 'DivMany'
-FIB = 'Fib'
-SUM = 'Sum'
-
-def _fibbonacci(limit):
- left, right = 0, 1
- for _ in xrange(limit):
- yield left
- left, right = right, left + right
-
-
-def _div(request, unused_context):
- return math_pb2.DivReply(
- quotient=request.dividend / request.divisor,
- remainder=request.dividend % request.divisor)
-
-
-def _div_many(request_iterator, unused_context):
- for request in request_iterator:
- yield math_pb2.DivReply(
- quotient=request.dividend / request.divisor,
- remainder=request.dividend % request.divisor)
-
-
-def _fib(request, unused_context):
- for number in _fibbonacci(request.limit):
- yield math_pb2.Num(num=number)
-
-
-def _sum(request_iterator, unused_context):
- accumulation = 0
- for request in request_iterator:
- accumulation += request.num
- return math_pb2.Num(num=accumulation)
-
-
-_IMPLEMENTATIONS = {
- DIV: face_utilities.unary_unary_inline(_div),
- DIV_MANY: face_utilities.stream_stream_inline(_div_many),
- FIB: face_utilities.unary_stream_inline(_fib),
- SUM: face_utilities.stream_unary_inline(_sum),
-}
-
-_CARDINALITIES = {
- name: implementation.cardinality
- for name, implementation in _IMPLEMENTATIONS.iteritems()}
-
-_TIMEOUT = 10
-
-
-class PipeLink(tickets_interfaces.ForeLink, tickets_interfaces.RearLink):
-
- def __init__(self):
- self._fore_lock = threading.Lock()
- self._fore_link = null.NULL_FORE_LINK
- self._rear_lock = threading.Lock()
- self._rear_link = null.NULL_REAR_LINK
-
- def __enter__(self):
- return self
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- return False
-
- def start(self):
- pass
-
- def stop(self):
- pass
-
- def accept_back_to_front_ticket(self, ticket):
- with self._fore_lock:
- self._fore_link.accept_back_to_front_ticket(ticket)
-
- def join_rear_link(self, rear_link):
- with self._rear_lock:
- self._rear_link = null.NULL_REAR_LINK if rear_link is None else rear_link
-
- def accept_front_to_back_ticket(self, ticket):
- with self._rear_lock:
- self._rear_link.accept_front_to_back_ticket(ticket)
-
- def join_fore_link(self, fore_link):
- with self._fore_lock:
- self._fore_link = null.NULL_FORE_LINK if fore_link is None else fore_link
-
-
-class FaceStubTest(unittest.TestCase):
-
- def testUnaryUnary(self):
- divisor = 7
- dividend = 13
- expected_quotient = 1
- expected_remainder = 6
- pipe = PipeLink()
- service = implementations.assemble_service(_IMPLEMENTATIONS, pipe)
- face_stub = implementations.assemble_face_stub(pipe)
-
- service.start()
- try:
- with face_stub:
- response = face_stub.blocking_value_in_value_out(
- DIV, math_pb2.DivArgs(divisor=divisor, dividend=dividend),
- _TIMEOUT)
- self.assertEqual(expected_quotient, response.quotient)
- self.assertEqual(expected_remainder, response.remainder)
- finally:
- service.stop()
-
- def testUnaryStream(self):
- stream_length = 29
- pipe = PipeLink()
- service = implementations.assemble_service(_IMPLEMENTATIONS, pipe)
- face_stub = implementations.assemble_face_stub(pipe)
-
- with service, face_stub:
- responses = list(
- face_stub.inline_value_in_stream_out(
- FIB, math_pb2.FibArgs(limit=stream_length), _TIMEOUT))
- numbers = [response.num for response in responses]
- for early, middle, later in zip(numbers, numbers[1:], numbers[2:]):
- self.assertEqual(early + middle, later)
-
- def testStreamUnary(self):
- stream_length = 13
- pipe = PipeLink()
- service = implementations.assemble_service(_IMPLEMENTATIONS, pipe)
- face_stub = implementations.assemble_face_stub(pipe)
-
- with service, face_stub:
- multi_callable = face_stub.stream_unary_multi_callable(SUM)
- response_future = multi_callable.future(
- (math_pb2.Num(num=index) for index in range(stream_length)),
- _TIMEOUT)
- self.assertEqual(
- (stream_length * (stream_length - 1)) / 2,
- response_future.result().num)
-
- def testStreamStream(self):
- stream_length = 17
- divisor_offset = 7
- dividend_offset = 17
- pipe = PipeLink()
- service = implementations.assemble_service(_IMPLEMENTATIONS, pipe)
- face_stub = implementations.assemble_face_stub(pipe)
-
- with service, face_stub:
- response_iterator = face_stub.inline_stream_in_stream_out(
- DIV_MANY,
- (math_pb2.DivArgs(
- divisor=divisor_offset + index,
- dividend=dividend_offset + index)
- for index in range(stream_length)),
- _TIMEOUT)
- for index, response in enumerate(response_iterator):
- self.assertEqual(
- (dividend_offset + index) / (divisor_offset + index),
- response.quotient)
- self.assertEqual(
- (dividend_offset + index) % (divisor_offset + index),
- response.remainder)
- self.assertEqual(stream_length, index + 1)
-
-
-class DynamicInlineStubTest(unittest.TestCase):
-
- def testUnaryUnary(self):
- divisor = 59
- dividend = 973
- expected_quotient = dividend / divisor
- expected_remainder = dividend % divisor
- pipe = PipeLink()
- service = implementations.assemble_service(_IMPLEMENTATIONS, pipe)
- dynamic_stub = implementations.assemble_dynamic_inline_stub(
- _CARDINALITIES, pipe)
-
- service.start()
- with dynamic_stub:
- response = dynamic_stub.Div(
- math_pb2.DivArgs(divisor=divisor, dividend=dividend), _TIMEOUT)
- self.assertEqual(expected_quotient, response.quotient)
- self.assertEqual(expected_remainder, response.remainder)
- service.stop()
-
- def testUnaryStream(self):
- stream_length = 43
- pipe = PipeLink()
- service = implementations.assemble_service(_IMPLEMENTATIONS, pipe)
- dynamic_stub = implementations.assemble_dynamic_inline_stub(
- _CARDINALITIES, pipe)
-
- with service, dynamic_stub:
- response_iterator = dynamic_stub.Fib(
- math_pb2.FibArgs(limit=stream_length), _TIMEOUT)
- numbers = tuple(response.num for response in response_iterator)
- for early, middle, later in zip(numbers, numbers[:1], numbers[:2]):
- self.assertEqual(early + middle, later)
- self.assertEqual(stream_length, len(numbers))
-
- def testStreamUnary(self):
- stream_length = 127
- pipe = PipeLink()
- service = implementations.assemble_service(_IMPLEMENTATIONS, pipe)
- dynamic_stub = implementations.assemble_dynamic_inline_stub(
- _CARDINALITIES, pipe)
-
- with service, dynamic_stub:
- response_future = dynamic_stub.Sum.future(
- (math_pb2.Num(num=index) for index in range(stream_length)),
- _TIMEOUT)
- self.assertEqual(
- (stream_length * (stream_length - 1)) / 2,
- response_future.result().num)
-
- def testStreamStream(self):
- stream_length = 179
- divisor_offset = 71
- dividend_offset = 1763
- pipe = PipeLink()
- service = implementations.assemble_service(_IMPLEMENTATIONS, pipe)
- dynamic_stub = implementations.assemble_dynamic_inline_stub(
- _CARDINALITIES, pipe)
-
- with service, dynamic_stub:
- response_iterator = dynamic_stub.DivMany(
- (math_pb2.DivArgs(
- divisor=divisor_offset + index,
- dividend=dividend_offset + index)
- for index in range(stream_length)),
- _TIMEOUT)
- for index, response in enumerate(response_iterator):
- self.assertEqual(
- (dividend_offset + index) / (divisor_offset + index),
- response.quotient)
- self.assertEqual(
- (dividend_offset + index) % (divisor_offset + index),
- response.remainder)
- self.assertEqual(stream_length, index + 1)
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/src/python/src/grpc/framework/assembly/interfaces.py b/src/python/src/grpc/framework/assembly/interfaces.py
deleted file mode 100644
index c469dc4..0000000
--- a/src/python/src/grpc/framework/assembly/interfaces.py
+++ /dev/null
@@ -1,58 +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.
-
-# TODO(nathaniel): The assembly layer only exists to smooth out wrinkles in
-# the face layer. The two should be squashed together as soon as manageable.
-"""Interfaces for assembling RPC Framework values."""
-
-import abc
-
-from grpc.framework.foundation import activated
-
-
-class Server(activated.Activated):
- """The server interface.
-
- Aside from being able to be activated and deactivated, objects of this type
- are able to report the port on which they are servicing RPCs.
- """
- __metaclass__ = abc.ABCMeta
-
- # TODO(issue 726): This is an abstraction violation; not every Server is
- # necessarily serving over a network at all.
- @abc.abstractmethod
- def port(self):
- """Identifies the port on which this Server is servicing RPCs.
-
- This method may only be called while the server is active.
-
- Returns:
- The number of the port on which this Server is servicing RPCs.
- """
- raise NotImplementedError()
diff --git a/src/python/src/grpc/framework/face/implementations.py b/src/python/src/grpc/framework/face/implementations.py
index e8d91a3..4a6de52 100644
--- a/src/python/src/grpc/framework/face/implementations.py
+++ b/src/python/src/grpc/framework/face/implementations.py
@@ -213,14 +213,14 @@
self._pool = pool
def __getattr__(self, attr):
- cardinality = self._cardinalities.get(attr)
- if cardinality is cardinality.Cardinality.UNARY_UNARY:
+ method_cardinality = self._cardinalities.get(attr)
+ if method_cardinality is cardinality.Cardinality.UNARY_UNARY:
return _UnaryUnaryMultiCallable(self._front, attr)
- elif cardinality is cardinality.Cardinality.UNARY_STREAM:
+ elif method_cardinality is cardinality.Cardinality.UNARY_STREAM:
return _UnaryStreamMultiCallable(self._front, attr)
- elif cardinality is cardinality.Cardinality.STREAM_UNARY:
+ elif method_cardinality is cardinality.Cardinality.STREAM_UNARY:
return _StreamUnaryMultiCallable(self._front, attr, self._pool)
- elif cardinality is cardinality.Cardinality.STREAM_STREAM:
+ elif method_cardinality is cardinality.Cardinality.STREAM_STREAM:
return _StreamStreamMultiCallable(self._front, attr, self._pool)
else:
raise AttributeError('_DynamicStub object has no attribute "%s"!' % attr)
@@ -315,4 +315,4 @@
An interfaces.DynamicStub that performs RPCs via the given
base_interfaces.Front.
"""
- return _DynamicStub(cardinalities, front, pool, prefix)
+ return _DynamicStub(cardinalities, front, pool)
diff --git a/src/python/src/setup.py b/src/python/src/setup.py
index cdb82a9..a513a28 100644
--- a/src/python/src/setup.py
+++ b/src/python/src/setup.py
@@ -64,7 +64,6 @@
'grpc._junkdrawer',
'grpc.early_adopter',
'grpc.framework',
- 'grpc.framework.assembly',
'grpc.framework.base',
'grpc.framework.base.packets',
'grpc.framework.common',
diff --git a/templates/Makefile.template b/templates/Makefile.template
index 6573e03..a69c7a7 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -176,9 +176,14 @@
$(error Invalid CONFIG value '$(CONFIG)')
endif
+ifeq ($(SYSTEM),Linux)
+TMPOUT = /dev/null
+else
+TMPOUT = `mktemp /tmp/test-out-XXXXXX`
+endif
# Detect if we can use C++11
-CXX11_CHECK_CMD = $(CXX) -std=c++11 -o /dev/null -c test/build/c++11.cc
+CXX11_CHECK_CMD = $(CXX) -std=c++11 -o $(TMPOUT) -c test/build/c++11.cc
HAS_CXX11 = $(shell $(CXX11_CHECK_CMD) 2> /dev/null && echo true || echo false)
# The HOST compiler settings are used to compile the protoc plugins.
@@ -211,9 +216,25 @@
INCLUDES = . include $(GENDIR)
ifeq ($(SYSTEM),Darwin)
-INCLUDES += /usr/local/ssl/include /opt/local/include
+ifneq ($(wildcard /usr/local/ssl/include),)
+INCLUDES += /usr/local/ssl/include
+endif
+ifneq ($(wildcard /opt/local/include),)
+INCLUDES += /opt/local/include
+endif
+ifneq ($(wildcard /usr/local/include),)
+INCLUDES += /usr/local/include
+endif
LIBS = m z
-LDFLAGS += -L/usr/local/ssl/lib -L/opt/local/lib
+ifneq ($(wildcard /usr/local/ssl/lib),)
+LDFLAGS += -L/usr/local/ssl/lib
+endif
+ifneq ($(wildcard /opt/local/lib),)
+LDFLAGS += -L/opt/local/lib
+endif
+ifneq ($(wildcard /usr/local/lib),)
+LDFLAGS += -L/usr/local/lib
+endif
else
LIBS = rt m z pthread
LDFLAGS += -pthread
@@ -268,10 +289,10 @@
IS_GIT_FOLDER = true
endif
-OPENSSL_ALPN_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o /dev/null test/build/openssl-alpn.c -lssl -lcrypto -ldl $(LDFLAGS)
-ZLIB_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o /dev/null test/build/zlib.c -lz $(LDFLAGS)
-PERFTOOLS_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o /dev/null test/build/perftools.c -lprofiler $(LDFLAGS)
-PROTOBUF_CHECK_CMD = $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o /dev/null test/build/protobuf.cc -lprotobuf $(LDFLAGS)
+OPENSSL_ALPN_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o $(TMPOUT) test/build/openssl-alpn.c -lssl -lcrypto -ldl $(LDFLAGS)
+ZLIB_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o $(TMPOUT) test/build/zlib.c -lz $(LDFLAGS)
+PERFTOOLS_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o $(TMPOUT) test/build/perftools.c -lprofiler $(LDFLAGS)
+PROTOBUF_CHECK_CMD = $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $(TMPOUT) test/build/protobuf.cc -lprotobuf $(LDFLAGS)
PROTOC_CMD = which protoc
PROTOC_CHECK_CMD = protoc --version | grep -q libprotoc.3
@@ -810,10 +831,10 @@
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/${lib.name}.$(SHARED_EXT) $(prefix)/lib/${lib.name}.$(SHARED_EXT)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/lib${lib.name}-imp.a $(prefix)/lib/lib${lib.name}-imp.a
else
+ifneq ($(SYSTEM),Darwin)
$(E) "[INSTALL] Installing lib${lib.name}.$(SHARED_EXT)"
$(Q) $(INSTALL) -d $(prefix)/lib
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/lib${lib.name}.$(SHARED_EXT) $(prefix)/lib/lib${lib.name}.$(SHARED_EXT)
-ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf lib${lib.name}.$(SHARED_EXT) $(prefix)/lib/lib${lib.name}.so
endif
endif
diff --git a/test/core/security/credentials_test.c b/test/core/security/credentials_test.c
index 0784624..d1d1ec1 100644
--- a/test/core/security/credentials_test.c
+++ b/test/core/security/credentials_test.c
@@ -84,6 +84,13 @@
"\"777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent."
"com\", \"type\": \"service_account\" }";
+/* Test refresh token. */
+static const char test_refresh_token_str[] =
+ "{ \"client_id\": \"32555999999.apps.googleusercontent.com\","
+ " \"client_secret\": \"EmssLNjJy1332hD4KFsecret\","
+ " \"refresh_token\": \"1/Blahblasj424jladJDSGNf-u4Sua3HDA2ngjd42\","
+ " \"type\": \"authorized_user\"}";
+
static const char valid_oauth2_json_response[] =
"{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\","
" \"expires_in\":3599, "
@@ -97,10 +104,6 @@
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImY0OTRkN2M1YWU2MGRmOTcyNmM4YW"
"U0MDcyZTViYTdmZDkwODg2YzcifQ";
-static const char expected_service_account_http_body_prefix[] =
- "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&"
- "assertion=";
-
static const char test_service_url[] = "https://foo.com/foo.v1";
static const char other_test_service_url[] = "https://bar.com/bar.v1";
@@ -463,6 +466,87 @@
grpc_httpcli_set_override(NULL, NULL);
}
+static void validate_refresh_token_http_request(
+ const grpc_httpcli_request *request, const char *body, size_t body_size) {
+ /* The content of the assertion is tested extensively in json_token_test. */
+ char *expected_body = NULL;
+ GPR_ASSERT(body != NULL);
+ GPR_ASSERT(body_size != 0);
+ gpr_asprintf(&expected_body, GRPC_REFRESH_TOKEN_POST_BODY_FORMAT_STRING,
+ "32555999999.apps.googleusercontent.com",
+ "EmssLNjJy1332hD4KFsecret",
+ "1/Blahblasj424jladJDSGNf-u4Sua3HDA2ngjd42");
+ GPR_ASSERT(strlen(expected_body) == body_size);
+ GPR_ASSERT(memcmp(expected_body, body, body_size) == 0);
+ gpr_free(expected_body);
+ GPR_ASSERT(request->use_ssl);
+ GPR_ASSERT(strcmp(request->host, GRPC_GOOGLE_OAUTH2_SERVICE_HOST) == 0);
+ GPR_ASSERT(strcmp(request->path, GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH) == 0);
+ GPR_ASSERT(request->hdr_count == 1);
+ GPR_ASSERT(strcmp(request->hdrs[0].key, "Content-Type") == 0);
+ GPR_ASSERT(strcmp(request->hdrs[0].value,
+ "application/x-www-form-urlencoded") == 0);
+}
+
+static int refresh_token_httpcli_post_success(
+ const grpc_httpcli_request *request, const char *body, size_t body_size,
+ gpr_timespec deadline, grpc_httpcli_response_cb on_response,
+ void *user_data) {
+ grpc_httpcli_response response =
+ http_response(200, valid_oauth2_json_response);
+ validate_refresh_token_http_request(request, body, body_size);
+ on_response(user_data, &response);
+ return 1;
+}
+
+static int refresh_token_httpcli_post_failure(
+ const grpc_httpcli_request *request, const char *body, size_t body_size,
+ gpr_timespec deadline, grpc_httpcli_response_cb on_response,
+ void *user_data) {
+ grpc_httpcli_response response = http_response(403, "Not Authorized.");
+ validate_refresh_token_http_request(request, body, body_size);
+ on_response(user_data, &response);
+ return 1;
+}
+
+static void test_refresh_token_creds_success(void) {
+ grpc_credentials *refresh_token_creds =
+ grpc_refresh_token_credentials_create(test_refresh_token_str);
+ GPR_ASSERT(grpc_credentials_has_request_metadata(refresh_token_creds));
+ GPR_ASSERT(grpc_credentials_has_request_metadata_only(refresh_token_creds));
+
+ /* First request: http get should be called. */
+ grpc_httpcli_set_override(httpcli_get_should_not_be_called,
+ refresh_token_httpcli_post_success);
+ grpc_credentials_get_request_metadata(refresh_token_creds, test_service_url,
+ on_oauth2_creds_get_metadata_success,
+ (void *)test_user_data);
+
+ /* Second request: the cached token should be served directly. */
+ grpc_httpcli_set_override(httpcli_get_should_not_be_called,
+ httpcli_post_should_not_be_called);
+ grpc_credentials_get_request_metadata(refresh_token_creds, test_service_url,
+ on_oauth2_creds_get_metadata_success,
+ (void *)test_user_data);
+
+ grpc_credentials_unref(refresh_token_creds);
+ grpc_httpcli_set_override(NULL, NULL);
+}
+
+static void test_refresh_token_creds_failure(void) {
+ grpc_credentials *refresh_token_creds =
+ grpc_refresh_token_credentials_create(test_refresh_token_str);
+ grpc_httpcli_set_override(httpcli_get_should_not_be_called,
+ refresh_token_httpcli_post_failure);
+ GPR_ASSERT(grpc_credentials_has_request_metadata(refresh_token_creds));
+ GPR_ASSERT(grpc_credentials_has_request_metadata_only(refresh_token_creds));
+ grpc_credentials_get_request_metadata(refresh_token_creds, test_service_url,
+ on_oauth2_creds_get_metadata_failure,
+ (void *)test_user_data);
+ grpc_credentials_unref(refresh_token_creds);
+ grpc_httpcli_set_override(NULL, NULL);
+}
+
static void validate_jwt_encode_and_sign_params(
const grpc_auth_json_key *json_key, const char *scope,
gpr_timespec token_lifetime) {
@@ -515,13 +599,13 @@
GPR_ASSERT(body != NULL);
GPR_ASSERT(body_size != 0);
gpr_asprintf(&expected_body, "%s%s",
- expected_service_account_http_body_prefix, test_signed_jwt);
+ GRPC_SERVICE_ACCOUNT_POST_BODY_PREFIX, test_signed_jwt);
GPR_ASSERT(strlen(expected_body) == body_size);
- GPR_ASSERT(!memcmp(expected_body, body, body_size));
+ GPR_ASSERT(memcmp(expected_body, body, body_size) == 0);
gpr_free(expected_body);
GPR_ASSERT(request->use_ssl);
- GPR_ASSERT(strcmp(request->host, "www.googleapis.com") == 0);
- GPR_ASSERT(strcmp(request->path, "/oauth2/v3/token") == 0);
+ GPR_ASSERT(strcmp(request->host, GRPC_GOOGLE_OAUTH2_SERVICE_HOST) == 0);
+ GPR_ASSERT(strcmp(request->path, GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH) == 0);
GPR_ASSERT(request->hdr_count == 1);
GPR_ASSERT(strcmp(request->hdrs[0].key, "Content-Type") == 0);
GPR_ASSERT(strcmp(request->hdrs[0].value,
@@ -711,6 +795,8 @@
test_ssl_oauth2_iam_composite_creds();
test_compute_engine_creds_success();
test_compute_engine_creds_failure();
+ test_refresh_token_creds_success();
+ test_refresh_token_creds_failure();
test_service_account_creds_success();
test_service_account_creds_http_failure();
test_service_account_creds_signing_failure();
diff --git a/test/core/security/fetch_oauth2.c b/test/core/security/fetch_oauth2.c
index 748a598..cc847c8 100644
--- a/test/core/security/fetch_oauth2.c
+++ b/test/core/security/fetch_oauth2.c
@@ -34,7 +34,6 @@
#include <stdio.h>
#include <string.h>
-#include "src/core/security/credentials.h"
#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
#include <grpc/support/alloc.h>
@@ -43,6 +42,9 @@
#include <grpc/support/slice.h>
#include <grpc/support/sync.h>
+#include "src/core/security/credentials.h"
+#include "src/core/support/file.h"
+
typedef struct {
gpr_cv cv;
gpr_mu mu;
@@ -74,50 +76,50 @@
static grpc_credentials *create_service_account_creds(
const char *json_key_file_path, const char *scope) {
- char json_key[8192]; /* Should be plenty. */
- char *current = json_key;
- FILE *json_key_file = fopen(json_key_file_path, "r");
- if (json_key_file == NULL) {
- gpr_log(GPR_ERROR, "Invalid path for json key file: %s.",
- json_key_file_path);
+ int success;
+ gpr_slice json_key = gpr_load_file(json_key_file_path, &success);
+ if (!success) {
+ gpr_log(GPR_ERROR, "Could not read file %s.", json_key_file_path);
exit(1);
}
+ return grpc_service_account_credentials_create(
+ (const char *)GPR_SLICE_START_PTR(json_key), scope,
+ grpc_max_auth_token_lifetime);
+}
- do {
- size_t bytes_read = fread(
- current, 1, sizeof(json_key) - (current - json_key), json_key_file);
- if (bytes_read == 0) {
- if (!feof(json_key_file)) {
- gpr_log(GPR_ERROR, "Error occured while reading %s.",
- json_key_file_path);
- exit(1);
- }
- break;
- }
- current += bytes_read;
- } while (sizeof(json_key) > (size_t)(current - json_key));
-
- if ((current - json_key) == sizeof(json_key)) {
- gpr_log(GPR_ERROR, "Json key file %s exceeds size limit (%d bytes).",
- json_key_file_path, (int)sizeof(json_key));
+static grpc_credentials *create_refresh_token_creds(
+ const char *json_refresh_token_file_path) {
+ int success;
+ gpr_slice refresh_token =
+ gpr_load_file(json_refresh_token_file_path, &success);
+ if (!success) {
+ gpr_log(GPR_ERROR, "Could not read file %s.", json_refresh_token_file_path);
exit(1);
}
- fclose(json_key_file);
-
- return grpc_service_account_credentials_create(json_key, scope,
- grpc_max_auth_token_lifetime);
+ return grpc_refresh_token_credentials_create(
+ (const char *)GPR_SLICE_START_PTR(refresh_token));
}
int main(int argc, char **argv) {
synchronizer sync;
grpc_credentials *creds = NULL;
char *json_key_file_path = NULL;
+ char *json_refresh_token_file_path = NULL;
int use_gce = 0;
char *scope = NULL;
gpr_cmdline *cl = gpr_cmdline_create("fetch_oauth2");
- gpr_cmdline_add_string(cl, "json_key", "File path of the json key.",
+ gpr_cmdline_add_string(cl, "json_key",
+ "File path of the json key. Mutually exclusive with "
+ "--json_refresh_token.",
&json_key_file_path);
- gpr_cmdline_add_string(cl, "scope", "Space delimited permissions.", &scope);
+ gpr_cmdline_add_string(cl, "json_refresh_token",
+ "File path of the json refresh token. Mutually "
+ "exclusive with --json_key.",
+ &json_refresh_token_file_path);
+ gpr_cmdline_add_string(cl, "scope",
+ "Space delimited permissions. Only used for "
+ "--json_key, ignored otherwise.",
+ &scope);
gpr_cmdline_add_flag(
cl, "gce",
"Get a token from the GCE metadata server (only works in GCE).",
@@ -126,6 +128,12 @@
grpc_init();
+ if (json_key_file_path != NULL && json_refresh_token_file_path != NULL) {
+ gpr_log(GPR_ERROR,
+ "--json_key and --json_refresh_token are mutually exclusive.");
+ exit(1);
+ }
+
if (use_gce) {
if (json_key_file_path != NULL || scope != NULL) {
gpr_log(GPR_INFO,
@@ -137,6 +145,15 @@
gpr_log(GPR_ERROR, "Could not create gce credentials.");
exit(1);
}
+ } else if (json_refresh_token_file_path != NULL) {
+ creds = create_refresh_token_creds(json_refresh_token_file_path);
+ if (creds == NULL) {
+ gpr_log(GPR_ERROR,
+ "Could not create refresh token creds. %s does probably not "
+ "contain a valid json refresh token.",
+ json_refresh_token_file_path);
+ exit(1);
+ }
} else {
if (json_key_file_path == NULL) {
gpr_log(GPR_ERROR, "Missing --json_key option.");
diff --git a/test/core/security/json_token_test.c b/test/core/security/json_token_test.c
index ca5b889..b43e042 100644
--- a/test/core/security/json_token_test.c
+++ b/test/core/security/json_token_test.c
@@ -78,6 +78,13 @@
"\"777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent."
"com\", \"type\": \"service_account\" }";
+/* Test refresh token. */
+static const char test_refresh_token_str[] =
+ "{ \"client_id\": \"32555999999.apps.googleusercontent.com\","
+ " \"client_secret\": \"EmssLNjJy1332hD4KFsecret\","
+ " \"refresh_token\": \"1/Blahblasj424jladJDSGNf-u4Sua3HDA2ngjd42\","
+ " \"type\": \"authorized_user\"}";
+
static const char test_scope[] = "myperm1 myperm2";
static const char test_service_url[] = "https://foo.com/foo.v1";
@@ -419,6 +426,64 @@
jwt_creds_check_jwt_claim);
}
+static void test_parse_refresh_token_success(void) {
+ grpc_auth_refresh_token refresh_token =
+ grpc_auth_refresh_token_create_from_string(test_refresh_token_str);
+ GPR_ASSERT(grpc_auth_refresh_token_is_valid(&refresh_token));
+ GPR_ASSERT(refresh_token.type != NULL &&
+ (strcmp(refresh_token.type, "authorized_user") == 0));
+ GPR_ASSERT(refresh_token.client_id != NULL &&
+ (strcmp(refresh_token.client_id,
+ "32555999999.apps.googleusercontent.com") == 0));
+ GPR_ASSERT(
+ refresh_token.client_secret != NULL &&
+ (strcmp(refresh_token.client_secret, "EmssLNjJy1332hD4KFsecret") == 0));
+ GPR_ASSERT(refresh_token.refresh_token != NULL &&
+ (strcmp(refresh_token.refresh_token,
+ "1/Blahblasj424jladJDSGNf-u4Sua3HDA2ngjd42") == 0));
+ grpc_auth_refresh_token_destruct(&refresh_token);
+}
+
+static void test_parse_refresh_token_failure_no_type(void) {
+ const char refresh_token_str[] =
+ "{ \"client_id\": \"32555999999.apps.googleusercontent.com\","
+ " \"client_secret\": \"EmssLNjJy1332hD4KFsecret\","
+ " \"refresh_token\": \"1/Blahblasj424jladJDSGNf-u4Sua3HDA2ngjd42\"}";
+ grpc_auth_refresh_token refresh_token =
+ grpc_auth_refresh_token_create_from_string(refresh_token_str);
+ GPR_ASSERT(!grpc_auth_refresh_token_is_valid(&refresh_token));
+}
+
+static void test_parse_refresh_token_failure_no_client_id(void) {
+ const char refresh_token_str[] =
+ "{ \"client_secret\": \"EmssLNjJy1332hD4KFsecret\","
+ " \"refresh_token\": \"1/Blahblasj424jladJDSGNf-u4Sua3HDA2ngjd42\","
+ " \"type\": \"authorized_user\"}";
+ grpc_auth_refresh_token refresh_token =
+ grpc_auth_refresh_token_create_from_string(refresh_token_str);
+ GPR_ASSERT(!grpc_auth_refresh_token_is_valid(&refresh_token));
+}
+
+static void test_parse_refresh_token_failure_no_client_secret(void) {
+ const char refresh_token_str[] =
+ "{ \"client_id\": \"32555999999.apps.googleusercontent.com\","
+ " \"refresh_token\": \"1/Blahblasj424jladJDSGNf-u4Sua3HDA2ngjd42\","
+ " \"type\": \"authorized_user\"}";
+ grpc_auth_refresh_token refresh_token =
+ grpc_auth_refresh_token_create_from_string(refresh_token_str);
+ GPR_ASSERT(!grpc_auth_refresh_token_is_valid(&refresh_token));
+}
+
+static void test_parse_refresh_token_failure_no_refresh_token(void) {
+ const char refresh_token_str[] =
+ "{ \"client_id\": \"32555999999.apps.googleusercontent.com\","
+ " \"client_secret\": \"EmssLNjJy1332hD4KFsecret\","
+ " \"type\": \"authorized_user\"}";
+ grpc_auth_refresh_token refresh_token =
+ grpc_auth_refresh_token_create_from_string(refresh_token_str);
+ GPR_ASSERT(!grpc_auth_refresh_token_is_valid(&refresh_token));
+}
+
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
test_parse_json_key_success();
@@ -430,5 +495,10 @@
test_parse_json_key_failure_no_private_key();
test_service_account_creds_jwt_encode_and_sign();
test_jwt_creds_jwt_encode_and_sign();
+ test_parse_refresh_token_success();
+ test_parse_refresh_token_failure_no_type();
+ test_parse_refresh_token_failure_no_client_id();
+ test_parse_refresh_token_failure_no_client_secret();
+ test_parse_refresh_token_failure_no_refresh_token();
return 0;
}
diff --git a/test/core/support/slice_buffer_test.c b/test/core/support/slice_buffer_test.c
index 8301795..a482784 100644
--- a/test/core/support/slice_buffer_test.c
+++ b/test/core/support/slice_buffer_test.c
@@ -62,8 +62,13 @@
}
GPR_ASSERT(buf.count > 0);
GPR_ASSERT(buf.length == 50);
- gpr_slice_unref(aaa);
- gpr_slice_unref(bb);
+ for (i = 0; i < 10; i++) {
+ gpr_slice_buffer_pop(&buf);
+ gpr_slice_unref(aaa);
+ gpr_slice_unref(bb);
+ }
+ GPR_ASSERT(buf.count == 0);
+ GPR_ASSERT(buf.length == 0);
gpr_slice_buffer_destroy(&buf);
return 0;
diff --git a/tools/dockerfile/grpc_csharp_mono/Dockerfile b/tools/dockerfile/grpc_csharp_mono/Dockerfile
index 8f86366..703b658 100644
--- a/tools/dockerfile/grpc_csharp_mono/Dockerfile
+++ b/tools/dockerfile/grpc_csharp_mono/Dockerfile
@@ -51,5 +51,5 @@
# Add a service_account directory containing the auth creds file
ADD service_account service_account
-# TODO: add command to run the interop server
-CMD ["/bin/bash", "-l"]
+# Run the C# Interop Server
+CMD ["/bin/bash", "-l", "-c", "cd /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Server/bin/Debug && mono Grpc.IntegrationTesting.Server.exe --use_tls=true --port=8070"]
diff --git a/tools/dockerfile/grpc_python/Dockerfile b/tools/dockerfile/grpc_python/Dockerfile
index 58a3d8c..fd07e9c 100644
--- a/tools/dockerfile/grpc_python/Dockerfile
+++ b/tools/dockerfile/grpc_python/Dockerfile
@@ -53,13 +53,15 @@
&& python2.7 -B -m grpc._adapter._links_test \
&& python2.7 -B -m grpc._adapter._lonely_rear_link_test \
&& python2.7 -B -m grpc._adapter._low_test \
- && python2.7 -B -m grpc.framework.assembly.implementations_test \
+ && python2.7 -B -m grpc.early_adopter.implementations_test \
&& python2.7 -B -m grpc.framework.base.packets.implementations_test \
&& python2.7 -B -m grpc.framework.face.blocking_invocation_inline_service_test \
&& python2.7 -B -m grpc.framework.face.event_invocation_synchronous_event_service_test \
&& python2.7 -B -m grpc.framework.face.future_invocation_asynchronous_event_service_test \
&& python2.7 -B -m grpc.framework.foundation._later_test \
- && python2.7 -B -m grpc.framework.foundation._logging_pool_test
+ && python2.7 -B -m grpc.framework.foundation._logging_pool_test \
+ && python2.7 -B -m interop._insecure_interop_test \
+ && python2.7 -B -m interop._secure_interop_test
# Add a cacerts directory containing the Google root pem file, allowing the interop client to access the production test instance
ADD cacerts cacerts
diff --git a/tools/gce_setup/cloud_prod_runner.sh b/tools/gce_setup/cloud_prod_runner.sh
index 520dfcd..3a9ae51 100755
--- a/tools/gce_setup/cloud_prod_runner.sh
+++ b/tools/gce_setup/cloud_prod_runner.sh
@@ -28,11 +28,14 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+thisfile=$(readlink -ne "${BASH_SOURCE[0]}")
+current_time=$(date "+%Y-%m-%d-%H-%M-%S")
+result_file_name=cloud_prod_result.$current_time.html
+echo $result_file_name
main() {
source grpc_docker.sh
- # temporarily remove ping_pong and cancel_after_first_response while investigating timeout
- test_cases=(large_unary empty_unary client_streaming server_streaming cancel_after_begin)
+ test_cases=(large_unary empty_unary ping_pong client_streaming server_streaming cancel_after_begin cancel_after_first_response)
auth_test_cases=(service_account_creds compute_engine_creds)
clients=(cxx java go ruby node csharp_mono)
for test_case in "${test_cases[@]}"
@@ -41,9 +44,9 @@
do
if grpc_cloud_prod_test $test_case grpc-docker-testclients $client
then
- echo "$test_case $client $server passed" >> /tmp/cloud_prod_result.txt
+ echo " ['$test_case', '$client', 'prod', true]," >> /tmp/cloud_prod_result.txt
else
- echo "$test_case $client $server failed" >> /tmp/cloud_prod_result.txt
+ echo " ['$test_case', '$client', 'prod', false]," >> /tmp/cloud_prod_result.txt
fi
done
done
@@ -53,14 +56,20 @@
do
if grpc_cloud_prod_auth_test $test_case grpc-docker-testclients $client
then
- echo "$test_case $client $server passed" >> /tmp/cloud_prod_result.txt
+ echo " ['$test_case', '$client', 'prod', true]," >> /tmp/cloud_prod_result.txt
else
- echo "$test_case $client $server failed" >> /tmp/cloud_prod_result.txt
+ echo " ['$test_case', '$client', 'prod', false]," >> /tmp/cloud_prod_result.txt
fi
done
done
- gsutil cp /tmp/cloud_prod_result.txt gs://stoked-keyword-656-output/cloud_prod_result.txt
- rm /tmp/cloud_prod_result.txt
+ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
+ cat pre.html /tmp/cloud_prod_result.txt post.html > /tmp/cloud_prod_result.html
+ gsutil cp /tmp/cloud_prod_result.txt gs://stoked-keyword-656-output/cloud_prod_result.txt
+ gsutil cp /tmp/cloud_prod_result.html gs://stoked-keyword-656-output/cloud_prod_result.html
+ gsutil cp /tmp/cloud_prod_result.html gs://stoked-keyword-656-output/result_history/$result_file_name
+ rm /tmp/cloud_prod_result.txt
+ rm /tmp/cloud_prod_result.html
+ fi
}
set -x
diff --git a/tools/gce_setup/grpc_docker.sh b/tools/gce_setup/grpc_docker.sh
index 619eff5..3deef05 100755
--- a/tools/gce_setup/grpc_docker.sh
+++ b/tools/gce_setup/grpc_docker.sh
@@ -731,6 +731,44 @@
done
}
+# Runs a test command on a docker instance
+#
+# The test command is issued via gcloud compute
+#
+# There are 3 possible results:
+# 1. successful return code and finished within 60 seconds
+# 2. failure return code and finished within 60 seconds
+# 3. command does not return within 60 seconds, in which case it will be killed.
+test_runner() {
+ local project_opt="--project $grpc_project"
+ local zone_opt="--zone $grpc_zone"
+ local ssh_cmd="bash -l -c \"$cmd\""
+ echo "will run:"
+ echo " $ssh_cmd"
+ echo "on $host"
+ [[ $dry_run == 1 ]] && return 0 # don't run the command on a dry run
+ gcloud compute $project_opt ssh $zone_opt $host --command "$cmd" &
+ PID=$!
+ echo "pid is $PID"
+ for x in {0..5}
+ do
+ if ps -p $PID
+ then
+ # test command has not returned and 60 seconds timeout has not reached
+ sleep 10
+ else
+ # test command has returned, return the return code from the test command
+ wait $PID
+ local ret=$?
+ echo " test runner return $ret before timeout"
+ return $ret
+ fi
+ done
+ kill $PID
+ echo "test got killed by timeout return as failure"
+ return 1
+}
+
# Runs a test command on a docker instance.
#
# call-seq:
@@ -790,14 +828,7 @@
cmd=$($grpc_gen_test_cmd $flags)
[[ -n $cmd ]] || return 1
- local project_opt="--project $grpc_project"
- local zone_opt="--zone $grpc_zone"
- local ssh_cmd="bash -l -c \"$cmd\""
- echo "will run:"
- echo " $ssh_cmd"
- echo "on $host"
- [[ $dry_run == 1 ]] && return 0 # don't run the command on a dry run
- gcloud compute $project_opt ssh $zone_opt $host --command "$cmd"
+ test_runner
}
# Runs a test command on a docker instance.
@@ -836,14 +867,7 @@
cmd=$($grpc_gen_test_cmd $test_case_flag)
[[ -n $cmd ]] || return 1
- local project_opt="--project $grpc_project"
- local zone_opt="--zone $grpc_zone"
- local ssh_cmd="bash -l -c \"$cmd\""
- echo "will run:"
- echo " $ssh_cmd"
- echo "on $host"
- [[ $dry_run == 1 ]] && return 0 # don't run the command on a dry run
- gcloud compute $project_opt ssh $zone_opt $host --command "$cmd"
+ test_runner
}
# Runs a test command on a docker instance.
@@ -882,14 +906,7 @@
cmd=$($grpc_gen_test_cmd $test_case_flag)
[[ -n $cmd ]] || return 1
- local project_opt="--project $grpc_project"
- local zone_opt="--zone $grpc_zone"
- local ssh_cmd="bash -l -c \"$cmd\""
- echo "will run:"
- echo " $ssh_cmd"
- echo "on $host"
- [[ $dry_run == 1 ]] && return 0 # don't run the command on a dry run
- gcloud compute $project_opt ssh $zone_opt $host --command "$cmd"
+ test_runner
}
# constructs the full dockerized ruby interop test cmd.
@@ -904,6 +921,17 @@
echo $the_cmd
}
+# constructs the full dockerized python interop test cmd.
+#
+# call-seq:
+# flags= .... # generic flags to include the command
+# cmd=$($grpc_gen_test_cmd $flags)
+grpc_interop_gen_python_cmd() {
+ local cmd_prefix="sudo docker run grpc/python bin/bash -l -c"
+ local the_cmd="$cmd_prefix 'python -B -m interop.client --use_test_ca --use_tls $@'"
+ echo $the_cmd
+}
+
# constructs the full dockerized java interop test cmd.
#
# call-seq:
diff --git a/tools/gce_setup/interop_test_runner.sh b/tools/gce_setup/interop_test_runner.sh
index ebc631c..430ad09 100755
--- a/tools/gce_setup/interop_test_runner.sh
+++ b/tools/gce_setup/interop_test_runner.sh
@@ -35,9 +35,8 @@
main() {
source grpc_docker.sh
- # temporarily remove ping_pong and cancel_after_first_response while investigating timeout
- test_cases=(large_unary empty_unary client_streaming server_streaming cancel_after_begin)
- clients=(cxx java go ruby node csharp_mono)
+ test_cases=(large_unary empty_unary ping_pong client_streaming server_streaming cancel_after_begin cancel_after_first_response)
+ clients=(cxx java go ruby node python csharp_mono)
servers=(cxx java go ruby node python)
for test_case in "${test_cases[@]}"
do
diff --git a/tools/run_tests/python_tests.json b/tools/run_tests/python_tests.json
index 69022af..ef483d9 100755
--- a/tools/run_tests/python_tests.json
+++ b/tools/run_tests/python_tests.json
@@ -27,9 +27,6 @@
"module": "grpc.early_adopter.implementations_test"
},
{
- "module": "grpc.framework.assembly.implementations_test"
- },
- {
"module": "grpc.framework.base.packets.implementations_test"
},
{