aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/csharp
diff options
context:
space:
mode:
authorGravatar Jan Tattermusch <jtattermusch@users.noreply.github.com>2016-04-05 10:58:32 -0700
committerGravatar Jan Tattermusch <jtattermusch@users.noreply.github.com>2016-04-05 10:58:32 -0700
commited1307df3324b76ccfac259c3c3f733f22d643da (patch)
tree613f7bfa12eac80fe4b3b4b08d476ea7e6f8da54 /src/csharp
parente6aa55c014364878bf539e95649b0e3327fd225f (diff)
parent5d2703012858201810069e04d218f26d95bc22d1 (diff)
Merge pull request #5928 from jtattermusch/csharp_clientside_abstractclass
Make adding a new RPC to a service non-breaking for generated C#
Diffstat (limited to 'src/csharp')
-rw-r--r--src/csharp/Grpc.Core/CallInvoker.cs84
-rw-r--r--src/csharp/Grpc.Core/ClientBase.cs161
-rw-r--r--src/csharp/Grpc.Core/DefaultCallInvoker.cs112
-rw-r--r--src/csharp/Grpc.Core/Grpc.Core.csproj4
-rw-r--r--src/csharp/Grpc.Core/Internal/InterceptingCallInvoker.cs134
-rw-r--r--src/csharp/Grpc.Core/Internal/UnimplementedCallInvoker.cs75
-rw-r--r--src/csharp/Grpc.Examples.MathClient/MathClient.cs4
-rw-r--r--src/csharp/Grpc.Examples/MathExamples.cs14
-rw-r--r--src/csharp/Grpc.Examples/MathGrpc.cs105
-rw-r--r--src/csharp/Grpc.Examples/MathServiceImpl.cs12
-rw-r--r--src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs2
-rw-r--r--src/csharp/Grpc.HealthCheck/HealthGrpc.cs57
-rw-r--r--src/csharp/Grpc.HealthCheck/HealthServiceImpl.cs4
-rw-r--r--src/csharp/Grpc.IntegrationTesting/BenchmarkServiceImpl.cs8
-rw-r--r--src/csharp/Grpc.IntegrationTesting/ClientRunners.cs2
-rw-r--r--src/csharp/Grpc.IntegrationTesting/GeneratedClientTest.cs106
-rw-r--r--src/csharp/Grpc.IntegrationTesting/GeneratedServiceBaseTest.cs116
-rw-r--r--src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj3
-rw-r--r--src/csharp/Grpc.IntegrationTesting/InteropClient.cs26
-rw-r--r--src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs2
-rw-r--r--src/csharp/Grpc.IntegrationTesting/MetadataCredentialsTest.cs8
-rw-r--r--src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs188
-rw-r--r--src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs4
-rw-r--r--src/csharp/Grpc.IntegrationTesting/TestGrpc.cs287
-rw-r--r--src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs16
-rw-r--r--src/csharp/Grpc.IntegrationTesting/WorkerServiceImpl.cs10
-rw-r--r--src/csharp/tests.json3
27 files changed, 1253 insertions, 294 deletions
diff --git a/src/csharp/Grpc.Core/CallInvoker.cs b/src/csharp/Grpc.Core/CallInvoker.cs
new file mode 100644
index 0000000000..39199b1fd5
--- /dev/null
+++ b/src/csharp/Grpc.Core/CallInvoker.cs
@@ -0,0 +1,84 @@
+#region Copyright notice and license
+
+// Copyright 2015-2016, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System.Threading.Tasks;
+using Grpc.Core.Internal;
+
+namespace Grpc.Core
+{
+ /// <summary>
+ /// Abstraction of client-side RPC invocation.
+ /// </summary>
+ /// <seealso cref="Calls"/>
+ public abstract class CallInvoker
+ {
+ /// <summary>
+ /// Invokes a simple remote call in a blocking fashion.
+ /// </summary>
+ public abstract TResponse BlockingUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
+ where TRequest : class
+ where TResponse : class;
+
+ /// <summary>
+ /// Invokes a simple remote call asynchronously.
+ /// </summary>
+ public abstract AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
+ where TRequest : class
+ where TResponse : class;
+
+ /// <summary>
+ /// Invokes a server streaming call asynchronously.
+ /// In server streaming scenario, client sends on request and server responds with a stream of responses.
+ /// </summary>
+ public abstract AsyncServerStreamingCall<TResponse> AsyncServerStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
+ where TRequest : class
+ where TResponse : class;
+
+ /// <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>
+ public abstract AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options)
+ where TRequest : class
+ where TResponse : class;
+
+ /// <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>
+ public abstract AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options)
+ where TRequest : class
+ where TResponse : class;
+ }
+}
diff --git a/src/csharp/Grpc.Core/ClientBase.cs b/src/csharp/Grpc.Core/ClientBase.cs
index e5b398062b..5517233e3c 100644
--- a/src/csharp/Grpc.Core/ClientBase.cs
+++ b/src/csharp/Grpc.Core/ClientBase.cs
@@ -1,6 +1,6 @@
#region Copyright notice and license
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -31,93 +31,156 @@
#endregion
-using System;
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
+using Grpc.Core.Internal;
+using Grpc.Core.Utils;
namespace Grpc.Core
{
/// <summary>
- /// Interceptor for call headers.
+ /// Generic base class for client-side stubs.
/// </summary>
- /// <remarks>Header interceptor is no longer to recommented way to perform authentication.
- /// For header (initial metadata) based auth such as OAuth2 or JWT access token, use <see cref="MetadataCredentials"/>.
- /// </remarks>
- public delegate void HeaderInterceptor(IMethod method, Metadata metadata);
+ public abstract class ClientBase<T> : ClientBase
+ where T : ClientBase<T>
+ {
+ /// <summary>
+ /// Initializes a new instance of <c>ClientBase</c> class that
+ /// throws <c>NotImplementedException</c> upon invocation of any RPC.
+ /// This constructor is only provided to allow creation of test doubles
+ /// for client classes (e.g. mocking requires a parameterless constructor).
+ /// </summary>
+ protected ClientBase() : base()
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of <c>ClientBase</c> class.
+ /// </summary>
+ /// <param name="configuration">The configuration.</param>
+ protected ClientBase(ClientBaseConfiguration configuration) : base(configuration)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of <c>ClientBase</c> class.
+ /// </summary>
+ /// <param name="channel">The channel to use for remote call invocation.</param>
+ public ClientBase(Channel channel) : base(channel)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of <c>ClientBase</c> class.
+ /// </summary>
+ /// <param name="callInvoker">The <c>CallInvoker</c> for remote call invocation.</param>
+ public ClientBase(CallInvoker callInvoker) : base(callInvoker)
+ {
+ }
+
+ /// <summary>
+ /// Creates a new client that sets host field for calls explicitly.
+ /// gRPC supports multiple "hosts" being served by a single server.
+ /// By default (if a client was not created by calling this method),
+ /// host <c>null</c> with the meaning "use default host" is used.
+ /// </summary>
+ public T WithHost(string host)
+ {
+ var newConfiguration = this.Configuration.WithHost(host);
+ return NewInstance(newConfiguration);
+ }
+
+ /// <summary>
+ /// Creates a new instance of client from given <c>ClientBaseConfiguration</c>.
+ /// </summary>
+ protected abstract T NewInstance(ClientBaseConfiguration configuration);
+ }
/// <summary>
/// Base class for client-side stubs.
/// </summary>
public abstract class ClientBase
{
- readonly Channel channel;
+ readonly ClientBaseConfiguration configuration;
+ readonly CallInvoker callInvoker;
+
+ /// <summary>
+ /// Initializes a new instance of <c>ClientBase</c> class that
+ /// throws <c>NotImplementedException</c> upon invocation of any RPC.
+ /// This constructor is only provided to allow creation of test doubles
+ /// for client classes (e.g. mocking requires a parameterless constructor).
+ /// </summary>
+ protected ClientBase() : this(new UnimplementedCallInvoker())
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of <c>ClientBase</c> class.
+ /// </summary>
+ /// <param name="configuration">The configuration.</param>
+ protected ClientBase(ClientBaseConfiguration configuration)
+ {
+ this.configuration = GrpcPreconditions.CheckNotNull(configuration, "configuration");
+ this.callInvoker = configuration.CreateDecoratedCallInvoker();
+ }
/// <summary>
/// Initializes a new instance of <c>ClientBase</c> class.
/// </summary>
/// <param name="channel">The channel to use for remote call invocation.</param>
- public ClientBase(Channel channel)
+ public ClientBase(Channel channel) : this(new DefaultCallInvoker(channel))
{
- this.channel = channel;
}
/// <summary>
- /// Can be used to register a custom header interceptor.
- /// The interceptor is invoked each time a new call on this client is started.
- /// It is not recommented to use header interceptor to add auth headers to RPC calls.
+ /// Initializes a new instance of <c>ClientBase</c> class.
/// </summary>
- /// <seealso cref="HeaderInterceptor"/>
- public HeaderInterceptor HeaderInterceptor
+ /// <param name="callInvoker">The <c>CallInvoker</c> for remote call invocation.</param>
+ public ClientBase(CallInvoker callInvoker) : this(new ClientBaseConfiguration(callInvoker, null))
{
- get;
- set;
}
/// <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".
+ /// Gets the call invoker.
/// </summary>
- public string Host
+ protected CallInvoker CallInvoker
{
- get;
- set;
+ get { return this.callInvoker; }
}
/// <summary>
- /// Channel associated with this client.
+ /// Gets the configuration.
/// </summary>
- public Channel Channel
+ internal ClientBaseConfiguration Configuration
{
- get
- {
- return this.channel;
- }
+ get { return this.configuration; }
}
/// <summary>
- /// Creates a new call to given method.
+ /// Represents configuration of ClientBase. The class itself is visible to
+ /// subclasses, but contents are marked as internal to make the instances opaque.
+ /// The verbose name of this class was chosen to make name clash in generated code
+ /// less likely.
/// </summary>
- /// <param name="method">The method to invoke.</param>
- /// <param name="options">The call options.</param>
- /// <typeparam name="TRequest">Request message type.</typeparam>
- /// <typeparam name="TResponse">Response message type.</typeparam>
- /// <returns>The call invocation details.</returns>
- protected CallInvocationDetails<TRequest, TResponse> CreateCall<TRequest, TResponse>(Method<TRequest, TResponse> method, CallOptions options)
- where TRequest : class
- where TResponse : class
+ protected internal class ClientBaseConfiguration
{
- var interceptor = HeaderInterceptor;
- if (interceptor != null)
+ readonly CallInvoker undecoratedCallInvoker;
+ readonly string host;
+
+ internal ClientBaseConfiguration(CallInvoker undecoratedCallInvoker, string host)
+ {
+ this.undecoratedCallInvoker = GrpcPreconditions.CheckNotNull(undecoratedCallInvoker);
+ this.host = host;
+ }
+
+ internal CallInvoker CreateDecoratedCallInvoker()
+ {
+ return new InterceptingCallInvoker(undecoratedCallInvoker, hostInterceptor: (h) => host);
+ }
+
+ internal ClientBaseConfiguration WithHost(string host)
{
- if (options.Headers == null)
- {
- options = options.WithHeaders(new Metadata());
- }
- interceptor(method, options.Headers);
+ GrpcPreconditions.CheckNotNull(host, "host");
+ return new ClientBaseConfiguration(this.undecoratedCallInvoker, host);
}
- return new CallInvocationDetails<TRequest, TResponse>(channel, method, Host, options);
}
}
}
diff --git a/src/csharp/Grpc.Core/DefaultCallInvoker.cs b/src/csharp/Grpc.Core/DefaultCallInvoker.cs
new file mode 100644
index 0000000000..1a99e41153
--- /dev/null
+++ b/src/csharp/Grpc.Core/DefaultCallInvoker.cs
@@ -0,0 +1,112 @@
+#region Copyright notice and license
+
+// Copyright 2015-2016, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System.Threading.Tasks;
+using Grpc.Core.Internal;
+using Grpc.Core.Utils;
+
+namespace Grpc.Core
+{
+ /// <summary>
+ /// Invokes client RPCs using <see cref="Calls"/>.
+ /// </summary>
+ public class DefaultCallInvoker : CallInvoker
+ {
+ readonly Channel channel;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Grpc.Core.DefaultCallInvoker"/> class.
+ /// </summary>
+ /// <param name="channel">Channel to use.</param>
+ public DefaultCallInvoker(Channel channel)
+ {
+ this.channel = GrpcPreconditions.CheckNotNull(channel);
+ }
+
+ /// <summary>
+ /// Invokes a simple remote call in a blocking fashion.
+ /// </summary>
+ public override TResponse BlockingUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
+ {
+ var call = CreateCall(method, host, options);
+ return Calls.BlockingUnaryCall(call, request);
+ }
+
+ /// <summary>
+ /// Invokes a simple remote call asynchronously.
+ /// </summary>
+ public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
+ {
+ var call = CreateCall(method, host, options);
+ return Calls.AsyncUnaryCall(call, request);
+ }
+
+ /// <summary>
+ /// Invokes a server streaming call asynchronously.
+ /// In server streaming scenario, client sends on request and server responds with a stream of responses.
+ /// </summary>
+ public override AsyncServerStreamingCall<TResponse> AsyncServerStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
+ {
+ var call = CreateCall(method, host, options);
+ return Calls.AsyncServerStreamingCall(call, request);
+ }
+
+ /// <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>
+ public override AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options)
+ {
+ var call = CreateCall(method, host, options);
+ return Calls.AsyncClientStreamingCall(call);
+ }
+
+ /// <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>
+ public override AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options)
+ {
+ var call = CreateCall(method, host, options);
+ return Calls.AsyncDuplexStreamingCall(call);
+ }
+
+ protected virtual CallInvocationDetails<TRequest, TResponse> CreateCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options)
+ where TRequest : class
+ where TResponse : class
+ {
+ return new CallInvocationDetails<TRequest, TResponse>(channel, method, host, options);
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj
index 3189835ccd..251a688946 100644
--- a/src/csharp/Grpc.Core/Grpc.Core.csproj
+++ b/src/csharp/Grpc.Core/Grpc.Core.csproj
@@ -129,6 +129,10 @@
<Compile Include="Profiling\Profilers.cs" />
<Compile Include="Internal\DefaultSslRootsOverride.cs" />
<Compile Include="Utils\GrpcPreconditions.cs" />
+ <Compile Include="CallInvoker.cs" />
+ <Compile Include="DefaultCallInvoker.cs" />
+ <Compile Include="Internal\UnimplementedCallInvoker.cs" />
+ <Compile Include="Internal\InterceptingCallInvoker.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Grpc.Core.nuspec" />
diff --git a/src/csharp/Grpc.Core/Internal/InterceptingCallInvoker.cs b/src/csharp/Grpc.Core/Internal/InterceptingCallInvoker.cs
new file mode 100644
index 0000000000..ef48dc7121
--- /dev/null
+++ b/src/csharp/Grpc.Core/Internal/InterceptingCallInvoker.cs
@@ -0,0 +1,134 @@
+#region Copyright notice and license
+
+// Copyright 2015-2016, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Grpc.Core.Utils;
+
+namespace Grpc.Core.Internal
+{
+ /// <summary>
+ /// Decorates an underlying <c>CallInvoker</c> to intercept call invocations.
+ /// </summary>
+ internal class InterceptingCallInvoker : CallInvoker
+ {
+ readonly CallInvoker callInvoker;
+ readonly Func<string, string> hostInterceptor;
+ readonly Func<CallOptions, CallOptions> callOptionsInterceptor;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Grpc.Core.InterceptingCallInvoker"/> class.
+ /// </summary>
+ public InterceptingCallInvoker(CallInvoker callInvoker,
+ Func<string, string> hostInterceptor = null,
+ Func<CallOptions, CallOptions> callOptionsInterceptor = null)
+ {
+ this.callInvoker = GrpcPreconditions.CheckNotNull(callInvoker);
+ this.hostInterceptor = hostInterceptor;
+ this.callOptionsInterceptor = callOptionsInterceptor;
+ }
+
+ /// <summary>
+ /// Intercepts a unary call.
+ /// </summary>
+ public override TResponse BlockingUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
+ {
+ host = InterceptHost(host);
+ options = InterceptCallOptions(options);
+ return callInvoker.BlockingUnaryCall(method, host, options, request);
+ }
+
+ /// <summary>
+ /// Invokes a simple remote call asynchronously.
+ /// </summary>
+ public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
+ {
+ host = InterceptHost(host);
+ options = InterceptCallOptions(options);
+ return callInvoker.AsyncUnaryCall(method, host, options, request);
+ }
+
+ /// <summary>
+ /// Invokes a server streaming call asynchronously.
+ /// In server streaming scenario, client sends on request and server responds with a stream of responses.
+ /// </summary>
+ public override AsyncServerStreamingCall<TResponse> AsyncServerStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
+ {
+ host = InterceptHost(host);
+ options = InterceptCallOptions(options);
+ return callInvoker.AsyncServerStreamingCall(method, host, options, request);
+ }
+
+ /// <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>
+ public override AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options)
+ {
+ host = InterceptHost(host);
+ options = InterceptCallOptions(options);
+ return callInvoker.AsyncClientStreamingCall(method, host, options);
+ }
+
+ /// <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>
+ public override AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options)
+ {
+ host = InterceptHost(host);
+ options = InterceptCallOptions(options);
+ return callInvoker.AsyncDuplexStreamingCall(method, host, options);
+ }
+
+ private string InterceptHost(string host)
+ {
+ if (hostInterceptor == null)
+ {
+ return host;
+ }
+ return hostInterceptor(host);
+ }
+
+ private CallOptions InterceptCallOptions(CallOptions options)
+ {
+ if (callOptionsInterceptor == null)
+ {
+ return options;
+ }
+ return callOptionsInterceptor(options);
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/Internal/UnimplementedCallInvoker.cs b/src/csharp/Grpc.Core/Internal/UnimplementedCallInvoker.cs
new file mode 100644
index 0000000000..0c7340873b
--- /dev/null
+++ b/src/csharp/Grpc.Core/Internal/UnimplementedCallInvoker.cs
@@ -0,0 +1,75 @@
+#region Copyright notice and license
+
+// Copyright 2015-2016, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Grpc.Core.Utils;
+
+namespace Grpc.Core.Internal
+{
+ /// <summary>
+ /// Call invoker that throws <c>NotImplementedException</c> for all requests.
+ /// </summary>
+ internal class UnimplementedCallInvoker : CallInvoker
+ {
+ public UnimplementedCallInvoker()
+ {
+ }
+
+ public override TResponse BlockingUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override AsyncServerStreamingCall<TResponse> AsyncServerStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Examples.MathClient/MathClient.cs b/src/csharp/Grpc.Examples.MathClient/MathClient.cs
index 64e429ed5a..aadef6833d 100644
--- a/src/csharp/Grpc.Examples.MathClient/MathClient.cs
+++ b/src/csharp/Grpc.Examples.MathClient/MathClient.cs
@@ -1,5 +1,5 @@
#region Copyright notice and license
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -40,7 +40,7 @@ namespace Math
public static void Main(string[] args)
{
var channel = new Channel("127.0.0.1", 23456, ChannelCredentials.Insecure);
- Math.IMathClient client = new Math.MathClient(channel);
+ Math.MathClient client = new Math.MathClient(channel);
MathExamples.DivExample(client);
MathExamples.DivAsyncExample(client).Wait();
diff --git a/src/csharp/Grpc.Examples/MathExamples.cs b/src/csharp/Grpc.Examples/MathExamples.cs
index 8009ccbbfa..6075420974 100644
--- a/src/csharp/Grpc.Examples/MathExamples.cs
+++ b/src/csharp/Grpc.Examples/MathExamples.cs
@@ -1,5 +1,5 @@
#region Copyright notice and license
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -38,19 +38,19 @@ namespace Math
{
public static class MathExamples
{
- public static void DivExample(Math.IMathClient client)
+ public static void DivExample(Math.MathClient client)
{
DivReply result = client.Div(new DivArgs { Dividend = 10, Divisor = 3 });
Console.WriteLine("Div Result: " + result);
}
- public static async Task DivAsyncExample(Math.IMathClient client)
+ public static async Task DivAsyncExample(Math.MathClient client)
{
DivReply result = await client.DivAsync(new DivArgs { Dividend = 4, Divisor = 5 });
Console.WriteLine("DivAsync Result: " + result);
}
- public static async Task FibExample(Math.IMathClient client)
+ public static async Task FibExample(Math.MathClient client)
{
using (var call = client.Fib(new FibArgs { Limit = 5 }))
{
@@ -59,7 +59,7 @@ namespace Math
}
}
- public static async Task SumExample(Math.IMathClient client)
+ public static async Task SumExample(Math.MathClient client)
{
var numbers = new List<Num>
{
@@ -75,7 +75,7 @@ namespace Math
}
}
- public static async Task DivManyExample(Math.IMathClient client)
+ public static async Task DivManyExample(Math.MathClient client)
{
var divArgsList = new List<DivArgs>
{
@@ -90,7 +90,7 @@ namespace Math
}
}
- public static async Task DependendRequestsExample(Math.IMathClient client)
+ public static async Task DependendRequestsExample(Math.MathClient client)
{
var numbers = new List<Num>
{
diff --git a/src/csharp/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs
index a6e878d0f4..f3bb0d1cdc 100644
--- a/src/csharp/Grpc.Examples/MathGrpc.cs
+++ b/src/csharp/Grpc.Examples/MathGrpc.cs
@@ -52,6 +52,7 @@ namespace Math {
}
// client interface
+ [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
public interface IMathClient
{
global::Math.DivReply Div(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
@@ -67,6 +68,7 @@ namespace Math {
}
// server-side interface
+ [System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
public interface IMath
{
Task<global::Math.DivReply> Div(global::Math.DivArgs request, ServerCallContext context);
@@ -75,61 +77,92 @@ namespace Math {
Task<global::Math.Num> Sum(IAsyncStreamReader<global::Math.Num> requestStream, ServerCallContext context);
}
+ // server-side abstract class
+ public abstract class MathBase
+ {
+ public virtual Task<global::Math.DivReply> Div(global::Math.DivArgs request, ServerCallContext context)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+ }
+
+ public virtual Task DivMany(IAsyncStreamReader<global::Math.DivArgs> requestStream, IServerStreamWriter<global::Math.DivReply> responseStream, ServerCallContext context)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+ }
+
+ public virtual Task Fib(global::Math.FibArgs request, IServerStreamWriter<global::Math.Num> responseStream, ServerCallContext context)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+ }
+
+ public virtual Task<global::Math.Num> Sum(IAsyncStreamReader<global::Math.Num> requestStream, ServerCallContext context)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+ }
+
+ }
+
// client stub
- public class MathClient : ClientBase, IMathClient
+ public class MathClient : ClientBase<MathClient>, IMathClient
{
public MathClient(Channel channel) : base(channel)
{
}
- public global::Math.DivReply Div(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public MathClient(CallInvoker callInvoker) : base(callInvoker)
{
- var call = CreateCall(__Method_Div, new CallOptions(headers, deadline, cancellationToken));
- return Calls.BlockingUnaryCall(call, request);
}
- public global::Math.DivReply Div(global::Math.DivArgs request, CallOptions options)
+ ///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
+ protected MathClient() : base()
{
- var call = CreateCall(__Method_Div, options);
- return Calls.BlockingUnaryCall(call, request);
}
- public AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ ///<summary>Protected constructor to allow creation of configured clients.</summary>
+ protected MathClient(ClientBaseConfiguration configuration) : base(configuration)
{
- var call = CreateCall(__Method_Div, new CallOptions(headers, deadline, cancellationToken));
- return Calls.AsyncUnaryCall(call, request);
}
- public AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, CallOptions options)
+
+ public virtual global::Math.DivReply Div(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__Method_Div, options);
- return Calls.AsyncUnaryCall(call, request);
+ return Div(request, new CallOptions(headers, deadline, cancellationToken));
}
- public AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual global::Math.DivReply Div(global::Math.DivArgs request, CallOptions options)
{
- var call = CreateCall(__Method_DivMany, new CallOptions(headers, deadline, cancellationToken));
- return Calls.AsyncDuplexStreamingCall(call);
+ return CallInvoker.BlockingUnaryCall(__Method_Div, null, options, request);
}
- public AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(CallOptions options)
+ public virtual AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__Method_DivMany, options);
- return Calls.AsyncDuplexStreamingCall(call);
+ return DivAsync(request, new CallOptions(headers, deadline, cancellationToken));
}
- public AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, CallOptions options)
{
- var call = CreateCall(__Method_Fib, new CallOptions(headers, deadline, cancellationToken));
- return Calls.AsyncServerStreamingCall(call, request);
+ return CallInvoker.AsyncUnaryCall(__Method_Div, null, options, request);
}
- public AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, CallOptions options)
+ public virtual AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__Method_Fib, options);
- return Calls.AsyncServerStreamingCall(call, request);
+ return DivMany(new CallOptions(headers, deadline, cancellationToken));
}
- public AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(CallOptions options)
{
- var call = CreateCall(__Method_Sum, new CallOptions(headers, deadline, cancellationToken));
- return Calls.AsyncClientStreamingCall(call);
+ return CallInvoker.AsyncDuplexStreamingCall(__Method_DivMany, null, options);
}
- public AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(CallOptions options)
+ public virtual AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__Method_Sum, options);
- return Calls.AsyncClientStreamingCall(call);
+ return Fib(request, new CallOptions(headers, deadline, cancellationToken));
+ }
+ public virtual AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, CallOptions options)
+ {
+ return CallInvoker.AsyncServerStreamingCall(__Method_Fib, null, options, request);
+ }
+ public virtual AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ return Sum(new CallOptions(headers, deadline, cancellationToken));
+ }
+ public virtual AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(CallOptions options)
+ {
+ return CallInvoker.AsyncClientStreamingCall(__Method_Sum, null, options);
+ }
+ protected override MathClient NewInstance(ClientBaseConfiguration configuration)
+ {
+ return new MathClient(configuration);
}
}
@@ -143,6 +176,16 @@ namespace Math {
.AddMethod(__Method_Sum, serviceImpl.Sum).Build();
}
+ // creates service definition that can be registered with a server
+ public static ServerServiceDefinition BindService(MathBase serviceImpl)
+ {
+ return ServerServiceDefinition.CreateBuilder(__ServiceName)
+ .AddMethod(__Method_Div, serviceImpl.Div)
+ .AddMethod(__Method_DivMany, serviceImpl.DivMany)
+ .AddMethod(__Method_Fib, serviceImpl.Fib)
+ .AddMethod(__Method_Sum, serviceImpl.Sum).Build();
+ }
+
// creates a new client
public static MathClient NewClient(Channel channel)
{
diff --git a/src/csharp/Grpc.Examples/MathServiceImpl.cs b/src/csharp/Grpc.Examples/MathServiceImpl.cs
index 71dc655e46..79c56e57a8 100644
--- a/src/csharp/Grpc.Examples/MathServiceImpl.cs
+++ b/src/csharp/Grpc.Examples/MathServiceImpl.cs
@@ -1,6 +1,6 @@
#region Copyright notice and license
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -43,14 +43,14 @@ namespace Math
/// <summary>
/// Implementation of MathService server
/// </summary>
- public class MathServiceImpl : Math.IMath
+ public class MathServiceImpl : Math.MathBase
{
- public Task<DivReply> Div(DivArgs request, ServerCallContext context)
+ public override Task<DivReply> Div(DivArgs request, ServerCallContext context)
{
return Task.FromResult(DivInternal(request));
}
- public async Task Fib(FibArgs request, IServerStreamWriter<Num> responseStream, ServerCallContext context)
+ public override async Task Fib(FibArgs request, IServerStreamWriter<Num> responseStream, ServerCallContext context)
{
if (request.Limit <= 0)
{
@@ -72,7 +72,7 @@ namespace Math
}
}
- public async Task<Num> Sum(IAsyncStreamReader<Num> requestStream, ServerCallContext context)
+ public override async Task<Num> Sum(IAsyncStreamReader<Num> requestStream, ServerCallContext context)
{
long sum = 0;
await requestStream.ForEachAsync(async num =>
@@ -82,7 +82,7 @@ namespace Math
return new Num { Num_ = sum };
}
- public async Task DivMany(IAsyncStreamReader<DivArgs> requestStream, IServerStreamWriter<DivReply> responseStream, ServerCallContext context)
+ public override async Task DivMany(IAsyncStreamReader<DivArgs> requestStream, IServerStreamWriter<DivReply> responseStream, ServerCallContext context)
{
await requestStream.ForEachAsync(async divArgs => await responseStream.WriteAsync(DivInternal(divArgs)));
}
diff --git a/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs b/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs
index 8318e84277..fb292945a6 100644
--- a/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs
+++ b/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs
@@ -49,7 +49,7 @@ namespace Grpc.HealthCheck.Tests
const string Host = "localhost";
Server server;
Channel channel;
- Grpc.Health.V1.Health.IHealthClient client;
+ Grpc.Health.V1.Health.HealthClient client;
Grpc.HealthCheck.HealthServiceImpl serviceImpl;
[TestFixtureSetUp]
diff --git a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
index 68320eb5c2..72e11cca3a 100644
--- a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
+++ b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
@@ -29,6 +29,7 @@ namespace Grpc.Health.V1 {
}
// client interface
+ [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
public interface IHealthClient
{
global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
@@ -38,36 +39,59 @@ namespace Grpc.Health.V1 {
}
// server-side interface
+ [System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
public interface IHealth
{
Task<global::Grpc.Health.V1.HealthCheckResponse> Check(global::Grpc.Health.V1.HealthCheckRequest request, ServerCallContext context);
}
+ // server-side abstract class
+ public abstract class HealthBase
+ {
+ public virtual Task<global::Grpc.Health.V1.HealthCheckResponse> Check(global::Grpc.Health.V1.HealthCheckRequest request, ServerCallContext context)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+ }
+
+ }
+
// client stub
- public class HealthClient : ClientBase, IHealthClient
+ public class HealthClient : ClientBase<HealthClient>, IHealthClient
{
public HealthClient(Channel channel) : base(channel)
{
}
- public global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public HealthClient(CallInvoker callInvoker) : base(callInvoker)
{
- var call = CreateCall(__Method_Check, new CallOptions(headers, deadline, cancellationToken));
- return Calls.BlockingUnaryCall(call, request);
}
- public global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, CallOptions options)
+ ///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
+ protected HealthClient() : base()
+ {
+ }
+ ///<summary>Protected constructor to allow creation of configured clients.</summary>
+ protected HealthClient(ClientBaseConfiguration configuration) : base(configuration)
+ {
+ }
+
+ public virtual global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__Method_Check, options);
- return Calls.BlockingUnaryCall(call, request);
+ return Check(request, new CallOptions(headers, deadline, cancellationToken));
}
- public AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, CallOptions options)
{
- var call = CreateCall(__Method_Check, new CallOptions(headers, deadline, cancellationToken));
- return Calls.AsyncUnaryCall(call, request);
+ return CallInvoker.BlockingUnaryCall(__Method_Check, null, options, request);
}
- public AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, CallOptions options)
+ public virtual AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__Method_Check, options);
- return Calls.AsyncUnaryCall(call, request);
+ return CheckAsync(request, new CallOptions(headers, deadline, cancellationToken));
+ }
+ public virtual AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, CallOptions options)
+ {
+ return CallInvoker.AsyncUnaryCall(__Method_Check, null, options, request);
+ }
+ protected override HealthClient NewInstance(ClientBaseConfiguration configuration)
+ {
+ return new HealthClient(configuration);
}
}
@@ -78,6 +102,13 @@ namespace Grpc.Health.V1 {
.AddMethod(__Method_Check, serviceImpl.Check).Build();
}
+ // creates service definition that can be registered with a server
+ public static ServerServiceDefinition BindService(HealthBase serviceImpl)
+ {
+ return ServerServiceDefinition.CreateBuilder(__ServiceName)
+ .AddMethod(__Method_Check, serviceImpl.Check).Build();
+ }
+
// creates a new client
public static HealthClient NewClient(Channel channel)
{
diff --git a/src/csharp/Grpc.HealthCheck/HealthServiceImpl.cs b/src/csharp/Grpc.HealthCheck/HealthServiceImpl.cs
index a6e82aa0d4..d0406ece00 100644
--- a/src/csharp/Grpc.HealthCheck/HealthServiceImpl.cs
+++ b/src/csharp/Grpc.HealthCheck/HealthServiceImpl.cs
@@ -51,7 +51,7 @@ namespace Grpc.HealthCheck
/// server.AddServiceDefinition(Grpc.Health.V1.Health.BindService(serviceImpl));
/// </code>
/// </summary>
- public class HealthServiceImpl : Grpc.Health.V1.Health.IHealth
+ public class HealthServiceImpl : Grpc.Health.V1.Health.HealthBase
{
private readonly object myLock = new object();
private readonly Dictionary<string, HealthCheckResponse.Types.ServingStatus> statusMap =
@@ -99,7 +99,7 @@ namespace Grpc.HealthCheck
/// <param name="request">The check request.</param>
/// <param name="context">The call context.</param>
/// <returns>The asynchronous response.</returns>
- public Task<HealthCheckResponse> Check(HealthCheckRequest request, ServerCallContext context)
+ public override Task<HealthCheckResponse> Check(HealthCheckRequest request, ServerCallContext context)
{
lock (myLock)
{
diff --git a/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceImpl.cs b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceImpl.cs
index 7e7bc713a0..07f2703d4a 100644
--- a/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceImpl.cs
+++ b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceImpl.cs
@@ -1,6 +1,6 @@
#region Copyright notice and license
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -44,19 +44,19 @@ namespace Grpc.Testing
/// <summary>
/// Implementation of BenchmarkService server
/// </summary>
- public class BenchmarkServiceImpl : BenchmarkService.IBenchmarkService
+ public class BenchmarkServiceImpl : BenchmarkService.BenchmarkServiceBase
{
public BenchmarkServiceImpl()
{
}
- public Task<SimpleResponse> UnaryCall(SimpleRequest request, ServerCallContext context)
+ public override Task<SimpleResponse> UnaryCall(SimpleRequest request, ServerCallContext context)
{
var response = new SimpleResponse { Payload = CreateZerosPayload(request.ResponseSize) };
return Task.FromResult(response);
}
- public async Task StreamingCall(IAsyncStreamReader<SimpleRequest> requestStream, IServerStreamWriter<SimpleResponse> responseStream, ServerCallContext context)
+ public override async Task StreamingCall(IAsyncStreamReader<SimpleRequest> requestStream, IServerStreamWriter<SimpleResponse> responseStream, ServerCallContext context)
{
await requestStream.ForEachAsync(async request =>
{
diff --git a/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs b/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs
index 5bfc89d591..0bcacf76e5 100644
--- a/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs
+++ b/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs
@@ -112,7 +112,7 @@ namespace Grpc.IntegrationTesting
readonly PayloadConfig payloadConfig;
readonly Histogram histogram;
- readonly BenchmarkService.IBenchmarkServiceClient client;
+ readonly BenchmarkService.BenchmarkServiceClient client;
readonly Task runnerTask;
readonly CancellationTokenSource stoppedCts;
readonly WallClockStopwatch wallClockStopwatch = new WallClockStopwatch();
diff --git a/src/csharp/Grpc.IntegrationTesting/GeneratedClientTest.cs b/src/csharp/Grpc.IntegrationTesting/GeneratedClientTest.cs
new file mode 100644
index 0000000000..37786b6c30
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/GeneratedClientTest.cs
@@ -0,0 +1,106 @@
+#region Copyright notice and license
+
+// Copyright 2015-2016, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Grpc.Core.Utils;
+using Grpc.Testing;
+using Moq;
+using NUnit.Framework;
+
+namespace Grpc.IntegrationTesting
+{
+ public class GeneratedClientTest
+ {
+ TestService.TestServiceClient unimplementedClient = new UnimplementedTestServiceClient();
+
+ [Test]
+ public void ExpandedParamOverloadCanBeMocked()
+ {
+ var expected = new SimpleResponse();
+
+ var mockClient = new Mock<TestService.TestServiceClient>();
+ // mocking is relatively clumsy because one needs to specify value for all the optional params.
+ mockClient.Setup(m => m.UnaryCall(It.IsAny<SimpleRequest>(), null, null, CancellationToken.None)).Returns(expected);
+
+ Assert.AreSame(expected, mockClient.Object.UnaryCall(new SimpleRequest()));
+ }
+
+ [Test]
+ public void CallOptionsOverloadCanBeMocked()
+ {
+ var expected = new SimpleResponse();
+
+ var mockClient = new Mock<TestService.TestServiceClient>();
+ mockClient.Setup(m => m.UnaryCall(It.IsAny<SimpleRequest>(), It.IsAny<CallOptions>())).Returns(expected);
+
+ Assert.AreSame(expected, mockClient.Object.UnaryCall(new SimpleRequest(), new CallOptions()));
+ }
+
+ [Test]
+ public void DefaultMethodStubThrows_UnaryCall()
+ {
+ Assert.Throws(typeof(NotImplementedException), () => unimplementedClient.UnaryCall(new SimpleRequest()));
+ }
+
+ [Test]
+ public void DefaultMethodStubThrows_ClientStreaming()
+ {
+ Assert.Throws(typeof(NotImplementedException), () => unimplementedClient.StreamingInputCall());
+ }
+
+ [Test]
+ public void DefaultMethodStubThrows_ServerStreaming()
+ {
+ Assert.Throws(typeof(NotImplementedException), () => unimplementedClient.StreamingOutputCall(new StreamingOutputCallRequest()));
+ }
+
+ [Test]
+ public void DefaultMethodStubThrows_DuplexStreaming()
+ {
+ Assert.Throws(typeof(NotImplementedException), () => unimplementedClient.FullDuplexCall());
+ }
+
+ /// <summary>
+ /// Subclass of the generated client that doesn't override any method stubs.
+ /// </summary>
+ private class UnimplementedTestServiceClient : TestService.TestServiceClient
+ {
+ }
+ }
+}
diff --git a/src/csharp/Grpc.IntegrationTesting/GeneratedServiceBaseTest.cs b/src/csharp/Grpc.IntegrationTesting/GeneratedServiceBaseTest.cs
new file mode 100644
index 0000000000..99aa729030
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/GeneratedServiceBaseTest.cs
@@ -0,0 +1,116 @@
+#region Copyright notice and license
+
+// Copyright 2015-2016, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Grpc.Core.Utils;
+using Grpc.Testing;
+using Moq;
+using NUnit.Framework;
+
+namespace Grpc.IntegrationTesting
+{
+ public class GeneratedServiceBaseTest
+ {
+ const string Host = "localhost";
+ Server server;
+ Channel channel;
+ TestService.TestServiceClient client;
+
+ [SetUp]
+ public void Init()
+ {
+ server = new Server
+ {
+ Services = { TestService.BindService(new UnimplementedTestServiceImpl()) },
+ Ports = { { Host, ServerPort.PickUnused, SslServerCredentials.Insecure } }
+ };
+ server.Start();
+ channel = new Channel(Host, server.Ports.Single().BoundPort, ChannelCredentials.Insecure);
+ client = TestService.NewClient(channel);
+ }
+
+ [TearDown]
+ public void Cleanup()
+ {
+ channel.ShutdownAsync().Wait();
+ server.ShutdownAsync().Wait();
+ }
+
+ [Test]
+ public void UnimplementedByDefault_Unary()
+ {
+ var ex = Assert.Throws<RpcException>(() => client.UnaryCall(new SimpleRequest { }));
+ Assert.AreEqual(StatusCode.Unimplemented, ex.Status.StatusCode);
+ }
+
+ [Test]
+ public async Task UnimplementedByDefault_ClientStreaming()
+ {
+ var call = client.StreamingInputCall();
+
+ var ex = Assert.Throws<RpcException>(async () => await call);
+ Assert.AreEqual(StatusCode.Unimplemented, ex.Status.StatusCode);
+ }
+
+ [Test]
+ public async Task UnimplementedByDefault_ServerStreamingCall()
+ {
+ var call = client.StreamingOutputCall(new StreamingOutputCallRequest());
+
+ var ex = Assert.Throws<RpcException>(async () => await call.ResponseStream.MoveNext());
+ Assert.AreEqual(StatusCode.Unimplemented, ex.Status.StatusCode);
+ }
+
+ [Test]
+ public async Task UnimplementedByDefault_DuplexStreamingCall()
+ {
+ var call = client.FullDuplexCall();
+
+ var ex = Assert.Throws<RpcException>(async () => await call.ResponseStream.MoveNext());
+ Assert.AreEqual(StatusCode.Unimplemented, ex.Status.StatusCode);
+ }
+
+ /// <summary>
+ /// Implementation of TestService that doesn't override any methods.
+ /// </summary>
+ private class UnimplementedTestServiceImpl : TestService.TestServiceBase
+ {
+ }
+ }
+}
diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
index d3c572fe27..64d14b0df5 100644
--- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
+++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
@@ -84,7 +84,6 @@
<Compile Include="..\Grpc.Core\Version.cs">
<Link>Version.cs</Link>
</Compile>
- <Compile Include="HeaderInterceptorTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Empty.cs" />
<Compile Include="Messages.cs" />
@@ -114,6 +113,8 @@
<Compile Include="QpsWorker.cs" />
<Compile Include="WallClockStopwatch.cs" />
<Compile Include="GenericService.cs" />
+ <Compile Include="GeneratedServiceBaseTest.cs" />
+ <Compile Include="GeneratedClientTest.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
index b0e33e49f7..7ca5221936 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
@@ -1,6 +1,6 @@
#region Copyright notice and license
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -217,7 +217,7 @@ namespace Grpc.IntegrationTesting
}
}
- public static void RunEmptyUnary(TestService.ITestServiceClient client)
+ public static void RunEmptyUnary(TestService.TestServiceClient client)
{
Console.WriteLine("running empty_unary");
var response = client.EmptyCall(new Empty());
@@ -225,7 +225,7 @@ namespace Grpc.IntegrationTesting
Console.WriteLine("Passed!");
}
- public static void RunLargeUnary(TestService.ITestServiceClient client)
+ public static void RunLargeUnary(TestService.TestServiceClient client)
{
Console.WriteLine("running large_unary");
var request = new SimpleRequest
@@ -241,7 +241,7 @@ namespace Grpc.IntegrationTesting
Console.WriteLine("Passed!");
}
- public static async Task RunClientStreamingAsync(TestService.ITestServiceClient client)
+ public static async Task RunClientStreamingAsync(TestService.TestServiceClient client)
{
Console.WriteLine("running client_streaming");
@@ -257,7 +257,7 @@ namespace Grpc.IntegrationTesting
Console.WriteLine("Passed!");
}
- public static async Task RunServerStreamingAsync(TestService.ITestServiceClient client)
+ public static async Task RunServerStreamingAsync(TestService.TestServiceClient client)
{
Console.WriteLine("running server_streaming");
@@ -281,7 +281,7 @@ namespace Grpc.IntegrationTesting
Console.WriteLine("Passed!");
}
- public static async Task RunPingPongAsync(TestService.ITestServiceClient client)
+ public static async Task RunPingPongAsync(TestService.TestServiceClient client)
{
Console.WriteLine("running ping_pong");
@@ -338,7 +338,7 @@ namespace Grpc.IntegrationTesting
Console.WriteLine("Passed!");
}
- public static async Task RunEmptyStreamAsync(TestService.ITestServiceClient client)
+ public static async Task RunEmptyStreamAsync(TestService.TestServiceClient client)
{
Console.WriteLine("running empty_stream");
using (var call = client.FullDuplexCall())
@@ -434,7 +434,7 @@ namespace Grpc.IntegrationTesting
Console.WriteLine("Passed!");
}
- public static async Task RunCancelAfterBeginAsync(TestService.ITestServiceClient client)
+ public static async Task RunCancelAfterBeginAsync(TestService.TestServiceClient client)
{
Console.WriteLine("running cancel_after_begin");
@@ -451,7 +451,7 @@ namespace Grpc.IntegrationTesting
Console.WriteLine("Passed!");
}
- public static async Task RunCancelAfterFirstResponseAsync(TestService.ITestServiceClient client)
+ public static async Task RunCancelAfterFirstResponseAsync(TestService.TestServiceClient client)
{
Console.WriteLine("running cancel_after_first_response");
@@ -477,7 +477,7 @@ namespace Grpc.IntegrationTesting
Console.WriteLine("Passed!");
}
- public static async Task RunTimeoutOnSleepingServerAsync(TestService.ITestServiceClient client)
+ public static async Task RunTimeoutOnSleepingServerAsync(TestService.TestServiceClient client)
{
Console.WriteLine("running timeout_on_sleeping_server");
@@ -499,7 +499,7 @@ namespace Grpc.IntegrationTesting
Console.WriteLine("Passed!");
}
- public static async Task RunCustomMetadataAsync(TestService.ITestServiceClient client)
+ public static async Task RunCustomMetadataAsync(TestService.TestServiceClient client)
{
Console.WriteLine("running custom_metadata");
{
@@ -546,7 +546,7 @@ namespace Grpc.IntegrationTesting
Console.WriteLine("Passed!");
}
- public static async Task RunStatusCodeAndMessageAsync(TestService.ITestServiceClient client)
+ public static async Task RunStatusCodeAndMessageAsync(TestService.TestServiceClient client)
{
Console.WriteLine("running status_code_and_message");
var echoStatus = new EchoStatus
@@ -580,7 +580,7 @@ namespace Grpc.IntegrationTesting
Console.WriteLine("Passed!");
}
- public static void RunUnimplementedMethod(UnimplementedService.IUnimplementedServiceClient client)
+ public static void RunUnimplementedMethod(UnimplementedService.UnimplementedServiceClient client)
{
Console.WriteLine("running unimplemented_method");
var e = Assert.Throws<RpcException>(() => client.UnimplementedCall(new Empty()));
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs b/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
index 5facb87971..4ee1ff5ec8 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
@@ -51,7 +51,7 @@ namespace Grpc.IntegrationTesting
const string Host = "localhost";
Server server;
Channel channel;
- TestService.ITestServiceClient client;
+ TestService.TestServiceClient client;
[TestFixtureSetUp]
public void Init()
diff --git a/src/csharp/Grpc.IntegrationTesting/MetadataCredentialsTest.cs b/src/csharp/Grpc.IntegrationTesting/MetadataCredentialsTest.cs
index 1c8bfed1f6..f95af5008f 100644
--- a/src/csharp/Grpc.IntegrationTesting/MetadataCredentialsTest.cs
+++ b/src/csharp/Grpc.IntegrationTesting/MetadataCredentialsTest.cs
@@ -1,6 +1,6 @@
#region Copyright notice and license
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -50,15 +50,15 @@ namespace Grpc.IntegrationTesting
const string Host = "localhost";
Server server;
Channel channel;
- TestService.ITestServiceClient client;
+ TestService.TestServiceClient client;
List<ChannelOption> options;
- Mock<TestService.ITestService> serviceMock;
+ Mock<TestService.TestServiceBase> serviceMock;
AsyncAuthInterceptor asyncAuthInterceptor;
[SetUp]
public void Init()
{
- serviceMock = new Mock<TestService.ITestService>();
+ serviceMock = new Mock<TestService.TestServiceBase>();
serviceMock.Setup(m => m.UnaryCall(It.IsAny<SimpleRequest>(), It.IsAny<ServerCallContext>()))
.Returns(new Func<SimpleRequest, ServerCallContext, Task<SimpleResponse>>(UnaryCallHandler));
diff --git a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
index 996439afbf..46b16cf202 100644
--- a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
@@ -36,6 +36,7 @@ namespace Grpc.Testing {
}
// client interface
+ [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
public interface IBenchmarkServiceClient
{
global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
@@ -47,47 +48,73 @@ namespace Grpc.Testing {
}
// server-side interface
+ [System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
public interface IBenchmarkService
{
Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context);
Task StreamingCall(IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, ServerCallContext context);
}
+ // server-side abstract class
+ public abstract class BenchmarkServiceBase
+ {
+ public virtual Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+ }
+
+ public virtual Task StreamingCall(IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, ServerCallContext context)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+ }
+
+ }
+
// client stub
- public class BenchmarkServiceClient : ClientBase, IBenchmarkServiceClient
+ public class BenchmarkServiceClient : ClientBase<BenchmarkServiceClient>, IBenchmarkServiceClient
{
public BenchmarkServiceClient(Channel channel) : base(channel)
{
}
- public global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public BenchmarkServiceClient(CallInvoker callInvoker) : base(callInvoker)
+ {
+ }
+ ///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
+ protected BenchmarkServiceClient() : base()
{
- var call = CreateCall(__Method_UnaryCall, new CallOptions(headers, deadline, cancellationToken));
- return Calls.BlockingUnaryCall(call, request);
}
- public global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options)
+ ///<summary>Protected constructor to allow creation of configured clients.</summary>
+ protected BenchmarkServiceClient(ClientBaseConfiguration configuration) : base(configuration)
{
- var call = CreateCall(__Method_UnaryCall, options);
- return Calls.BlockingUnaryCall(call, request);
}
- public AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+
+ public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__Method_UnaryCall, new CallOptions(headers, deadline, cancellationToken));
- return Calls.AsyncUnaryCall(call, request);
+ return UnaryCall(request, new CallOptions(headers, deadline, cancellationToken));
}
- public AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options)
+ public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options)
{
- var call = CreateCall(__Method_UnaryCall, options);
- return Calls.AsyncUnaryCall(call, request);
+ return CallInvoker.BlockingUnaryCall(__Method_UnaryCall, null, options, request);
}
- public AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__Method_StreamingCall, new CallOptions(headers, deadline, cancellationToken));
- return Calls.AsyncDuplexStreamingCall(call);
+ return UnaryCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
}
- public AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(CallOptions options)
+ public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options)
{
- var call = CreateCall(__Method_StreamingCall, options);
- return Calls.AsyncDuplexStreamingCall(call);
+ return CallInvoker.AsyncUnaryCall(__Method_UnaryCall, null, options, request);
+ }
+ public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ return StreamingCall(new CallOptions(headers, deadline, cancellationToken));
+ }
+ public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(CallOptions options)
+ {
+ return CallInvoker.AsyncDuplexStreamingCall(__Method_StreamingCall, null, options);
+ }
+ protected override BenchmarkServiceClient NewInstance(ClientBaseConfiguration configuration)
+ {
+ return new BenchmarkServiceClient(configuration);
}
}
@@ -99,6 +126,14 @@ namespace Grpc.Testing {
.AddMethod(__Method_StreamingCall, serviceImpl.StreamingCall).Build();
}
+ // creates service definition that can be registered with a server
+ public static ServerServiceDefinition BindService(BenchmarkServiceBase serviceImpl)
+ {
+ return ServerServiceDefinition.CreateBuilder(__ServiceName)
+ .AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall)
+ .AddMethod(__Method_StreamingCall, serviceImpl.StreamingCall).Build();
+ }
+
// creates a new client
public static BenchmarkServiceClient NewClient(Channel channel)
{
@@ -153,6 +188,7 @@ namespace Grpc.Testing {
}
// client interface
+ [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
public interface IWorkerServiceClient
{
AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
@@ -170,6 +206,7 @@ namespace Grpc.Testing {
}
// server-side interface
+ [System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
public interface IWorkerService
{
Task RunServer(IAsyncStreamReader<global::Grpc.Testing.ServerArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ServerStatus> responseStream, ServerCallContext context);
@@ -178,71 +215,100 @@ namespace Grpc.Testing {
Task<global::Grpc.Testing.Void> QuitWorker(global::Grpc.Testing.Void request, ServerCallContext context);
}
+ // server-side abstract class
+ public abstract class WorkerServiceBase
+ {
+ public virtual Task RunServer(IAsyncStreamReader<global::Grpc.Testing.ServerArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ServerStatus> responseStream, ServerCallContext context)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+ }
+
+ public virtual Task RunClient(IAsyncStreamReader<global::Grpc.Testing.ClientArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ClientStatus> responseStream, ServerCallContext context)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+ }
+
+ public virtual Task<global::Grpc.Testing.CoreResponse> CoreCount(global::Grpc.Testing.CoreRequest request, ServerCallContext context)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+ }
+
+ public virtual Task<global::Grpc.Testing.Void> QuitWorker(global::Grpc.Testing.Void request, ServerCallContext context)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+ }
+
+ }
+
// client stub
- public class WorkerServiceClient : ClientBase, IWorkerServiceClient
+ public class WorkerServiceClient : ClientBase<WorkerServiceClient>, IWorkerServiceClient
{
public WorkerServiceClient(Channel channel) : base(channel)
{
}
- public AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public WorkerServiceClient(CallInvoker callInvoker) : base(callInvoker)
{
- var call = CreateCall(__Method_RunServer, new CallOptions(headers, deadline, cancellationToken));
- return Calls.AsyncDuplexStreamingCall(call);
}
- public AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(CallOptions options)
+ ///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
+ protected WorkerServiceClient() : base()
{
- var call = CreateCall(__Method_RunServer, options);
- return Calls.AsyncDuplexStreamingCall(call);
}
- public AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ ///<summary>Protected constructor to allow creation of configured clients.</summary>
+ protected WorkerServiceClient(ClientBaseConfiguration configuration) : base(configuration)
{
- var call = CreateCall(__Method_RunClient, new CallOptions(headers, deadline, cancellationToken));
- return Calls.AsyncDuplexStreamingCall(call);
}
- public AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(CallOptions options)
+
+ public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__Method_RunClient, options);
- return Calls.AsyncDuplexStreamingCall(call);
+ return RunServer(new CallOptions(headers, deadline, cancellationToken));
}
- public global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(CallOptions options)
{
- var call = CreateCall(__Method_CoreCount, new CallOptions(headers, deadline, cancellationToken));
- return Calls.BlockingUnaryCall(call, request);
+ return CallInvoker.AsyncDuplexStreamingCall(__Method_RunServer, null, options);
}
- public global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, CallOptions options)
+ public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__Method_CoreCount, options);
- return Calls.BlockingUnaryCall(call, request);
+ return RunClient(new CallOptions(headers, deadline, cancellationToken));
}
- public AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(CallOptions options)
{
- var call = CreateCall(__Method_CoreCount, new CallOptions(headers, deadline, cancellationToken));
- return Calls.AsyncUnaryCall(call, request);
+ return CallInvoker.AsyncDuplexStreamingCall(__Method_RunClient, null, options);
}
- public AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, CallOptions options)
+ public virtual global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__Method_CoreCount, options);
- return Calls.AsyncUnaryCall(call, request);
+ return CoreCount(request, new CallOptions(headers, deadline, cancellationToken));
}
- public global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, CallOptions options)
{
- var call = CreateCall(__Method_QuitWorker, new CallOptions(headers, deadline, cancellationToken));
- return Calls.BlockingUnaryCall(call, request);
+ return CallInvoker.BlockingUnaryCall(__Method_CoreCount, null, options, request);
}
- public global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, CallOptions options)
+ public virtual AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__Method_QuitWorker, options);
- return Calls.BlockingUnaryCall(call, request);
+ return CoreCountAsync(request, new CallOptions(headers, deadline, cancellationToken));
}
- public AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, CallOptions options)
{
- var call = CreateCall(__Method_QuitWorker, new CallOptions(headers, deadline, cancellationToken));
- return Calls.AsyncUnaryCall(call, request);
+ return CallInvoker.AsyncUnaryCall(__Method_CoreCount, null, options, request);
}
- public AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, CallOptions options)
+ public virtual global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__Method_QuitWorker, options);
- return Calls.AsyncUnaryCall(call, request);
+ return QuitWorker(request, new CallOptions(headers, deadline, cancellationToken));
+ }
+ public virtual global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, CallOptions options)
+ {
+ return CallInvoker.BlockingUnaryCall(__Method_QuitWorker, null, options, request);
+ }
+ public virtual AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ return QuitWorkerAsync(request, new CallOptions(headers, deadline, cancellationToken));
+ }
+ public virtual AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, CallOptions options)
+ {
+ return CallInvoker.AsyncUnaryCall(__Method_QuitWorker, null, options, request);
+ }
+ protected override WorkerServiceClient NewInstance(ClientBaseConfiguration configuration)
+ {
+ return new WorkerServiceClient(configuration);
}
}
@@ -256,6 +322,16 @@ namespace Grpc.Testing {
.AddMethod(__Method_QuitWorker, serviceImpl.QuitWorker).Build();
}
+ // creates service definition that can be registered with a server
+ public static ServerServiceDefinition BindService(WorkerServiceBase serviceImpl)
+ {
+ return ServerServiceDefinition.CreateBuilder(__ServiceName)
+ .AddMethod(__Method_RunServer, serviceImpl.RunServer)
+ .AddMethod(__Method_RunClient, serviceImpl.RunClient)
+ .AddMethod(__Method_CoreCount, serviceImpl.CoreCount)
+ .AddMethod(__Method_QuitWorker, serviceImpl.QuitWorker).Build();
+ }
+
// creates a new client
public static WorkerServiceClient NewClient(Channel channel)
{
diff --git a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs
index 37b2518c21..3df45b5f70 100644
--- a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs
+++ b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs
@@ -1,6 +1,6 @@
#region Copyright notice and license
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -53,7 +53,7 @@ namespace Grpc.IntegrationTesting
const string Host = "localhost";
Server server;
Channel channel;
- TestService.ITestServiceClient client;
+ TestService.TestServiceClient client;
[TestFixtureSetUp]
public void Init()
diff --git a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
index 2c469080d9..b84ec2d984 100644
--- a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
@@ -69,6 +69,7 @@ namespace Grpc.Testing {
}
// client interface
+ [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
public interface ITestServiceClient
{
global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
@@ -90,6 +91,7 @@ namespace Grpc.Testing {
}
// server-side interface
+ [System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
public interface ITestService
{
Task<global::Grpc.Testing.Empty> EmptyCall(global::Grpc.Testing.Empty request, ServerCallContext context);
@@ -100,91 +102,126 @@ namespace Grpc.Testing {
Task HalfDuplexCall(IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context);
}
+ // server-side abstract class
+ public abstract class TestServiceBase
+ {
+ public virtual Task<global::Grpc.Testing.Empty> EmptyCall(global::Grpc.Testing.Empty request, ServerCallContext context)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+ }
+
+ public virtual Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+ }
+
+ public virtual Task StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+ }
+
+ public virtual Task<global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(IAsyncStreamReader<global::Grpc.Testing.StreamingInputCallRequest> requestStream, ServerCallContext context)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+ }
+
+ public virtual Task FullDuplexCall(IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+ }
+
+ public virtual Task HalfDuplexCall(IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+ }
+
+ }
+
// client stub
- public class TestServiceClient : ClientBase, ITestServiceClient
+ public class TestServiceClient : ClientBase<TestServiceClient>, ITestServiceClient
{
public TestServiceClient(Channel channel) : base(channel)
{
}
- public global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public TestServiceClient(CallInvoker callInvoker) : base(callInvoker)
+ {
+ }
+ ///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
+ protected TestServiceClient() : base()
+ {
+ }
+ ///<summary>Protected constructor to allow creation of configured clients.</summary>
+ protected TestServiceClient(ClientBaseConfiguration configuration) : base(configuration)
+ {
+ }
+
+ public virtual global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__Method_EmptyCall, new CallOptions(headers, deadline, cancellationToken));
- return Calls.BlockingUnaryCall(call, request);
+ return EmptyCall(request, new CallOptions(headers, deadline, cancellationToken));
}
- public global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, CallOptions options)
+ public virtual global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, CallOptions options)
{
- var call = CreateCall(__Method_EmptyCall, options);
- return Calls.BlockingUnaryCall(call, request);
+ return CallInvoker.BlockingUnaryCall(__Method_EmptyCall, null, options, request);
}
- public AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__Method_EmptyCall, new CallOptions(headers, deadline, cancellationToken));
- return Calls.AsyncUnaryCall(call, request);
+ return EmptyCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
}
- public AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, CallOptions options)
+ public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, CallOptions options)
{
- var call = CreateCall(__Method_EmptyCall, options);
- return Calls.AsyncUnaryCall(call, request);
+ return CallInvoker.AsyncUnaryCall(__Method_EmptyCall, null, options, request);
}
- public global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__Method_UnaryCall, new CallOptions(headers, deadline, cancellationToken));
- return Calls.BlockingUnaryCall(call, request);
+ return UnaryCall(request, new CallOptions(headers, deadline, cancellationToken));
}
- public global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options)
+ public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options)
{
- var call = CreateCall(__Method_UnaryCall, options);
- return Calls.BlockingUnaryCall(call, request);
+ return CallInvoker.BlockingUnaryCall(__Method_UnaryCall, null, options, request);
}
- public AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__Method_UnaryCall, new CallOptions(headers, deadline, cancellationToken));
- return Calls.AsyncUnaryCall(call, request);
+ return UnaryCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
}
- public AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options)
+ public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options)
{
- var call = CreateCall(__Method_UnaryCall, options);
- return Calls.AsyncUnaryCall(call, request);
+ return CallInvoker.AsyncUnaryCall(__Method_UnaryCall, null, options, request);
}
- public AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__Method_StreamingOutputCall, new CallOptions(headers, deadline, cancellationToken));
- return Calls.AsyncServerStreamingCall(call, request);
+ return StreamingOutputCall(request, new CallOptions(headers, deadline, cancellationToken));
}
- public AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, CallOptions options)
+ public virtual AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, CallOptions options)
{
- var call = CreateCall(__Method_StreamingOutputCall, options);
- return Calls.AsyncServerStreamingCall(call, request);
+ return CallInvoker.AsyncServerStreamingCall(__Method_StreamingOutputCall, null, options, request);
}
- public AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__Method_StreamingInputCall, new CallOptions(headers, deadline, cancellationToken));
- return Calls.AsyncClientStreamingCall(call);
+ return StreamingInputCall(new CallOptions(headers, deadline, cancellationToken));
}
- public AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(CallOptions options)
+ public virtual AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(CallOptions options)
{
- var call = CreateCall(__Method_StreamingInputCall, options);
- return Calls.AsyncClientStreamingCall(call);
+ return CallInvoker.AsyncClientStreamingCall(__Method_StreamingInputCall, null, options);
}
- public AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__Method_FullDuplexCall, new CallOptions(headers, deadline, cancellationToken));
- return Calls.AsyncDuplexStreamingCall(call);
+ return FullDuplexCall(new CallOptions(headers, deadline, cancellationToken));
}
- public AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(CallOptions options)
+ public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(CallOptions options)
{
- var call = CreateCall(__Method_FullDuplexCall, options);
- return Calls.AsyncDuplexStreamingCall(call);
+ return CallInvoker.AsyncDuplexStreamingCall(__Method_FullDuplexCall, null, options);
}
- public AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__Method_HalfDuplexCall, new CallOptions(headers, deadline, cancellationToken));
- return Calls.AsyncDuplexStreamingCall(call);
+ return HalfDuplexCall(new CallOptions(headers, deadline, cancellationToken));
}
- public AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(CallOptions options)
+ public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(CallOptions options)
{
- var call = CreateCall(__Method_HalfDuplexCall, options);
- return Calls.AsyncDuplexStreamingCall(call);
+ return CallInvoker.AsyncDuplexStreamingCall(__Method_HalfDuplexCall, null, options);
+ }
+ protected override TestServiceClient NewInstance(ClientBaseConfiguration configuration)
+ {
+ return new TestServiceClient(configuration);
}
}
@@ -200,6 +237,18 @@ namespace Grpc.Testing {
.AddMethod(__Method_HalfDuplexCall, serviceImpl.HalfDuplexCall).Build();
}
+ // creates service definition that can be registered with a server
+ public static ServerServiceDefinition BindService(TestServiceBase serviceImpl)
+ {
+ return ServerServiceDefinition.CreateBuilder(__ServiceName)
+ .AddMethod(__Method_EmptyCall, serviceImpl.EmptyCall)
+ .AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall)
+ .AddMethod(__Method_StreamingOutputCall, serviceImpl.StreamingOutputCall)
+ .AddMethod(__Method_StreamingInputCall, serviceImpl.StreamingInputCall)
+ .AddMethod(__Method_FullDuplexCall, serviceImpl.FullDuplexCall)
+ .AddMethod(__Method_HalfDuplexCall, serviceImpl.HalfDuplexCall).Build();
+ }
+
// creates a new client
public static TestServiceClient NewClient(Channel channel)
{
@@ -227,6 +276,7 @@ namespace Grpc.Testing {
}
// client interface
+ [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
public interface IUnimplementedServiceClient
{
global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
@@ -236,36 +286,59 @@ namespace Grpc.Testing {
}
// server-side interface
+ [System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
public interface IUnimplementedService
{
Task<global::Grpc.Testing.Empty> UnimplementedCall(global::Grpc.Testing.Empty request, ServerCallContext context);
}
+ // server-side abstract class
+ public abstract class UnimplementedServiceBase
+ {
+ public virtual Task<global::Grpc.Testing.Empty> UnimplementedCall(global::Grpc.Testing.Empty request, ServerCallContext context)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+ }
+
+ }
+
// client stub
- public class UnimplementedServiceClient : ClientBase, IUnimplementedServiceClient
+ public class UnimplementedServiceClient : ClientBase<UnimplementedServiceClient>, IUnimplementedServiceClient
{
public UnimplementedServiceClient(Channel channel) : base(channel)
{
}
- public global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public UnimplementedServiceClient(CallInvoker callInvoker) : base(callInvoker)
+ {
+ }
+ ///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
+ protected UnimplementedServiceClient() : base()
+ {
+ }
+ ///<summary>Protected constructor to allow creation of configured clients.</summary>
+ protected UnimplementedServiceClient(ClientBaseConfiguration configuration) : base(configuration)
+ {
+ }
+
+ public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ return UnimplementedCall(request, new CallOptions(headers, deadline, cancellationToken));
+ }
+ public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, CallOptions options)
{
- var call = CreateCall(__Method_UnimplementedCall, new CallOptions(headers, deadline, cancellationToken));
- return Calls.BlockingUnaryCall(call, request);
+ return CallInvoker.BlockingUnaryCall(__Method_UnimplementedCall, null, options, request);
}
- public global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, CallOptions options)
+ public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__Method_UnimplementedCall, options);
- return Calls.BlockingUnaryCall(call, request);
+ return UnimplementedCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
}
- public AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, CallOptions options)
{
- var call = CreateCall(__Method_UnimplementedCall, new CallOptions(headers, deadline, cancellationToken));
- return Calls.AsyncUnaryCall(call, request);
+ return CallInvoker.AsyncUnaryCall(__Method_UnimplementedCall, null, options, request);
}
- public AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, CallOptions options)
+ protected override UnimplementedServiceClient NewInstance(ClientBaseConfiguration configuration)
{
- var call = CreateCall(__Method_UnimplementedCall, options);
- return Calls.AsyncUnaryCall(call, request);
+ return new UnimplementedServiceClient(configuration);
}
}
@@ -276,6 +349,13 @@ namespace Grpc.Testing {
.AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall).Build();
}
+ // creates service definition that can be registered with a server
+ public static ServerServiceDefinition BindService(UnimplementedServiceBase serviceImpl)
+ {
+ return ServerServiceDefinition.CreateBuilder(__ServiceName)
+ .AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall).Build();
+ }
+
// creates a new client
public static UnimplementedServiceClient NewClient(Channel channel)
{
@@ -311,6 +391,7 @@ namespace Grpc.Testing {
}
// client interface
+ [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
public interface IReconnectServiceClient
{
global::Grpc.Testing.Empty Start(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
@@ -324,57 +405,81 @@ namespace Grpc.Testing {
}
// server-side interface
+ [System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
public interface IReconnectService
{
Task<global::Grpc.Testing.Empty> Start(global::Grpc.Testing.Empty request, ServerCallContext context);
Task<global::Grpc.Testing.ReconnectInfo> Stop(global::Grpc.Testing.Empty request, ServerCallContext context);
}
+ // server-side abstract class
+ public abstract class ReconnectServiceBase
+ {
+ public virtual Task<global::Grpc.Testing.Empty> Start(global::Grpc.Testing.Empty request, ServerCallContext context)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+ }
+
+ public virtual Task<global::Grpc.Testing.ReconnectInfo> Stop(global::Grpc.Testing.Empty request, ServerCallContext context)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+ }
+
+ }
+
// client stub
- public class ReconnectServiceClient : ClientBase, IReconnectServiceClient
+ public class ReconnectServiceClient : ClientBase<ReconnectServiceClient>, IReconnectServiceClient
{
public ReconnectServiceClient(Channel channel) : base(channel)
{
}
- public global::Grpc.Testing.Empty Start(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public ReconnectServiceClient(CallInvoker callInvoker) : base(callInvoker)
{
- var call = CreateCall(__Method_Start, new CallOptions(headers, deadline, cancellationToken));
- return Calls.BlockingUnaryCall(call, request);
}
- public global::Grpc.Testing.Empty Start(global::Grpc.Testing.Empty request, CallOptions options)
+ ///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
+ protected ReconnectServiceClient() : base()
{
- var call = CreateCall(__Method_Start, options);
- return Calls.BlockingUnaryCall(call, request);
}
- public AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ ///<summary>Protected constructor to allow creation of configured clients.</summary>
+ protected ReconnectServiceClient(ClientBaseConfiguration configuration) : base(configuration)
{
- var call = CreateCall(__Method_Start, new CallOptions(headers, deadline, cancellationToken));
- return Calls.AsyncUnaryCall(call, request);
}
- public AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.Empty request, CallOptions options)
+
+ public virtual global::Grpc.Testing.Empty Start(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__Method_Start, options);
- return Calls.AsyncUnaryCall(call, request);
+ return Start(request, new CallOptions(headers, deadline, cancellationToken));
}
- public global::Grpc.Testing.ReconnectInfo Stop(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual global::Grpc.Testing.Empty Start(global::Grpc.Testing.Empty request, CallOptions options)
{
- var call = CreateCall(__Method_Stop, new CallOptions(headers, deadline, cancellationToken));
- return Calls.BlockingUnaryCall(call, request);
+ return CallInvoker.BlockingUnaryCall(__Method_Start, null, options, request);
}
- public global::Grpc.Testing.ReconnectInfo Stop(global::Grpc.Testing.Empty request, CallOptions options)
+ public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__Method_Stop, options);
- return Calls.BlockingUnaryCall(call, request);
+ return StartAsync(request, new CallOptions(headers, deadline, cancellationToken));
}
- public AsyncUnaryCall<global::Grpc.Testing.ReconnectInfo> StopAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.Empty request, CallOptions options)
{
- var call = CreateCall(__Method_Stop, new CallOptions(headers, deadline, cancellationToken));
- return Calls.AsyncUnaryCall(call, request);
+ return CallInvoker.AsyncUnaryCall(__Method_Start, null, options, request);
}
- public AsyncUnaryCall<global::Grpc.Testing.ReconnectInfo> StopAsync(global::Grpc.Testing.Empty request, CallOptions options)
+ public virtual global::Grpc.Testing.ReconnectInfo Stop(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__Method_Stop, options);
- return Calls.AsyncUnaryCall(call, request);
+ return Stop(request, new CallOptions(headers, deadline, cancellationToken));
+ }
+ public virtual global::Grpc.Testing.ReconnectInfo Stop(global::Grpc.Testing.Empty request, CallOptions options)
+ {
+ return CallInvoker.BlockingUnaryCall(__Method_Stop, null, options, request);
+ }
+ public virtual AsyncUnaryCall<global::Grpc.Testing.ReconnectInfo> StopAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ return StopAsync(request, new CallOptions(headers, deadline, cancellationToken));
+ }
+ public virtual AsyncUnaryCall<global::Grpc.Testing.ReconnectInfo> StopAsync(global::Grpc.Testing.Empty request, CallOptions options)
+ {
+ return CallInvoker.AsyncUnaryCall(__Method_Stop, null, options, request);
+ }
+ protected override ReconnectServiceClient NewInstance(ClientBaseConfiguration configuration)
+ {
+ return new ReconnectServiceClient(configuration);
}
}
@@ -386,6 +491,14 @@ namespace Grpc.Testing {
.AddMethod(__Method_Stop, serviceImpl.Stop).Build();
}
+ // creates service definition that can be registered with a server
+ public static ServerServiceDefinition BindService(ReconnectServiceBase serviceImpl)
+ {
+ return ServerServiceDefinition.CreateBuilder(__ServiceName)
+ .AddMethod(__Method_Start, serviceImpl.Start)
+ .AddMethod(__Method_Stop, serviceImpl.Stop).Build();
+ }
+
// creates a new client
public static ReconnectServiceClient NewClient(Channel channel)
{
diff --git a/src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs b/src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs
index 5a1b4cf319..354318e80e 100644
--- a/src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs
+++ b/src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs
@@ -1,6 +1,6 @@
#region Copyright notice and license
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -45,14 +45,14 @@ namespace Grpc.Testing
/// <summary>
/// Implementation of TestService server
/// </summary>
- public class TestServiceImpl : TestService.ITestService
+ public class TestServiceImpl : TestService.TestServiceBase
{
- public Task<Empty> EmptyCall(Empty request, ServerCallContext context)
+ public override Task<Empty> EmptyCall(Empty request, ServerCallContext context)
{
return Task.FromResult(new Empty());
}
- public async Task<SimpleResponse> UnaryCall(SimpleRequest request, ServerCallContext context)
+ public override async Task<SimpleResponse> UnaryCall(SimpleRequest request, ServerCallContext context)
{
await EnsureEchoMetadataAsync(context);
EnsureEchoStatus(request.ResponseStatus, context);
@@ -61,7 +61,7 @@ namespace Grpc.Testing
return response;
}
- public async Task StreamingOutputCall(StreamingOutputCallRequest request, IServerStreamWriter<StreamingOutputCallResponse> responseStream, ServerCallContext context)
+ public override async Task StreamingOutputCall(StreamingOutputCallRequest request, IServerStreamWriter<StreamingOutputCallResponse> responseStream, ServerCallContext context)
{
await EnsureEchoMetadataAsync(context);
EnsureEchoStatus(request.ResponseStatus, context);
@@ -73,7 +73,7 @@ namespace Grpc.Testing
}
}
- public async Task<StreamingInputCallResponse> StreamingInputCall(IAsyncStreamReader<StreamingInputCallRequest> requestStream, ServerCallContext context)
+ public override async Task<StreamingInputCallResponse> StreamingInputCall(IAsyncStreamReader<StreamingInputCallRequest> requestStream, ServerCallContext context)
{
await EnsureEchoMetadataAsync(context);
@@ -85,7 +85,7 @@ namespace Grpc.Testing
return new StreamingInputCallResponse { AggregatedPayloadSize = sum };
}
- public async Task FullDuplexCall(IAsyncStreamReader<StreamingOutputCallRequest> requestStream, IServerStreamWriter<StreamingOutputCallResponse> responseStream, ServerCallContext context)
+ public override async Task FullDuplexCall(IAsyncStreamReader<StreamingOutputCallRequest> requestStream, IServerStreamWriter<StreamingOutputCallResponse> responseStream, ServerCallContext context)
{
await EnsureEchoMetadataAsync(context);
@@ -100,7 +100,7 @@ namespace Grpc.Testing
});
}
- public async Task HalfDuplexCall(IAsyncStreamReader<StreamingOutputCallRequest> requestStream, IServerStreamWriter<StreamingOutputCallResponse> responseStream, ServerCallContext context)
+ public override async Task HalfDuplexCall(IAsyncStreamReader<StreamingOutputCallRequest> requestStream, IServerStreamWriter<StreamingOutputCallResponse> responseStream, ServerCallContext context)
{
throw new NotImplementedException();
}
diff --git a/src/csharp/Grpc.IntegrationTesting/WorkerServiceImpl.cs b/src/csharp/Grpc.IntegrationTesting/WorkerServiceImpl.cs
index e5ad0caa03..80dad9fdd9 100644
--- a/src/csharp/Grpc.IntegrationTesting/WorkerServiceImpl.cs
+++ b/src/csharp/Grpc.IntegrationTesting/WorkerServiceImpl.cs
@@ -45,7 +45,7 @@ namespace Grpc.Testing
/// <summary>
/// Implementation of WorkerService server
/// </summary>
- public class WorkerServiceImpl : WorkerService.IWorkerService
+ public class WorkerServiceImpl : WorkerService.WorkerServiceBase
{
readonly Action stopRequestHandler;
@@ -54,7 +54,7 @@ namespace Grpc.Testing
this.stopRequestHandler = GrpcPreconditions.CheckNotNull(stopRequestHandler);
}
- public async Task RunServer(IAsyncStreamReader<ServerArgs> requestStream, IServerStreamWriter<ServerStatus> responseStream, ServerCallContext context)
+ public override async Task RunServer(IAsyncStreamReader<ServerArgs> requestStream, IServerStreamWriter<ServerStatus> responseStream, ServerCallContext context)
{
GrpcPreconditions.CheckState(await requestStream.MoveNext());
var serverConfig = requestStream.Current.Setup;
@@ -78,7 +78,7 @@ namespace Grpc.Testing
await runner.StopAsync();
}
- public async Task RunClient(IAsyncStreamReader<ClientArgs> requestStream, IServerStreamWriter<ClientStatus> responseStream, ServerCallContext context)
+ public override async Task RunClient(IAsyncStreamReader<ClientArgs> requestStream, IServerStreamWriter<ClientStatus> responseStream, ServerCallContext context)
{
GrpcPreconditions.CheckState(await requestStream.MoveNext());
var clientConfig = requestStream.Current.Setup;
@@ -100,12 +100,12 @@ namespace Grpc.Testing
await runner.StopAsync();
}
- public Task<CoreResponse> CoreCount(CoreRequest request, ServerCallContext context)
+ public override Task<CoreResponse> CoreCount(CoreRequest request, ServerCallContext context)
{
return Task.FromResult(new CoreResponse { Cores = Environment.ProcessorCount });
}
- public Task<Void> QuitWorker(Void request, ServerCallContext context)
+ public override Task<Void> QuitWorker(Void request, ServerCallContext context)
{
stopRequestHandler();
return Task.FromResult(new Void());
diff --git a/src/csharp/tests.json b/src/csharp/tests.json
index d66cb1b100..718bfa3287 100644
--- a/src/csharp/tests.json
+++ b/src/csharp/tests.json
@@ -36,8 +36,9 @@
"Math.Tests.MathClientServerTest",
"Grpc.HealthCheck.Tests.HealthClientServerTest",
"Grpc.HealthCheck.Tests.HealthServiceImplTest",
- "Grpc.IntegrationTesting.HeaderInterceptorTest",
"Grpc.IntegrationTesting.HistogramTest",
+ "Grpc.IntegrationTesting.GeneratedClientTest",
+ "Grpc.IntegrationTesting.GeneratedServiceBaseTest",
"Grpc.IntegrationTesting.InteropClientServerTest",
"Grpc.IntegrationTesting.MetadataCredentialsTest",
"Grpc.IntegrationTesting.RunnerClientServerTest",