public override AsyncUnaryCall <TResponse> AsyncUnaryCall <TRequest, TResponse>(Method <TRequest, TResponse> method , string host , CallOptions options , TRequest request) { return(Calls.AsyncUnaryCall(CreateCall(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) { var call = CreateCall(method, host, options); var response = Calls.AsyncUnaryCall(call, request); return(response); }
public override AsyncUnaryCall <TResponse> AsyncUnaryCall <TRequest, TResponse>(Method <TRequest, TResponse> method, string host, CallOptions options, TRequest request) { options = options.Headers == null?options.WithHeaders(new Metadata()) : options; var _context = new ClientInterceptorContext <TRequest, TResponse>(method, host, options); _tracer.Request(request, _context); var rspCnt = Calls.AsyncUnaryCall(CreateCall(method, host, options), request); var rspAsync = rspCnt.ResponseAsync.ContinueWith(rspTask => { try { var response = rspTask.Result; _tracer.Response(response, _context); _tracer.Finish(_context); return(response); } catch (AggregateException ex) { _tracer.Exception(_context, ex.InnerException, request); throw ex.InnerException; } }); return(new AsyncUnaryCall <TResponse>(rspAsync, rspCnt.ResponseHeadersAsync, rspCnt.GetStatus, rspCnt.GetTrailers, rspCnt.Dispose)); }
public async Task PropagateDeadline() { var deadline = DateTime.UtcNow.AddDays(7); helper.UnaryHandler = new UnaryServerMethod <string, string>((request, context) => { Assert.IsTrue(context.Deadline < deadline.AddMinutes(1)); Assert.IsTrue(context.Deadline > deadline.AddMinutes(-1)); return(Task.FromResult("PASS")); }); helper.ClientStreamingHandler = new ClientStreamingServerMethod <string, string>(async(requestStream, context) => { Assert.Throws(typeof(ArgumentException), () => { // Trying to override deadline while propagating deadline from parent call will throw. Calls.BlockingUnaryCall(helper.CreateUnaryCall( new CallOptions(deadline: DateTime.UtcNow.AddDays(8), propagationToken: context.CreatePropagationToken())), ""); }); var callOptions = new CallOptions(propagationToken: context.CreatePropagationToken()); return(await Calls.AsyncUnaryCall(helper.CreateUnaryCall(callOptions), "xyz")); }); var call = Calls.AsyncClientStreamingCall(helper.CreateClientStreamingCall(new CallOptions(deadline: deadline))); await call.RequestStream.CompleteAsync(); Assert.AreEqual("PASS", await call); }
/// <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 trace = this.ResolveTraceSpan().Child(); trace.Record(Annotations.ClientSend()); trace.Record(Annotations.ServiceName(_serviceName)); trace.Record(Annotations.Rpc("grpc")); var channel = new Channel(_target, ChannelCredentials.Insecure); var call = CreateCall(channel, method, host, options, trace); try { trace.Record(Annotations.Tag("grpc.host", _target)); trace.Record(Annotations.Tag("grpc.request", JsonConvert.SerializeObject(request))); var response = Calls.AsyncUnaryCall(call, request); trace.Record(Annotations.Tag("grpc.response", JsonConvert.SerializeObject(response))); return(response); } finally { trace.Record(Annotations.ClientRecv()); channel.ShutdownAsync(); } }
public async Task AsyncUnaryCall_EchoMetadata() { helper.UnaryHandler = new UnaryServerMethod <string, string>(async(request, context) => { foreach (Metadata.Entry metadataEntry in context.RequestHeaders) { if (metadataEntry.Key != "user-agent") { context.ResponseTrailers.Add(metadataEntry); } } return(""); }); var headers = new Metadata { { "ascii-header", "abcdefg" }, { "binary-header-bin", new byte[] { 1, 2, 3, 0, 0xff } } }; var call = Calls.AsyncUnaryCall(helper.CreateUnaryCall(new CallOptions(headers: headers)), "ABC"); await call; Assert.AreEqual(StatusCode.OK, call.GetStatus().StatusCode); var trailers = call.GetTrailers(); Assert.AreEqual(2, trailers.Count); Assert.AreEqual(headers[0].Key, trailers[0].Key); Assert.AreEqual(headers[0].Value, trailers[0].Value); Assert.AreEqual(headers[1].Key, trailers[1].Key); CollectionAssert.AreEqual(headers[1].ValueBytes, trailers[1].ValueBytes); }
public void AsyncUnaryCall() { var call = new Call <string, string>(ServiceName, EchoMethod, channel, Metadata.Empty); var result = Calls.AsyncUnaryCall(call, "ABC", CancellationToken.None).Result; Assert.AreEqual("ABC", result); }
public void StartAsyncUnaryCallAfterChannelShutdown() { // create a channel and immediately shut it down. var channel = new Channel("127.0.0.1", 1000, ChannelCredentials.Insecure); channel.ShutdownAsync().Wait(); // also shuts down GrpcEnvironment Assert.Throws(typeof(ObjectDisposedException), () => Calls.AsyncUnaryCall(new CallInvocationDetails <string, string>(channel, dummyUnaryMethod, new CallOptions()), "THE REQUEST")); }
public async Task ForeignPropagationTokenIsIgnored() { helper.UnaryHandler = new UnaryServerMethod <string, string>((request, context) => { return(Task.FromResult("PASS")); }); var callOptions = new CallOptions(propagationToken: new ForeignContextPropagationToken()); await Calls.AsyncUnaryCall(helper.CreateUnaryCall(callOptions), "xyz"); }
public async Task UnaryCall() { helper.UnaryHandler = new UnaryServerMethod <string, string>(async(request, context) => { return(request); }); Assert.AreEqual("ABC", Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "ABC")); Assert.AreEqual("ABC", await Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "ABC")); }
/// <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) { CallOptions updateOptions = ProcessOptions(options); var call = CreateCall(method, host, updateOptions); return(Calls.AsyncUnaryCall(call, request)); }
public async Task ContinuationDoesNotRunOnGrpcThread() { helper.UnaryHandler = new UnaryServerMethod <string, string>(async(request, context) => { return(request); }); await Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "ABC"); Assert.IsFalse(IsRunningOnGrpcThreadPool()); }
/// <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) { if (unaryInvoker == null) { var call = CreateCall(method, host, options); return(Calls.AsyncUnaryCall(call, request)); } else { return(unaryInvoker.AsyncUnaryCall(method, host, options, request)); } }
public async Task UnaryCall() { helper.UnaryHandler = new UnaryServerMethod <string, string>((request, context) => { return(Task.FromResult(request)); }); Assert.AreEqual("ABC", Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "ABC")); Assert.AreEqual("ABC", await Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "ABC")); Assert.AreEqual("ABC", await Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "ABC").ConfigureAwait(false)); }
public async Task PropagateCancellation() { var readyToCancelTcs = new TaskCompletionSource <object>(); var successTcs = new TaskCompletionSource <string>(); helper.UnaryHandler = new UnaryServerMethod <string, string>(async(request, context) => { readyToCancelTcs.SetResult(null); // child call running, ready to parent call while (!context.CancellationToken.IsCancellationRequested) { await Task.Delay(10); } successTcs.SetResult("CHILD_CALL_CANCELLED"); return(""); }); helper.ClientStreamingHandler = new ClientStreamingServerMethod <string, string>(async(requestStream, context) => { var propagationToken = context.CreatePropagationToken(); Assert.IsNotNull(propagationToken.AsImplOrNull().ParentCall); var callOptions = new CallOptions(propagationToken: propagationToken); try { await Calls.AsyncUnaryCall(helper.CreateUnaryCall(callOptions), "xyz"); } catch (RpcException) { // Child call will get cancelled, eat the exception. } return(""); }); var cts = new CancellationTokenSource(); var parentCall = Calls.AsyncClientStreamingCall(helper.CreateClientStreamingCall(new CallOptions(cancellationToken: cts.Token))); await readyToCancelTcs.Task; cts.Cancel(); try { // cannot use Assert.ThrowsAsync because it uses Task.Wait and would deadlock. await parentCall; Assert.Fail(); } catch (RpcException) { } Assert.AreEqual("CHILD_CALL_CANCELLED", await successTcs.Task); }
public async Task UnaryServerHandler_Auth_Failed() { var helper = new MockServiceBuilder(); helper.UnaryHandler = new UnaryServerMethod <string, string>((request, context) => Task.FromResult("ok")); helper.ServiceDefinition = helper.ServiceDefinition.Intercept(_authInterceptor); _server = helper.GetServer(); _server.Start(); _channel = helper.GetChannel(); await ShouldBeCancelRpcExceptionAsync(async() => await Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "")); var method = new Method <string, string>(MethodType.Unary, MockServiceBuilder.ServiceName, "Unary", Marshallers.StringMarshaller, Marshallers.StringMarshaller); var peer = _peerPool.GetPeersByHost("127.0.0.1").First(); ((GrpcPeer)peer).InboundSessionId = new byte[] { 1, 2, 3 }; var callInvoker = helper.GetChannel().Intercept(metadata => { metadata = new Metadata { { GrpcConstants.PubkeyMetadataKey, peer.Info.Pubkey } }; return(metadata); }); await ShouldBeCancelRpcExceptionAsync(async() => await callInvoker.AsyncUnaryCall(method, "localhost", new CallOptions(), "")); callInvoker = helper.GetChannel().Intercept(metadata => { metadata = new Metadata { { GrpcConstants.PubkeyMetadataKey, peer.Info.Pubkey }, { GrpcConstants.SessionIdMetadataKey, new byte[] { 4, 5, 6 } } }; return(metadata); }); await ShouldBeCancelRpcExceptionAsync(async() => await callInvoker.AsyncUnaryCall(method, "localhost", new CallOptions(), "")); ((GrpcPeer)peer).InboundSessionId = null; await ShouldBeCancelRpcExceptionAsync(async() => await callInvoker.AsyncUnaryCall(method, "localhost", new CallOptions(), "")); }
public void UnaryCall_ServerHandlerThrows() { helper.UnaryHandler = new UnaryServerMethod <string, string>((request, context) => { throw new Exception("This was thrown on purpose by a test"); }); var ex = Assert.Throws <RpcException>(() => Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "abc")); Assert.AreEqual(StatusCode.Unknown, ex.Status.StatusCode); var ex2 = Assert.Throws <RpcException>(async() => await Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "abc")); Assert.AreEqual(StatusCode.Unknown, ex2.Status.StatusCode); }
public void UnaryCall_ServerHandlerThrowsRpcException() { helper.UnaryHandler = new UnaryServerMethod <string, string>((request, context) => { throw new RpcException(new Status(StatusCode.Unauthenticated, "")); }); var ex = Assert.Throws <RpcException>(() => Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "abc")); Assert.AreEqual(StatusCode.Unauthenticated, ex.Status.StatusCode); var ex2 = Assert.Throws <RpcException>(async() => await Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "abc")); Assert.AreEqual(StatusCode.Unauthenticated, ex2.Status.StatusCode); }
public void AsyncUnaryCall_ServerHandlerThrows() { Task.Run(async() => { var call = new Call <string, string>(ServiceName, EchoMethod, channel, Metadata.Empty); try { await Calls.AsyncUnaryCall(call, "THROW", CancellationToken.None); Assert.Fail(); } catch (RpcException e) { Assert.AreEqual(StatusCode.Unknown, e.Status.StatusCode); } }).Wait(); }
public async Task ServiceConfigRetryPolicy_AsyncUnaryCall() { var counter = new AtomicCounter(); helper.UnaryHandler = new UnaryServerMethod <string, string>((request, context) => { var attempt = counter.Increment(); if (attempt <= 2) { throw new RpcException(new Status(StatusCode.Unavailable, $"Attempt {attempt} failed on purpose")); } return(Task.FromResult("PASS")); }); Assert.AreEqual("PASS", await Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "abc")); }
public async Task ResponseHeadersAsync_UnaryCall() { helper.UnaryHandler = new UnaryServerMethod <string, string>(async(request, context) => { await context.WriteResponseHeadersAsync(headers); return("PASS"); }); var call = Calls.AsyncUnaryCall(helper.CreateUnaryCall(), ""); var responseHeaders = await call.ResponseHeadersAsync; Assert.AreEqual(headers.Count, responseHeaders.Count); Assert.AreEqual("ascii-header", responseHeaders[0].Key); Assert.AreEqual("abcdefg", responseHeaders[0].Value); Assert.AreEqual("PASS", await call.ResponseAsync); }
public async Task Issue18100() { var server = new Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) }); // this port will successfully bind int successfullyBoundPort = server.Ports.Add(new ServerPort("localhost", ServerPort.PickUnused, ServerCredentials.Insecure)); Assert.AreNotEqual(0, successfullyBoundPort); // use bad ssl server credentials so this port is guaranteed to fail to bind Assert.AreEqual(0, server.Ports.Add(new ServerPort("localhost", ServerPort.PickUnused, MakeBadSslServerCredentials()))); try { server.Start(); } catch (IOException ex) { // eat the expected "Failed to bind port" exception. Console.Error.WriteLine($"Ignoring expected exception when starting the server: {ex}"); } // Create a channel to the port that has been bound successfully var channel = new Channel("localhost", successfullyBoundPort, ChannelCredentials.Insecure); var callDeadline = DateTime.UtcNow.AddSeconds(5); // set deadline to make sure we fail quickly if the server doesn't respond // call a method that's not implemented on the server. var call = Calls.AsyncUnaryCall(new CallInvocationDetails <string, string>(channel, UnimplementedMethod, new CallOptions(deadline: callDeadline)), "someRequest"); try { await call; Assert.Fail("the call should have failed."); } catch (RpcException) { // We called a nonexistent method. A healthy server should immediately respond with StatusCode.Unimplemented Assert.AreEqual(StatusCode.Unimplemented, call.GetStatus().StatusCode); } await channel.ShutdownAsync(); await server.ShutdownAsync(); }
public async Task Channel_WaitForStateChangedAsync() { helper.UnaryHandler = new UnaryServerMethod <string, string>(async(request, context) => { return(request); }); Assert.Throws(typeof(TaskCanceledException), async() => await channel.WaitForStateChangedAsync(channel.State, DateTime.UtcNow.AddMilliseconds(10))); var stateChangedTask = channel.WaitForStateChangedAsync(channel.State); await Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "abc"); await stateChangedTask; Assert.AreEqual(ChannelState.Ready, channel.State); }
public void UnaryCall_ServerHandlerSetsStatus() { helper.UnaryHandler = new UnaryServerMethod <string, string>((request, context) => { context.Status = new Status(StatusCode.Unauthenticated, ""); return(Task.FromResult("")); }); var ex = Assert.Throws <RpcException>(() => Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "abc")); Assert.AreEqual(StatusCode.Unauthenticated, ex.Status.StatusCode); Assert.AreEqual(0, ex.Trailers.Count); var ex2 = Assert.ThrowsAsync <RpcException>(async() => await Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "abc")); Assert.AreEqual(StatusCode.Unauthenticated, ex2.Status.StatusCode); Assert.AreEqual(0, ex2.Trailers.Count); }
/// <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 result = _resourceManager.ExecuteAsync(async(grpcResource, retryCount) => { var overriddenOptions = OverrideCallOptions(options); var call = new CallInvocationDetails <TRequest, TResponse>(grpcResource.Channel, method, host, overriddenOptions); var asyncCall = Calls.AsyncUnaryCall(call, request); // Await for any exception, but return the original object because we don't want to lose any information var response = await asyncCall.ResponseAsync.ConfigureAwait(false); var headers = await asyncCall.ResponseHeadersAsync.ConfigureAwait(false); var status = asyncCall.GetStatus(); var trailers = asyncCall.GetTrailers(); return(Tuple.Create(response, headers, status, trailers)); }, _shouldRetry, _onError); return(new AsyncUnaryCallWrapper <TResponse>(result).GetAsyncUnaryCall()); }
public void UnaryCall_StatusDebugErrorStringNotTransmittedFromServer() { helper.UnaryHandler = new UnaryServerMethod <string, string>((request, context) => { context.Status = new Status(StatusCode.Unauthenticated, "", new CoreErrorDetailException("this DebugErrorString value should not be transmitted to the client")); return(Task.FromResult("")); }); var ex = Assert.Throws <RpcException>(() => Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "abc")); Assert.AreEqual(StatusCode.Unauthenticated, ex.Status.StatusCode); StringAssert.Contains("Error received from peer", ex.Status.DebugException.Message, "Is \"Error received from peer\" still a valid substring to search for in the client-generated error message from C-core?"); Assert.AreEqual(0, ex.Trailers.Count); var ex2 = Assert.ThrowsAsync <RpcException>(async() => await Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "abc")); Assert.AreEqual(StatusCode.Unauthenticated, ex2.Status.StatusCode); StringAssert.Contains("Error received from peer", ex2.Status.DebugException.Message, "Is \"Error received from peer\" still a valid substring to search for in the client-generated error message from C-core?"); Assert.AreEqual(0, ex2.Trailers.Count); }
public async Task SuppressDeadlinePropagation() { helper.UnaryHandler = new UnaryServerMethod <string, string>((request, context) => { Assert.AreEqual(DateTime.MaxValue, context.Deadline); return(Task.FromResult("PASS")); }); helper.ClientStreamingHandler = new ClientStreamingServerMethod <string, string>(async(requestStream, context) => { Assert.IsTrue(context.CancellationToken.CanBeCanceled); var callOptions = new CallOptions(propagationToken: context.CreatePropagationToken(new ContextPropagationOptions(propagateDeadline: false))); return(await Calls.AsyncUnaryCall(helper.CreateUnaryCall(callOptions), "xyz")); }); var cts = new CancellationTokenSource(); var call = Calls.AsyncClientStreamingCall(helper.CreateClientStreamingCall(new CallOptions(deadline: DateTime.UtcNow.AddDays(7)))); await call.RequestStream.CompleteAsync(); Assert.AreEqual("PASS", await call); }
AsyncUnaryCall <TRequest, TResponse>(Method <TRequest, TResponse> method, string host, CallOptions options, TRequest request) { affinityByMethod.TryGetValue(method.FullName, out AffinityConfig affinityConfig); Tuple <ChannelRef, string> tupleResult = PreProcess(affinityConfig, request); ChannelRef channelRef = tupleResult.Item1; string boundKey = tupleResult.Item2; var callDetails = new CallInvocationDetails <TRequest, TResponse>(channelRef.Channel, method, host, options); var originalCall = Calls.AsyncUnaryCall(callDetails, request); // Executes affinity postprocess once the async response finishes. var gcpResponseAsync = PostProcessPropagateResult(originalCall.ResponseAsync); // Create a wrapper of the original AsyncUnaryCall. return(new AsyncUnaryCall <TResponse>( gcpResponseAsync, originalCall.ResponseHeadersAsync, () => originalCall.GetStatus(), () => originalCall.GetTrailers(), () => originalCall.Dispose())); async Task <TResponse> PostProcessPropagateResult(Task <TResponse> task) { TResponse response = default(TResponse); try { response = await task.ConfigureAwait(false); return(response); } finally { PostProcess(affinityConfig, channelRef, boundKey, response); } } }
public void UnaryCall_ServerHandlerSetsStatusAndTrailers() { helper.UnaryHandler = new UnaryServerMethod <string, string>(async(request, context) => { context.Status = new Status(StatusCode.Unauthenticated, ""); context.ResponseTrailers.Add("xyz", "xyz-value"); return(""); }); var ex = Assert.Throws <RpcException>(() => Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "abc")); Assert.AreEqual(StatusCode.Unauthenticated, ex.Status.StatusCode); Assert.AreEqual(1, ex.Trailers.Count); Assert.AreEqual("xyz", ex.Trailers[0].Key); Assert.AreEqual("xyz-value", ex.Trailers[0].Value); var ex2 = Assert.ThrowsAsync <RpcException>(async() => await Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "abc")); Assert.AreEqual(StatusCode.Unauthenticated, ex2.Status.StatusCode); Assert.AreEqual(1, ex2.Trailers.Count); Assert.AreEqual("xyz", ex2.Trailers[0].Key); Assert.AreEqual("xyz-value", ex2.Trailers[0].Value); }
public void UnaryCall_ServerHandlerThrowsRpcExceptionWithTrailers() { helper.UnaryHandler = new UnaryServerMethod <string, string>((request, context) => { var trailers = new Metadata { { "xyz", "xyz-value" } }; throw new RpcException(new Status(StatusCode.Unauthenticated, ""), trailers); }); var ex = Assert.Throws <RpcException>(() => Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "abc")); Assert.AreEqual(StatusCode.Unauthenticated, ex.Status.StatusCode); Assert.AreEqual(1, ex.Trailers.Count); Assert.AreEqual("xyz", ex.Trailers[0].Key); Assert.AreEqual("xyz-value", ex.Trailers[0].Value); var ex2 = Assert.ThrowsAsync <RpcException>(async() => await Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "abc")); Assert.AreEqual(StatusCode.Unauthenticated, ex2.Status.StatusCode); Assert.AreEqual(1, ex2.Trailers.Count); Assert.AreEqual("xyz", ex2.Trailers[0].Key); Assert.AreEqual("xyz-value", ex2.Trailers[0].Value); }