aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--BUILD2
-rw-r--r--INSTALL1
-rw-r--r--Makefile2
-rw-r--r--build.json1
-rw-r--r--doc/health-checking.md70
-rw-r--r--include/grpc++/auth_context.h32
-rw-r--r--include/grpc++/auth_property_iterator.h77
-rw-r--r--include/grpc/grpc.h39
-rw-r--r--src/core/channel/client_channel.c1
-rw-r--r--src/core/surface/call.c14
-rw-r--r--src/cpp/client/secure_credentials.cc9
-rw-r--r--src/cpp/common/auth_property_iterator.cc2
-rw-r--r--src/csharp/Grpc.Auth/GoogleCredential.cs125
-rw-r--r--src/csharp/Grpc.Auth/Grpc.Auth.csproj27
-rw-r--r--src/csharp/Grpc.Auth/OAuth2Interceptors.cs26
-rw-r--r--src/csharp/Grpc.Auth/app.config4
-rw-r--r--src/csharp/Grpc.Auth/packages.config4
-rw-r--r--src/csharp/Grpc.Core.Tests/ChannelOptionsTest.cs6
-rw-r--r--src/csharp/Grpc.Core.Tests/ChannelTest.cs6
-rw-r--r--src/csharp/Grpc.Core.Tests/ClientServerTest.cs6
-rw-r--r--src/csharp/Grpc.Core.Tests/CompressionTest.cs4
-rw-r--r--src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs31
-rw-r--r--src/csharp/Grpc.Core.Tests/MockServiceHelper.cs12
-rw-r--r--src/csharp/Grpc.Core.Tests/ResponseHeadersTest.cs4
-rw-r--r--src/csharp/Grpc.Core/CallInvocationDetails.cs72
-rw-r--r--src/csharp/Grpc.Core/CallOptions.cs86
-rw-r--r--src/csharp/Grpc.Core/Calls.cs46
-rw-r--r--src/csharp/Grpc.Core/Channel.cs24
-rw-r--r--src/csharp/Grpc.Core/ChannelOptions.cs6
-rw-r--r--src/csharp/Grpc.Core/ClientBase.cs29
-rw-r--r--src/csharp/Grpc.Core/ContextPropagationToken.cs58
-rw-r--r--src/csharp/Grpc.Core/Grpc.Core.csproj2
-rw-r--r--src/csharp/Grpc.Core/GrpcEnvironment.cs20
-rw-r--r--src/csharp/Grpc.Core/IAsyncStreamReader.cs2
-rw-r--r--src/csharp/Grpc.Core/Internal/AsyncCall.cs19
-rw-r--r--src/csharp/Grpc.Core/Internal/AsyncCallBase.cs4
-rw-r--r--src/csharp/Grpc.Core/Internal/Timespec.cs2
-rw-r--r--src/csharp/Grpc.Core/KeyCertificatePair.cs4
-rw-r--r--src/csharp/Grpc.Core/Logging/ConsoleLogger.cs13
-rw-r--r--src/csharp/Grpc.Core/Logging/ILogger.cs6
-rw-r--r--src/csharp/Grpc.Core/Marshaller.cs23
-rw-r--r--src/csharp/Grpc.Core/Metadata.cs8
-rw-r--r--src/csharp/Grpc.Core/Method.cs60
-rw-r--r--src/csharp/Grpc.Core/OperationFailedException.cs47
-rw-r--r--src/csharp/Grpc.Core/RpcException.cs14
-rw-r--r--src/csharp/Grpc.Core/Server.cs2
-rw-r--r--src/csharp/Grpc.Core/ServerCredentials.cs2
-rw-r--r--src/csharp/Grpc.Core/ServerMethods.cs4
-rw-r--r--src/csharp/Grpc.Core/ServerPort.cs4
-rw-r--r--src/csharp/Grpc.Core/ServerServiceDefinition.cs8
-rw-r--r--src/csharp/Grpc.Core/Status.cs13
-rw-r--r--src/csharp/Grpc.Core/StatusCode.cs156
-rw-r--r--src/csharp/Grpc.Core/Utils/AsyncStreamExtensions.cs9
-rw-r--r--src/csharp/Grpc.Core/Utils/BenchmarkUtil.cs3
-rw-r--r--src/csharp/Grpc.Core/Utils/ExceptionHelper.cs57
-rw-r--r--src/csharp/Grpc.Core/Utils/Preconditions.cs25
-rw-r--r--src/csharp/Grpc.Core/Version.cs36
-rw-r--r--src/csharp/Grpc.Core/VersionInfo.cs37
-rw-r--r--src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs10
-rw-r--r--src/csharp/Grpc.Examples/MathExamples.cs10
-rw-r--r--src/csharp/Grpc.Examples/MathServiceImpl.cs7
-rw-r--r--src/csharp/Grpc.HealthCheck.Tests/HealthServiceImplTest.cs8
-rw-r--r--src/csharp/Grpc.IntegrationTesting.Client/app.config4
-rw-r--r--src/csharp/Grpc.IntegrationTesting.Server/app.config4
-rw-r--r--src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj38
-rw-r--r--src/csharp/Grpc.IntegrationTesting/InteropClient.cs86
-rw-r--r--src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs4
-rw-r--r--src/csharp/Grpc.IntegrationTesting/app.config4
-rw-r--r--src/csharp/Grpc.IntegrationTesting/packages.config4
-rw-r--r--src/csharp/doc/README.md2
-rw-r--r--src/csharp/doc/grpc_csharp_public.shfbproj70
-rw-r--r--src/node/binding.gyp3
-rw-r--r--src/node/examples/perf_test.js2
-rw-r--r--src/node/ext/call.cc19
-rw-r--r--src/node/ext/channel.cc25
-rw-r--r--src/node/ext/channel.h6
-rw-r--r--src/node/interop/interop_client.js27
-rw-r--r--src/node/src/client.js59
-rw-r--r--src/node/test/call_test.js5
-rw-r--r--src/node/test/end_to_end_test.js8
-rw-r--r--src/python/grpcio/grpc/_adapter/_c/module.c6
-rw-r--r--src/python/grpcio/grpc/_adapter/_c/types/server.c2
-rw-r--r--src/python/grpcio/grpc/_adapter/_low.py4
-rw-r--r--src/python/grpcio_test/grpc_interop/_interop_test_case.py3
-rw-r--r--src/python/grpcio_test/grpc_interop/methods.py23
-rw-r--r--src/python/grpcio_test/grpc_protoc_plugin/__init__.py30
-rw-r--r--src/python/grpcio_test/grpc_protoc_plugin/python_plugin_test.py (renamed from test/compiler/python_plugin_test.py)20
-rw-r--r--src/python/grpcio_test/grpc_protoc_plugin/test.proto (renamed from test/compiler/test.proto)0
-rw-r--r--src/python/grpcio_test/grpc_test/_adapter/_low_test.py17
-rw-r--r--src/python/grpcio_test/grpc_test/framework/face/testing/blocking_invocation_inline_service_test_case.py34
-rw-r--r--src/python/grpcio_test/grpc_test/framework/face/testing/event_invocation_synchronous_event_service_test_case.py64
-rw-r--r--src/python/grpcio_test/grpc_test/framework/face/testing/future_invocation_asynchronous_event_service_test_case.py45
-rw-r--r--src/python/grpcio_test/setup.py11
-rw-r--r--src/ruby/ext/grpc/rb_call.c14
-rw-r--r--src/ruby/ext/grpc/rb_channel.c22
-rwxr-xr-xsrc/ruby/grpc.gemspec13
-rw-r--r--src/ruby/lib/grpc/generic/client_stub.rb8
-rw-r--r--src/ruby/spec/call_spec.rb2
-rw-r--r--src/ruby/spec/channel_spec.rb4
-rw-r--r--src/ruby/spec/client_server_spec.rb19
-rw-r--r--src/ruby/spec/generic/active_call_spec.rb2
-rw-r--r--test/core/security/verify_jwt.c2
-rw-r--r--test/cpp/end2end/end2end_test.cc2
-rw-r--r--tools/dockerfile/grpc_go/Dockerfile2
-rwxr-xr-xtools/dockerfile/grpc_go/build.sh35
-rw-r--r--tools/doxygen/Doxyfile.c++1
-rw-r--r--tools/doxygen/Doxyfile.c++.internal1
-rwxr-xr-xtools/run_tests/run_interops.py18
-rwxr-xr-xtools/run_tests/run_interops_build.sh36
-rwxr-xr-xtools/run_tests/run_interops_test.sh11
-rwxr-xr-xtools/run_tests/run_python.sh1
-rw-r--r--tools/run_tests/sources_and_headers.json4
-rw-r--r--vsprojects/grpc++/grpc++.vcxproj1
-rw-r--r--vsprojects/grpc++/grpc++.vcxproj.filters3
-rw-r--r--vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj1
-rw-r--r--vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj.filters3
116 files changed, 1387 insertions, 888 deletions
diff --git a/BUILD b/BUILD
index dcabd648e4..9eaabbbccd 100644
--- a/BUILD
+++ b/BUILD
@@ -690,7 +690,6 @@ cc_library(
"include/grpc++/async_generic_service.h",
"include/grpc++/async_unary_call.h",
"include/grpc++/auth_context.h",
- "include/grpc++/auth_property_iterator.h",
"include/grpc++/byte_buffer.h",
"include/grpc++/channel_arguments.h",
"include/grpc++/channel_interface.h",
@@ -778,7 +777,6 @@ cc_library(
"include/grpc++/async_generic_service.h",
"include/grpc++/async_unary_call.h",
"include/grpc++/auth_context.h",
- "include/grpc++/auth_property_iterator.h",
"include/grpc++/byte_buffer.h",
"include/grpc++/channel_arguments.h",
"include/grpc++/channel_interface.h",
diff --git a/INSTALL b/INSTALL
index 8a0a98ad2e..808166dfed 100644
--- a/INSTALL
+++ b/INSTALL
@@ -132,6 +132,7 @@ We will also need to make openssl and install it appropriately
$ cd <git directory>
$ cd third_party/openssl
+ $ ./config
$ sudo make install
$ cd ../../
diff --git a/Makefile b/Makefile
index 5c021a710c..46e23db5ea 100644
--- a/Makefile
+++ b/Makefile
@@ -4484,7 +4484,6 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/async_generic_service.h \
include/grpc++/async_unary_call.h \
include/grpc++/auth_context.h \
- include/grpc++/auth_property_iterator.h \
include/grpc++/byte_buffer.h \
include/grpc++/channel_arguments.h \
include/grpc++/channel_interface.h \
@@ -4728,7 +4727,6 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/async_generic_service.h \
include/grpc++/async_unary_call.h \
include/grpc++/auth_context.h \
- include/grpc++/auth_property_iterator.h \
include/grpc++/byte_buffer.h \
include/grpc++/channel_arguments.h \
include/grpc++/channel_interface.h \
diff --git a/build.json b/build.json
index bf4c7a27e2..896cbee8c8 100644
--- a/build.json
+++ b/build.json
@@ -33,7 +33,6 @@
"include/grpc++/async_generic_service.h",
"include/grpc++/async_unary_call.h",
"include/grpc++/auth_context.h",
- "include/grpc++/auth_property_iterator.h",
"include/grpc++/byte_buffer.h",
"include/grpc++/channel_arguments.h",
"include/grpc++/channel_interface.h",
diff --git a/doc/health-checking.md b/doc/health-checking.md
new file mode 100644
index 0000000000..0b3f9c6a03
--- /dev/null
+++ b/doc/health-checking.md
@@ -0,0 +1,70 @@
+GRPC Health Checking Protocol
+================================
+
+Health checks are used to probe whether the server is able to handle rpcs. The
+client-to-server health checking can happen from point to point or via some
+control system. A server may choose to reply “unhealthy” because it
+is not ready to take requests, it is shutting down or some other reason.
+The client can act accordingly if the response is not received within some time
+window or the response says unhealthy in it.
+
+
+A GRPC service is used as the health checking mechanism for both simple
+client-to-server scenario and other control systems such as load-balancing.
+Being a high
+level service provides some benefits. Firstly, since it is a GRPC service
+itself, doing a health check is in the same format as a normal rpc. Secondly,
+it has rich semantics such as per-service health status. Thirdly, as a GRPC
+service, it is able reuse all the existing billing, quota infrastructure, etc,
+and thus the server has full control over the access of the health checking
+service.
+
+## Service Definition
+
+The server should export a service defined in the following proto:
+
+```
+syntax = "proto3";
+
+package grpc.health.v1alpha;
+
+message HealthCheckRequest {
+ string service = 1;
+}
+
+message HealthCheckResponse {
+ enum ServingStatus {
+ UNKNOWN = 0;
+ SERVING = 1;
+ NOT_SERVING = 2;
+ }
+ ServingStatus status = 1;
+}
+
+service Health {
+ rpc Check(HealthCheckRequest) returns (HealthCheckResponse);
+}
+```
+
+A client can query the server’s health status by calling the `Check` method, and
+a deadline should be set on the rpc. The client can optionally set the service
+name it wants to query for health status. The suggested format of service name
+is `package_names.ServiceName`, such as `grpc.health.v1alpha.Health`.
+
+The server should register all the services manually and set
+the individual status, including an empty service name and its status. For each
+request received, if the service name can be found in the registry,
+a response must be sent back with an `OK` status and the status field should be
+set to `SERVING` or `NOT_SERVING` accordingly. If the service name is not
+registered, the server returns a `NOT_FOUND` GRPC status.
+
+The server should use an empty string as the key for server’s
+overall health status, so that a client not interested in a specific service can
+query the server's status with an empty request. The server can just do exact
+matching of the service name without support of any kind of wildcard matching.
+However, the service owner has the freedom to implement more complicated
+matching semantics that both the client and server agree upon.
+
+A client can declare the server as unhealthy if the rpc is not finished after
+some amount of time. The client should be able to handle the case where server
+does not have the Health service.
diff --git a/include/grpc++/auth_context.h b/include/grpc++/auth_context.h
index c42105b927..f8ea8ad6f4 100644
--- a/include/grpc++/auth_context.h
+++ b/include/grpc++/auth_context.h
@@ -34,12 +34,42 @@
#ifndef GRPCXX_AUTH_CONTEXT_H
#define GRPCXX_AUTH_CONTEXT_H
+#include <iterator>
#include <vector>
-#include <grpc++/auth_property_iterator.h>
#include <grpc++/config.h>
+struct grpc_auth_context;
+struct grpc_auth_property;
+struct grpc_auth_property_iterator;
+
namespace grpc {
+class SecureAuthContext;
+
+typedef std::pair<grpc::string, grpc::string> AuthProperty;
+
+class AuthPropertyIterator
+ : public std::iterator<std::input_iterator_tag, const AuthProperty> {
+ public:
+ ~AuthPropertyIterator();
+ AuthPropertyIterator& operator++();
+ AuthPropertyIterator operator++(int);
+ bool operator==(const AuthPropertyIterator& rhs) const;
+ bool operator!=(const AuthPropertyIterator& rhs) const;
+ const AuthProperty operator*();
+
+ protected:
+ AuthPropertyIterator();
+ AuthPropertyIterator(const grpc_auth_property* property,
+ const grpc_auth_property_iterator* iter);
+ private:
+ friend class SecureAuthContext;
+ const grpc_auth_property* property_;
+ // The following items form a grpc_auth_property_iterator.
+ const grpc_auth_context* ctx_;
+ size_t index_;
+ const char* name_;
+};
class AuthContext {
public:
diff --git a/include/grpc++/auth_property_iterator.h b/include/grpc++/auth_property_iterator.h
deleted file mode 100644
index c7870c46be..0000000000
--- a/include/grpc++/auth_property_iterator.h
+++ /dev/null
@@ -1,77 +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.
- *
- */
-
-#ifndef GRPCXX_AUTH_PROPERTY_ITERATOR_H
-#define GRPCXX_AUTH_PROPERTY_ITERATOR_H
-
-#include <iterator>
-#include <vector>
-
-#include <grpc++/config.h>
-
-struct grpc_auth_context;
-struct grpc_auth_property;
-struct grpc_auth_property_iterator;
-
-namespace grpc {
-class SecureAuthContext;
-
-typedef std::pair<grpc::string, grpc::string> AuthProperty;
-
-class AuthPropertyIterator
- : public std::iterator<std::input_iterator_tag, const AuthProperty> {
- public:
- ~AuthPropertyIterator();
- AuthPropertyIterator& operator++();
- AuthPropertyIterator operator++(int);
- bool operator==(const AuthPropertyIterator& rhs) const;
- bool operator!=(const AuthPropertyIterator& rhs) const;
- const AuthProperty operator*();
-
- protected:
- AuthPropertyIterator();
- AuthPropertyIterator(const grpc_auth_property* property,
- const grpc_auth_property_iterator* iter);
- private:
- friend class SecureAuthContext;
- const grpc_auth_property* property_;
- // The following items form a grpc_auth_property_iterator.
- const grpc_auth_context* ctx_;
- size_t index_;
- const char* name_;
-};
-
-} // namespace grpc
-
- #endif // GRPCXX_AUTH_PROPERTY_ITERATOR_H
-
diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h
index bf340e81ca..5915dda2ba 100644
--- a/include/grpc/grpc.h
+++ b/include/grpc/grpc.h
@@ -181,7 +181,9 @@ typedef enum grpc_call_error {
GRPC_CALL_ERROR_INVALID_MESSAGE,
/** completion queue for notification has not been registered with the
server */
- GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE
+ GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE,
+ /** this batch of operations leads to more operations than allowed */
+ GRPC_CALL_ERROR_BATCH_TOO_BIG
} grpc_call_error;
/* Write Flags: */
@@ -256,31 +258,44 @@ void grpc_call_details_destroy(grpc_call_details *details);
typedef enum {
/** Send initial metadata: one and only one instance MUST be sent for each
- call, unless the call was cancelled - in which case this can be skipped */
+ call, unless the call was cancelled - in which case this can be skipped.
+ This op completes after all bytes of metadata have been accepted by
+ outgoing flow control. */
GRPC_OP_SEND_INITIAL_METADATA = 0,
- /** Send a message: 0 or more of these operations can occur for each call */
+ /** Send a message: 0 or more of these operations can occur for each call.
+ This op completes after all bytes for the message have been accepted by
+ outgoing flow control. */
GRPC_OP_SEND_MESSAGE,
/** Send a close from the client: one and only one instance MUST be sent from
the client, unless the call was cancelled - in which case this can be
- skipped */
+ skipped.
+ This op completes after all bytes for the call (including the close)
+ have passed outgoing flow control. */
GRPC_OP_SEND_CLOSE_FROM_CLIENT,
/** Send status from the server: one and only one instance MUST be sent from
the server unless the call was cancelled - in which case this can be
- skipped */
+ skipped.
+ This op completes after all bytes for the call (including the status)
+ have passed outgoing flow control. */
GRPC_OP_SEND_STATUS_FROM_SERVER,
/** Receive initial metadata: one and only one MUST be made on the client,
- must not be made on the server */
+ must not be made on the server.
+ This op completes after all initial metadata has been read from the
+ peer. */
GRPC_OP_RECV_INITIAL_METADATA,
- /** Receive a message: 0 or more of these operations can occur for each call
- */
+ /** Receive a message: 0 or more of these operations can occur for each call.
+ This op completes after all bytes of the received message have been
+ read, or after a half-close has been received on this call. */
GRPC_OP_RECV_MESSAGE,
/** Receive status on the client: one and only one must be made on the client.
- This operation always succeeds, meaning ops paired with this operation
- will also appear to succeed, even though they may not have. In that case
- the status will indicate some failure. */
+ This operation always succeeds, meaning ops paired with this operation
+ will also appear to succeed, even though they may not have. In that case
+ the status will indicate some failure.
+ This op completes after all activity on the call has completed. */
GRPC_OP_RECV_STATUS_ON_CLIENT,
/** Receive close on the server: one and only one must be made on the
- server */
+ server.
+ This op completes after the close has been received by the server. */
GRPC_OP_RECV_CLOSE_ON_SERVER
} grpc_op_type;
diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c
index a293c93ec6..6c2e6b38a8 100644
--- a/src/core/channel/client_channel.c
+++ b/src/core/channel/client_channel.c
@@ -527,6 +527,7 @@ static void cc_on_config_changed(void *arg, int iomgr_success) {
}
if (old_lb_policy != NULL) {
+ grpc_lb_policy_shutdown(old_lb_policy);
GRPC_LB_POLICY_UNREF(old_lb_policy, "channel");
}
diff --git a/src/core/surface/call.c b/src/core/surface/call.c
index 6e566e6a8f..5839d3ac2e 100644
--- a/src/core/surface/call.c
+++ b/src/core/surface/call.c
@@ -1539,6 +1539,7 @@ grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
/* Flag validation: currently allow no flags */
if (op->flags != 0) return GRPC_CALL_ERROR_INVALID_FLAGS;
req = &reqs[out++];
+ if (out > GRPC_IOREQ_OP_COUNT) return GRPC_CALL_ERROR_BATCH_TOO_BIG;
req->op = GRPC_IOREQ_SEND_INITIAL_METADATA;
req->data.send_metadata.count = op->data.send_initial_metadata.count;
req->data.send_metadata.metadata =
@@ -1553,6 +1554,7 @@ grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
return GRPC_CALL_ERROR_INVALID_MESSAGE;
}
req = &reqs[out++];
+ if (out > GRPC_IOREQ_OP_COUNT) return GRPC_CALL_ERROR_BATCH_TOO_BIG;
req->op = GRPC_IOREQ_SEND_MESSAGE;
req->data.send_message = op->data.send_message;
req->flags = op->flags;
@@ -1564,6 +1566,7 @@ grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
return GRPC_CALL_ERROR_NOT_ON_SERVER;
}
req = &reqs[out++];
+ if (out > GRPC_IOREQ_OP_COUNT) return GRPC_CALL_ERROR_BATCH_TOO_BIG;
req->op = GRPC_IOREQ_SEND_CLOSE;
req->flags = op->flags;
break;
@@ -1574,6 +1577,7 @@ grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
return GRPC_CALL_ERROR_NOT_ON_CLIENT;
}
req = &reqs[out++];
+ if (out > GRPC_IOREQ_OP_COUNT) return GRPC_CALL_ERROR_BATCH_TOO_BIG;
req->op = GRPC_IOREQ_SEND_TRAILING_METADATA;
req->flags = op->flags;
req->data.send_metadata.count =
@@ -1581,6 +1585,7 @@ grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
req->data.send_metadata.metadata =
op->data.send_status_from_server.trailing_metadata;
req = &reqs[out++];
+ if (out > GRPC_IOREQ_OP_COUNT) return GRPC_CALL_ERROR_BATCH_TOO_BIG;
req->op = GRPC_IOREQ_SEND_STATUS;
req->data.send_status.code = op->data.send_status_from_server.status;
req->data.send_status.details =
@@ -1590,6 +1595,7 @@ grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
op->data.send_status_from_server.status_details, 0)
: NULL;
req = &reqs[out++];
+ if (out > GRPC_IOREQ_OP_COUNT) return GRPC_CALL_ERROR_BATCH_TOO_BIG;
req->op = GRPC_IOREQ_SEND_CLOSE;
break;
case GRPC_OP_RECV_INITIAL_METADATA:
@@ -1599,6 +1605,7 @@ grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
return GRPC_CALL_ERROR_NOT_ON_SERVER;
}
req = &reqs[out++];
+ if (out > GRPC_IOREQ_OP_COUNT) return GRPC_CALL_ERROR_BATCH_TOO_BIG;
req->op = GRPC_IOREQ_RECV_INITIAL_METADATA;
req->data.recv_metadata = op->data.recv_initial_metadata;
req->data.recv_metadata->count = 0;
@@ -1608,6 +1615,7 @@ grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
/* Flag validation: currently allow no flags */
if (op->flags != 0) return GRPC_CALL_ERROR_INVALID_FLAGS;
req = &reqs[out++];
+ if (out > GRPC_IOREQ_OP_COUNT) return GRPC_CALL_ERROR_BATCH_TOO_BIG;
req->op = GRPC_IOREQ_RECV_MESSAGE;
req->data.recv_message = op->data.recv_message;
req->flags = op->flags;
@@ -1619,22 +1627,26 @@ grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
return GRPC_CALL_ERROR_NOT_ON_SERVER;
}
req = &reqs[out++];
+ if (out > GRPC_IOREQ_OP_COUNT) return GRPC_CALL_ERROR_BATCH_TOO_BIG;
req->op = GRPC_IOREQ_RECV_STATUS;
req->flags = op->flags;
req->data.recv_status.set_value = set_status_value_directly;
req->data.recv_status.user_data = op->data.recv_status_on_client.status;
req = &reqs[out++];
+ if (out > GRPC_IOREQ_OP_COUNT) return GRPC_CALL_ERROR_BATCH_TOO_BIG;
req->op = GRPC_IOREQ_RECV_STATUS_DETAILS;
req->data.recv_status_details.details =
op->data.recv_status_on_client.status_details;
req->data.recv_status_details.details_capacity =
op->data.recv_status_on_client.status_details_capacity;
req = &reqs[out++];
+ if (out > GRPC_IOREQ_OP_COUNT) return GRPC_CALL_ERROR_BATCH_TOO_BIG;
req->op = GRPC_IOREQ_RECV_TRAILING_METADATA;
req->data.recv_metadata =
op->data.recv_status_on_client.trailing_metadata;
req->data.recv_metadata->count = 0;
req = &reqs[out++];
+ if (out > GRPC_IOREQ_OP_COUNT) return GRPC_CALL_ERROR_BATCH_TOO_BIG;
req->op = GRPC_IOREQ_RECV_CLOSE;
finish_func = finish_batch_with_close;
break;
@@ -1642,12 +1654,14 @@ grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
/* Flag validation: currently allow no flags */
if (op->flags != 0) return GRPC_CALL_ERROR_INVALID_FLAGS;
req = &reqs[out++];
+ if (out > GRPC_IOREQ_OP_COUNT) return GRPC_CALL_ERROR_BATCH_TOO_BIG;
req->op = GRPC_IOREQ_RECV_STATUS;
req->flags = op->flags;
req->data.recv_status.set_value = set_cancelled_value;
req->data.recv_status.user_data =
op->data.recv_close_on_server.cancelled;
req = &reqs[out++];
+ if (out > GRPC_IOREQ_OP_COUNT) return GRPC_CALL_ERROR_BATCH_TOO_BIG;
req->op = GRPC_IOREQ_RECV_CLOSE;
finish_func = finish_batch_with_close;
break;
diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc
index 2d6114e06b..6cd6b77fcf 100644
--- a/src/cpp/client/secure_credentials.cc
+++ b/src/cpp/client/secure_credentials.cc
@@ -34,6 +34,7 @@
#include <grpc/support/log.h>
#include <grpc++/channel_arguments.h>
+#include <grpc++/impl/grpc_library.h>
#include "src/cpp/client/channel.h"
#include "src/cpp/client/secure_credentials.h"
@@ -61,12 +62,14 @@ std::shared_ptr<Credentials> WrapCredentials(grpc_credentials* creds) {
} // namespace
std::shared_ptr<Credentials> GoogleDefaultCredentials() {
+ GrpcLibrary init; // To call grpc_init().
return WrapCredentials(grpc_google_default_credentials_create());
}
// Builds SSL Credentials given SSL specific options
std::shared_ptr<Credentials> SslCredentials(
const SslCredentialsOptions& options) {
+ GrpcLibrary init; // To call grpc_init().
grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {
options.pem_private_key.c_str(), options.pem_cert_chain.c_str()};
@@ -78,6 +81,7 @@ std::shared_ptr<Credentials> SslCredentials(
// Builds credentials for use when running in GCE
std::shared_ptr<Credentials> ComputeEngineCredentials() {
+ GrpcLibrary init; // To call grpc_init().
return WrapCredentials(grpc_compute_engine_credentials_create());
}
@@ -85,6 +89,7 @@ std::shared_ptr<Credentials> ComputeEngineCredentials() {
std::shared_ptr<Credentials> ServiceAccountCredentials(
const grpc::string& json_key, const grpc::string& scope,
long token_lifetime_seconds) {
+ GrpcLibrary init; // To call grpc_init().
if (token_lifetime_seconds <= 0) {
gpr_log(GPR_ERROR,
"Trying to create ServiceAccountCredentials "
@@ -100,6 +105,7 @@ std::shared_ptr<Credentials> ServiceAccountCredentials(
// Builds JWT credentials.
std::shared_ptr<Credentials> ServiceAccountJWTAccessCredentials(
const grpc::string& json_key, long token_lifetime_seconds) {
+ GrpcLibrary init; // To call grpc_init().
if (token_lifetime_seconds <= 0) {
gpr_log(GPR_ERROR,
"Trying to create JWTCredentials with non-positive lifetime");
@@ -114,6 +120,7 @@ std::shared_ptr<Credentials> ServiceAccountJWTAccessCredentials(
// Builds refresh token credentials.
std::shared_ptr<Credentials> RefreshTokenCredentials(
const grpc::string& json_refresh_token) {
+ GrpcLibrary init; // To call grpc_init().
return WrapCredentials(
grpc_refresh_token_credentials_create(json_refresh_token.c_str()));
}
@@ -121,6 +128,7 @@ std::shared_ptr<Credentials> RefreshTokenCredentials(
// Builds access token credentials.
std::shared_ptr<Credentials> AccessTokenCredentials(
const grpc::string& access_token) {
+ GrpcLibrary init; // To call grpc_init().
return WrapCredentials(
grpc_access_token_credentials_create(access_token.c_str()));
}
@@ -129,6 +137,7 @@ std::shared_ptr<Credentials> AccessTokenCredentials(
std::shared_ptr<Credentials> IAMCredentials(
const grpc::string& authorization_token,
const grpc::string& authority_selector) {
+ GrpcLibrary init; // To call grpc_init().
return WrapCredentials(grpc_iam_credentials_create(
authorization_token.c_str(), authority_selector.c_str()));
}
diff --git a/src/cpp/common/auth_property_iterator.cc b/src/cpp/common/auth_property_iterator.cc
index e706c6c921..ba88983515 100644
--- a/src/cpp/common/auth_property_iterator.cc
+++ b/src/cpp/common/auth_property_iterator.cc
@@ -31,7 +31,7 @@
*
*/
-#include <grpc++/auth_property_iterator.h>
+#include <grpc++/auth_context.h>
#include <grpc/grpc_security.h>
diff --git a/src/csharp/Grpc.Auth/GoogleCredential.cs b/src/csharp/Grpc.Auth/GoogleCredential.cs
deleted file mode 100644
index 9936cf583c..0000000000
--- a/src/csharp/Grpc.Auth/GoogleCredential.cs
+++ /dev/null
@@ -1,125 +0,0 @@
-#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.IO;
-using System.Security.Cryptography;
-using System.Threading;
-using System.Threading.Tasks;
-
-using Google.Apis.Auth.OAuth2;
-using Google.Apis.Auth.OAuth2.Responses;
-using Newtonsoft.Json.Linq;
-using Org.BouncyCastle.Crypto.Parameters;
-using Org.BouncyCastle.Security;
-
-namespace Grpc.Auth
-{
- // TODO(jtattermusch): Remove this class once possible.
- /// <summary>
- /// A temporary placeholder for Google credential from
- /// Google Auth library for .NET. It emulates the usage pattern
- /// for Usable auth.
- /// </summary>
- public class GoogleCredential
- {
- private const string GoogleApplicationCredentialsEnvName = "GOOGLE_APPLICATION_CREDENTIALS";
- private const string ClientEmailFieldName = "client_email";
- private const string PrivateKeyFieldName = "private_key";
-
- private ServiceCredential credential;
-
- private GoogleCredential(ServiceCredential credential)
- {
- this.credential = credential;
- }
-
- public static GoogleCredential GetApplicationDefault()
- {
- return new GoogleCredential(null);
- }
-
- public bool IsCreateScopedRequired
- {
- get
- {
- return true;
- }
- }
-
- public GoogleCredential CreateScoped(IEnumerable<string> scopes)
- {
- var credsPath = Environment.GetEnvironmentVariable(GoogleApplicationCredentialsEnvName);
- if (credsPath == null)
- {
- // Default to ComputeCredentials if path to JSON key is not set.
- // ComputeCredential is not scoped actually, but for our use case it's
- // fine to treat is as such.
- return new GoogleCredential(new ComputeCredential(new ComputeCredential.Initializer()));
- }
-
- JObject jsonCredentialParameters = JObject.Parse(File.ReadAllText(credsPath));
- string clientEmail = jsonCredentialParameters.GetValue(ClientEmailFieldName).Value<string>();
- string privateKeyString = jsonCredentialParameters.GetValue(PrivateKeyFieldName).Value<string>();
-
- var serviceCredential = new ServiceAccountCredential(
- new ServiceAccountCredential.Initializer(clientEmail)
- {
- Scopes = scopes,
- }.FromPrivateKey(privateKeyString));
- return new GoogleCredential(serviceCredential);
- }
-
- public Task<bool> RequestAccessTokenAsync(CancellationToken taskCancellationToken)
- {
- return credential.RequestAccessTokenAsync(taskCancellationToken);
- }
-
- public TokenResponse Token
- {
- get
- {
- return credential.Token;
- }
- }
-
- internal ServiceCredential InternalCredential
- {
- get
- {
- return credential;
- }
- }
- }
-}
diff --git a/src/csharp/Grpc.Auth/Grpc.Auth.csproj b/src/csharp/Grpc.Auth/Grpc.Auth.csproj
index 8e5036832d..930a34b0c3 100644
--- a/src/csharp/Grpc.Auth/Grpc.Auth.csproj
+++ b/src/csharp/Grpc.Auth/Grpc.Auth.csproj
@@ -11,7 +11,7 @@
<AssemblyName>Grpc.Auth</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<DocumentationFile>bin\$(Configuration)\Grpc.Auth.Xml</DocumentationFile>
- <NuGetPackageImportStamp>9b408026</NuGetPackageImportStamp>
+ <NuGetPackageImportStamp>4f8487a9</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -41,28 +41,32 @@
<AssemblyOriginatorKeyFile>C:\keys\Grpc.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup>
- <Reference Include="BouncyCastle.Crypto">
+ <Reference Include="BouncyCastle.Crypto, Version=1.7.4137.9688, Culture=neutral, PublicKeyToken=a4292a325f69b123, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
</Reference>
- <Reference Include="Google.Apis.Auth, Version=1.9.2.27817, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+ <Reference Include="Google.Apis.Auth, Version=1.9.3.19379, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\Google.Apis.Auth.1.9.2\lib\net40\Google.Apis.Auth.dll</HintPath>
+ <HintPath>..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.dll</HintPath>
</Reference>
- <Reference Include="Google.Apis.Auth.PlatformServices, Version=1.9.2.27820, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+ <Reference Include="Google.Apis.Auth.PlatformServices, Version=1.9.3.19383, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\Google.Apis.Auth.1.9.2\lib\net40\Google.Apis.Auth.PlatformServices.dll</HintPath>
+ <HintPath>..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.PlatformServices.dll</HintPath>
</Reference>
- <Reference Include="Google.Apis.Core, Version=1.9.2.27816, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+ <Reference Include="Google.Apis.Core, Version=1.9.3.19379, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\Google.Apis.Core.1.9.2\lib\portable-net40+sl50+win+wpa81+wp80\Google.Apis.Core.dll</HintPath>
+ <HintPath>..\packages\Google.Apis.Core.1.9.3\lib\portable-net40+sl50+win+wpa81+wp80\Google.Apis.Core.dll</HintPath>
</Reference>
- <Reference Include="Microsoft.Threading.Tasks">
+ <Reference Include="Microsoft.Threading.Tasks, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath>
</Reference>
- <Reference Include="Microsoft.Threading.Tasks.Extensions">
+ <Reference Include="Microsoft.Threading.Tasks.Extensions, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
- <Reference Include="Microsoft.Threading.Tasks.Extensions.Desktop">
+ <Reference Include="Microsoft.Threading.Tasks.Extensions.Desktop, Version=1.0.168.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
@@ -87,7 +91,6 @@
<Link>Version.cs</Link>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="GoogleCredential.cs" />
<Compile Include="OAuth2Interceptors.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
diff --git a/src/csharp/Grpc.Auth/OAuth2Interceptors.cs b/src/csharp/Grpc.Auth/OAuth2Interceptors.cs
index cc9d2c175f..d628a83246 100644
--- a/src/csharp/Grpc.Auth/OAuth2Interceptors.cs
+++ b/src/csharp/Grpc.Auth/OAuth2Interceptors.cs
@@ -54,7 +54,7 @@ namespace Grpc.Auth
/// </summary>
public static MetadataInterceptorDelegate FromCredential(GoogleCredential googleCredential)
{
- var interceptor = new OAuth2Interceptor(googleCredential.InternalCredential, SystemClock.Default);
+ var interceptor = new OAuth2Interceptor(googleCredential, SystemClock.Default);
return new MetadataInterceptorDelegate(interceptor.InterceptHeaders);
}
@@ -66,7 +66,7 @@ namespace Grpc.Auth
public static MetadataInterceptorDelegate FromAccessToken(string oauth2Token)
{
Preconditions.CheckNotNull(oauth2Token);
- return new MetadataInterceptorDelegate((metadata) =>
+ return new MetadataInterceptorDelegate((authUri, metadata) =>
{
metadata.Add(OAuth2Interceptor.CreateBearerTokenHeader(oauth2Token));
});
@@ -80,10 +80,10 @@ namespace Grpc.Auth
private const string AuthorizationHeader = "Authorization";
private const string Schema = "Bearer";
- private ServiceCredential credential;
+ private ITokenAccess credential;
private IClock clock;
- public OAuth2Interceptor(ServiceCredential credential, IClock clock)
+ public OAuth2Interceptor(ITokenAccess credential, IClock clock)
{
this.credential = credential;
this.clock = clock;
@@ -94,23 +94,15 @@ namespace Grpc.Auth
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
- public string GetAccessToken(CancellationToken cancellationToken)
+ public string GetAccessToken(string authUri, CancellationToken cancellationToken)
{
- if (credential.Token == null || credential.Token.IsExpired(clock))
- {
- // TODO(jtattermusch): Parallel requests will spawn multiple requests to refresh the token once the token expires.
- // TODO(jtattermusch): Rethink synchronous wait to obtain the result.
- if (!credential.RequestAccessTokenAsync(cancellationToken).Result)
- {
- throw new InvalidOperationException("The access token has expired but we can't refresh it");
- }
- }
- return credential.Token.AccessToken;
+ // TODO(jtattermusch): Rethink synchronous wait to obtain the result.
+ return credential.GetAccessTokenForRequestAsync(authUri, cancellationToken: cancellationToken).GetAwaiter().GetResult();
}
- public void InterceptHeaders(Metadata metadata)
+ public void InterceptHeaders(string authUri, Metadata metadata)
{
- var accessToken = GetAccessToken(CancellationToken.None);
+ var accessToken = GetAccessToken(authUri, CancellationToken.None);
metadata.Add(CreateBearerTokenHeader(accessToken));
}
diff --git a/src/csharp/Grpc.Auth/app.config b/src/csharp/Grpc.Auth/app.config
index 0a82bb4f16..84d7534d65 100644
--- a/src/csharp/Grpc.Auth/app.config
+++ b/src/csharp/Grpc.Auth/app.config
@@ -10,6 +10,10 @@
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.28.0" newVersion="4.0.0.0" />
</dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="Google.Apis.Core" publicKeyToken="4b01fa6e34db77ab" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-1.9.2.38523" newVersion="1.9.2.38523" />
+ </dependentAssembly>
</assemblyBinding>
</runtime>
</configuration> \ No newline at end of file
diff --git a/src/csharp/Grpc.Auth/packages.config b/src/csharp/Grpc.Auth/packages.config
index 29be953bf3..7a02c95db9 100644
--- a/src/csharp/Grpc.Auth/packages.config
+++ b/src/csharp/Grpc.Auth/packages.config
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
- <package id="Google.Apis.Auth" version="1.9.2" targetFramework="net45" />
- <package id="Google.Apis.Core" version="1.9.2" targetFramework="net45" />
+ <package id="Google.Apis.Auth" version="1.9.3" targetFramework="net45" />
+ <package id="Google.Apis.Core" version="1.9.3" targetFramework="net45" />
<package id="Microsoft.Bcl" version="1.1.10" targetFramework="net45" />
<package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net45" />
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net45" />
diff --git a/src/csharp/Grpc.Core.Tests/ChannelOptionsTest.cs b/src/csharp/Grpc.Core.Tests/ChannelOptionsTest.cs
index df09857efe..52be77c846 100644
--- a/src/csharp/Grpc.Core.Tests/ChannelOptionsTest.cs
+++ b/src/csharp/Grpc.Core.Tests/ChannelOptionsTest.cs
@@ -67,9 +67,9 @@ namespace Grpc.Core.Internal.Tests
[Test]
public void ConstructorPreconditions()
{
- Assert.Throws(typeof(NullReferenceException), () => { new ChannelOption(null, "abc"); });
- Assert.Throws(typeof(NullReferenceException), () => { new ChannelOption(null, 1); });
- Assert.Throws(typeof(NullReferenceException), () => { new ChannelOption("abc", null); });
+ Assert.Throws(typeof(ArgumentNullException), () => { new ChannelOption(null, "abc"); });
+ Assert.Throws(typeof(ArgumentNullException), () => { new ChannelOption(null, 1); });
+ Assert.Throws(typeof(ArgumentNullException), () => { new ChannelOption("abc", null); });
}
[Test]
diff --git a/src/csharp/Grpc.Core.Tests/ChannelTest.cs b/src/csharp/Grpc.Core.Tests/ChannelTest.cs
index 60b45176e5..2787572924 100644
--- a/src/csharp/Grpc.Core.Tests/ChannelTest.cs
+++ b/src/csharp/Grpc.Core.Tests/ChannelTest.cs
@@ -50,7 +50,7 @@ namespace Grpc.Core.Tests
[Test]
public void Constructor_RejectsInvalidParams()
{
- Assert.Throws(typeof(NullReferenceException), () => new Channel(null, Credentials.Insecure));
+ Assert.Throws(typeof(ArgumentNullException), () => new Channel(null, Credentials.Insecure));
}
[Test]
@@ -72,11 +72,11 @@ namespace Grpc.Core.Tests
}
[Test]
- public void Target()
+ public void ResolvedTarget()
{
using (var channel = new Channel("127.0.0.1", Credentials.Insecure))
{
- Assert.IsTrue(channel.Target.Contains("127.0.0.1"));
+ Assert.IsTrue(channel.ResolvedTarget.Contains("127.0.0.1"));
}
}
diff --git a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs
index c5fc85b3fe..e49fdb5268 100644
--- a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs
+++ b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs
@@ -138,7 +138,7 @@ namespace Grpc.Core.Tests
helper.ClientStreamingHandler = new ClientStreamingServerMethod<string, string>(async (requestStream, context) =>
{
string result = "";
- await requestStream.ForEach(async (request) =>
+ await requestStream.ForEachAsync(async (request) =>
{
result += request;
});
@@ -147,7 +147,7 @@ namespace Grpc.Core.Tests
});
var call = Calls.AsyncClientStreamingCall(helper.CreateClientStreamingCall());
- await call.RequestStream.WriteAll(new string[] { "A", "B", "C" });
+ await call.RequestStream.WriteAllAsync(new string[] { "A", "B", "C" });
Assert.AreEqual("ABC", await call.ResponseAsync);
}
@@ -159,7 +159,7 @@ namespace Grpc.Core.Tests
helper.ClientStreamingHandler = new ClientStreamingServerMethod<string, string>(async (requestStream, context) =>
{
barrier.SetResult(null);
- await requestStream.ToList();
+ await requestStream.ToListAsync();
return "";
});
diff --git a/src/csharp/Grpc.Core.Tests/CompressionTest.cs b/src/csharp/Grpc.Core.Tests/CompressionTest.cs
index ac0c3d6b5f..9547683f60 100644
--- a/src/csharp/Grpc.Core.Tests/CompressionTest.cs
+++ b/src/csharp/Grpc.Core.Tests/CompressionTest.cs
@@ -90,7 +90,7 @@ namespace Grpc.Core.Tests
{
helper.DuplexStreamingHandler = new DuplexStreamingServerMethod<string, string>(async (requestStream, responseStream, context) =>
{
- await requestStream.ToList();
+ await requestStream.ToListAsync();
context.WriteOptions = new WriteOptions(WriteFlags.NoCompress);
@@ -122,7 +122,7 @@ namespace Grpc.Core.Tests
await call.RequestStream.CompleteAsync();
- await call.ResponseStream.ToList();
+ await call.ResponseStream.ToListAsync();
}
}
}
diff --git a/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs b/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs
index a7f5075874..db5f953b0e 100644
--- a/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs
+++ b/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs
@@ -110,6 +110,14 @@ namespace Grpc.Core.Tests
helper.ClientStreamingHandler = new ClientStreamingServerMethod<string, string>(async (requestStream, context) =>
{
+ Assert.Throws(typeof(ArgumentException), () =>
+ {
+ // Trying to override deadline while propagating deadline from parent call will throw.
+ Calls.BlockingUnaryCall(helper.CreateUnaryCall(
+ new CallOptions(deadline: DateTime.UtcNow.AddDays(8),
+ propagationToken: context.CreatePropagationToken())), "");
+ });
+
var callOptions = new CallOptions(propagationToken: context.CreatePropagationToken());
return await Calls.AsyncUnaryCall(helper.CreateUnaryCall(callOptions), "xyz");
});
@@ -118,5 +126,28 @@ namespace Grpc.Core.Tests
await call.RequestStream.CompleteAsync();
Assert.AreEqual("PASS", await call);
}
+
+ [Test]
+ public async Task SuppressDeadlinePropagation()
+ {
+ helper.UnaryHandler = new UnaryServerMethod<string, string>(async (request, context) =>
+ {
+ Assert.AreEqual(DateTime.MaxValue, context.Deadline);
+ return "PASS";
+ });
+
+ helper.ClientStreamingHandler = new ClientStreamingServerMethod<string, string>(async (requestStream, context) =>
+ {
+ Assert.IsTrue(context.CancellationToken.CanBeCanceled);
+
+ var callOptions = new CallOptions(propagationToken: context.CreatePropagationToken(new ContextPropagationOptions(propagateDeadline: false)));
+ return await Calls.AsyncUnaryCall(helper.CreateUnaryCall(callOptions), "xyz");
+ });
+
+ var cts = new CancellationTokenSource();
+ var call = Calls.AsyncClientStreamingCall(helper.CreateClientStreamingCall(new CallOptions(deadline: DateTime.UtcNow.AddDays(7))));
+ await call.RequestStream.CompleteAsync();
+ Assert.AreEqual("PASS", await call);
+ }
}
}
diff --git a/src/csharp/Grpc.Core.Tests/MockServiceHelper.cs b/src/csharp/Grpc.Core.Tests/MockServiceHelper.cs
index b642286b11..bb69648d8b 100644
--- a/src/csharp/Grpc.Core.Tests/MockServiceHelper.cs
+++ b/src/csharp/Grpc.Core.Tests/MockServiceHelper.cs
@@ -153,27 +153,23 @@ namespace Grpc.Core.Tests
return channel;
}
- public CallInvocationDetails<string, string> CreateUnaryCall(CallOptions options = null)
+ public CallInvocationDetails<string, string> CreateUnaryCall(CallOptions options = default(CallOptions))
{
- options = options ?? new CallOptions();
return new CallInvocationDetails<string, string>(channel, UnaryMethod, options);
}
- public CallInvocationDetails<string, string> CreateClientStreamingCall(CallOptions options = null)
+ public CallInvocationDetails<string, string> CreateClientStreamingCall(CallOptions options = default(CallOptions))
{
- options = options ?? new CallOptions();
return new CallInvocationDetails<string, string>(channel, ClientStreamingMethod, options);
}
- public CallInvocationDetails<string, string> CreateServerStreamingCall(CallOptions options = null)
+ public CallInvocationDetails<string, string> CreateServerStreamingCall(CallOptions options = default(CallOptions))
{
- options = options ?? new CallOptions();
return new CallInvocationDetails<string, string>(channel, ServerStreamingMethod, options);
}
- public CallInvocationDetails<string, string> CreateDuplexStreamingCall(CallOptions options = null)
+ public CallInvocationDetails<string, string> CreateDuplexStreamingCall(CallOptions options = default(CallOptions))
{
- options = options ?? new CallOptions();
return new CallInvocationDetails<string, string>(channel, DuplexStreamingMethod, options);
}
diff --git a/src/csharp/Grpc.Core.Tests/ResponseHeadersTest.cs b/src/csharp/Grpc.Core.Tests/ResponseHeadersTest.cs
index 8925041ba4..981b8ea3c8 100644
--- a/src/csharp/Grpc.Core.Tests/ResponseHeadersTest.cs
+++ b/src/csharp/Grpc.Core.Tests/ResponseHeadersTest.cs
@@ -84,7 +84,7 @@ namespace Grpc.Core.Tests
{
helper.UnaryHandler = new UnaryServerMethod<string, string>(async (request, context) =>
{
- Assert.Throws(typeof(NullReferenceException), async () => await context.WriteResponseHeadersAsync(null));
+ Assert.Throws(typeof(ArgumentNullException), async () => await context.WriteResponseHeadersAsync(null));
return "PASS";
});
@@ -129,7 +129,7 @@ namespace Grpc.Core.Tests
});
var call = Calls.AsyncServerStreamingCall(helper.CreateServerStreamingCall(), "");
- var responses = await call.ResponseStream.ToList();
+ var responses = await call.ResponseStream.ToListAsync();
CollectionAssert.AreEqual(new[] { "A", "B" }, responses);
}
}
diff --git a/src/csharp/Grpc.Core/CallInvocationDetails.cs b/src/csharp/Grpc.Core/CallInvocationDetails.cs
index eb23a3a209..6565073fc5 100644
--- a/src/csharp/Grpc.Core/CallInvocationDetails.cs
+++ b/src/csharp/Grpc.Core/CallInvocationDetails.cs
@@ -40,30 +40,60 @@ namespace Grpc.Core
/// <summary>
/// Details about a client-side call to be invoked.
/// </summary>
- public class CallInvocationDetails<TRequest, TResponse>
+ public struct CallInvocationDetails<TRequest, TResponse>
{
readonly Channel channel;
readonly string method;
readonly string host;
readonly Marshaller<TRequest> requestMarshaller;
readonly Marshaller<TResponse> responseMarshaller;
- readonly CallOptions options;
+ CallOptions options;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Grpc.Core.CallInvocationDetails`2"/> struct.
+ /// </summary>
+ /// <param name="channel">Channel to use for this call.</param>
+ /// <param name="method">Method to call.</param>
+ /// <param name="options">Call options.</param>
public CallInvocationDetails(Channel channel, Method<TRequest, TResponse> method, CallOptions options) :
- this(channel, method.FullName, null, method.RequestMarshaller, method.ResponseMarshaller, options)
+ this(channel, method, null, options)
{
}
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Grpc.Core.CallInvocationDetails`2"/> struct.
+ /// </summary>
+ /// <param name="channel">Channel to use for this call.</param>
+ /// <param name="method">Method to call.</param>
+ /// <param name="host">Host that contains the method. if <c>null</c>, default host will be used.</param>
+ /// <param name="options">Call options.</param>
+ public CallInvocationDetails(Channel channel, Method<TRequest, TResponse> method, string host, CallOptions options) :
+ this(channel, method.FullName, host, method.RequestMarshaller, method.ResponseMarshaller, options)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Grpc.Core.CallInvocationDetails`2"/> struct.
+ /// </summary>
+ /// <param name="channel">Channel to use for this call.</param>
+ /// <param name="method">Qualified method name.</param>
+ /// <param name="host">Host that contains the method.</param>
+ /// <param name="requestMarshaller">Request marshaller.</param>
+ /// <param name="responseMarshaller">Response marshaller.</param>
+ /// <param name="options">Call options.</param>
public CallInvocationDetails(Channel channel, string method, string host, Marshaller<TRequest> requestMarshaller, Marshaller<TResponse> responseMarshaller, CallOptions options)
{
- this.channel = Preconditions.CheckNotNull(channel);
- this.method = Preconditions.CheckNotNull(method);
+ this.channel = Preconditions.CheckNotNull(channel, "channel");
+ this.method = Preconditions.CheckNotNull(method, "method");
this.host = host;
- this.requestMarshaller = Preconditions.CheckNotNull(requestMarshaller);
- this.responseMarshaller = Preconditions.CheckNotNull(responseMarshaller);
- this.options = Preconditions.CheckNotNull(options);
+ this.requestMarshaller = Preconditions.CheckNotNull(requestMarshaller, "requestMarshaller");
+ this.responseMarshaller = Preconditions.CheckNotNull(responseMarshaller, "responseMarshaller");
+ this.options = options;
}
+ /// <summary>
+ /// Get channel associated with this call.
+ /// </summary>
public Channel Channel
{
get
@@ -72,6 +102,9 @@ namespace Grpc.Core
}
}
+ /// <summary>
+ /// Gets name of method to be called.
+ /// </summary>
public string Method
{
get
@@ -80,6 +113,9 @@ namespace Grpc.Core
}
}
+ /// <summary>
+ /// Get name of host.
+ /// </summary>
public string Host
{
get
@@ -88,6 +124,9 @@ namespace Grpc.Core
}
}
+ /// <summary>
+ /// Gets marshaller used to serialize requests.
+ /// </summary>
public Marshaller<TRequest> RequestMarshaller
{
get
@@ -96,6 +135,9 @@ namespace Grpc.Core
}
}
+ /// <summary>
+ /// Gets marshaller used to deserialized responses.
+ /// </summary>
public Marshaller<TResponse> ResponseMarshaller
{
get
@@ -104,6 +146,9 @@ namespace Grpc.Core
}
}
+ /// <summary>
+ /// Gets the call options.
+ /// </summary>
public CallOptions Options
{
get
@@ -111,5 +156,16 @@ namespace Grpc.Core
return options;
}
}
+
+ /// <summary>
+ /// Returns new instance of <see cref="CallInvocationDetails"/> with
+ /// <c>Options</c> set to the value provided. Values of all other fields are preserved.
+ /// </summary>
+ public CallInvocationDetails<TRequest, TResponse> WithOptions(CallOptions options)
+ {
+ var newDetails = this;
+ newDetails.options = options;
+ return newDetails;
+ }
}
}
diff --git a/src/csharp/Grpc.Core/CallOptions.cs b/src/csharp/Grpc.Core/CallOptions.cs
index 0d82b5a28e..3dfe80b48c 100644
--- a/src/csharp/Grpc.Core/CallOptions.cs
+++ b/src/csharp/Grpc.Core/CallOptions.cs
@@ -42,29 +42,28 @@ namespace Grpc.Core
/// <summary>
/// Options for calls made by client.
/// </summary>
- public class CallOptions
+ public struct CallOptions
{
- readonly Metadata headers;
- readonly DateTime deadline;
- readonly CancellationToken cancellationToken;
- readonly WriteOptions writeOptions;
- readonly ContextPropagationToken propagationToken;
+ Metadata headers;
+ DateTime? deadline;
+ CancellationToken cancellationToken;
+ WriteOptions writeOptions;
+ ContextPropagationToken propagationToken;
/// <summary>
- /// Creates a new instance of <c>CallOptions</c>.
+ /// Creates a new instance of <c>CallOptions</c> struct.
/// </summary>
/// <param name="headers">Headers to be sent with the call.</param>
/// <param name="deadline">Deadline for the call to finish. null means no deadline.</param>
/// <param name="cancellationToken">Can be used to request cancellation of the call.</param>
/// <param name="writeOptions">Write options that will be used for this call.</param>
/// <param name="propagationToken">Context propagation token obtained from <see cref="ServerCallContext"/>.</param>
- public CallOptions(Metadata headers = null, DateTime? deadline = null, CancellationToken? cancellationToken = null,
+ public CallOptions(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken),
WriteOptions writeOptions = null, ContextPropagationToken propagationToken = null)
{
- // TODO(jtattermusch): consider only creating metadata object once it's really needed.
- this.headers = headers ?? new Metadata();
- this.deadline = deadline ?? (propagationToken != null ? propagationToken.Deadline : DateTime.MaxValue);
- this.cancellationToken = cancellationToken ?? (propagationToken != null ? propagationToken.CancellationToken : CancellationToken.None);
+ this.headers = headers;
+ this.deadline = deadline;
+ this.cancellationToken = cancellationToken;
this.writeOptions = writeOptions;
this.propagationToken = propagationToken;
}
@@ -80,7 +79,7 @@ namespace Grpc.Core
/// <summary>
/// Call deadline.
/// </summary>
- public DateTime Deadline
+ public DateTime? Deadline
{
get { return deadline; }
}
@@ -114,5 +113,66 @@ namespace Grpc.Core
return this.propagationToken;
}
}
+
+ /// <summary>
+ /// Returns new instance of <see cref="CallOptions"/> with
+ /// <c>Headers</c> set to the value provided. Values of all other fields are preserved.
+ /// </summary>
+ public CallOptions WithHeaders(Metadata headers)
+ {
+ var newOptions = this;
+ newOptions.headers = headers;
+ return newOptions;
+ }
+
+ /// <summary>
+ /// Returns new instance of <see cref="CallOptions"/> with
+ /// <c>Deadline</c> set to the value provided. Values of all other fields are preserved.
+ /// </summary>
+ public CallOptions WithDeadline(DateTime deadline)
+ {
+ var newOptions = this;
+ newOptions.deadline = deadline;
+ return newOptions;
+ }
+
+ /// <summary>
+ /// Returns new instance of <see cref="CallOptions"/> with
+ /// <c>CancellationToken</c> set to the value provided. Values of all other fields are preserved.
+ /// </summary>
+ public CallOptions WithCancellationToken(CancellationToken cancellationToken)
+ {
+ var newOptions = this;
+ newOptions.cancellationToken = cancellationToken;
+ return newOptions;
+ }
+
+ /// <summary>
+ /// Returns a new instance of <see cref="CallOptions"/> with
+ /// all previously unset values set to their defaults and deadline and cancellation
+ /// token propagated when appropriate.
+ /// </summary>
+ internal CallOptions Normalize()
+ {
+ var newOptions = this;
+ if (propagationToken != null)
+ {
+ if (propagationToken.Options.IsPropagateDeadline)
+ {
+ Preconditions.CheckArgument(!newOptions.deadline.HasValue,
+ "Cannot propagate deadline from parent call. The deadline has already been set explicitly.");
+ newOptions.deadline = propagationToken.ParentDeadline;
+ }
+ if (propagationToken.Options.IsPropagateCancellation)
+ {
+ Preconditions.CheckArgument(!newOptions.cancellationToken.CanBeCanceled,
+ "Cannot propagate cancellation token from parent call. The cancellation token has already been set to a non-default value.");
+ }
+ }
+
+ newOptions.headers = newOptions.headers ?? Metadata.Empty;
+ newOptions.deadline = newOptions.deadline ?? DateTime.MaxValue;
+ return newOptions;
+ }
}
}
diff --git a/src/csharp/Grpc.Core/Calls.cs b/src/csharp/Grpc.Core/Calls.cs
index 00a8cabf82..7067456638 100644
--- a/src/csharp/Grpc.Core/Calls.cs
+++ b/src/csharp/Grpc.Core/Calls.cs
@@ -31,8 +31,6 @@
#endregion
-using System;
-using System.Threading;
using System.Threading.Tasks;
using Grpc.Core.Internal;
@@ -40,9 +38,20 @@ namespace Grpc.Core
{
/// <summary>
/// Helper methods for generated clients to make RPC calls.
+ /// Most users will use this class only indirectly and will be
+ /// making calls using client object generated from protocol
+ /// buffer definition files.
/// </summary>
public static class Calls
{
+ /// <summary>
+ /// Invokes a simple remote call in a blocking fashion.
+ /// </summary>
+ /// <returns>The response.</returns>
+ /// <param name="call">The call defintion.</param>
+ /// <param name="req">Request message.</param>
+ /// <typeparam name="TRequest">Type of request message.</typeparam>
+ /// <typeparam name="TResponse">The of response message.</typeparam>
public static TResponse BlockingUnaryCall<TRequest, TResponse>(CallInvocationDetails<TRequest, TResponse> call, TRequest req)
where TRequest : class
where TResponse : class
@@ -51,6 +60,14 @@ namespace Grpc.Core
return asyncCall.UnaryCall(req);
}
+ /// <summary>
+ /// Invokes a simple remote call asynchronously.
+ /// </summary>
+ /// <returns>An awaitable call object providing access to the response.</returns>
+ /// <param name="call">The call defintion.</param>
+ /// <param name="req">Request message.</param>
+ /// <typeparam name="TRequest">Type of request message.</typeparam>
+ /// <typeparam name="TResponse">The of response message.</typeparam>
public static AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(CallInvocationDetails<TRequest, TResponse> call, TRequest req)
where TRequest : class
where TResponse : class
@@ -60,6 +77,15 @@ namespace Grpc.Core
return new AsyncUnaryCall<TResponse>(asyncResult, asyncCall.GetStatus, asyncCall.GetTrailers, asyncCall.Cancel);
}
+ /// <summary>
+ /// Invokes a server streaming call asynchronously.
+ /// In server streaming scenario, client sends on request and server responds with a stream of responses.
+ /// </summary>
+ /// <returns>A call object providing access to the asynchronous response stream.</returns>
+ /// <param name="call">The call defintion.</param>
+ /// <param name="req">Request message.</param>
+ /// <typeparam name="TRequest">Type of request message.</typeparam>
+ /// <typeparam name="TResponse">The of response messages.</typeparam>
public static AsyncServerStreamingCall<TResponse> AsyncServerStreamingCall<TRequest, TResponse>(CallInvocationDetails<TRequest, TResponse> call, TRequest req)
where TRequest : class
where TResponse : class
@@ -70,6 +96,13 @@ namespace Grpc.Core
return new AsyncServerStreamingCall<TResponse>(responseStream, asyncCall.GetStatus, asyncCall.GetTrailers, asyncCall.Cancel);
}
+ /// <summary>
+ /// Invokes a client streaming call asynchronously.
+ /// In client streaming scenario, client sends a stream of requests and server responds with a single response.
+ /// </summary>
+ /// <returns>An awaitable call object providing access to the response.</returns>
+ /// <typeparam name="TRequest">Type of request messages.</typeparam>
+ /// <typeparam name="TResponse">The of response message.</typeparam>
public static AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>(CallInvocationDetails<TRequest, TResponse> call)
where TRequest : class
where TResponse : class
@@ -80,6 +113,15 @@ namespace Grpc.Core
return new AsyncClientStreamingCall<TRequest, TResponse>(requestStream, resultTask, asyncCall.GetStatus, asyncCall.GetTrailers, asyncCall.Cancel);
}
+ /// <summary>
+ /// Invokes a duplex streaming call asynchronously.
+ /// In duplex streaming scenario, client sends a stream of requests and server responds with a stream of responses.
+ /// The response stream is completely independent and both side can be sending messages at the same time.
+ /// </summary>
+ /// <returns>A call object providing access to the asynchronous request and response streams.</returns>
+ /// <param name="call">The call definition.</param>
+ /// <typeparam name="TRequest">Type of request messages.</typeparam>
+ /// <typeparam name="TResponse">Type of reponse messages.</typeparam>
public static AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCall<TRequest, TResponse>(CallInvocationDetails<TRequest, TResponse> call)
where TRequest : class
where TResponse : class
diff --git a/src/csharp/Grpc.Core/Channel.cs b/src/csharp/Grpc.Core/Channel.cs
index 9273ea4582..64c6adf2bf 100644
--- a/src/csharp/Grpc.Core/Channel.cs
+++ b/src/csharp/Grpc.Core/Channel.cs
@@ -49,6 +49,7 @@ namespace Grpc.Core
{
static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<Channel>();
+ readonly string target;
readonly GrpcEnvironment environment;
readonly ChannelSafeHandle handle;
readonly List<ChannelOption> options;
@@ -58,12 +59,12 @@ namespace Grpc.Core
/// Creates a channel that connects to a specific host.
/// Port will default to 80 for an unsecure channel and to 443 for a secure channel.
/// </summary>
- /// <param name="host">The name or IP address of the host.</param>
+ /// <param name="target">Target of the channel.</param>
/// <param name="credentials">Credentials to secure the channel.</param>
/// <param name="options">Channel options.</param>
- public Channel(string host, Credentials credentials, IEnumerable<ChannelOption> options = null)
+ public Channel(string target, Credentials credentials, IEnumerable<ChannelOption> options = null)
{
- Preconditions.CheckNotNull(host);
+ this.target = Preconditions.CheckNotNull(target, "target");
this.environment = GrpcEnvironment.GetInstance();
this.options = options != null ? new List<ChannelOption>(options) : new List<ChannelOption>();
@@ -73,11 +74,11 @@ namespace Grpc.Core
{
if (nativeCredentials != null)
{
- this.handle = ChannelSafeHandle.CreateSecure(nativeCredentials, host, nativeChannelArgs);
+ this.handle = ChannelSafeHandle.CreateSecure(nativeCredentials, target, nativeChannelArgs);
}
else
{
- this.handle = ChannelSafeHandle.CreateInsecure(host, nativeChannelArgs);
+ this.handle = ChannelSafeHandle.CreateInsecure(target, nativeChannelArgs);
}
}
}
@@ -131,8 +132,8 @@ namespace Grpc.Core
return tcs.Task;
}
- /// <summary> Address of the remote endpoint in URI format.</summary>
- public string Target
+ /// <summary>Resolved address of the remote endpoint in URI format.</summary>
+ public string ResolvedTarget
{
get
{
@@ -140,6 +141,15 @@ namespace Grpc.Core
}
}
+ /// <summary>The original target used to create the channel.</summary>
+ public string Target
+ {
+ get
+ {
+ return this.target;
+ }
+ }
+
/// <summary>
/// Allows explicitly requesting channel to connect without starting an RPC.
/// Returned task completes once state Ready was seen. If the deadline is reached,
diff --git a/src/csharp/Grpc.Core/ChannelOptions.cs b/src/csharp/Grpc.Core/ChannelOptions.cs
index 1e0f90287a..0cb2953f2c 100644
--- a/src/csharp/Grpc.Core/ChannelOptions.cs
+++ b/src/csharp/Grpc.Core/ChannelOptions.cs
@@ -63,8 +63,8 @@ namespace Grpc.Core
public ChannelOption(string name, string stringValue)
{
this.type = OptionType.String;
- this.name = Preconditions.CheckNotNull(name);
- this.stringValue = Preconditions.CheckNotNull(stringValue);
+ this.name = Preconditions.CheckNotNull(name, "name");
+ this.stringValue = Preconditions.CheckNotNull(stringValue, "stringValue");
}
/// <summary>
@@ -75,7 +75,7 @@ namespace Grpc.Core
public ChannelOption(string name, int intValue)
{
this.type = OptionType.Integer;
- this.name = Preconditions.CheckNotNull(name);
+ this.name = Preconditions.CheckNotNull(name, "name");
this.intValue = intValue;
}
diff --git a/src/csharp/Grpc.Core/ClientBase.cs b/src/csharp/Grpc.Core/ClientBase.cs
index 88494bb4ac..f46184406c 100644
--- a/src/csharp/Grpc.Core/ClientBase.cs
+++ b/src/csharp/Grpc.Core/ClientBase.cs
@@ -35,21 +35,26 @@ using System;
using System.Collections.Generic;
using Grpc.Core.Internal;
+using System.Text.RegularExpressions;
namespace Grpc.Core
{
- public delegate void MetadataInterceptorDelegate(Metadata metadata);
+ public delegate void MetadataInterceptorDelegate(string authUri, Metadata metadata);
/// <summary>
/// Base class for client-side stubs.
/// </summary>
public abstract class ClientBase
{
+ static readonly Regex TrailingPortPattern = new Regex(":[0-9]+/?$");
readonly Channel channel;
+ readonly string authUriBase;
public ClientBase(Channel channel)
{
this.channel = channel;
+ // TODO(jtattermush): we shouldn't need to hand-curate the channel.Target contents.
+ this.authUriBase = "https://" + TrailingPortPattern.Replace(channel.Target, "") + "/";
}
/// <summary>
@@ -63,6 +68,18 @@ namespace Grpc.Core
}
/// <summary>
+ /// gRPC supports multiple "hosts" being served by a single server.
+ /// This property can be used to set the target host explicitly.
+ /// By default, this will be set to <c>null</c> with the meaning
+ /// "use default host".
+ /// </summary>
+ public string Host
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
/// Channel associated with this client.
/// </summary>
public Channel Channel
@@ -83,10 +100,14 @@ namespace Grpc.Core
var interceptor = HeaderInterceptor;
if (interceptor != null)
{
- interceptor(options.Headers);
- options.Headers.Freeze();
+ if (options.Headers == null)
+ {
+ options = options.WithHeaders(new Metadata());
+ }
+ var authUri = authUriBase + method.ServiceName;
+ interceptor(authUri, options.Headers);
}
- return new CallInvocationDetails<TRequest, TResponse>(channel, method, options);
+ return new CallInvocationDetails<TRequest, TResponse>(channel, method, Host, options);
}
}
}
diff --git a/src/csharp/Grpc.Core/ContextPropagationToken.cs b/src/csharp/Grpc.Core/ContextPropagationToken.cs
index b6ea5115a4..2e4bfc9e47 100644
--- a/src/csharp/Grpc.Core/ContextPropagationToken.cs
+++ b/src/csharp/Grpc.Core/ContextPropagationToken.cs
@@ -52,7 +52,7 @@ namespace Grpc.Core
/// <summary>
/// Default propagation mask used by C core.
/// </summary>
- const ContextPropagationFlags DefaultCoreMask = (ContextPropagationFlags)0xffff;
+ private const ContextPropagationFlags DefaultCoreMask = (ContextPropagationFlags)0xffff;
/// <summary>
/// Default propagation mask used by C# - we want to propagate deadline
@@ -74,6 +74,9 @@ namespace Grpc.Core
this.options = options ?? ContextPropagationOptions.Default;
}
+ /// <summary>
+ /// Gets the native handle of the parent call.
+ /// </summary>
internal CallSafeHandle ParentCall
{
get
@@ -82,7 +85,10 @@ namespace Grpc.Core
}
}
- internal DateTime Deadline
+ /// <summary>
+ /// Gets the parent call's deadline.
+ /// </summary>
+ internal DateTime ParentDeadline
{
get
{
@@ -90,7 +96,10 @@ namespace Grpc.Core
}
}
- internal CancellationToken CancellationToken
+ /// <summary>
+ /// Gets the parent call's cancellation token.
+ /// </summary>
+ internal CancellationToken ParentCancellationToken
{
get
{
@@ -98,6 +107,9 @@ namespace Grpc.Core
}
}
+ /// <summary>
+ /// Get the context propagation options.
+ /// </summary>
internal ContextPropagationOptions Options
{
get
@@ -105,16 +117,6 @@ namespace Grpc.Core
return this.options;
}
}
-
- internal bool IsPropagateDeadline
- {
- get { return false; }
- }
-
- internal bool IsPropagateCancellation
- {
- get { return false; }
- }
}
/// <summary>
@@ -122,7 +124,37 @@ namespace Grpc.Core
/// </summary>
public class ContextPropagationOptions
{
+ /// <summary>
+ /// The context propagation options that will be used by default.
+ /// </summary>
public static readonly ContextPropagationOptions Default = new ContextPropagationOptions();
+
+ bool propagateDeadline;
+ bool propagateCancellation;
+
+
+ /// <summary>
+ /// Creates new context propagation options.
+ /// </summary>
+ /// <param name="propagateDeadline">If set to <c>true</c> parent call's deadline will be propagated to the child call.</param>
+ /// <param name="propagateCancellation">If set to <c>true</c> parent call's cancellation token will be propagated to the child call.</param>
+ public ContextPropagationOptions(bool propagateDeadline = true, bool propagateCancellation = true)
+ {
+ this.propagateDeadline = propagateDeadline;
+ this.propagateCancellation = propagateCancellation;
+ }
+
+ /// <value><c>true</c> if parent call's deadline should be propagated to the child call.</value>
+ public bool IsPropagateDeadline
+ {
+ get { return this.propagateDeadline; }
+ }
+
+ /// <value><c>true</c> if parent call's cancellation token should be propagated to the child call.</value>
+ public bool IsPropagateCancellation
+ {
+ get { return this.propagateCancellation; }
+ }
}
/// <summary>
diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj
index e535c47f55..055aff1444 100644
--- a/src/csharp/Grpc.Core/Grpc.Core.csproj
+++ b/src/csharp/Grpc.Core/Grpc.Core.csproj
@@ -77,14 +77,12 @@
<Compile Include="ServerServiceDefinition.cs" />
<Compile Include="Utils\AsyncStreamExtensions.cs" />
<Compile Include="Utils\BenchmarkUtil.cs" />
- <Compile Include="Utils\ExceptionHelper.cs" />
<Compile Include="Internal\CredentialsSafeHandle.cs" />
<Compile Include="Credentials.cs" />
<Compile Include="Internal\ChannelArgsSafeHandle.cs" />
<Compile Include="Internal\AsyncCompletion.cs" />
<Compile Include="Internal\AsyncCallBase.cs" />
<Compile Include="Internal\AsyncCallServer.cs" />
- <Compile Include="OperationFailedException.cs" />
<Compile Include="Internal\AsyncCall.cs" />
<Compile Include="Utils\Preconditions.cs" />
<Compile Include="Internal\ServerCredentialsSafeHandle.cs" />
diff --git a/src/csharp/Grpc.Core/GrpcEnvironment.cs b/src/csharp/Grpc.Core/GrpcEnvironment.cs
index 1bb83c9962..30d8c80235 100644
--- a/src/csharp/Grpc.Core/GrpcEnvironment.cs
+++ b/src/csharp/Grpc.Core/GrpcEnvironment.cs
@@ -115,7 +115,7 @@ namespace Grpc.Core
/// </summary>
public static void SetLogger(ILogger customLogger)
{
- Preconditions.CheckNotNull(customLogger);
+ Preconditions.CheckNotNull(customLogger, "customLogger");
logger = customLogger;
}
@@ -192,23 +192,5 @@ namespace Grpc.Core
Logger.Info("gRPC shutdown.");
}
-
- /// <summary>
- /// Shuts down this environment asynchronously.
- /// </summary>
- private Task CloseAsync()
- {
- return Task.Run(() =>
- {
- try
- {
- Close();
- }
- catch (Exception e)
- {
- Logger.Error(e, "Error occured while shutting down GrpcEnvironment.");
- }
- });
- }
}
}
diff --git a/src/csharp/Grpc.Core/IAsyncStreamReader.cs b/src/csharp/Grpc.Core/IAsyncStreamReader.cs
index 371fbf27ce..c0a0674e50 100644
--- a/src/csharp/Grpc.Core/IAsyncStreamReader.cs
+++ b/src/csharp/Grpc.Core/IAsyncStreamReader.cs
@@ -43,7 +43,7 @@ namespace Grpc.Core
/// A stream of messages to be read.
/// </summary>
/// <typeparam name="T"></typeparam>
- public interface IAsyncStreamReader<TResponse> : IAsyncEnumerator<TResponse>
+ public interface IAsyncStreamReader<T> : IAsyncEnumerator<T>
{
// TODO(jtattermusch): consider just using IAsyncEnumerator instead of this interface.
}
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
index 0db9d2a515..2c3e3d75ea 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
@@ -63,7 +63,7 @@ namespace Grpc.Core.Internal
public AsyncCall(CallInvocationDetails<TRequest, TResponse> callDetails)
: base(callDetails.RequestMarshaller.Serializer, callDetails.ResponseMarshaller.Deserializer)
{
- this.details = callDetails;
+ this.details = callDetails.WithOptions(callDetails.Options.Normalize());
this.initialMetadataSent = true; // we always send metadata at the very beginning of the call.
}
@@ -109,15 +109,9 @@ namespace Grpc.Core.Internal
}
}
- try
- {
- // Once the blocking call returns, the result should be available synchronously.
- return unaryResponseTcs.Task.Result;
- }
- catch (AggregateException ae)
- {
- throw ExceptionHelper.UnwrapRpcException(ae);
- }
+ // Once the blocking call returns, the result should be available synchronously.
+ // Note that GetAwaiter().GetResult() doesn't wrap exceptions in AggregateException.
+ return unaryResponseTcs.Task.GetAwaiter().GetResult();
}
}
@@ -324,12 +318,11 @@ namespace Grpc.Core.Internal
private void Initialize(CompletionQueueSafeHandle cq)
{
- var propagationToken = details.Options.PropagationToken;
- var parentCall = propagationToken != null ? propagationToken.ParentCall : CallSafeHandle.NullInstance;
+ var parentCall = details.Options.PropagationToken != null ? details.Options.PropagationToken.ParentCall : CallSafeHandle.NullInstance;
var call = details.Channel.Handle.CreateCall(details.Channel.Environment.CompletionRegistry,
parentCall, ContextPropagationToken.DefaultMask, cq,
- details.Method, details.Host, Timespec.FromDateTime(details.Options.Deadline));
+ details.Method, details.Host, Timespec.FromDateTime(details.Options.Deadline.Value));
details.Channel.Environment.DebugStats.ActiveClientCalls.Increment();
InitializeInternal(call);
RegisterCancellationCallback();
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
index 9fa0baca87..6ca4bbdafc 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
@@ -293,7 +293,7 @@ namespace Grpc.Core.Internal
if (!success)
{
- FireCompletion(origCompletionDelegate, null, new OperationFailedException("Send failed"));
+ FireCompletion(origCompletionDelegate, null, new InvalidOperationException("Send failed"));
}
else
{
@@ -318,7 +318,7 @@ namespace Grpc.Core.Internal
if (!success)
{
- FireCompletion(origCompletionDelegate, null, new OperationFailedException("Halfclose failed"));
+ FireCompletion(origCompletionDelegate, null, new InvalidOperationException("Halfclose failed"));
}
else
{
diff --git a/src/csharp/Grpc.Core/Internal/Timespec.cs b/src/csharp/Grpc.Core/Internal/Timespec.cs
index e83d21f4a4..daf85d5f61 100644
--- a/src/csharp/Grpc.Core/Internal/Timespec.cs
+++ b/src/csharp/Grpc.Core/Internal/Timespec.cs
@@ -211,7 +211,7 @@ namespace Grpc.Core.Internal
return Timespec.InfPast;
}
- Preconditions.CheckArgument(dateTime.Kind == DateTimeKind.Utc, "dateTime");
+ Preconditions.CheckArgument(dateTime.Kind == DateTimeKind.Utc, "dateTime needs of kind DateTimeKind.Utc or be equal to DateTime.MaxValue or DateTime.MinValue.");
try
{
diff --git a/src/csharp/Grpc.Core/KeyCertificatePair.cs b/src/csharp/Grpc.Core/KeyCertificatePair.cs
index 5def15a656..6f691975e9 100644
--- a/src/csharp/Grpc.Core/KeyCertificatePair.cs
+++ b/src/csharp/Grpc.Core/KeyCertificatePair.cs
@@ -54,8 +54,8 @@ namespace Grpc.Core
/// <param name="privateKey">PEM encoded private key.</param>
public KeyCertificatePair(string certificateChain, string privateKey)
{
- this.certificateChain = Preconditions.CheckNotNull(certificateChain);
- this.privateKey = Preconditions.CheckNotNull(privateKey);
+ this.certificateChain = Preconditions.CheckNotNull(certificateChain, "certificateChain");
+ this.privateKey = Preconditions.CheckNotNull(privateKey, "privateKey");
}
/// <summary>
diff --git a/src/csharp/Grpc.Core/Logging/ConsoleLogger.cs b/src/csharp/Grpc.Core/Logging/ConsoleLogger.cs
index c67765c78d..382481d871 100644
--- a/src/csharp/Grpc.Core/Logging/ConsoleLogger.cs
+++ b/src/csharp/Grpc.Core/Logging/ConsoleLogger.cs
@@ -42,16 +42,21 @@ namespace Grpc.Core.Logging
readonly Type forType;
readonly string forTypeString;
+ /// <summary>Creates a console logger not associated to any specific type.</summary>
public ConsoleLogger() : this(null)
{
}
+ /// <summary>Creates a console logger that logs messsage specific for given type.</summary>
private ConsoleLogger(Type forType)
{
this.forType = forType;
this.forTypeString = forType != null ? forType.FullName + " " : "";
}
-
+
+ /// <summary>
+ /// Returns a logger associated with the specified type.
+ /// </summary>
public ILogger ForType<T>()
{
if (typeof(T) == forType)
@@ -61,31 +66,37 @@ namespace Grpc.Core.Logging
return new ConsoleLogger(typeof(T));
}
+ /// <summary>Logs a message with severity Debug.</summary>
public void Debug(string message, params object[] formatArgs)
{
Log("D", message, formatArgs);
}
+ /// <summary>Logs a message with severity Info.</summary>
public void Info(string message, params object[] formatArgs)
{
Log("I", message, formatArgs);
}
+ /// <summary>Logs a message with severity Warning.</summary>
public void Warning(string message, params object[] formatArgs)
{
Log("W", message, formatArgs);
}
+ /// <summary>Logs a message and an associated exception with severity Warning.</summary>
public void Warning(Exception exception, string message, params object[] formatArgs)
{
Log("W", message + " " + exception, formatArgs);
}
+ /// <summary>Logs a message with severity Error.</summary>
public void Error(string message, params object[] formatArgs)
{
Log("E", message, formatArgs);
}
+ /// <summary>Logs a message and an associated exception with severity Error.</summary>
public void Error(Exception exception, string message, params object[] formatArgs)
{
Log("E", message + " " + exception, formatArgs);
diff --git a/src/csharp/Grpc.Core/Logging/ILogger.cs b/src/csharp/Grpc.Core/Logging/ILogger.cs
index 0d58f133e3..61e0c91388 100644
--- a/src/csharp/Grpc.Core/Logging/ILogger.cs
+++ b/src/csharp/Grpc.Core/Logging/ILogger.cs
@@ -42,16 +42,22 @@ namespace Grpc.Core.Logging
/// <summary>Returns a logger associated with the specified type.</summary>
ILogger ForType<T>();
+ /// <summary>Logs a message with severity Debug.</summary>
void Debug(string message, params object[] formatArgs);
+ /// <summary>Logs a message with severity Info.</summary>
void Info(string message, params object[] formatArgs);
+ /// <summary>Logs a message with severity Warning.</summary>
void Warning(string message, params object[] formatArgs);
+ /// <summary>Logs a message and an associated exception with severity Warning.</summary>
void Warning(Exception exception, string message, params object[] formatArgs);
+ /// <summary>Logs a message with severity Error.</summary>
void Error(string message, params object[] formatArgs);
+ /// <summary>Logs a message and an associated exception with severity Error.</summary>
void Error(Exception exception, string message, params object[] formatArgs);
}
}
diff --git a/src/csharp/Grpc.Core/Marshaller.cs b/src/csharp/Grpc.Core/Marshaller.cs
index 8b1a929074..f38cb0863f 100644
--- a/src/csharp/Grpc.Core/Marshaller.cs
+++ b/src/csharp/Grpc.Core/Marshaller.cs
@@ -37,19 +37,27 @@ using Grpc.Core.Utils;
namespace Grpc.Core
{
/// <summary>
- /// For serializing and deserializing messages.
+ /// Encapsulates the logic for serializing and deserializing messages.
/// </summary>
public struct Marshaller<T>
{
readonly Func<T, byte[]> serializer;
readonly Func<byte[], T> deserializer;
+ /// <summary>
+ /// Initializes a new marshaller.
+ /// </summary>
+ /// <param name="serializer">Function that will be used to serialize messages.</param>
+ /// <param name="deserializer">Function that will be used to deserialize messages.</param>
public Marshaller(Func<T, byte[]> serializer, Func<byte[], T> deserializer)
{
- this.serializer = Preconditions.CheckNotNull(serializer);
- this.deserializer = Preconditions.CheckNotNull(deserializer);
+ this.serializer = Preconditions.CheckNotNull(serializer, "serializer");
+ this.deserializer = Preconditions.CheckNotNull(deserializer, "deserializer");
}
+ /// <summary>
+ /// Gets the serializer function.
+ /// </summary>
public Func<T, byte[]> Serializer
{
get
@@ -58,6 +66,9 @@ namespace Grpc.Core
}
}
+ /// <summary>
+ /// Gets the deserializer function.
+ /// </summary>
public Func<byte[], T> Deserializer
{
get
@@ -72,11 +83,17 @@ namespace Grpc.Core
/// </summary>
public static class Marshallers
{
+ /// <summary>
+ /// Creates a marshaller from specified serializer and deserializer.
+ /// </summary>
public static Marshaller<T> Create<T>(Func<T, byte[]> serializer, Func<byte[], T> deserializer)
{
return new Marshaller<T>(serializer, deserializer);
}
+ /// <summary>
+ /// Returns a marshaller for <c>string</c> type. This is useful for testing.
+ /// </summary>
public static Marshaller<string> StringMarshaller
{
get
diff --git a/src/csharp/Grpc.Core/Metadata.cs b/src/csharp/Grpc.Core/Metadata.cs
index a58dbdbc93..9db2abf46e 100644
--- a/src/csharp/Grpc.Core/Metadata.cs
+++ b/src/csharp/Grpc.Core/Metadata.cs
@@ -186,15 +186,15 @@ namespace Grpc.Core
public Entry(string key, byte[] valueBytes)
{
- this.key = Preconditions.CheckNotNull(key);
+ this.key = Preconditions.CheckNotNull(key, "key");
this.value = null;
- this.valueBytes = Preconditions.CheckNotNull(valueBytes);
+ this.valueBytes = Preconditions.CheckNotNull(valueBytes, "valueBytes");
}
public Entry(string key, string value)
{
- this.key = Preconditions.CheckNotNull(key);
- this.value = Preconditions.CheckNotNull(value);
+ this.key = Preconditions.CheckNotNull(key, "key");
+ this.value = Preconditions.CheckNotNull(value, "value");
this.valueBytes = null;
}
diff --git a/src/csharp/Grpc.Core/Method.cs b/src/csharp/Grpc.Core/Method.cs
index cc047ac9f8..4c208b4a26 100644
--- a/src/csharp/Grpc.Core/Method.cs
+++ b/src/csharp/Grpc.Core/Method.cs
@@ -41,14 +41,21 @@ namespace Grpc.Core
/// </summary>
public enum MethodType
{
- Unary, // Unary request, unary response.
- ClientStreaming, // Streaming request, unary response.
- ServerStreaming, // Unary request, streaming response.
- DuplexStreaming // Streaming request, streaming response.
+ /// <summary>Single request sent from client, single response received from server.</summary>
+ Unary,
+
+ /// <summary>Stream of request sent from client, single response received from server.</summary>
+ ClientStreaming,
+
+ /// <summary>Single request sent from client, stream of responses received from server.</summary>
+ ServerStreaming,
+
+ /// <summary>Both server and client can stream arbitrary number of requests and responses simultaneously.</summary>
+ DuplexStreaming
}
/// <summary>
- /// A description of a service method.
+ /// A description of a remote method.
/// </summary>
public class Method<TRequest, TResponse>
{
@@ -59,16 +66,27 @@ namespace Grpc.Core
readonly Marshaller<TResponse> responseMarshaller;
readonly string fullName;
+ /// <summary>
+ /// Initializes a new instance of the <c>Method</c> class.
+ /// </summary>
+ /// <param name="type">Type of method.</param>
+ /// <param name="serviceName">Name of service this method belongs to.</param>
+ /// <param name="name">Unqualified name of the method.</param>
+ /// <param name="requestMarshaller">Marshaller used for request messages.</param>
+ /// <param name="responseMarshaller">Marshaller used for response messages.</param>
public Method(MethodType type, string serviceName, string name, Marshaller<TRequest> requestMarshaller, Marshaller<TResponse> responseMarshaller)
{
this.type = type;
- this.serviceName = Preconditions.CheckNotNull(serviceName);
- this.name = Preconditions.CheckNotNull(name);
- this.requestMarshaller = Preconditions.CheckNotNull(requestMarshaller);
- this.responseMarshaller = Preconditions.CheckNotNull(responseMarshaller);
- this.fullName = GetFullName(serviceName);
+ this.serviceName = Preconditions.CheckNotNull(serviceName, "serviceName");
+ this.name = Preconditions.CheckNotNull(name, "name");
+ this.requestMarshaller = Preconditions.CheckNotNull(requestMarshaller, "requestMarshaller");
+ this.responseMarshaller = Preconditions.CheckNotNull(responseMarshaller, "responseMarshaller");
+ this.fullName = GetFullName(serviceName, name);
}
+ /// <summary>
+ /// Gets the type of the method.
+ /// </summary>
public MethodType Type
{
get
@@ -77,6 +95,9 @@ namespace Grpc.Core
}
}
+ /// <summary>
+ /// Gets the name of the service to which this method belongs.
+ /// </summary>
public string ServiceName
{
get
@@ -85,6 +106,9 @@ namespace Grpc.Core
}
}
+ /// <summary>
+ /// Gets the unqualified name of the method.
+ /// </summary>
public string Name
{
get
@@ -93,6 +117,9 @@ namespace Grpc.Core
}
}
+ /// <summary>
+ /// Gets the marshaller used for request messages.
+ /// </summary>
public Marshaller<TRequest> RequestMarshaller
{
get
@@ -101,6 +128,9 @@ namespace Grpc.Core
}
}
+ /// <summary>
+ /// Gets the marshaller used for response messages.
+ /// </summary>
public Marshaller<TResponse> ResponseMarshaller
{
get
@@ -108,7 +138,11 @@ namespace Grpc.Core
return this.responseMarshaller;
}
}
-
+
+ /// <summary>
+ /// Gets the fully qualified name of the method. On the server side, methods are dispatched
+ /// based on this name.
+ /// </summary>
public string FullName
{
get
@@ -120,9 +154,9 @@ namespace Grpc.Core
/// <summary>
/// Gets full name of the method including the service name.
/// </summary>
- internal string GetFullName(string serviceName)
+ internal static string GetFullName(string serviceName, string methodName)
{
- return "/" + Preconditions.CheckNotNull(serviceName) + "/" + this.Name;
+ return "/" + serviceName + "/" + methodName;
}
}
}
diff --git a/src/csharp/Grpc.Core/OperationFailedException.cs b/src/csharp/Grpc.Core/OperationFailedException.cs
deleted file mode 100644
index 9b1c24d0c1..0000000000
--- a/src/csharp/Grpc.Core/OperationFailedException.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-#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;
-
-namespace Grpc.Core
-{
- /// <summary>
- /// Thrown when gRPC operation fails.
- /// </summary>
- public class OperationFailedException : Exception
- {
- public OperationFailedException(string message) : base(message)
- {
- }
- }
-}
diff --git a/src/csharp/Grpc.Core/RpcException.cs b/src/csharp/Grpc.Core/RpcException.cs
index c58578286b..cac417e626 100644
--- a/src/csharp/Grpc.Core/RpcException.cs
+++ b/src/csharp/Grpc.Core/RpcException.cs
@@ -36,22 +36,34 @@ using System;
namespace Grpc.Core
{
/// <summary>
- /// Thrown when remote procedure call fails.
+ /// Thrown when remote procedure call fails. Every <c>RpcException</c> is associated with a resulting <see cref="Status"/> of the call.
/// </summary>
public class RpcException : Exception
{
private readonly Status status;
+ /// <summary>
+ /// Creates a new <c>RpcException</c> associated with given status.
+ /// </summary>
+ /// <param name="status">Resulting status of a call.</param>
public RpcException(Status status) : base(status.ToString())
{
this.status = status;
}
+ /// <summary>
+ /// Creates a new <c>RpcException</c> associated with given status and message.
+ /// </summary>
+ /// <param name="status">Resulting status of a call.</param>
+ /// <param name="message">The exception message.</param>
public RpcException(Status status, string message) : base(message)
{
this.status = status;
}
+ /// <summary>
+ /// Resulting status of the call.
+ /// </summary>
public Status Status
{
get
diff --git a/src/csharp/Grpc.Core/Server.cs b/src/csharp/Grpc.Core/Server.cs
index eb5b043d1c..c76f126026 100644
--- a/src/csharp/Grpc.Core/Server.cs
+++ b/src/csharp/Grpc.Core/Server.cs
@@ -192,7 +192,7 @@ namespace Grpc.Core
{
lock (myLock)
{
- Preconditions.CheckNotNull(serverPort.Credentials);
+ Preconditions.CheckNotNull(serverPort.Credentials, "serverPort");
Preconditions.CheckState(!startRequested);
var address = string.Format("{0}:{1}", serverPort.Host, serverPort.Port);
int boundPort;
diff --git a/src/csharp/Grpc.Core/ServerCredentials.cs b/src/csharp/Grpc.Core/ServerCredentials.cs
index c11a1ede08..3c6703d30e 100644
--- a/src/csharp/Grpc.Core/ServerCredentials.cs
+++ b/src/csharp/Grpc.Core/ServerCredentials.cs
@@ -91,7 +91,7 @@ namespace Grpc.Core
{
this.keyCertificatePairs = new List<KeyCertificatePair>(keyCertificatePairs).AsReadOnly();
Preconditions.CheckArgument(this.keyCertificatePairs.Count > 0,
- "At least one KeyCertificatePair needs to be provided");
+ "At least one KeyCertificatePair needs to be provided.");
if (forceClientAuth)
{
Preconditions.CheckNotNull(rootCertificates,
diff --git a/src/csharp/Grpc.Core/ServerMethods.cs b/src/csharp/Grpc.Core/ServerMethods.cs
index d457770203..1f119a80ff 100644
--- a/src/csharp/Grpc.Core/ServerMethods.cs
+++ b/src/csharp/Grpc.Core/ServerMethods.cs
@@ -31,12 +31,8 @@
#endregion
-using System;
-using System.Threading;
using System.Threading.Tasks;
-using Grpc.Core.Internal;
-
namespace Grpc.Core
{
/// <summary>
diff --git a/src/csharp/Grpc.Core/ServerPort.cs b/src/csharp/Grpc.Core/ServerPort.cs
index 55e4bd0062..598404d045 100644
--- a/src/csharp/Grpc.Core/ServerPort.cs
+++ b/src/csharp/Grpc.Core/ServerPort.cs
@@ -62,9 +62,9 @@ namespace Grpc.Core
/// <param name="credentials">credentials to use to secure this port.</param>
public ServerPort(string host, int port, ServerCredentials credentials)
{
- this.host = Preconditions.CheckNotNull(host);
+ this.host = Preconditions.CheckNotNull(host, "host");
this.port = port;
- this.credentials = Preconditions.CheckNotNull(credentials);
+ this.credentials = Preconditions.CheckNotNull(credentials, "credentials");
}
/// <summary>
diff --git a/src/csharp/Grpc.Core/ServerServiceDefinition.cs b/src/csharp/Grpc.Core/ServerServiceDefinition.cs
index a00d156e52..94b0a320c3 100644
--- a/src/csharp/Grpc.Core/ServerServiceDefinition.cs
+++ b/src/csharp/Grpc.Core/ServerServiceDefinition.cs
@@ -79,7 +79,7 @@ namespace Grpc.Core
where TRequest : class
where TResponse : class
{
- callHandlers.Add(method.GetFullName(serviceName), ServerCalls.UnaryCall(method, handler));
+ callHandlers.Add(method.FullName, ServerCalls.UnaryCall(method, handler));
return this;
}
@@ -89,7 +89,7 @@ namespace Grpc.Core
where TRequest : class
where TResponse : class
{
- callHandlers.Add(method.GetFullName(serviceName), ServerCalls.ClientStreamingCall(method, handler));
+ callHandlers.Add(method.FullName, ServerCalls.ClientStreamingCall(method, handler));
return this;
}
@@ -99,7 +99,7 @@ namespace Grpc.Core
where TRequest : class
where TResponse : class
{
- callHandlers.Add(method.GetFullName(serviceName), ServerCalls.ServerStreamingCall(method, handler));
+ callHandlers.Add(method.FullName, ServerCalls.ServerStreamingCall(method, handler));
return this;
}
@@ -109,7 +109,7 @@ namespace Grpc.Core
where TRequest : class
where TResponse : class
{
- callHandlers.Add(method.GetFullName(serviceName), ServerCalls.DuplexStreamingCall(method, handler));
+ callHandlers.Add(method.FullName, ServerCalls.DuplexStreamingCall(method, handler));
return this;
}
diff --git a/src/csharp/Grpc.Core/Status.cs b/src/csharp/Grpc.Core/Status.cs
index 754f6cb3ca..6bd8dc820b 100644
--- a/src/csharp/Grpc.Core/Status.cs
+++ b/src/csharp/Grpc.Core/Status.cs
@@ -29,13 +29,12 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
-using System;
-using System.Runtime.InteropServices;
+using Grpc.Core.Utils;
namespace Grpc.Core
{
/// <summary>
- /// Represents RPC result.
+ /// Represents RPC result, which consists of <see cref="StatusCode"/> and an optional detail string.
/// </summary>
public struct Status
{
@@ -52,6 +51,11 @@ namespace Grpc.Core
readonly StatusCode statusCode;
readonly string detail;
+ /// <summary>
+ /// Creates a new instance of <c>Status</c>.
+ /// </summary>
+ /// <param name="statusCode">Status code.</param>
+ /// <param name="detail">Detail.</param>
public Status(StatusCode statusCode, string detail)
{
this.statusCode = statusCode;
@@ -80,6 +84,9 @@ namespace Grpc.Core
}
}
+ /// <summary>
+ /// Returns a <see cref="System.String"/> that represents the current <see cref="Grpc.Core.Status"/>.
+ /// </summary>
public override string ToString()
{
return string.Format("Status(StatusCode={0}, Detail=\"{1}\")", statusCode, detail);
diff --git a/src/csharp/Grpc.Core/StatusCode.cs b/src/csharp/Grpc.Core/StatusCode.cs
index a9696fa469..90606955af 100644
--- a/src/csharp/Grpc.Core/StatusCode.cs
+++ b/src/csharp/Grpc.Core/StatusCode.cs
@@ -31,8 +31,6 @@
#endregion
-using System;
-
namespace Grpc.Core
{
/// <summary>
@@ -41,101 +39,101 @@ namespace Grpc.Core
/// </summary>
public enum StatusCode
{
- /* Not an error; returned on success */
+ /// <summary>Not an error; returned on success.</summary>
OK = 0,
- /* The operation was cancelled (typically by the caller). */
+
+ /// <summary>The operation was cancelled (typically by the caller).</summary>
Cancelled = 1,
- /* Unknown error. An example of where this error may be returned is
- if a Status value received from another address space belongs to
- an error-space that is not known in this address space. Also
- errors raised by APIs that do not return enough error information
- may be converted to this error. */
+
+ /// <summary>
+ /// Unknown error. An example of where this error may be returned is
+ /// if a Status value received from another address space belongs to
+ /// an error-space that is not known in this address space. Also
+ /// errors raised by APIs that do not return enough error information
+ /// may be converted to this error.
+ /// </summary>
Unknown = 2,
- /* Client specified an invalid argument. Note that this differs
- from FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments
- that are problematic regardless of the state of the system
- (e.g., a malformed file name). */
+
+ /// <summary>
+ /// Client specified an invalid argument. Note that this differs
+ /// from FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments
+ /// that are problematic regardless of the state of the system
+ /// (e.g., a malformed file name).
+ /// </summary>
InvalidArgument = 3,
- /* Deadline expired before operation could complete. For operations
- that change the state of the system, this error may be returned
- even if the operation has completed successfully. For example, a
- successful response from a server could have been delayed long
- enough for the deadline to expire. */
+
+ /// <summary>
+ /// Deadline expired before operation could complete. For operations
+ /// that change the state of the system, this error may be returned
+ /// even if the operation has completed successfully. For example, a
+ /// successful response from a server could have been delayed long
+ /// enough for the deadline to expire.
+ /// </summary>
DeadlineExceeded = 4,
- /* Some requested entity (e.g., file or directory) was not found. */
+
+ /// <summary>Some requested entity (e.g., file or directory) was not found.</summary>
NotFound = 5,
- /* Some entity that we attempted to create (e.g., file or directory)
- already exists. */
+
+ /// <summary>Some entity that we attempted to create (e.g., file or directory) already exists.</summary>
AlreadyExists = 6,
- /* The caller does not have permission to execute the specified
- operation. PERMISSION_DENIED must not be used for rejections
- caused by exhausting some resource (use RESOURCE_EXHAUSTED
- instead for those errors). PERMISSION_DENIED must not be
- used if the caller can not be identified (use UNAUTHENTICATED
- instead for those errors). */
+
+ /// <summary>
+ /// The caller does not have permission to execute the specified
+ /// operation. PERMISSION_DENIED must not be used for rejections
+ /// caused by exhausting some resource (use RESOURCE_EXHAUSTED
+ /// instead for those errors). PERMISSION_DENIED must not be
+ /// used if the caller can not be identified (use UNAUTHENTICATED
+ /// instead for those errors).
+ /// </summary>
PermissionDenied = 7,
- /* The request does not have valid authentication credentials for the
- operation. */
+
+ /// <summary>The request does not have valid authentication credentials for the operation.</summary>
Unauthenticated = 16,
- /* Some resource has been exhausted, perhaps a per-user quota, or
- perhaps the entire file system is out of space. */
+
+ /// <summary>
+ /// Some resource has been exhausted, perhaps a per-user quota, or
+ /// perhaps the entire file system is out of space.
+ /// </summary>
ResourceExhausted = 8,
- /* Operation was rejected because the system is not in a state
- required for the operation's execution. For example, directory
- to be deleted may be non-empty, an rmdir operation is applied to
- a non-directory, etc.
-
- A litmus test that may help a service implementor in deciding
- between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE:
- (a) Use UNAVAILABLE if the client can retry just the failing call.
- (b) Use ABORTED if the client should retry at a higher-level
- (e.g., restarting a read-modify-write sequence).
- (c) Use FAILED_PRECONDITION if the client should not retry until
- the system state has been explicitly fixed. E.g., if an "rmdir"
- fails because the directory is non-empty, FAILED_PRECONDITION
- should be returned since the client should not retry unless
- they have first fixed up the directory by deleting files from it.
- (d) Use FAILED_PRECONDITION if the client performs conditional
- REST Get/Update/Delete on a resource and the resource on the
- server does not match the condition. E.g., conflicting
- read-modify-write on the same resource. */
+
+ /// <summary>
+ /// Operation was rejected because the system is not in a state
+ /// required for the operation's execution. For example, directory
+ /// to be deleted may be non-empty, an rmdir operation is applied to
+ /// a non-directory, etc.
+ /// </summary>
FailedPrecondition = 9,
- /* The operation was aborted, typically due to a concurrency issue
- like sequencer check failures, transaction aborts, etc.
- See litmus test above for deciding between FAILED_PRECONDITION,
- ABORTED, and UNAVAILABLE. */
+ /// <summary>
+ /// The operation was aborted, typically due to a concurrency issue
+ /// like sequencer check failures, transaction aborts, etc.
+ /// </summary>
Aborted = 10,
- /* Operation was attempted past the valid range. E.g., seeking or
- reading past end of file.
-
- Unlike INVALID_ARGUMENT, this error indicates a problem that may
- be fixed if the system state changes. For example, a 32-bit file
- system will generate INVALID_ARGUMENT if asked to read at an
- offset that is not in the range [0,2^32-1], but it will generate
- OUT_OF_RANGE if asked to read from an offset past the current
- file size.
-
- There is a fair bit of overlap between FAILED_PRECONDITION and
- OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific
- error) when it applies so that callers who are iterating through
- a space can easily look for an OUT_OF_RANGE error to detect when
- they are done. */
+
+ /// <summary>
+ /// Operation was attempted past the valid range. E.g., seeking or
+ /// reading past end of file.
+ /// </summary>
OutOfRange = 11,
- /* Operation is not implemented or not supported/enabled in this service. */
+
+ /// <summary>Operation is not implemented or not supported/enabled in this service.</summary>
Unimplemented = 12,
- /* Internal errors. Means some invariants expected by underlying
- system has been broken. If you see one of these errors,
- something is very broken. */
+
+ /// <summary>
+ /// Internal errors. Means some invariants expected by underlying
+ /// system has been broken. If you see one of these errors,
+ /// something is very broken.
+ /// </summary>
Internal = 13,
- /* The service is currently unavailable. This is a most likely a
- transient condition and may be corrected by retrying with
- a backoff.
- See litmus test above for deciding between FAILED_PRECONDITION,
- ABORTED, and UNAVAILABLE. */
+ /// <summary>
+ /// The service is currently unavailable. This is a most likely a
+ /// transient condition and may be corrected by retrying with
+ /// a backoff.
+ /// </summary>
Unavailable = 14,
- /* Unrecoverable data loss or corruption. */
+
+ /// <summary>Unrecoverable data loss or corruption.</summary>
DataLoss = 15
}
}
diff --git a/src/csharp/Grpc.Core/Utils/AsyncStreamExtensions.cs b/src/csharp/Grpc.Core/Utils/AsyncStreamExtensions.cs
index 8a748b45a8..cdf1e51026 100644
--- a/src/csharp/Grpc.Core/Utils/AsyncStreamExtensions.cs
+++ b/src/csharp/Grpc.Core/Utils/AsyncStreamExtensions.cs
@@ -33,7 +33,6 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using System.Threading.Tasks;
namespace Grpc.Core.Utils
@@ -46,7 +45,7 @@ namespace Grpc.Core.Utils
/// <summary>
/// Reads the entire stream and executes an async action for each element.
/// </summary>
- public static async Task ForEach<T>(this IAsyncStreamReader<T> streamReader, Func<T, Task> asyncAction)
+ public static async Task ForEachAsync<T>(this IAsyncStreamReader<T> streamReader, Func<T, Task> asyncAction)
where T : class
{
while (await streamReader.MoveNext())
@@ -58,7 +57,7 @@ namespace Grpc.Core.Utils
/// <summary>
/// Reads the entire stream and creates a list containing all the elements read.
/// </summary>
- public static async Task<List<T>> ToList<T>(this IAsyncStreamReader<T> streamReader)
+ public static async Task<List<T>> ToListAsync<T>(this IAsyncStreamReader<T> streamReader)
where T : class
{
var result = new List<T>();
@@ -73,7 +72,7 @@ namespace Grpc.Core.Utils
/// Writes all elements from given enumerable to the stream.
/// Completes the stream afterwards unless close = false.
/// </summary>
- public static async Task WriteAll<T>(this IClientStreamWriter<T> streamWriter, IEnumerable<T> elements, bool complete = true)
+ public static async Task WriteAllAsync<T>(this IClientStreamWriter<T> streamWriter, IEnumerable<T> elements, bool complete = true)
where T : class
{
foreach (var element in elements)
@@ -89,7 +88,7 @@ namespace Grpc.Core.Utils
/// <summary>
/// Writes all elements from given enumerable to the stream.
/// </summary>
- public static async Task WriteAll<T>(this IServerStreamWriter<T> streamWriter, IEnumerable<T> elements)
+ public static async Task WriteAllAsync<T>(this IServerStreamWriter<T> streamWriter, IEnumerable<T> elements)
where T : class
{
foreach (var element in elements)
diff --git a/src/csharp/Grpc.Core/Utils/BenchmarkUtil.cs b/src/csharp/Grpc.Core/Utils/BenchmarkUtil.cs
index 82653c3a1f..eb3a5b16e3 100644
--- a/src/csharp/Grpc.Core/Utils/BenchmarkUtil.cs
+++ b/src/csharp/Grpc.Core/Utils/BenchmarkUtil.cs
@@ -39,6 +39,9 @@ using System.Threading.Tasks;
namespace Grpc.Core.Utils
{
+ /// <summary>
+ /// Utility methods to run microbenchmarks.
+ /// </summary>
public static class BenchmarkUtil
{
/// <summary>
diff --git a/src/csharp/Grpc.Core/Utils/ExceptionHelper.cs b/src/csharp/Grpc.Core/Utils/ExceptionHelper.cs
deleted file mode 100644
index c4d6bee058..0000000000
--- a/src/csharp/Grpc.Core/Utils/ExceptionHelper.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-#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;
-
-namespace Grpc.Core.Utils
-{
- public static class ExceptionHelper
- {
- /// <summary>
- /// If inner exceptions contain RpcException, rethrows it.
- /// 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)
- {
- foreach (var e in ae.InnerExceptions)
- {
- if (e is RpcException)
- {
- throw e;
- }
- }
- throw ae;
- }
- }
-}
diff --git a/src/csharp/Grpc.Core/Utils/Preconditions.cs b/src/csharp/Grpc.Core/Utils/Preconditions.cs
index aeb5d210a7..374262f87a 100644
--- a/src/csharp/Grpc.Core/Utils/Preconditions.cs
+++ b/src/csharp/Grpc.Core/Utils/Preconditions.cs
@@ -32,17 +32,16 @@
#endregion
using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Threading.Tasks;
namespace Grpc.Core.Utils
{
+ /// <summary>
+ /// Utility methods to simplify checking preconditions in the code.
+ /// </summary>
public static class Preconditions
{
/// <summary>
- /// Throws ArgumentException if condition is false.
+ /// Throws <see cref="ArgumentException"/> if condition is false.
/// </summary>
public static void CheckArgument(bool condition)
{
@@ -53,7 +52,7 @@ namespace Grpc.Core.Utils
}
/// <summary>
- /// Throws ArgumentException with given message if condition is false.
+ /// Throws <see cref="ArgumentException"/> with given message if condition is false.
/// </summary>
public static void CheckArgument(bool condition, string errorMessage)
{
@@ -64,31 +63,31 @@ namespace Grpc.Core.Utils
}
/// <summary>
- /// Throws NullReferenceException if reference is null.
+ /// Throws <see cref="ArgumentNullException"/> if reference is null.
/// </summary>
public static T CheckNotNull<T>(T reference)
{
if (reference == null)
{
- throw new NullReferenceException();
+ throw new ArgumentNullException();
}
return reference;
}
/// <summary>
- /// Throws NullReferenceException with given message if reference is null.
+ /// Throws <see cref="ArgumentNullException"/> if reference is null.
/// </summary>
- public static T CheckNotNull<T>(T reference, string errorMessage)
+ public static T CheckNotNull<T>(T reference, string paramName)
{
if (reference == null)
{
- throw new NullReferenceException(errorMessage);
+ throw new ArgumentNullException(paramName);
}
return reference;
}
/// <summary>
- /// Throws InvalidOperationException if condition is false.
+ /// Throws <see cref="InvalidOperationException"/> if condition is false.
/// </summary>
public static void CheckState(bool condition)
{
@@ -99,7 +98,7 @@ namespace Grpc.Core.Utils
}
/// <summary>
- /// Throws InvalidOperationException with given message if condition is false.
+ /// Throws <see cref="InvalidOperationException"/> with given message if condition is false.
/// </summary>
public static void CheckState(bool condition, string errorMessage)
{
diff --git a/src/csharp/Grpc.Core/Version.cs b/src/csharp/Grpc.Core/Version.cs
index b5cb652945..d02b301cac 100644
--- a/src/csharp/Grpc.Core/Version.cs
+++ b/src/csharp/Grpc.Core/Version.cs
@@ -1,5 +1,37 @@
+#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.Reflection;
-using System.Runtime.CompilerServices;
// The current version of gRPC C#.
-[assembly: AssemblyVersion(Grpc.Core.VersionInfo.CurrentVersion + ".*")]
+[assembly: AssemblyVersion(Grpc.Core.VersionInfo.CurrentVersion + ".0")]
diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs
index 939372e237..b6dbd3b49c 100644
--- a/src/csharp/Grpc.Core/VersionInfo.cs
+++ b/src/csharp/Grpc.Core/VersionInfo.cs
@@ -1,8 +1,41 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
+#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
namespace Grpc.Core
{
+ /// <summary>
+ /// Provides info about current version of gRPC.
+ /// </summary>
public static class VersionInfo
{
/// <summary>
diff --git a/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs b/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs
index 73d2a1ca9b..fdef950f09 100644
--- a/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs
+++ b/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs
@@ -109,7 +109,7 @@ namespace math.Tests
{
using (var call = client.Fib(new FibArgs.Builder { Limit = 6 }.Build()))
{
- var responses = await call.ResponseStream.ToList();
+ var responses = await call.ResponseStream.ToListAsync();
CollectionAssert.AreEqual(new List<long> { 1, 1, 2, 3, 5, 8 },
responses.ConvertAll((n) => n.Num_));
}
@@ -151,7 +151,7 @@ namespace math.Tests
using (var call = client.Fib(new FibArgs.Builder { Limit = 0 }.Build(),
deadline: DateTime.UtcNow.AddMilliseconds(500)))
{
- var ex = Assert.Throws<RpcException>(async () => await call.ResponseStream.ToList());
+ var ex = Assert.Throws<RpcException>(async () => await call.ResponseStream.ToListAsync());
// We can't guarantee the status code always DeadlineExceeded. See issue #2685.
Assert.Contains(ex.Status.StatusCode, new[] { StatusCode.DeadlineExceeded, StatusCode.Internal });
@@ -167,7 +167,7 @@ namespace math.Tests
var numbers = new List<long> { 10, 20, 30 }.ConvertAll(
n => Num.CreateBuilder().SetNum_(n).Build());
- await call.RequestStream.WriteAll(numbers);
+ await call.RequestStream.WriteAllAsync(numbers);
var result = await call.ResponseAsync;
Assert.AreEqual(60, result.Num_);
}
@@ -185,8 +185,8 @@ namespace math.Tests
using (var call = client.DivMany())
{
- await call.RequestStream.WriteAll(divArgsList);
- var result = await call.ResponseStream.ToList();
+ await call.RequestStream.WriteAllAsync(divArgsList);
+ var result = await call.ResponseStream.ToListAsync();
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/MathExamples.cs b/src/csharp/Grpc.Examples/MathExamples.cs
index 06d81a4d83..dc1bf43995 100644
--- a/src/csharp/Grpc.Examples/MathExamples.cs
+++ b/src/csharp/Grpc.Examples/MathExamples.cs
@@ -54,7 +54,7 @@ namespace math
{
using (var call = client.Fib(new FibArgs.Builder { Limit = 5 }.Build()))
{
- List<Num> result = await call.ResponseStream.ToList();
+ List<Num> result = await call.ResponseStream.ToListAsync();
Console.WriteLine("Fib Result: " + string.Join("|", result));
}
}
@@ -70,7 +70,7 @@ namespace math
using (var call = client.Sum())
{
- await call.RequestStream.WriteAll(numbers);
+ await call.RequestStream.WriteAllAsync(numbers);
Console.WriteLine("Sum Result: " + await call.ResponseAsync);
}
}
@@ -85,8 +85,8 @@ namespace math
};
using (var call = client.DivMany())
{
- await call.RequestStream.WriteAll(divArgsList);
- Console.WriteLine("DivMany Result: " + string.Join("|", await call.ResponseStream.ToList()));
+ await call.RequestStream.WriteAllAsync(divArgsList);
+ Console.WriteLine("DivMany Result: " + string.Join("|", await call.ResponseStream.ToListAsync()));
}
}
@@ -102,7 +102,7 @@ namespace math
Num sum;
using (var sumCall = client.Sum())
{
- await sumCall.RequestStream.WriteAll(numbers);
+ await sumCall.RequestStream.WriteAllAsync(numbers);
sum = await sumCall.ResponseAsync;
}
diff --git a/src/csharp/Grpc.Examples/MathServiceImpl.cs b/src/csharp/Grpc.Examples/MathServiceImpl.cs
index dd26b1d350..7b2684615c 100644
--- a/src/csharp/Grpc.Examples/MathServiceImpl.cs
+++ b/src/csharp/Grpc.Examples/MathServiceImpl.cs
@@ -75,7 +75,7 @@ namespace math
public async Task<Num> Sum(IAsyncStreamReader<Num> requestStream, ServerCallContext context)
{
long sum = 0;
- await requestStream.ForEach(async num =>
+ await requestStream.ForEachAsync(async num =>
{
sum += num.Num_;
});
@@ -84,10 +84,7 @@ namespace math
public async Task DivMany(IAsyncStreamReader<DivArgs> requestStream, IServerStreamWriter<DivReply> responseStream, ServerCallContext context)
{
- await requestStream.ForEach(async divArgs =>
- {
- await responseStream.WriteAsync(DivInternal(divArgs));
- });
+ await requestStream.ForEachAsync(async divArgs => await responseStream.WriteAsync(DivInternal(divArgs)));
}
static DivReply DivInternal(DivArgs args)
diff --git a/src/csharp/Grpc.HealthCheck.Tests/HealthServiceImplTest.cs b/src/csharp/Grpc.HealthCheck.Tests/HealthServiceImplTest.cs
index 7184415655..c4caa3b57a 100644
--- a/src/csharp/Grpc.HealthCheck.Tests/HealthServiceImplTest.cs
+++ b/src/csharp/Grpc.HealthCheck.Tests/HealthServiceImplTest.cs
@@ -92,11 +92,11 @@ namespace Grpc.HealthCheck.Tests
public void NullsRejected()
{
var impl = new HealthServiceImpl();
- Assert.Throws(typeof(NullReferenceException), () => impl.SetStatus(null, "", HealthCheckResponse.Types.ServingStatus.SERVING));
- Assert.Throws(typeof(NullReferenceException), () => impl.SetStatus("", null, HealthCheckResponse.Types.ServingStatus.SERVING));
+ Assert.Throws(typeof(ArgumentNullException), () => impl.SetStatus(null, "", HealthCheckResponse.Types.ServingStatus.SERVING));
+ Assert.Throws(typeof(ArgumentNullException), () => impl.SetStatus("", null, HealthCheckResponse.Types.ServingStatus.SERVING));
- Assert.Throws(typeof(NullReferenceException), () => impl.ClearStatus(null, ""));
- Assert.Throws(typeof(NullReferenceException), () => impl.ClearStatus("", null));
+ Assert.Throws(typeof(ArgumentNullException), () => impl.ClearStatus(null, ""));
+ Assert.Throws(typeof(ArgumentNullException), () => impl.ClearStatus("", null));
}
private static HealthCheckResponse.Types.ServingStatus GetStatusHelper(HealthServiceImpl impl, string host, string service)
diff --git a/src/csharp/Grpc.IntegrationTesting.Client/app.config b/src/csharp/Grpc.IntegrationTesting.Client/app.config
index 0a82bb4f16..84d7534d65 100644
--- a/src/csharp/Grpc.IntegrationTesting.Client/app.config
+++ b/src/csharp/Grpc.IntegrationTesting.Client/app.config
@@ -10,6 +10,10 @@
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.28.0" newVersion="4.0.0.0" />
</dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="Google.Apis.Core" publicKeyToken="4b01fa6e34db77ab" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-1.9.2.38523" newVersion="1.9.2.38523" />
+ </dependentAssembly>
</assemblyBinding>
</runtime>
</configuration> \ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting.Server/app.config b/src/csharp/Grpc.IntegrationTesting.Server/app.config
index 0a82bb4f16..84d7534d65 100644
--- a/src/csharp/Grpc.IntegrationTesting.Server/app.config
+++ b/src/csharp/Grpc.IntegrationTesting.Server/app.config
@@ -10,6 +10,10 @@
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.28.0" newVersion="4.0.0.0" />
</dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="Google.Apis.Core" publicKeyToken="4b01fa6e34db77ab" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-1.9.2.38523" newVersion="1.9.2.38523" />
+ </dependentAssembly>
</assemblyBinding>
</runtime>
</configuration> \ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
index 06a75a3351..2020a76d39 100644
--- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
+++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
@@ -8,7 +8,7 @@
<RootNamespace>Grpc.IntegrationTesting</RootNamespace>
<AssemblyName>Grpc.IntegrationTesting</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
- <NuGetPackageImportStamp>041c163e</NuGetPackageImportStamp>
+ <NuGetPackageImportStamp>6566287f</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -38,20 +38,33 @@
<AssemblyOriginatorKeyFile>C:\keys\Grpc.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup>
- <Reference Include="BouncyCastle.Crypto">
+ <Reference Include="BouncyCastle.Crypto, Version=1.7.4137.9688, Culture=neutral, PublicKeyToken=a4292a325f69b123, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
</Reference>
- <Reference Include="Google.Apis.Auth, Version=1.9.2.27817, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+ <Reference Include="Google.Apis.Auth, Version=1.9.3.19379, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.dll</HintPath>
+ </Reference>
+ <Reference Include="Google.Apis.Auth.PlatformServices, Version=1.9.3.19383, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.PlatformServices.dll</HintPath>
+ </Reference>
+ <Reference Include="Google.Apis.Core, Version=1.9.3.19379, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\packages\Google.Apis.Core.1.9.3\lib\portable-net40+sl50+win+wpa81+wp80\Google.Apis.Core.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.Threading.Tasks, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\Google.Apis.Auth.1.9.2\lib\net40\Google.Apis.Auth.dll</HintPath>
+ <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath>
</Reference>
- <Reference Include="Google.Apis.Auth.PlatformServices, Version=1.9.2.27820, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+ <Reference Include="Microsoft.Threading.Tasks.Extensions, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\Google.Apis.Auth.1.9.2\lib\net40\Google.Apis.Auth.PlatformServices.dll</HintPath>
+ <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
- <Reference Include="Google.Apis.Core, Version=1.9.2.27816, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+ <Reference Include="Microsoft.Threading.Tasks.Extensions.Desktop, Version=1.0.168.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\Google.Apis.Core.1.9.2\lib\portable-net40+sl50+win+wpa81+wp80\Google.Apis.Core.dll</HintPath>
+ <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@@ -78,15 +91,6 @@
<HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http.WebRequest" />
- <Reference Include="Microsoft.Threading.Tasks">
- <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath>
- </Reference>
- <Reference Include="Microsoft.Threading.Tasks.Extensions">
- <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
- </Reference>
- <Reference Include="Microsoft.Threading.Tasks.Extensions.Desktop">
- <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll</HintPath>
- </Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="..\Grpc.Core\Version.cs">
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
index 6802de489d..385ca92086 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
@@ -43,6 +43,7 @@ using Grpc.Auth;
using Grpc.Core;
using Grpc.Core.Utils;
using NUnit.Framework;
+using Google.Apis.Auth.OAuth2;
namespace Grpc.IntegrationTesting
{
@@ -97,10 +98,10 @@ namespace Grpc.IntegrationTesting
}
var interopClient = new InteropClient(options);
- interopClient.Run();
+ interopClient.Run().Wait();
}
- private void Run()
+ private async Task Run()
{
Credentials credentials = null;
if (options.useTls)
@@ -120,17 +121,7 @@ namespace Grpc.IntegrationTesting
using (Channel channel = new Channel(options.serverHost, options.serverPort.Value, credentials, channelOptions))
{
TestService.TestServiceClient client = new TestService.TestServiceClient(channel);
- if (options.testCase == "service_account_creds" || options.testCase == "compute_engine_creds")
- {
- var credential = GoogleCredential.GetApplicationDefault();
- if (credential.IsCreateScopedRequired)
- {
- credential = credential.CreateScoped(new[] { AuthScope });
- }
- client.HeaderInterceptor = OAuth2Interceptors.FromCredential(credential);
- }
-
- RunTestCaseAsync(options.testCase, client).Wait();
+ await RunTestCaseAsync(options.testCase, client);
}
GrpcEnvironment.Shutdown();
}
@@ -158,16 +149,19 @@ namespace Grpc.IntegrationTesting
await RunEmptyStreamAsync(client);
break;
case "service_account_creds":
- RunServiceAccountCreds(client);
+ await RunServiceAccountCredsAsync(client);
break;
case "compute_engine_creds":
- RunComputeEngineCreds(client);
+ await RunComputeEngineCredsAsync(client);
+ break;
+ case "jwt_token_creds":
+ await RunJwtTokenCredsAsync(client);
break;
case "oauth2_auth_token":
- RunOAuth2AuthToken(client);
+ await RunOAuth2AuthTokenAsync(client);
break;
case "per_rpc_creds":
- RunPerRpcCreds(client);
+ await RunPerRpcCredsAsync(client);
break;
case "cancel_after_begin":
await RunCancelAfterBeginAsync(client);
@@ -215,7 +209,7 @@ namespace Grpc.IntegrationTesting
using (var call = client.StreamingInputCall())
{
- await call.RequestStream.WriteAll(bodySizes);
+ await call.RequestStream.WriteAllAsync(bodySizes);
var response = await call.ResponseAsync;
Assert.AreEqual(74922, response.AggregatedPayloadSize);
@@ -237,7 +231,7 @@ namespace Grpc.IntegrationTesting
using (var call = client.StreamingOutputCall(request))
{
- var responseList = await call.ResponseStream.ToList();
+ var responseList = await call.ResponseStream.ToListAsync();
foreach (var res in responseList)
{
Assert.AreEqual(PayloadType.COMPRESSABLE, res.Payload.Type);
@@ -303,15 +297,19 @@ namespace Grpc.IntegrationTesting
{
await call.RequestStream.CompleteAsync();
- var responseList = await call.ResponseStream.ToList();
+ var responseList = await call.ResponseStream.ToListAsync();
Assert.AreEqual(0, responseList.Count);
}
Console.WriteLine("Passed!");
}
- public static void RunServiceAccountCreds(TestService.ITestServiceClient client)
+ public static async Task RunServiceAccountCredsAsync(TestService.TestServiceClient client)
{
Console.WriteLine("running service_account_creds");
+ var credential = await GoogleCredential.GetApplicationDefaultAsync();
+ credential = credential.CreateScoped(new[] { AuthScope });
+ client.HeaderInterceptor = OAuth2Interceptors.FromCredential(credential);
+
var request = SimpleRequest.CreateBuilder()
.SetResponseType(PayloadType.COMPRESSABLE)
.SetResponseSize(314159)
@@ -329,9 +327,13 @@ namespace Grpc.IntegrationTesting
Console.WriteLine("Passed!");
}
- public static void RunComputeEngineCreds(TestService.ITestServiceClient client)
+ public static async Task RunComputeEngineCredsAsync(TestService.TestServiceClient client)
{
Console.WriteLine("running compute_engine_creds");
+ var credential = await GoogleCredential.GetApplicationDefaultAsync();
+ Assert.IsFalse(credential.IsCreateScopedRequired);
+ client.HeaderInterceptor = OAuth2Interceptors.FromCredential(credential);
+
var request = SimpleRequest.CreateBuilder()
.SetResponseType(PayloadType.COMPRESSABLE)
.SetResponseSize(314159)
@@ -349,12 +351,35 @@ namespace Grpc.IntegrationTesting
Console.WriteLine("Passed!");
}
- public static void RunOAuth2AuthToken(TestService.TestServiceClient client)
+ public static async Task RunJwtTokenCredsAsync(TestService.TestServiceClient client)
+ {
+ Console.WriteLine("running jwt_token_creds");
+ var credential = await GoogleCredential.GetApplicationDefaultAsync();
+ // check this a credential with scope support, but don't add the scope.
+ Assert.IsTrue(credential.IsCreateScopedRequired);
+ client.HeaderInterceptor = OAuth2Interceptors.FromCredential(credential);
+
+ var request = SimpleRequest.CreateBuilder()
+ .SetResponseType(PayloadType.COMPRESSABLE)
+ .SetResponseSize(314159)
+ .SetPayload(CreateZerosPayload(271828))
+ .SetFillUsername(true)
+ .SetFillOauthScope(true)
+ .Build();
+
+ var response = client.UnaryCall(request);
+
+ Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type);
+ Assert.AreEqual(314159, response.Payload.Body.Length);
+ Assert.AreEqual(ServiceAccountUser, response.Username);
+ Console.WriteLine("Passed!");
+ }
+
+ public static async Task RunOAuth2AuthTokenAsync(TestService.TestServiceClient client)
{
Console.WriteLine("running oauth2_auth_token");
- var credential = GoogleCredential.GetApplicationDefault().CreateScoped(new[] { AuthScope });
- Assert.IsTrue(credential.RequestAccessTokenAsync(CancellationToken.None).Result);
- string oauth2Token = credential.Token.AccessToken;
+ ITokenAccess credential = (await GoogleCredential.GetApplicationDefaultAsync()).CreateScoped(new[] { AuthScope });
+ string oauth2Token = await credential.GetAccessTokenForRequestAsync();
client.HeaderInterceptor = OAuth2Interceptors.FromAccessToken(oauth2Token);
@@ -370,13 +395,12 @@ namespace Grpc.IntegrationTesting
Console.WriteLine("Passed!");
}
- public static void RunPerRpcCreds(TestService.TestServiceClient client)
+ public static async Task RunPerRpcCredsAsync(TestService.TestServiceClient client)
{
Console.WriteLine("running per_rpc_creds");
- var credential = GoogleCredential.GetApplicationDefault().CreateScoped(new[] { AuthScope });
- Assert.IsTrue(credential.RequestAccessTokenAsync(CancellationToken.None).Result);
- string oauth2Token = credential.Token.AccessToken;
+ ITokenAccess credential = (await GoogleCredential.GetApplicationDefaultAsync()).CreateScoped(new[] { AuthScope });
+ string oauth2Token = await credential.GetAccessTokenForRequestAsync();
var headerInterceptor = OAuth2Interceptors.FromAccessToken(oauth2Token);
var request = SimpleRequest.CreateBuilder()
@@ -385,7 +409,7 @@ namespace Grpc.IntegrationTesting
.Build();
var headers = new Metadata();
- headerInterceptor(headers);
+ headerInterceptor("", headers);
var response = client.UnaryCall(request, headers: headers);
Assert.AreEqual(AuthScopeResponse, response.OauthScope);
diff --git a/src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs b/src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs
index ccf9fe6ced..ceebd5dd8c 100644
--- a/src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs
+++ b/src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs
@@ -71,7 +71,7 @@ namespace grpc.testing
public async Task<StreamingInputCallResponse> StreamingInputCall(IAsyncStreamReader<StreamingInputCallRequest> requestStream, ServerCallContext context)
{
int sum = 0;
- await requestStream.ForEach(async request =>
+ await requestStream.ForEachAsync(async request =>
{
sum += request.Payload.Body.Length;
});
@@ -80,7 +80,7 @@ namespace grpc.testing
public async Task FullDuplexCall(IAsyncStreamReader<StreamingOutputCallRequest> requestStream, IServerStreamWriter<StreamingOutputCallResponse> responseStream, ServerCallContext context)
{
- await requestStream.ForEach(async request =>
+ await requestStream.ForEachAsync(async request =>
{
foreach (var responseParam in request.ResponseParametersList)
{
diff --git a/src/csharp/Grpc.IntegrationTesting/app.config b/src/csharp/Grpc.IntegrationTesting/app.config
index 0a82bb4f16..84d7534d65 100644
--- a/src/csharp/Grpc.IntegrationTesting/app.config
+++ b/src/csharp/Grpc.IntegrationTesting/app.config
@@ -10,6 +10,10 @@
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.28.0" newVersion="4.0.0.0" />
</dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="Google.Apis.Core" publicKeyToken="4b01fa6e34db77ab" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-1.9.2.38523" newVersion="1.9.2.38523" />
+ </dependentAssembly>
</assemblyBinding>
</runtime>
</configuration> \ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting/packages.config b/src/csharp/Grpc.IntegrationTesting/packages.config
index 7d1f84f303..0867b091b9 100644
--- a/src/csharp/Grpc.IntegrationTesting/packages.config
+++ b/src/csharp/Grpc.IntegrationTesting/packages.config
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
- <package id="Google.Apis.Auth" version="1.9.2" targetFramework="net45" />
- <package id="Google.Apis.Core" version="1.9.2" targetFramework="net45" />
+ <package id="Google.Apis.Auth" version="1.9.3" targetFramework="net45" />
+ <package id="Google.Apis.Core" version="1.9.3" targetFramework="net45" />
<package id="Google.ProtocolBuffers" version="2.4.1.521" targetFramework="net45" />
<package id="Ix-Async" version="1.2.3" targetFramework="net45" />
<package id="Microsoft.Bcl" version="1.1.10" targetFramework="net45" />
diff --git a/src/csharp/doc/README.md b/src/csharp/doc/README.md
new file mode 100644
index 0000000000..585500b5ca
--- /dev/null
+++ b/src/csharp/doc/README.md
@@ -0,0 +1,2 @@
+
+SandCastle project files to generate HTML reference documentation. \ No newline at end of file
diff --git a/src/csharp/doc/grpc_csharp_public.shfbproj b/src/csharp/doc/grpc_csharp_public.shfbproj
new file mode 100644
index 0000000000..05c93f4a13
--- /dev/null
+++ b/src/csharp/doc/grpc_csharp_public.shfbproj
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <!-- The configuration and platform will be used to determine which assemblies to include from solution and
+ project documentation sources -->
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{77e3da09-fc92-486f-a90a-99ca788e8b59}</ProjectGuid>
+ <SHFBSchemaVersion>2015.6.5.0</SHFBSchemaVersion>
+ <!-- AssemblyName, Name, and RootNamespace are not used by SHFB but Visual Studio adds them anyway -->
+ <AssemblyName>Documentation</AssemblyName>
+ <RootNamespace>Documentation</RootNamespace>
+ <Name>Documentation</Name>
+ <!-- SHFB properties -->
+ <FrameworkVersion>.NET Framework 4.5</FrameworkVersion>
+ <OutputPath>..\..\..\doc\ref\csharp\html</OutputPath>
+ <Language>en-US</Language>
+ <DocumentationSources>
+ <DocumentationSource sourceFile="..\Grpc.Auth\Grpc.Auth.csproj" />
+<DocumentationSource sourceFile="..\Grpc.Core\Grpc.Core.csproj" /></DocumentationSources>
+ <BuildAssemblerVerbosity>OnlyWarningsAndErrors</BuildAssemblerVerbosity>
+ <HelpFileFormat>Website</HelpFileFormat>
+ <IndentHtml>False</IndentHtml>
+ <KeepLogFile>True</KeepLogFile>
+ <DisableCodeBlockComponent>False</DisableCodeBlockComponent>
+ <CleanIntermediates>True</CleanIntermediates>
+ <HelpFileVersion>1.0.0.0</HelpFileVersion>
+ <MaximumGroupParts>2</MaximumGroupParts>
+ <NamespaceGrouping>False</NamespaceGrouping>
+ <SyntaxFilters>Standard</SyntaxFilters>
+ <SdkLinkTarget>Blank</SdkLinkTarget>
+ <RootNamespaceContainer>True</RootNamespaceContainer>
+ <PresentationStyle>VS2013</PresentationStyle>
+ <Preliminary>False</Preliminary>
+ <NamingMethod>MemberName</NamingMethod>
+ <HelpTitle>gRPC C#</HelpTitle>
+ <ContentPlacement>AboveNamespaces</ContentPlacement>
+ <HtmlHelpName>Documentation</HtmlHelpName>
+ </PropertyGroup>
+ <!-- There are no properties for these groups. AnyCPU needs to appear in order for Visual Studio to perform
+ the build. The others are optional common platform types that may appear. -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|Win32' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|Win32' ">
+ </PropertyGroup>
+ <!-- Import the SHFB build targets -->
+ <Import Project="$(SHFBROOT)\SandcastleHelpFileBuilder.targets" />
+ <!-- The pre-build and post-build event properties must appear *after* the targets file import in order to be
+ evaluated correctly. -->
+ <PropertyGroup>
+ <PreBuildEvent>
+ </PreBuildEvent>
+ <PostBuildEvent>
+ </PostBuildEvent>
+ <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
+ </PropertyGroup>
+</Project> \ No newline at end of file
diff --git a/src/node/binding.gyp b/src/node/binding.gyp
index 6ba233388a..734dc8410b 100644
--- a/src/node/binding.gyp
+++ b/src/node/binding.gyp
@@ -11,7 +11,8 @@
'-pedantic',
'-g',
'-zdefs',
- '-Werror'
+ '-Werror',
+ '-Wno-error=deprecated-declarations'
],
'ldflags': [
'-g'
diff --git a/src/node/examples/perf_test.js b/src/node/examples/perf_test.js
index 0f38725f72..214b9384d5 100644
--- a/src/node/examples/perf_test.js
+++ b/src/node/examples/perf_test.js
@@ -63,7 +63,7 @@ function runTest(iterations, callback) {
var timeDiff = process.hrtime(startTime);
intervals[i] = timeDiff[0] * 1000000 + timeDiff[1] / 1000;
next(i+1);
- }, {}, deadline);
+ }, {}, {deadline: deadline});
}
}
next(0);
diff --git a/src/node/ext/call.cc b/src/node/ext/call.cc
index fe585a0d4f..c5c8313385 100644
--- a/src/node/ext/call.cc
+++ b/src/node/ext/call.cc
@@ -510,10 +510,21 @@ NAN_METHOD(Call::New) {
NanUtf8String method(args[1]);
double deadline = args[2]->NumberValue();
grpc_channel *wrapped_channel = channel->GetWrappedChannel();
- grpc_call *wrapped_call = grpc_channel_create_call(
- wrapped_channel, NULL, GRPC_PROPAGATE_DEFAULTS,
- CompletionQueueAsyncWorker::GetQueue(), *method, channel->GetHost(),
- MillisecondsToTimespec(deadline));
+ grpc_call *wrapped_call;
+ if (args[3]->IsString()) {
+ NanUtf8String host_override(args[3]);
+ wrapped_call = grpc_channel_create_call(
+ wrapped_channel, NULL, GRPC_PROPAGATE_DEFAULTS,
+ CompletionQueueAsyncWorker::GetQueue(), *method,
+ *host_override, MillisecondsToTimespec(deadline));
+ } else if (args[3]->IsUndefined() || args[3]->IsNull()) {
+ wrapped_call = grpc_channel_create_call(
+ wrapped_channel, NULL, GRPC_PROPAGATE_DEFAULTS,
+ CompletionQueueAsyncWorker::GetQueue(), *method,
+ NULL, MillisecondsToTimespec(deadline));
+ } else {
+ return NanThrowTypeError("Call's fourth argument must be a string");
+ }
call = new Call(wrapped_call);
args.This()->SetHiddenValue(NanNew("channel_"), channel_object);
}
diff --git a/src/node/ext/channel.cc b/src/node/ext/channel.cc
index d02ed95672..457a58c057 100644
--- a/src/node/ext/channel.cc
+++ b/src/node/ext/channel.cc
@@ -59,14 +59,12 @@ using v8::Value;
NanCallback *Channel::constructor;
Persistent<FunctionTemplate> Channel::fun_tpl;
-Channel::Channel(grpc_channel *channel, NanUtf8String *host)
- : wrapped_channel(channel), host(host) {}
+Channel::Channel(grpc_channel *channel) : wrapped_channel(channel) {}
Channel::~Channel() {
if (wrapped_channel != NULL) {
grpc_channel_destroy(wrapped_channel);
}
- delete host;
}
void Channel::Init(Handle<Object> exports) {
@@ -91,8 +89,6 @@ bool Channel::HasInstance(Handle<Value> val) {
grpc_channel *Channel::GetWrappedChannel() { return this->wrapped_channel; }
-char *Channel::GetHost() { return **this->host; }
-
NAN_METHOD(Channel::New) {
NanScope();
@@ -103,8 +99,7 @@ NAN_METHOD(Channel::New) {
}
grpc_channel *wrapped_channel;
// Owned by the Channel object
- NanUtf8String *host = new NanUtf8String(args[0]);
- NanUtf8String *host_override = NULL;
+ NanUtf8String host(args[0]);
grpc_credentials *creds;
if (!Credentials::HasInstance(args[1])) {
return NanThrowTypeError(
@@ -116,12 +111,9 @@ NAN_METHOD(Channel::New) {
grpc_channel_args *channel_args_ptr;
if (args[2]->IsUndefined()) {
channel_args_ptr = NULL;
- wrapped_channel = grpc_insecure_channel_create(**host, NULL);
+ wrapped_channel = grpc_insecure_channel_create(*host, NULL);
} else if (args[2]->IsObject()) {
Handle<Object> args_hash(args[2]->ToObject()->Clone());
- if (args_hash->HasOwnProperty(NanNew(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG))) {
- host_override = new NanUtf8String(args_hash->Get(NanNew(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)));
- }
Handle<Array> keys(args_hash->GetOwnPropertyNames());
grpc_channel_args channel_args;
channel_args.num_args = keys->Length();
@@ -153,20 +145,15 @@ NAN_METHOD(Channel::New) {
return NanThrowTypeError("Channel expects a string and an object");
}
if (creds == NULL) {
- wrapped_channel = grpc_insecure_channel_create(**host, channel_args_ptr);
+ wrapped_channel = grpc_insecure_channel_create(*host, channel_args_ptr);
} else {
wrapped_channel =
- grpc_secure_channel_create(creds, **host, channel_args_ptr);
+ grpc_secure_channel_create(creds, *host, channel_args_ptr);
}
if (channel_args_ptr != NULL) {
free(channel_args_ptr->args);
}
- Channel *channel;
- if (host_override == NULL) {
- channel = new Channel(wrapped_channel, host);
- } else {
- channel = new Channel(wrapped_channel, host_override);
- }
+ Channel *channel = new Channel(wrapped_channel);
channel->Wrap(args.This());
NanReturnValue(args.This());
} else {
diff --git a/src/node/ext/channel.h b/src/node/ext/channel.h
index 6725ebb03f..e2182cb45c 100644
--- a/src/node/ext/channel.h
+++ b/src/node/ext/channel.h
@@ -53,11 +53,8 @@ class Channel : public ::node::ObjectWrap {
/* Returns the grpc_channel struct that this object wraps */
grpc_channel *GetWrappedChannel();
- /* Return the hostname that this channel connects to */
- char *GetHost();
-
private:
- explicit Channel(grpc_channel *channel, NanUtf8String *host);
+ explicit Channel(grpc_channel *channel);
~Channel();
// Prevent copying
@@ -71,7 +68,6 @@ class Channel : public ::node::ObjectWrap {
static v8::Persistent<v8::FunctionTemplate> fun_tpl;
grpc_channel *wrapped_channel;
- NanUtf8String *host;
};
} // namespace node
diff --git a/src/node/interop/interop_client.js b/src/node/interop/interop_client.js
index 236b36616c..27f6c19c13 100644
--- a/src/node/interop/interop_client.js
+++ b/src/node/interop/interop_client.js
@@ -67,11 +67,8 @@ function zeroBuffer(size) {
* primarily for use with mocha
*/
function emptyUnary(client, done) {
- var call = client.emptyCall({}, function(err, resp) {
+ client.emptyCall({}, function(err, resp) {
assert.ifError(err);
- });
- call.on('status', function(status) {
- assert.strictEqual(status.code, grpc.status.OK);
if (done) {
done();
}
@@ -92,13 +89,10 @@ function largeUnary(client, done) {
body: zeroBuffer(271828)
}
};
- var call = client.unaryCall(arg, function(err, resp) {
+ client.unaryCall(arg, function(err, resp) {
assert.ifError(err);
assert.strictEqual(resp.payload.type, 'COMPRESSABLE');
assert.strictEqual(resp.payload.body.length, 314159);
- });
- call.on('status', function(status) {
- assert.strictEqual(status.code, grpc.status.OK);
if (done) {
done();
}
@@ -115,9 +109,6 @@ function clientStreaming(client, done) {
var call = client.streamingInputCall(function(err, resp) {
assert.ifError(err);
assert.strictEqual(resp.aggregated_payload_size, 74922);
- });
- call.on('status', function(status) {
- assert.strictEqual(status.code, grpc.status.OK);
if (done) {
done();
}
@@ -268,7 +259,7 @@ function cancelAfterFirstResponse(client, done) {
function timeoutOnSleepingServer(client, done) {
var deadline = new Date();
deadline.setMilliseconds(deadline.getMilliseconds() + 1);
- var call = client.fullDuplexCall(null, deadline);
+ var call = client.fullDuplexCall(null, {deadline: deadline});
call.write({
payload: {body: zeroBuffer(27182)}
});
@@ -302,15 +293,12 @@ function authTest(expected_user, scope, client, done) {
fill_username: true,
fill_oauth_scope: true
};
- var call = client.unaryCall(arg, function(err, resp) {
+ client.unaryCall(arg, function(err, resp) {
assert.ifError(err);
assert.strictEqual(resp.payload.type, 'COMPRESSABLE');
assert.strictEqual(resp.payload.body.length, 314159);
assert.strictEqual(resp.username, expected_user);
assert.strictEqual(resp.oauth_scope, AUTH_SCOPE_RESPONSE);
- });
- call.on('status', function(status) {
- assert.strictEqual(status.code, grpc.status.OK);
if (done) {
done();
}
@@ -340,13 +328,10 @@ function oauth2Test(expected_user, scope, per_rpc, client, done) {
};
var makeTestCall = function(error, client_metadata) {
assert.ifError(error);
- var call = client.unaryCall(arg, function(err, resp) {
+ client.unaryCall(arg, function(err, resp) {
assert.ifError(err);
assert.strictEqual(resp.username, expected_user);
assert.strictEqual(resp.oauth_scope, AUTH_SCOPE_RESPONSE);
- });
- call.on('status', function(status) {
- assert.strictEqual(status.code, grpc.status.OK);
if (done) {
done();
}
@@ -358,7 +343,6 @@ function oauth2Test(expected_user, scope, per_rpc, client, done) {
client.updateMetadata = updateMetadata;
makeTestCall(null, {});
}
-
});
});
}
@@ -409,6 +393,7 @@ function runTest(address, host_override, test_case, tls, test_ca, done) {
creds = grpc.Credentials.createSsl(ca_data);
if (host_override) {
options['grpc.ssl_target_name_override'] = host_override;
+ options['grpc.default_authority'] = host_override;
}
} else {
creds = grpc.Credentials.createInsecure();
diff --git a/src/node/src/client.js b/src/node/src/client.js
index b2b4423707..87c7690dc0 100644
--- a/src/node/src/client.js
+++ b/src/node/src/client.js
@@ -208,6 +208,25 @@ ClientWritableStream.prototype.getPeer = getPeer;
ClientDuplexStream.prototype.getPeer = getPeer;
/**
+ * Get a call object built with the provided options. Keys for options are
+ * 'deadline', which takes a date or number, and 'host', which takes a string
+ * and overrides the hostname to connect to.
+ * @param {Object} options Options map.
+ */
+function getCall(channel, method, options) {
+ var deadline;
+ var host;
+ if (options) {
+ deadline = options.deadline;
+ host = options.host;
+ }
+ if (deadline === undefined) {
+ deadline = Infinity;
+ }
+ return new grpc.Call(channel, method, deadline, host);
+}
+
+/**
* Get a function that can make unary requests to the specified method.
* @param {string} method The name of the method to request
* @param {function(*):Buffer} serialize The serialization function for inputs
@@ -226,17 +245,13 @@ function makeUnaryRequestFunction(method, serialize, deserialize) {
* response is received
* @param {array=} metadata Array of metadata key/value pairs to add to the
* call
- * @param {(number|Date)=} deadline The deadline for processing this request.
- * Defaults to infinite future
+ * @param {Object=} options Options map
* @return {EventEmitter} An event emitter for stream related events
*/
- function makeUnaryRequest(argument, callback, metadata, deadline) {
+ function makeUnaryRequest(argument, callback, metadata, options) {
/* jshint validthis: true */
- if (deadline === undefined) {
- deadline = Infinity;
- }
var emitter = new EventEmitter();
- var call = new grpc.Call(this.channel, method, deadline);
+ var call = getCall(this.channel, method, options);
if (metadata === null || metadata === undefined) {
metadata = {};
}
@@ -300,16 +315,12 @@ function makeClientStreamRequestFunction(method, serialize, deserialize) {
* response is received
* @param {array=} metadata Array of metadata key/value pairs to add to the
* call
- * @param {(number|Date)=} deadline The deadline for processing this request.
- * Defaults to infinite future
+ * @param {Object=} options Options map
* @return {EventEmitter} An event emitter for stream related events
*/
- function makeClientStreamRequest(callback, metadata, deadline) {
+ function makeClientStreamRequest(callback, metadata, options) {
/* jshint validthis: true */
- if (deadline === undefined) {
- deadline = Infinity;
- }
- var call = new grpc.Call(this.channel, method, deadline);
+ var call = getCall(this.channel, method, options);
if (metadata === null || metadata === undefined) {
metadata = {};
}
@@ -374,16 +385,12 @@ function makeServerStreamRequestFunction(method, serialize, deserialize) {
* serialize
* @param {array=} metadata Array of metadata key/value pairs to add to the
* call
- * @param {(number|Date)=} deadline The deadline for processing this request.
- * Defaults to infinite future
+ * @param {Object} options Options map
* @return {EventEmitter} An event emitter for stream related events
*/
- function makeServerStreamRequest(argument, metadata, deadline) {
+ function makeServerStreamRequest(argument, metadata, options) {
/* jshint validthis: true */
- if (deadline === undefined) {
- deadline = Infinity;
- }
- var call = new grpc.Call(this.channel, method, deadline);
+ var call = getCall(this.channel, method, options);
if (metadata === null || metadata === undefined) {
metadata = {};
}
@@ -446,16 +453,12 @@ function makeBidiStreamRequestFunction(method, serialize, deserialize) {
* @this {SurfaceClient} Client object. Must have a channel member.
* @param {array=} metadata Array of metadata key/value pairs to add to the
* call
- * @param {(number|Date)=} deadline The deadline for processing this request.
- * Defaults to infinite future
+ * @param {Options} options Options map
* @return {EventEmitter} An event emitter for stream related events
*/
- function makeBidiStreamRequest(metadata, deadline) {
+ function makeBidiStreamRequest(metadata, options) {
/* jshint validthis: true */
- if (deadline === undefined) {
- deadline = Infinity;
- }
- var call = new grpc.Call(this.channel, method, deadline);
+ var call = getCall(this.channel, method, options);
if (metadata === null || metadata === undefined) {
metadata = {};
}
diff --git a/src/node/test/call_test.js b/src/node/test/call_test.js
index 48d859a8ec..8d0f20b074 100644
--- a/src/node/test/call_test.js
+++ b/src/node/test/call_test.js
@@ -84,6 +84,11 @@ describe('call', function() {
new grpc.Call(channel, 'method', 0);
});
});
+ it('should accept an optional fourth string parameter', function() {
+ assert.doesNotThrow(function() {
+ new grpc.Call(channel, 'method', new Date(), 'host_override');
+ });
+ });
it('should fail with a closed channel', function() {
var local_channel = new grpc.Channel('hostname', insecureCreds);
local_channel.close();
diff --git a/src/node/test/end_to_end_test.js b/src/node/test/end_to_end_test.js
index ea41dfc28c..7574d98b8a 100644
--- a/src/node/test/end_to_end_test.js
+++ b/src/node/test/end_to_end_test.js
@@ -74,8 +74,6 @@ describe('end-to-end', function() {
});
it('should start and end a request without error', function(complete) {
var done = multiDone(complete, 2);
- var deadline = new Date();
- deadline.setSeconds(deadline.getSeconds() + 3);
var status_text = 'xyz';
var call = new grpc.Call(channel,
'dummy_method',
@@ -126,8 +124,6 @@ describe('end-to-end', function() {
});
it('should successfully send and receive metadata', function(complete) {
var done = multiDone(complete, 2);
- var deadline = new Date();
- deadline.setSeconds(deadline.getSeconds() + 3);
var status_text = 'xyz';
var call = new grpc.Call(channel,
'dummy_method',
@@ -184,8 +180,6 @@ describe('end-to-end', function() {
var req_text = 'client_request';
var reply_text = 'server_response';
var done = multiDone(complete, 2);
- var deadline = new Date();
- deadline.setSeconds(deadline.getSeconds() + 3);
var status_text = 'success';
var call = new grpc.Call(channel,
'dummy_method',
@@ -241,8 +235,6 @@ describe('end-to-end', function() {
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',
diff --git a/src/python/grpcio/grpc/_adapter/_c/module.c b/src/python/grpcio/grpc/_adapter/_c/module.c
index 1f3aedd9d8..9b93b051f6 100644
--- a/src/python/grpcio/grpc/_adapter/_c/module.c
+++ b/src/python/grpcio/grpc/_adapter/_c/module.c
@@ -53,6 +53,12 @@ PyMODINIT_FUNC init_c(void) {
return;
}
+ if (PyModule_AddStringConstant(
+ module, "PRIMARY_USER_AGENT_KEY",
+ GRPC_ARG_PRIMARY_USER_AGENT_STRING) < 0) {
+ return;
+ }
+
/* GRPC maintains an internal counter of how many times it has been
initialized and handles multiple pairs of grpc_init()/grpc_shutdown()
invocations accordingly. */
diff --git a/src/python/grpcio/grpc/_adapter/_c/types/server.c b/src/python/grpcio/grpc/_adapter/_c/types/server.c
index c2190ea672..2a11d09d21 100644
--- a/src/python/grpcio/grpc/_adapter/_c/types/server.c
+++ b/src/python/grpcio/grpc/_adapter/_c/types/server.c
@@ -96,7 +96,7 @@ Server *pygrpc_Server_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
PyObject *py_args;
grpc_channel_args c_args;
char *keywords[] = {"cq", "args", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O:Channel", keywords,
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O:Server", keywords,
&pygrpc_CompletionQueue_type, &cq, &py_args)) {
return NULL;
}
diff --git a/src/python/grpcio/grpc/_adapter/_low.py b/src/python/grpcio/grpc/_adapter/_low.py
index 06d30c1b32..147086e725 100644
--- a/src/python/grpcio/grpc/_adapter/_low.py
+++ b/src/python/grpcio/grpc/_adapter/_low.py
@@ -27,9 +27,12 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+from grpc import _grpcio_metadata
from grpc._adapter import _c
from grpc._adapter import _types
+_USER_AGENT = 'Python-gRPC-{}'.format(_grpcio_metadata.__version__)
+
ClientCredentials = _c.ClientCredentials
ServerCredentials = _c.ServerCredentials
@@ -79,6 +82,7 @@ class Call(_types.Call):
class Channel(_types.Channel):
def __init__(self, target, args, creds=None):
+ args = list(args) + [(_c.PRIMARY_USER_AGENT_KEY, _USER_AGENT)]
if creds is None:
self.channel = _c.Channel(target, args)
else:
diff --git a/src/python/grpcio_test/grpc_interop/_interop_test_case.py b/src/python/grpcio_test/grpc_interop/_interop_test_case.py
index ed8f7ef009..b6d06b300d 100644
--- a/src/python/grpcio_test/grpc_interop/_interop_test_case.py
+++ b/src/python/grpcio_test/grpc_interop/_interop_test_case.py
@@ -59,3 +59,6 @@ class InteropTestCase(object):
def testCancelAfterFirstResponse(self):
methods.TestCase.CANCEL_AFTER_FIRST_RESPONSE.test_interoperability(self.stub, None)
+
+ def testTimeoutOnSleepingServer(self):
+ methods.TestCase.TIMEOUT_ON_SLEEPING_SERVER.test_interoperability(self.stub, None)
diff --git a/src/python/grpcio_test/grpc_interop/methods.py b/src/python/grpcio_test/grpc_interop/methods.py
index f4c94685ee..7a831f3cbd 100644
--- a/src/python/grpcio_test/grpc_interop/methods.py
+++ b/src/python/grpcio_test/grpc_interop/methods.py
@@ -33,10 +33,12 @@ import enum
import json
import os
import threading
+import time
from oauth2client import client as oauth2client_client
from grpc.framework.alpha import utilities
+from grpc.framework.alpha import exceptions
from grpc_interop import empty_pb2
from grpc_interop import messages_pb2
@@ -318,6 +320,24 @@ def _cancel_after_first_response(stub):
raise ValueError('expected call to be cancelled')
+def _timeout_on_sleeping_server(stub):
+ request_payload_size = 27182
+ with stub, _Pipe() as pipe:
+ response_iterator = stub.FullDuplexCall(pipe, 0.001)
+
+ request = messages_pb2.StreamingOutputCallRequest(
+ response_type=messages_pb2.COMPRESSABLE,
+ payload=messages_pb2.Payload(body=b'\x00' * request_payload_size))
+ pipe.add(request)
+ time.sleep(0.1)
+ try:
+ next(response_iterator)
+ except exceptions.ExpirationError:
+ pass
+ else:
+ raise ValueError('expected call to exceed deadline')
+
+
def _compute_engine_creds(stub, args):
response = _large_unary_common_behavior(stub, True, True)
if args.default_service_account != response.username:
@@ -351,6 +371,7 @@ class TestCase(enum.Enum):
CANCEL_AFTER_FIRST_RESPONSE = 'cancel_after_first_response'
COMPUTE_ENGINE_CREDS = 'compute_engine_creds'
SERVICE_ACCOUNT_CREDS = 'service_account_creds'
+ TIMEOUT_ON_SLEEPING_SERVER = 'timeout_on_sleeping_server'
def test_interoperability(self, stub, args):
if self is TestCase.EMPTY_UNARY:
@@ -367,6 +388,8 @@ class TestCase(enum.Enum):
_cancel_after_begin(stub)
elif self is TestCase.CANCEL_AFTER_FIRST_RESPONSE:
_cancel_after_first_response(stub)
+ elif self is TestCase.TIMEOUT_ON_SLEEPING_SERVER:
+ _timeout_on_sleeping_server(stub)
elif self is TestCase.COMPUTE_ENGINE_CREDS:
_compute_engine_creds(stub, args)
elif self is TestCase.SERVICE_ACCOUNT_CREDS:
diff --git a/src/python/grpcio_test/grpc_protoc_plugin/__init__.py b/src/python/grpcio_test/grpc_protoc_plugin/__init__.py
new file mode 100644
index 0000000000..7086519106
--- /dev/null
+++ b/src/python/grpcio_test/grpc_protoc_plugin/__init__.py
@@ -0,0 +1,30 @@
+# 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/test/compiler/python_plugin_test.py b/src/python/grpcio_test/grpc_protoc_plugin/python_plugin_test.py
index 0e58d912b9..b200d129a9 100644
--- a/test/compiler/python_plugin_test.py
+++ b/src/python/grpcio_test/grpc_protoc_plugin/python_plugin_test.py
@@ -29,9 +29,11 @@
import argparse
import contextlib
+import distutils.spawn
import errno
import itertools
import os
+import pkg_resources
import shutil
import subprocess
import sys
@@ -58,9 +60,6 @@ SHORT_TIMEOUT = 2
LONG_TIMEOUT = 600
NO_DELAY = 0
-# Build mode environment variable set by tools/run_tests/run_tests.py.
-_build_mode = os.environ['CONFIG']
-
class _ServicerMethods(object):
@@ -228,9 +227,13 @@ class PythonPluginTest(unittest.TestCase):
"""
def setUp(self):
- protoc_command = '../../bins/%s/protobuf/protoc' % _build_mode
- protoc_plugin_filename = '../../bins/%s/grpc_python_plugin' % _build_mode
- test_proto_filename = './test.proto'
+ # Assume that the appropriate protoc and grpc_python_plugins are on the
+ # path.
+ protoc_command = 'protoc'
+ protoc_plugin_filename = distutils.spawn.find_executable(
+ 'grpc_python_plugin')
+ test_proto_filename = pkg_resources.resource_filename(
+ 'grpc_protoc_plugin', 'test.proto')
if not os.path.isfile(protoc_command):
# Assume that if we haven't built protoc that it's on the system.
protoc_command = 'protoc'
@@ -242,12 +245,13 @@ class PythonPluginTest(unittest.TestCase):
cmd = [
protoc_command,
'--plugin=protoc-gen-python-grpc=%s' % protoc_plugin_filename,
- '-I %s' % os.path.dirname(test_proto_filename),
+ '-I .',
'--python_out=%s' % self.outdir,
'--python-grpc_out=%s' % self.outdir,
os.path.basename(test_proto_filename),
]
- subprocess.call(' '.join(cmd), shell=True)
+ subprocess.check_call(' '.join(cmd), shell=True, env=os.environ,
+ cwd=os.path.dirname(test_proto_filename))
sys.path.append(self.outdir)
def tearDown(self):
diff --git a/test/compiler/test.proto b/src/python/grpcio_test/grpc_protoc_plugin/test.proto
index ed7c6a7b79..ed7c6a7b79 100644
--- a/test/compiler/test.proto
+++ b/src/python/grpcio_test/grpc_protoc_plugin/test.proto
diff --git a/src/python/grpcio_test/grpc_test/_adapter/_low_test.py b/src/python/grpcio_test/grpc_test/_adapter/_low_test.py
index 1e3aeb1787..44fe760fbc 100644
--- a/src/python/grpcio_test/grpc_test/_adapter/_low_test.py
+++ b/src/python/grpcio_test/grpc_test/_adapter/_low_test.py
@@ -31,11 +31,12 @@ import threading
import time
import unittest
+from grpc import _grpcio_metadata
from grpc._adapter import _types
from grpc._adapter import _low
-def WaitForEvents(completion_queues, deadline):
+def wait_for_events(completion_queues, deadline):
"""
Args:
completion_queues: list of completion queues to wait for events on
@@ -62,6 +63,7 @@ def WaitForEvents(completion_queues, deadline):
thread.join()
return results
+
class InsecureServerInsecureClient(unittest.TestCase):
def setUp(self):
@@ -123,16 +125,21 @@ class InsecureServerInsecureClient(unittest.TestCase):
], client_call_tag)
self.assertEquals(_types.CallError.OK, client_start_batch_result)
- client_no_event, request_event, = WaitForEvents([self.client_completion_queue, self.server_completion_queue], time.time() + 2)
+ client_no_event, request_event, = wait_for_events([self.client_completion_queue, self.server_completion_queue], time.time() + 2)
self.assertEquals(client_no_event, None)
self.assertEquals(_types.EventType.OP_COMPLETE, request_event.type)
self.assertIsInstance(request_event.call, _low.Call)
self.assertIs(server_request_tag, request_event.tag)
self.assertEquals(1, len(request_event.results))
- got_initial_metadata = dict(request_event.results[0].initial_metadata)
+ received_initial_metadata = dict(request_event.results[0].initial_metadata)
+ # Check that our metadata were transmitted
self.assertEquals(
dict(client_initial_metadata),
- dict((x, got_initial_metadata[x]) for x in zip(*client_initial_metadata)[0]))
+ dict((x, received_initial_metadata[x]) for x in zip(*client_initial_metadata)[0]))
+ # Check that Python's user agent string is a part of the full user agent
+ # string
+ self.assertIn('Python-gRPC-{}'.format(_grpcio_metadata.__version__),
+ received_initial_metadata['user-agent'])
self.assertEquals(METHOD, request_event.call_details.method)
self.assertEquals(HOST, request_event.call_details.host)
self.assertLess(abs(DEADLINE - request_event.call_details.deadline), DEADLINE_TOLERANCE)
@@ -159,7 +166,7 @@ class InsecureServerInsecureClient(unittest.TestCase):
], server_call_tag)
self.assertEquals(_types.CallError.OK, server_start_batch_result)
- client_event, server_event, = WaitForEvents([self.client_completion_queue, self.server_completion_queue], time.time() + 1)
+ client_event, server_event, = wait_for_events([self.client_completion_queue, self.server_completion_queue], time.time() + 1)
self.assertEquals(6, len(client_event.results))
found_client_op_types = set()
diff --git a/src/python/grpcio_test/grpc_test/framework/face/testing/blocking_invocation_inline_service_test_case.py b/src/python/grpcio_test/grpc_test/framework/face/testing/blocking_invocation_inline_service_test_case.py
index 7e1158f96b..251e1eb68e 100644
--- a/src/python/grpcio_test/grpc_test/framework/face/testing/blocking_invocation_inline_service_test_case.py
+++ b/src/python/grpcio_test/grpc_test/framework/face/testing/blocking_invocation_inline_service_test_case.py
@@ -34,15 +34,13 @@ import abc
import unittest # pylint: disable=unused-import
from grpc.framework.face import exceptions
+from grpc_test.framework.common import test_constants
from grpc_test.framework.face.testing import control
from grpc_test.framework.face.testing import coverage
from grpc_test.framework.face.testing import digest
from grpc_test.framework.face.testing import stock_service
from grpc_test.framework.face.testing import test_case
-_TIMEOUT = 3
-_LONG_TIMEOUT = 45
-
class BlockingInvocationInlineServiceTestCase(
test_case.FaceTestCase, coverage.BlockingCoverage):
@@ -79,7 +77,7 @@ class BlockingInvocationInlineServiceTestCase(
request = test_messages.request()
response = self.stub.blocking_value_in_value_out(
- name, request, _LONG_TIMEOUT)
+ name, request, test_constants.LONG_TIMEOUT)
test_messages.verify(request, response, self)
@@ -90,7 +88,7 @@ class BlockingInvocationInlineServiceTestCase(
request = test_messages.request()
response_iterator = self.stub.inline_value_in_stream_out(
- name, request, _LONG_TIMEOUT)
+ name, request, test_constants.LONG_TIMEOUT)
responses = list(response_iterator)
test_messages.verify(request, responses, self)
@@ -102,7 +100,7 @@ class BlockingInvocationInlineServiceTestCase(
requests = test_messages.requests()
response = self.stub.blocking_stream_in_value_out(
- name, iter(requests), _LONG_TIMEOUT)
+ name, iter(requests), test_constants.LONG_TIMEOUT)
test_messages.verify(requests, response, self)
@@ -113,7 +111,7 @@ class BlockingInvocationInlineServiceTestCase(
requests = test_messages.requests()
response_iterator = self.stub.inline_stream_in_stream_out(
- name, iter(requests), _LONG_TIMEOUT)
+ name, iter(requests), test_constants.LONG_TIMEOUT)
responses = list(response_iterator)
test_messages.verify(requests, responses, self)
@@ -126,12 +124,12 @@ class BlockingInvocationInlineServiceTestCase(
second_request = test_messages.request()
first_response = self.stub.blocking_value_in_value_out(
- name, first_request, _TIMEOUT)
+ name, first_request, test_constants.SHORT_TIMEOUT)
test_messages.verify(first_request, first_response, self)
second_response = self.stub.blocking_value_in_value_out(
- name, second_request, _TIMEOUT)
+ name, second_request, test_constants.SHORT_TIMEOUT)
test_messages.verify(second_request, second_response, self)
@@ -144,7 +142,7 @@ class BlockingInvocationInlineServiceTestCase(
with self.control.pause(), self.assertRaises(
exceptions.ExpirationError):
multi_callable = self.stub.unary_unary_multi_callable(name)
- multi_callable(request, _TIMEOUT)
+ multi_callable(request, test_constants.SHORT_TIMEOUT)
def testExpiredUnaryRequestStreamResponse(self):
for name, test_messages_sequence in (
@@ -155,7 +153,7 @@ class BlockingInvocationInlineServiceTestCase(
with self.control.pause(), self.assertRaises(
exceptions.ExpirationError):
response_iterator = self.stub.inline_value_in_stream_out(
- name, request, _TIMEOUT)
+ name, request, test_constants.SHORT_TIMEOUT)
list(response_iterator)
def testExpiredStreamRequestUnaryResponse(self):
@@ -167,7 +165,7 @@ class BlockingInvocationInlineServiceTestCase(
with self.control.pause(), self.assertRaises(
exceptions.ExpirationError):
multi_callable = self.stub.stream_unary_multi_callable(name)
- multi_callable(iter(requests), _TIMEOUT)
+ multi_callable(iter(requests), test_constants.SHORT_TIMEOUT)
def testExpiredStreamRequestStreamResponse(self):
for name, test_messages_sequence in (
@@ -178,7 +176,7 @@ class BlockingInvocationInlineServiceTestCase(
with self.control.pause(), self.assertRaises(
exceptions.ExpirationError):
response_iterator = self.stub.inline_stream_in_stream_out(
- name, iter(requests), _TIMEOUT)
+ name, iter(requests), test_constants.SHORT_TIMEOUT)
list(response_iterator)
def testFailedUnaryRequestUnaryResponse(self):
@@ -188,7 +186,8 @@ class BlockingInvocationInlineServiceTestCase(
request = test_messages.request()
with self.control.fail(), self.assertRaises(exceptions.ServicerError):
- self.stub.blocking_value_in_value_out(name, request, _TIMEOUT)
+ self.stub.blocking_value_in_value_out(name, request,
+ test_constants.SHORT_TIMEOUT)
def testFailedUnaryRequestStreamResponse(self):
for name, test_messages_sequence in (
@@ -198,7 +197,7 @@ class BlockingInvocationInlineServiceTestCase(
with self.control.fail(), self.assertRaises(exceptions.ServicerError):
response_iterator = self.stub.inline_value_in_stream_out(
- name, request, _TIMEOUT)
+ name, request, test_constants.SHORT_TIMEOUT)
list(response_iterator)
def testFailedStreamRequestUnaryResponse(self):
@@ -208,7 +207,8 @@ class BlockingInvocationInlineServiceTestCase(
requests = test_messages.requests()
with self.control.fail(), self.assertRaises(exceptions.ServicerError):
- self.stub.blocking_stream_in_value_out(name, iter(requests), _TIMEOUT)
+ self.stub.blocking_stream_in_value_out(name, iter(requests),
+ test_constants.SHORT_TIMEOUT)
def testFailedStreamRequestStreamResponse(self):
for name, test_messages_sequence in (
@@ -218,5 +218,5 @@ class BlockingInvocationInlineServiceTestCase(
with self.control.fail(), self.assertRaises(exceptions.ServicerError):
response_iterator = self.stub.inline_stream_in_stream_out(
- name, iter(requests), _TIMEOUT)
+ name, iter(requests), test_constants.SHORT_TIMEOUT)
list(response_iterator)
diff --git a/src/python/grpcio_test/grpc_test/framework/face/testing/event_invocation_synchronous_event_service_test_case.py b/src/python/grpcio_test/grpc_test/framework/face/testing/event_invocation_synchronous_event_service_test_case.py
index 18eed53d6e..9df77678eb 100644
--- a/src/python/grpcio_test/grpc_test/framework/face/testing/event_invocation_synchronous_event_service_test_case.py
+++ b/src/python/grpcio_test/grpc_test/framework/face/testing/event_invocation_synchronous_event_service_test_case.py
@@ -33,6 +33,7 @@ import abc
import unittest
from grpc.framework.face import interfaces
+from grpc_test.framework.common import test_constants
from grpc_test.framework.face.testing import callback as testing_callback
from grpc_test.framework.face.testing import control
from grpc_test.framework.face.testing import coverage
@@ -40,8 +41,6 @@ from grpc_test.framework.face.testing import digest
from grpc_test.framework.face.testing import stock_service
from grpc_test.framework.face.testing import test_case
-_TIMEOUT = 3
-
class EventInvocationSynchronousEventServiceTestCase(
test_case.FaceTestCase, coverage.FullCoverage):
@@ -79,7 +78,8 @@ class EventInvocationSynchronousEventServiceTestCase(
callback = testing_callback.Callback()
self.stub.event_value_in_value_out(
- name, request, callback.complete, callback.abort, _TIMEOUT)
+ name, request, callback.complete, callback.abort,
+ test_constants.SHORT_TIMEOUT)
callback.block_until_terminated()
response = callback.response()
@@ -93,7 +93,8 @@ class EventInvocationSynchronousEventServiceTestCase(
callback = testing_callback.Callback()
self.stub.event_value_in_stream_out(
- name, request, callback, callback.abort, _TIMEOUT)
+ name, request, callback, callback.abort,
+ test_constants.SHORT_TIMEOUT)
callback.block_until_terminated()
responses = callback.responses()
@@ -107,7 +108,8 @@ class EventInvocationSynchronousEventServiceTestCase(
callback = testing_callback.Callback()
unused_call, request_consumer = self.stub.event_stream_in_value_out(
- name, callback.complete, callback.abort, _TIMEOUT)
+ name, callback.complete, callback.abort,
+ test_constants.SHORT_TIMEOUT)
for request in requests:
request_consumer.consume(request)
request_consumer.terminate()
@@ -124,7 +126,7 @@ class EventInvocationSynchronousEventServiceTestCase(
callback = testing_callback.Callback()
unused_call, request_consumer = self.stub.event_stream_in_stream_out(
- name, callback, callback.abort, _TIMEOUT)
+ name, callback, callback.abort, test_constants.SHORT_TIMEOUT)
for request in requests:
request_consumer.consume(request)
request_consumer.terminate()
@@ -147,11 +149,11 @@ class EventInvocationSynchronousEventServiceTestCase(
first_callback.complete(first_response)
self.stub.event_value_in_value_out(
name, second_request, second_callback.complete,
- second_callback.abort, _TIMEOUT)
+ second_callback.abort, test_constants.SHORT_TIMEOUT)
self.stub.event_value_in_value_out(
name, first_request, make_second_invocation, first_callback.abort,
- _TIMEOUT)
+ test_constants.SHORT_TIMEOUT)
second_callback.block_until_terminated()
first_response = first_callback.response()
@@ -168,7 +170,8 @@ class EventInvocationSynchronousEventServiceTestCase(
with self.control.pause():
self.stub.event_value_in_value_out(
- name, request, callback.complete, callback.abort, _TIMEOUT)
+ name, request, callback.complete, callback.abort,
+ test_constants.SHORT_TIMEOUT)
callback.block_until_terminated()
self.assertEqual(interfaces.Abortion.EXPIRED, callback.abortion())
@@ -182,7 +185,8 @@ class EventInvocationSynchronousEventServiceTestCase(
with self.control.pause():
self.stub.event_value_in_stream_out(
- name, request, callback, callback.abort, _TIMEOUT)
+ name, request, callback, callback.abort,
+ test_constants.SHORT_TIMEOUT)
callback.block_until_terminated()
self.assertEqual(interfaces.Abortion.EXPIRED, callback.abortion())
@@ -194,7 +198,8 @@ class EventInvocationSynchronousEventServiceTestCase(
callback = testing_callback.Callback()
self.stub.event_stream_in_value_out(
- name, callback.complete, callback.abort, _TIMEOUT)
+ name, callback.complete, callback.abort,
+ test_constants.SHORT_TIMEOUT)
callback.block_until_terminated()
self.assertEqual(interfaces.Abortion.EXPIRED, callback.abortion())
@@ -207,7 +212,7 @@ class EventInvocationSynchronousEventServiceTestCase(
callback = testing_callback.Callback()
unused_call, request_consumer = self.stub.event_stream_in_stream_out(
- name, callback, callback.abort, _TIMEOUT)
+ name, callback, callback.abort, test_constants.SHORT_TIMEOUT)
for request in requests:
request_consumer.consume(request)
callback.block_until_terminated()
@@ -223,10 +228,12 @@ class EventInvocationSynchronousEventServiceTestCase(
with self.control.fail():
self.stub.event_value_in_value_out(
- name, request, callback.complete, callback.abort, _TIMEOUT)
+ name, request, callback.complete, callback.abort,
+ test_constants.SHORT_TIMEOUT)
callback.block_until_terminated()
- self.assertEqual(interfaces.Abortion.SERVICER_FAILURE, callback.abortion())
+ self.assertEqual(interfaces.Abortion.SERVICER_FAILURE,
+ callback.abortion())
def testFailedUnaryRequestStreamResponse(self):
for name, test_messages_sequence in (
@@ -237,10 +244,12 @@ class EventInvocationSynchronousEventServiceTestCase(
with self.control.fail():
self.stub.event_value_in_stream_out(
- name, request, callback, callback.abort, _TIMEOUT)
+ name, request, callback, callback.abort,
+ test_constants.SHORT_TIMEOUT)
callback.block_until_terminated()
- self.assertEqual(interfaces.Abortion.SERVICER_FAILURE, callback.abortion())
+ self.assertEqual(interfaces.Abortion.SERVICER_FAILURE,
+ callback.abortion())
def testFailedStreamRequestUnaryResponse(self):
for name, test_messages_sequence in (
@@ -251,13 +260,15 @@ class EventInvocationSynchronousEventServiceTestCase(
with self.control.fail():
unused_call, request_consumer = self.stub.event_stream_in_value_out(
- name, callback.complete, callback.abort, _TIMEOUT)
+ name, callback.complete, callback.abort,
+ test_constants.SHORT_TIMEOUT)
for request in requests:
request_consumer.consume(request)
request_consumer.terminate()
callback.block_until_terminated()
- self.assertEqual(interfaces.Abortion.SERVICER_FAILURE, callback.abortion())
+ self.assertEqual(interfaces.Abortion.SERVICER_FAILURE,
+ callback.abortion())
def testFailedStreamRequestStreamResponse(self):
for name, test_messages_sequence in (
@@ -268,7 +279,7 @@ class EventInvocationSynchronousEventServiceTestCase(
with self.control.fail():
unused_call, request_consumer = self.stub.event_stream_in_stream_out(
- name, callback, callback.abort, _TIMEOUT)
+ name, callback, callback.abort, test_constants.SHORT_TIMEOUT)
for request in requests:
request_consumer.consume(request)
request_consumer.terminate()
@@ -287,10 +298,10 @@ class EventInvocationSynchronousEventServiceTestCase(
self.stub.event_value_in_value_out(
name, first_request, first_callback.complete, first_callback.abort,
- _TIMEOUT)
+ test_constants.SHORT_TIMEOUT)
self.stub.event_value_in_value_out(
name, second_request, second_callback.complete,
- second_callback.abort, _TIMEOUT)
+ second_callback.abort, test_constants.SHORT_TIMEOUT)
first_callback.block_until_terminated()
second_callback.block_until_terminated()
@@ -312,7 +323,8 @@ class EventInvocationSynchronousEventServiceTestCase(
with self.control.pause():
call = self.stub.event_value_in_value_out(
- name, request, callback.complete, callback.abort, _TIMEOUT)
+ name, request, callback.complete, callback.abort,
+ test_constants.SHORT_TIMEOUT)
call.cancel()
callback.block_until_terminated()
@@ -326,7 +338,8 @@ class EventInvocationSynchronousEventServiceTestCase(
callback = testing_callback.Callback()
call = self.stub.event_value_in_stream_out(
- name, request, callback, callback.abort, _TIMEOUT)
+ name, request, callback, callback.abort,
+ test_constants.SHORT_TIMEOUT)
call.cancel()
callback.block_until_terminated()
@@ -340,7 +353,8 @@ class EventInvocationSynchronousEventServiceTestCase(
callback = testing_callback.Callback()
call, request_consumer = self.stub.event_stream_in_value_out(
- name, callback.complete, callback.abort, _TIMEOUT)
+ name, callback.complete, callback.abort,
+ test_constants.SHORT_TIMEOUT)
for request in requests:
request_consumer.consume(request)
call.cancel()
@@ -355,7 +369,7 @@ class EventInvocationSynchronousEventServiceTestCase(
callback = testing_callback.Callback()
call, unused_request_consumer = self.stub.event_stream_in_stream_out(
- name, callback, callback.abort, _TIMEOUT)
+ name, callback, callback.abort, test_constants.SHORT_TIMEOUT)
call.cancel()
callback.block_until_terminated()
diff --git a/src/python/grpcio_test/grpc_test/framework/face/testing/future_invocation_asynchronous_event_service_test_case.py b/src/python/grpcio_test/grpc_test/framework/face/testing/future_invocation_asynchronous_event_service_test_case.py
index 3b42914342..70d86a0422 100644
--- a/src/python/grpcio_test/grpc_test/framework/face/testing/future_invocation_asynchronous_event_service_test_case.py
+++ b/src/python/grpcio_test/grpc_test/framework/face/testing/future_invocation_asynchronous_event_service_test_case.py
@@ -37,13 +37,13 @@ import unittest
from grpc.framework.face import exceptions
from grpc.framework.foundation import future
from grpc.framework.foundation import logging_pool
+from grpc_test.framework.common import test_constants
from grpc_test.framework.face.testing import control
from grpc_test.framework.face.testing import coverage
from grpc_test.framework.face.testing import digest
from grpc_test.framework.face.testing import stock_service
from grpc_test.framework.face.testing import test_case
-_TIMEOUT = 3
_MAXIMUM_POOL_SIZE = 10
@@ -110,7 +110,7 @@ class FutureInvocationAsynchronousEventServiceTestCase(
request = test_messages.request()
response_future = self.stub.future_value_in_value_out(
- name, request, _TIMEOUT)
+ name, request, test_constants.SHORT_TIMEOUT)
response = response_future.result()
test_messages.verify(request, response, self)
@@ -122,7 +122,7 @@ class FutureInvocationAsynchronousEventServiceTestCase(
request = test_messages.request()
response_iterator = self.stub.inline_value_in_stream_out(
- name, request, _TIMEOUT)
+ name, request, test_constants.SHORT_TIMEOUT)
responses = list(response_iterator)
test_messages.verify(request, responses, self)
@@ -138,7 +138,7 @@ class FutureInvocationAsynchronousEventServiceTestCase(
# returned to calling code before the iterator yields any requests.
with request_iterator.pause():
response_future = self.stub.future_stream_in_value_out(
- name, request_iterator, _TIMEOUT)
+ name, request_iterator, test_constants.SHORT_TIMEOUT)
response = response_future.result()
test_messages.verify(requests, response, self)
@@ -154,7 +154,7 @@ class FutureInvocationAsynchronousEventServiceTestCase(
# returned to calling code before the iterator yields any requests.
with request_iterator.pause():
response_iterator = self.stub.inline_stream_in_stream_out(
- name, request_iterator, _TIMEOUT)
+ name, request_iterator, test_constants.SHORT_TIMEOUT)
responses = list(response_iterator)
test_messages.verify(requests, responses, self)
@@ -167,13 +167,13 @@ class FutureInvocationAsynchronousEventServiceTestCase(
second_request = test_messages.request()
first_response_future = self.stub.future_value_in_value_out(
- name, first_request, _TIMEOUT)
+ name, first_request, test_constants.SHORT_TIMEOUT)
first_response = first_response_future.result()
test_messages.verify(first_request, first_response, self)
second_response_future = self.stub.future_value_in_value_out(
- name, second_request, _TIMEOUT)
+ name, second_request, test_constants.SHORT_TIMEOUT)
second_response = second_response_future.result()
test_messages.verify(second_request, second_response, self)
@@ -186,7 +186,8 @@ class FutureInvocationAsynchronousEventServiceTestCase(
with self.control.pause():
multi_callable = self.stub.unary_unary_multi_callable(name)
- response_future = multi_callable.future(request, _TIMEOUT)
+ response_future = multi_callable.future(request,
+ test_constants.SHORT_TIMEOUT)
self.assertIsInstance(
response_future.exception(), exceptions.ExpirationError)
with self.assertRaises(exceptions.ExpirationError):
@@ -200,7 +201,7 @@ class FutureInvocationAsynchronousEventServiceTestCase(
with self.control.pause():
response_iterator = self.stub.inline_value_in_stream_out(
- name, request, _TIMEOUT)
+ name, request, test_constants.SHORT_TIMEOUT)
with self.assertRaises(exceptions.ExpirationError):
list(response_iterator)
@@ -212,7 +213,8 @@ class FutureInvocationAsynchronousEventServiceTestCase(
with self.control.pause():
multi_callable = self.stub.stream_unary_multi_callable(name)
- response_future = multi_callable.future(iter(requests), _TIMEOUT)
+ response_future = multi_callable.future(iter(requests),
+ test_constants.SHORT_TIMEOUT)
self.assertIsInstance(
response_future.exception(), exceptions.ExpirationError)
with self.assertRaises(exceptions.ExpirationError):
@@ -226,7 +228,7 @@ class FutureInvocationAsynchronousEventServiceTestCase(
with self.control.pause():
response_iterator = self.stub.inline_stream_in_stream_out(
- name, iter(requests), _TIMEOUT)
+ name, iter(requests), test_constants.SHORT_TIMEOUT)
with self.assertRaises(exceptions.ExpirationError):
list(response_iterator)
@@ -238,7 +240,7 @@ class FutureInvocationAsynchronousEventServiceTestCase(
with self.control.fail():
response_future = self.stub.future_value_in_value_out(
- name, request, _TIMEOUT)
+ name, request, test_constants.SHORT_TIMEOUT)
# Because the servicer fails outside of the thread from which the
# servicer-side runtime called into it its failure is
@@ -261,7 +263,7 @@ class FutureInvocationAsynchronousEventServiceTestCase(
# expiration of the RPC.
with self.control.fail(), self.assertRaises(exceptions.ExpirationError):
response_iterator = self.stub.inline_value_in_stream_out(
- name, request, _TIMEOUT)
+ name, request, test_constants.SHORT_TIMEOUT)
list(response_iterator)
def testFailedStreamRequestUnaryResponse(self):
@@ -272,7 +274,7 @@ class FutureInvocationAsynchronousEventServiceTestCase(
with self.control.fail():
response_future = self.stub.future_stream_in_value_out(
- name, iter(requests), _TIMEOUT)
+ name, iter(requests), test_constants.SHORT_TIMEOUT)
# Because the servicer fails outside of the thread from which the
# servicer-side runtime called into it its failure is
@@ -295,7 +297,7 @@ class FutureInvocationAsynchronousEventServiceTestCase(
# expiration of the RPC.
with self.control.fail(), self.assertRaises(exceptions.ExpirationError):
response_iterator = self.stub.inline_stream_in_stream_out(
- name, iter(requests), _TIMEOUT)
+ name, iter(requests), test_constants.SHORT_TIMEOUT)
list(response_iterator)
def testParallelInvocations(self):
@@ -305,10 +307,11 @@ class FutureInvocationAsynchronousEventServiceTestCase(
first_request = test_messages.request()
second_request = test_messages.request()
+ # TODO(bug 2039): use LONG_TIMEOUT instead
first_response_future = self.stub.future_value_in_value_out(
- name, first_request, _TIMEOUT)
+ name, first_request, test_constants.SHORT_TIMEOUT)
second_response_future = self.stub.future_value_in_value_out(
- name, second_request, _TIMEOUT)
+ name, second_request, test_constants.SHORT_TIMEOUT)
first_response = first_response_future.result()
second_response = second_response_future.result()
@@ -327,7 +330,7 @@ class FutureInvocationAsynchronousEventServiceTestCase(
with self.control.pause():
response_future = self.stub.future_value_in_value_out(
- name, request, _TIMEOUT)
+ name, request, test_constants.SHORT_TIMEOUT)
cancel_method_return_value = response_future.cancel()
self.assertFalse(cancel_method_return_value)
@@ -341,7 +344,7 @@ class FutureInvocationAsynchronousEventServiceTestCase(
with self.control.pause():
response_iterator = self.stub.inline_value_in_stream_out(
- name, request, _TIMEOUT)
+ name, request, test_constants.SHORT_TIMEOUT)
response_iterator.cancel()
with self.assertRaises(future.CancelledError):
@@ -355,7 +358,7 @@ class FutureInvocationAsynchronousEventServiceTestCase(
with self.control.pause():
response_future = self.stub.future_stream_in_value_out(
- name, iter(requests), _TIMEOUT)
+ name, iter(requests), test_constants.SHORT_TIMEOUT)
cancel_method_return_value = response_future.cancel()
self.assertFalse(cancel_method_return_value)
@@ -369,7 +372,7 @@ class FutureInvocationAsynchronousEventServiceTestCase(
with self.control.pause():
response_iterator = self.stub.inline_stream_in_stream_out(
- name, iter(requests), _TIMEOUT)
+ name, iter(requests), test_constants.SHORT_TIMEOUT)
response_iterator.cancel()
with self.assertRaises(future.CancelledError):
diff --git a/src/python/grpcio_test/setup.py b/src/python/grpcio_test/setup.py
index 925c32720f..a6203cae2d 100644
--- a/src/python/grpcio_test/setup.py
+++ b/src/python/grpcio_test/setup.py
@@ -48,8 +48,13 @@ _PACKAGE_DIRECTORIES = {
_PACKAGE_DATA = {
'grpc_interop': [
- 'credentials/ca.pem', 'credentials/server1.key',
- 'credentials/server1.pem',]
+ 'credentials/ca.pem',
+ 'credentials/server1.key',
+ 'credentials/server1.pem',
+ ],
+ 'grpc_protoc_plugin': [
+ 'test.proto',
+ ],
}
_SETUP_REQUIRES = (
@@ -75,5 +80,5 @@ setuptools.setup(
package_data=_PACKAGE_DATA,
install_requires=_INSTALL_REQUIRES + _SETUP_REQUIRES,
setup_requires=_SETUP_REQUIRES,
- cmdclass=_COMMAND_CLASS
+ cmdclass=_COMMAND_CLASS,
)
diff --git a/src/ruby/ext/grpc/rb_call.c b/src/ruby/ext/grpc/rb_call.c
index a7607a83a3..88659da535 100644
--- a/src/ruby/ext/grpc/rb_call.c
+++ b/src/ruby/ext/grpc/rb_call.c
@@ -179,6 +179,19 @@ static VALUE grpc_rb_call_cancel(VALUE self) {
return Qnil;
}
+/* Called to obtain the peer that this call is connected to. */
+static VALUE grpc_rb_call_get_peer(VALUE self) {
+ VALUE res = Qnil;
+ grpc_call *call = NULL;
+ char *peer = NULL;
+ TypedData_Get_Struct(self, grpc_call, &grpc_call_data_type, call);
+ peer = grpc_call_get_peer(call);
+ res = rb_str_new2(peer);
+ gpr_free(peer);
+
+ return res;
+}
+
/*
call-seq:
status = call.status
@@ -720,6 +733,7 @@ void Init_grpc_call() {
/* Add ruby analogues of the Call methods. */
rb_define_method(grpc_rb_cCall, "run_batch", grpc_rb_call_run_batch, 4);
rb_define_method(grpc_rb_cCall, "cancel", grpc_rb_call_cancel, 0);
+ rb_define_method(grpc_rb_cCall, "peer", grpc_rb_call_get_peer, 0);
rb_define_method(grpc_rb_cCall, "status", grpc_rb_call_get_status, 0);
rb_define_method(grpc_rb_cCall, "status=", grpc_rb_call_set_status, 1);
rb_define_method(grpc_rb_cCall, "metadata", grpc_rb_call_get_metadata, 0);
diff --git a/src/ruby/ext/grpc/rb_channel.c b/src/ruby/ext/grpc/rb_channel.c
index a0663607c2..ac591f1563 100644
--- a/src/ruby/ext/grpc/rb_channel.c
+++ b/src/ruby/ext/grpc/rb_channel.c
@@ -37,6 +37,7 @@
#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
+#include <grpc/support/alloc.h>
#include "rb_grpc.h"
#include "rb_call.h"
#include "rb_channel_args.h"
@@ -202,7 +203,10 @@ static VALUE grpc_rb_channel_create_call(VALUE self, VALUE cqueue, VALUE method,
grpc_channel *ch = NULL;
grpc_completion_queue *cq = NULL;
char *method_chars = StringValueCStr(method);
- char *host_chars = StringValueCStr(host);
+ char *host_chars = NULL;
+ if (host != Qnil) {
+ host_chars = StringValueCStr(host);
+ }
cq = grpc_rb_get_wrapped_completion_queue(cqueue);
TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
@@ -249,6 +253,21 @@ static VALUE grpc_rb_channel_destroy(VALUE self) {
return Qnil;
}
+
+/* Called to obtain the target that this channel accesses. */
+static VALUE grpc_rb_channel_get_target(VALUE self) {
+ grpc_rb_channel *wrapper = NULL;
+ VALUE res = Qnil;
+ char* target = NULL;
+
+ TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
+ target = grpc_channel_get_target(wrapper->wrapped);
+ res = rb_str_new2(target);
+ gpr_free(target);
+
+ return res;
+}
+
void Init_grpc_channel() {
grpc_rb_cChannelArgs = rb_define_class("TmpChannelArgs", rb_cObject);
grpc_rb_cChannel =
@@ -265,6 +284,7 @@ void Init_grpc_channel() {
/* Add ruby analogues of the Channel methods. */
rb_define_method(grpc_rb_cChannel, "create_call",
grpc_rb_channel_create_call, 4);
+ rb_define_method(grpc_rb_cChannel, "target", grpc_rb_channel_get_target, 0);
rb_define_method(grpc_rb_cChannel, "destroy", grpc_rb_channel_destroy, 0);
rb_define_alias(grpc_rb_cChannel, "close", "destroy");
diff --git a/src/ruby/grpc.gemspec b/src/ruby/grpc.gemspec
index dd4e27df51..45f31329e9 100755
--- a/src/ruby/grpc.gemspec
+++ b/src/ruby/grpc.gemspec
@@ -16,12 +16,15 @@ Gem::Specification.new do |s|
s.required_ruby_version = '>= 2.0.0'
s.requirements << 'libgrpc ~> 0.10.0 needs to be installed'
- s.files = `git ls-files`.split("\n")
- s.test_files = `git ls-files -- spec/*`.split("\n")
- s.executables = `git ls-files -- bin/*.rb`.split("\n").map do |f|
- File.basename(f)
+ s.files = %w( Rakefile )
+ s.files += Dir.glob('lib/**/*')
+ s.files += Dir.glob('ext/**/*')
+ s.files += Dir.glob('bin/**/*')
+ s.test_files = Dir.glob('spec/**/*')
+ %w(math noproto).each do |b|
+ s.executables += [ "#{b}_client.rb", "#{b}_server.rb" ]
end
- s.require_paths = ['lib']
+ s.require_paths = %w( bin lib )
s.platform = Gem::Platform::RUBY
s.add_dependency 'google-protobuf', '~> 3.0.0alpha.1.1'
diff --git a/src/ruby/lib/grpc/generic/client_stub.rb b/src/ruby/lib/grpc/generic/client_stub.rb
index 7b2c04aa22..a2f1ec612d 100644
--- a/src/ruby/lib/grpc/generic/client_stub.rb
+++ b/src/ruby/lib/grpc/generic/client_stub.rb
@@ -28,6 +28,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
require 'grpc/generic/active_call'
+require 'grpc/version'
# GRPC contains the General RPC module.
module GRPC
@@ -36,8 +37,8 @@ module GRPC
include Core::StatusCodes
include Core::TimeConsts
- # Default timeout is 5 seconds.
- DEFAULT_TIMEOUT = 5
+ # Default timeout is infinity.
+ DEFAULT_TIMEOUT = INFINITE_FUTURE
# setup_channel is used by #initialize to constuct a channel from its
# arguments.
@@ -46,6 +47,7 @@ module GRPC
fail(TypeError, '!Channel') unless alt_chan.is_a?(Core::Channel)
return alt_chan
end
+ kw['grpc.primary_user_agent'] = "grpc-ruby/#{VERSION}"
return Core::Channel.new(host, kw) if creds.nil?
fail(TypeError, '!Credentials') unless creds.is_a?(Core::Credentials)
Core::Channel.new(host, kw, creds)
@@ -408,7 +410,7 @@ module GRPC
# @param timeout [TimeConst]
def new_active_call(method, marshal, unmarshal, timeout = nil)
deadline = from_relative_time(timeout.nil? ? @timeout : timeout)
- call = @ch.create_call(@queue, method, @host, deadline)
+ call = @ch.create_call(@queue, method, nil, deadline)
ActiveCall.new(call, @queue, marshal, unmarshal, deadline, started: false)
end
end
diff --git a/src/ruby/spec/call_spec.rb b/src/ruby/spec/call_spec.rb
index 4977c10a7e..36a442faed 100644
--- a/src/ruby/spec/call_spec.rb
+++ b/src/ruby/spec/call_spec.rb
@@ -137,7 +137,7 @@ describe GRPC::Core::Call do
end
def make_test_call
- @ch.create_call(client_queue, 'dummy_method', 'dummy_host', deadline)
+ @ch.create_call(client_queue, 'dummy_method', nil, deadline)
end
def deadline
diff --git a/src/ruby/spec/channel_spec.rb b/src/ruby/spec/channel_spec.rb
index d471ff5db6..9081f0e20c 100644
--- a/src/ruby/spec/channel_spec.rb
+++ b/src/ruby/spec/channel_spec.rb
@@ -117,7 +117,7 @@ describe GRPC::Core::Channel do
deadline = Time.now + 5
blk = proc do
- ch.create_call(cq, 'dummy_method', 'dummy_host', deadline)
+ ch.create_call(cq, 'dummy_method', nil, deadline)
end
expect(&blk).to_not raise_error
end
@@ -128,7 +128,7 @@ describe GRPC::Core::Channel do
deadline = Time.now + 5
blk = proc do
- ch.create_call(cq, 'dummy_method', 'dummy_host', deadline)
+ ch.create_call(cq, 'dummy_method', nil, deadline)
end
expect(&blk).to raise_error(RuntimeError)
end
diff --git a/src/ruby/spec/client_server_spec.rb b/src/ruby/spec/client_server_spec.rb
index 0e85441209..57c9a8de9b 100644
--- a/src/ruby/spec/client_server_spec.rb
+++ b/src/ruby/spec/client_server_spec.rb
@@ -61,7 +61,7 @@ shared_context 'setup: tags' do
end
def new_client_call
- @ch.create_call(@client_queue, '/method', 'foo.test.google.fr', deadline)
+ @ch.create_call(@client_queue, '/method', nil, deadline)
end
end
@@ -69,6 +69,23 @@ shared_examples 'basic GRPC message delivery is OK' do
include GRPC::Core
include_context 'setup: tags'
+ context 'the test channel' do
+ it 'should have a target' do
+ expect(@ch.target).to be_a(String)
+ end
+ end
+
+ context 'a client call' do
+ it 'should have a peer' do
+ expect(new_client_call.peer).to be_a(String)
+ end
+ end
+
+ it 'calls have peer info' do
+ call = new_client_call
+ expect(call.peer).to be_a(String)
+ end
+
it 'servers receive requests from clients and can respond' do
call = new_client_call
server_call = nil
diff --git a/src/ruby/spec/generic/active_call_spec.rb b/src/ruby/spec/generic/active_call_spec.rb
index bc3bee3d44..424b2dbdeb 100644
--- a/src/ruby/spec/generic/active_call_spec.rb
+++ b/src/ruby/spec/generic/active_call_spec.rb
@@ -338,7 +338,7 @@ describe GRPC::ActiveCall do
end
def make_test_call
- @ch.create_call(@client_queue, '/method', 'a.dummy.host', deadline)
+ @ch.create_call(@client_queue, '/method', nil, deadline)
end
def deadline
diff --git a/test/core/security/verify_jwt.c b/test/core/security/verify_jwt.c
index 9b334b3c3e..69bbc3cc0c 100644
--- a/test/core/security/verify_jwt.c
+++ b/test/core/security/verify_jwt.c
@@ -112,7 +112,7 @@ int main(int argc, char **argv) {
while (!sync.is_done) {
grpc_pollset_worker worker;
grpc_pollset_work(&sync.pollset, &worker,
- gpr_inf_future(GPR_CLOCK_REALTIME));
+ gpr_inf_future(GPR_CLOCK_MONOTONIC));
}
gpr_mu_unlock(GRPC_POLLSET_MU(&sync.pollset));
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index 5f0749daa5..37669815c6 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -117,7 +117,7 @@ class Proxy : public ::grpc::cpp::test::util::TestService::Service {
}
private:
- std::unique_ptr<::grpc::cpp::test::util::TestService::Stub> stub_;
+ std::unique_ptr< ::grpc::cpp::test::util::TestService::Stub> stub_;
};
class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service {
diff --git a/tools/dockerfile/grpc_go/Dockerfile b/tools/dockerfile/grpc_go/Dockerfile
index 06bb3e2d5e..7f3bd8719c 100644
--- a/tools/dockerfile/grpc_go/Dockerfile
+++ b/tools/dockerfile/grpc_go/Dockerfile
@@ -32,6 +32,8 @@ FROM golang:1.4
# Get the source from GitHub
RUN go get google.golang.org/grpc
+RUN go get golang.org/x/oauth2
+RUN go get google.golang.org/cloud
# Add a service_account directory containing the auth creds file
ADD service_account service_account
diff --git a/tools/dockerfile/grpc_go/build.sh b/tools/dockerfile/grpc_go/build.sh
new file mode 100755
index 0000000000..a3887c731b
--- /dev/null
+++ b/tools/dockerfile/grpc_go/build.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# 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.
+
+cp -R /var/local/git-clone/grpc-go/. /go/
+go get golang.org/x/oauth2
+go get google.golang.org/cloud
+cd src/google.golang.org/grpc/interop/client && go install
+cd src/google.golang.org/grpc/interop/server && go install
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index dd359f16ee..790e637b72 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -763,7 +763,6 @@ WARN_LOGFILE =
INPUT = include/grpc++/async_generic_service.h \
include/grpc++/async_unary_call.h \
include/grpc++/auth_context.h \
-include/grpc++/auth_property_iterator.h \
include/grpc++/byte_buffer.h \
include/grpc++/channel_arguments.h \
include/grpc++/channel_interface.h \
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 6e8437dc5b..cd1279e2a6 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -763,7 +763,6 @@ WARN_LOGFILE =
INPUT = include/grpc++/async_generic_service.h \
include/grpc++/async_unary_call.h \
include/grpc++/auth_context.h \
-include/grpc++/auth_property_iterator.h \
include/grpc++/byte_buffer.h \
include/grpc++/channel_arguments.h \
include/grpc++/channel_interface.h \
diff --git a/tools/run_tests/run_interops.py b/tools/run_tests/run_interops.py
index 1cf268526d..4e6b5ce2f6 100755
--- a/tools/run_tests/run_interops.py
+++ b/tools/run_tests/run_interops.py
@@ -4,24 +4,20 @@ import jobset
argp = argparse.ArgumentParser(description='Run interop tests.')
argp.add_argument('-l', '--language',
- choices=['build_only', 'c++'],
- nargs='+',
- default=['build_only'])
+ default='c++')
args = argp.parse_args()
# build job
-build_steps = 'tools/run_tests/run_interops_build.sh'
-build_job = jobset.JobSpec(cmdline=build_steps, shortname='build')
+build_job = jobset.JobSpec(cmdline=['tools/run_tests/run_interops_build.sh', '%s' % args.language], shortname='build')
-# test jobs
+# test jobs, each test is a separate job to run in parallel
_TESTS = ['large_unary', 'empty_unary', 'ping_pong', 'client_streaming', 'server_streaming']
jobs = []
jobNumber = 0
-for lang in args.language:
- for test in _TESTS:
- test_job = jobset.JobSpec(cmdline=['tools/run_tests/run_interops_test.sh', '%s' % lang, '%s' % test], shortname=test)
- jobs.append(test_job)
- jobNumber+=1
+for test in _TESTS:
+ test_job = jobset.JobSpec(cmdline=['tools/run_tests/run_interops_test.sh', '%s' % args.language, '%s' % test], shortname=test)
+ jobs.append(test_job)
+ jobNumber+=1
root = ET.Element('testsuites')
testsuite = ET.SubElement(root, 'testsuite', id='1', package='grpc', name='tests')
diff --git a/tools/run_tests/run_interops_build.sh b/tools/run_tests/run_interops_build.sh
index 23441a5300..ff1a26cf89 100755
--- a/tools/run_tests/run_interops_build.sh
+++ b/tools/run_tests/run_interops_build.sh
@@ -29,6 +29,8 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+language=$1
+
set -e
#clean up any old docker files and start mirroring repository if not started already
@@ -40,8 +42,34 @@ sudo docker run -d -e GCS_BUCKET=docker-interop-images -e STORAGE_PATH=/admin/d
#prepare building by pulling down base images and necessary files
sudo docker pull 0.0.0.0:5000/grpc/base
sudo docker tag -f 0.0.0.0:5000/grpc/base grpc/base
-gsutil cp -R gs://docker-interop-images/admin/service_account tools/dockerfile/grpc_cxx
-gsutil cp -R gs://docker-interop-images/admin/cacerts tools/dockerfile/grpc_cxx
-#build docker file, add more languages later
-sudo docker build --no-cache -t grpc/cxx tools/dockerfile/grpc_cxx
+if [ "$language" = "c++" ]
+then
+ gsutil cp -R gs://docker-interop-images/admin/service_account tools/dockerfile/grpc_cxx
+ gsutil cp -R gs://docker-interop-images/admin/cacerts tools/dockerfile/grpc_cxx
+ sudo docker build --no-cache -t grpc/cxx tools/dockerfile/grpc_cxx
+elif [ "$language" = "node" ]
+then
+ sudo docker pull 0.0.0.0:5000/grpc/node_base
+ sudo docker tag -f 0.0.0.0:5000/grpc/node_base grpc/node_base
+ gsutil cp -R gs://docker-interop-images/admin/service_account tools/dockerfile/grpc_node
+ gsutil cp -R gs://docker-interop-images/admin/cacerts tools/dockerfile/grpc_node
+ sudo docker build --no-cache -t grpc/node tools/dockerfile/grpc_node
+elif [ "$language" = "ruby" ]
+then
+ sudo docker pull 0.0.0.0:5000/grpc/ruby_base
+ sudo docker tag -f 0.0.0.0:5000/grpc/ruby_base grpc/ruby_base
+ gsutil cp -R gs://docker-interop-images/admin/service_account tools/dockerfile/grpc_ruby
+ gsutil cp -R gs://docker-interop-images/admin/cacerts tools/dockerfile/grpc_ruby
+ sudo docker build --no-cache -t grpc/ruby tools/dockerfile/grpc_ruby
+elif [ "$language" = "php" ]
+then
+ sudo docker pull 0.0.0.0:5000/grpc/php_base
+ sudo docker tag -f 0.0.0.0:5000/grpc/php_base grpc/php_base
+ gsutil cp -R gs://docker-interop-images/admin/service_account tools/dockerfile/grpc_php
+ gsutil cp -R gs://docker-interop-images/admin/cacerts tools/dockerfile/grpc_php
+ sudo docker build --no-cache -t grpc/php tools/dockerfile/grpc_php
+else
+ echo "interop testss not added for $language"
+ exit 1
+fi
diff --git a/tools/run_tests/run_interops_test.sh b/tools/run_tests/run_interops_test.sh
index 1d0eedad85..9be253af46 100755
--- a/tools/run_tests/run_interops_test.sh
+++ b/tools/run_tests/run_interops_test.sh
@@ -36,6 +36,17 @@ set -e
if [ "$language" = "c++" ]
then
sudo docker run grpc/cxx /var/local/git/grpc/bins/opt/interop_client --enable_ssl --use_prod_roots --server_host_override=grpc-test.sandbox.google.com --server_host=grpc-test.sandbox.google.com --server_port=443 --test_case=$test_case
+elif [ "$language" = "node" ]
+then
+ sudo docker run grpc/node /usr/bin/nodejs /var/local/git/grpc/src/node/interop/interop_client.js --use_tls=true --use_test_ca=true --server_port=443 --server_host=grpc-test.sandbox.google.com --server_host_override=grpc-test.sandbox.google.com --test_case=$test_case
+elif [ "$language" = "ruby" ]
+then
+ cmd_prefix="SSL_CERT_FILE=/cacerts/roots.pem ruby /var/local/git/grpc/src/ruby/bin/interop/interop_client.rb --use_tls --server_port=443 --server_host=grpc-test.sandbox.google.com --server_host_override=grpc-test.sandbox.google.com "
+ cmd="$cmd_prefix --test_case=$test_case"
+ sudo docker run grpc/ruby bin/bash -l -c '$cmd'
+elif [ "$language" = "php" ]
+then
+ sudo docker run -e SSL_CERT_FILE=/cacerts/roots.pem grpc/php /var/local/git/grpc/src/php/bin/interop_client.sh --server_port=443 --server_host=grpc-test.sandbox.google.com --server_host_override=grpc-test.sandbox.google.com --test_case=$test_case
else
echo "interop testss not added for $language"
exit 1
diff --git a/tools/run_tests/run_python.sh b/tools/run_tests/run_python.sh
index 5ffd4460b9..6f80219b0e 100755
--- a/tools/run_tests/run_python.sh
+++ b/tools/run_tests/run_python.sh
@@ -37,5 +37,6 @@ ROOT=`pwd`
GRPCIO_TEST=$ROOT/src/python/grpcio_test
export LD_LIBRARY_PATH=$ROOT/libs/$CONFIG
export DYLD_LIBRARY_PATH=$ROOT/libs/$CONFIG
+export PATH=$ROOT/bins/$CONFIG:$ROOT/bins/$CONFIG/protobuf:$PATH
source "python"$PYVER"_virtual_environment"/bin/activate
"python"$PYVER $GRPCIO_TEST/setup.py test -a "-n8 --cov=grpc --junitxml=./report.xml"
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index 5d23bf9e88..d2c3ec3add 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -13051,7 +13051,6 @@
"include/grpc++/async_generic_service.h",
"include/grpc++/async_unary_call.h",
"include/grpc++/auth_context.h",
- "include/grpc++/auth_property_iterator.h",
"include/grpc++/byte_buffer.h",
"include/grpc++/channel_arguments.h",
"include/grpc++/channel_interface.h",
@@ -13102,7 +13101,6 @@
"include/grpc++/async_generic_service.h",
"include/grpc++/async_unary_call.h",
"include/grpc++/auth_context.h",
- "include/grpc++/auth_property_iterator.h",
"include/grpc++/byte_buffer.h",
"include/grpc++/channel_arguments.h",
"include/grpc++/channel_interface.h",
@@ -13227,7 +13225,6 @@
"include/grpc++/async_generic_service.h",
"include/grpc++/async_unary_call.h",
"include/grpc++/auth_context.h",
- "include/grpc++/auth_property_iterator.h",
"include/grpc++/byte_buffer.h",
"include/grpc++/channel_arguments.h",
"include/grpc++/channel_interface.h",
@@ -13275,7 +13272,6 @@
"include/grpc++/async_generic_service.h",
"include/grpc++/async_unary_call.h",
"include/grpc++/auth_context.h",
- "include/grpc++/auth_property_iterator.h",
"include/grpc++/byte_buffer.h",
"include/grpc++/channel_arguments.h",
"include/grpc++/channel_interface.h",
diff --git a/vsprojects/grpc++/grpc++.vcxproj b/vsprojects/grpc++/grpc++.vcxproj
index 58474511fc..929bc1500e 100644
--- a/vsprojects/grpc++/grpc++.vcxproj
+++ b/vsprojects/grpc++/grpc++.vcxproj
@@ -216,7 +216,6 @@
<ClInclude Include="..\..\include\grpc++\async_generic_service.h" />
<ClInclude Include="..\..\include\grpc++\async_unary_call.h" />
<ClInclude Include="..\..\include\grpc++\auth_context.h" />
- <ClInclude Include="..\..\include\grpc++\auth_property_iterator.h" />
<ClInclude Include="..\..\include\grpc++\byte_buffer.h" />
<ClInclude Include="..\..\include\grpc++\channel_arguments.h" />
<ClInclude Include="..\..\include\grpc++\channel_interface.h" />
diff --git a/vsprojects/grpc++/grpc++.vcxproj.filters b/vsprojects/grpc++/grpc++.vcxproj.filters
index 2a8ee08b08..0408fb46a5 100644
--- a/vsprojects/grpc++/grpc++.vcxproj.filters
+++ b/vsprojects/grpc++/grpc++.vcxproj.filters
@@ -105,9 +105,6 @@
<ClInclude Include="..\..\include\grpc++\auth_context.h">
<Filter>include\grpc++</Filter>
</ClInclude>
- <ClInclude Include="..\..\include\grpc++\auth_property_iterator.h">
- <Filter>include\grpc++</Filter>
- </ClInclude>
<ClInclude Include="..\..\include\grpc++\byte_buffer.h">
<Filter>include\grpc++</Filter>
</ClInclude>
diff --git a/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj
index 0d989c4a93..2ff252e04e 100644
--- a/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj
+++ b/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj
@@ -216,7 +216,6 @@
<ClInclude Include="..\..\include\grpc++\async_generic_service.h" />
<ClInclude Include="..\..\include\grpc++\async_unary_call.h" />
<ClInclude Include="..\..\include\grpc++\auth_context.h" />
- <ClInclude Include="..\..\include\grpc++\auth_property_iterator.h" />
<ClInclude Include="..\..\include\grpc++\byte_buffer.h" />
<ClInclude Include="..\..\include\grpc++\channel_arguments.h" />
<ClInclude Include="..\..\include\grpc++\channel_interface.h" />
diff --git a/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
index 71d42e5c6d..b4fae7741c 100644
--- a/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
+++ b/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
@@ -90,9 +90,6 @@
<ClInclude Include="..\..\include\grpc++\auth_context.h">
<Filter>include\grpc++</Filter>
</ClInclude>
- <ClInclude Include="..\..\include\grpc++\auth_property_iterator.h">
- <Filter>include\grpc++</Filter>
- </ClInclude>
<ClInclude Include="..\..\include\grpc++\byte_buffer.h">
<Filter>include\grpc++</Filter>
</ClInclude>