Exemplo n.º 1
0
        protected override async Task HandleCallAsyncCore(HttpContext httpContext, HttpContextServerCallContext serverCallContext)
        {
            var request = await httpContext.Request.BodyReader.ReadSingleMessageAsync <TRequest>(serverCallContext, Method.RequestMarshaller.ContextualDeserializer);

            TResponse?response = null;

            if (_pipelineInvoker == null)
            {
                var service = (TService)ServiceActivator.Create(serverCallContext, typeof(TService));
                try
                {
                    response = await _invoker(service, request, serverCallContext);
                }
                finally
                {
                    await ServiceActivator.ReleaseAsync(service);
                }
            }
            else
            {
                response = await _pipelineInvoker(request, serverCallContext);
            }

            if (response == null)
            {
                // This is consistent with Grpc.Core when a null value is returned
                throw new RpcException(new Status(StatusCode.Cancelled, "No message returned from method."));
            }

            var responseBodyWriter = httpContext.Response.BodyWriter;
            await responseBodyWriter.WriteMessageAsync(response, serverCallContext, Method.ResponseMarshaller.ContextualSerializer, canFlush : false);
        }
        private async Task <bool> MoveNextCore(CancellationToken cancellationToken)
        {
            CancellationTokenSource?cts = null;

            try
            {
                // Linking tokens is expensive. Only create a linked token if the token passed in requires it
                if (cancellationToken.CanBeCanceled)
                {
                    cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, _call.CancellationToken);
                    cancellationToken = cts.Token;
                }
                else
                {
                    cancellationToken = _call.CancellationToken;
                }

                cancellationToken.ThrowIfCancellationRequested();

                if (_httpResponse == null)
                {
                    Debug.Assert(_call.SendTask != null);
                    await _call.SendTask.ConfigureAwait(false);

                    Debug.Assert(_call.HttpResponse != null);
                    _httpResponse = _call.HttpResponse;
                }
                if (_responseStream == null)
                {
                    _responseStream = await _httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);
                }

                Current = await _responseStream.ReadStreamedMessageAsync(
                    _call.Logger,
                    _call.Method.ResponseMarshaller.ContextualDeserializer,
                    GrpcProtocolHelpers.GetGrpcEncoding(_httpResponse),
                    _call.Channel.ReceiveMaxMessageSize,
                    _call.Channel.CompressionProviders,
                    cancellationToken).ConfigureAwait(false);

                if (Current == null)
                {
                    // No more content in response so mark as finished
                    _call.FinishResponse();
                    return(false);
                }

                GrpcEventSource.Log.MessageReceived();
                return(true);
            }
            catch (OperationCanceledException)
            {
                throw _call.CreateCanceledStatusException();
            }
            finally
            {
                cts?.Dispose();
            }
        }
Exemplo n.º 3
0
        protected override async Task HandleCallAsyncCore(HttpContext httpContext)
        {
            var serverCallContext = CreateServerCallContext(httpContext);

            GrpcProtocolHelpers.AddProtocolHeaders(httpContext.Response);

            try
            {
                serverCallContext.Initialize();

                var requestPayload = await httpContext.Request.BodyReader.ReadSingleMessageAsync(serverCallContext);

                var request = Method.RequestMarshaller.Deserializer(requestPayload);

                TResponse?response = null;

                if (_pipelineInvoker == null)
                {
                    var      activator = httpContext.RequestServices.GetRequiredService <IGrpcServiceActivator <TService> >();
                    TService?service   = null;
                    try
                    {
                        service  = activator.Create();
                        response = await _invoker(service, request, serverCallContext);
                    }
                    finally
                    {
                        if (service != null)
                        {
                            activator.Release(service);
                        }
                    }
                }
                else
                {
                    response = await _pipelineInvoker(request, serverCallContext);
                }

                if (response == null)
                {
                    // This is consistent with Grpc.Core when a null value is returned
                    throw new RpcException(new Status(StatusCode.Cancelled, "No message returned from method."));
                }

                var responseBodyWriter = httpContext.Response.BodyWriter;
                await responseBodyWriter.WriteMessageAsync(response, serverCallContext, Method.ResponseMarshaller.Serializer);

                await serverCallContext.EndCallAsync();
            }
            catch (Exception ex)
            {
                serverCallContext.ProcessHandlerError(ex, Method.Name);
            }
            finally
            {
                serverCallContext.Dispose();
            }
        }
Exemplo n.º 4
0
 public void Reply(TResponse?content)
 {
     if (Replied)
     {
         throw new MultipleReplyException();
     }
     _eventBus.AddReplyMessage(new EventBusRequest <TResponse>(MessageId, content));
     _eventBus.EmitSignal(nameof(EventBus.ReplySignal), MessageId);
     Replied = true;
 }
Exemplo n.º 5
0
        //public async Task<byte[]> DownloadAsync(WebMethods method, string url, CancellationToken cancel = default)
        //{
        //    WebRet ret = await Web.SimpleQueryAsync(method, true, url, cancel, Consts.MimeTypes.JoseJson);

        //    return ret.Data;
        //}

        public async Task <WebUserRet <TResponse> > RequestAsync <TResponse>(WebMethods method, PrivKey key, string?kid, string url, object?request, CancellationToken cancel = default)
        {
            string nonce = await GetNonceAsync(cancel);

            //("*** " + url)._Debug();

            WebRet webret = await Web.RequestWithJwsObjectAsync(method, key, kid, nonce, url, request, cancel, Consts.MimeTypes.JoseJson);

            TResponse?ret = webret.Deserialize <TResponse>(true);

            //webret.Headers._DebugHeaders();
            //webret.ToString()._Debug();

            return(webret.CreateUserRet(ret !));
        }
Exemplo n.º 6
0
        private async Task <TResponse?> HandleGet <TResponse>(IRequest <TResponse> request)
            where TResponse : class
        {
            TResponse?result = null;

            try
            {
                result = await Mediator.Send(request);
            }
            catch (Exception ex)
            {
                UpdateWarningText(exception: ex);
            }

            return(result);
        }
Exemplo n.º 7
0
        public async Task <TResponse?> Get <TResponse>(string url) where TResponse : class
        {
            await SetAuthorizationHeader();

            TResponse?response = null;

            try
            {
                response = await _client.GetFromJsonAsync <TResponse>(url);
            }
            catch (HttpRequestException exception)
            {
                RedirectToLoginIfUnauthorized(exception);
            }

            return(response);
        }
Exemplo n.º 8
0
        protected override async Task HandleCallAsyncCore(HttpContext httpContext, HttpContextServerCallContext serverCallContext)
        {
            var requestPayload = await httpContext.Request.BodyReader.ReadSingleMessageAsync(serverCallContext);

            serverCallContext.DeserializationContext.SetPayload(requestPayload);
            var request = Method.RequestMarshaller.ContextualDeserializer(serverCallContext.DeserializationContext);

            serverCallContext.DeserializationContext.SetPayload(null);

            GrpcEventSource.Log.MessageReceived();

            TResponse?response = null;

            if (_pipelineInvoker == null)
            {
                GrpcActivatorHandle <TService> serviceHandle = default;
                try
                {
                    serviceHandle = ServiceActivator.Create(httpContext.RequestServices);
                    response      = await _invoker(serviceHandle.Instance, request, serverCallContext);
                }
                finally
                {
                    if (serviceHandle.Instance != null)
                    {
                        ServiceActivator.Release(serviceHandle);
                    }
                }
            }
            else
            {
                response = await _pipelineInvoker(request, serverCallContext);
            }

            if (response == null)
            {
                // This is consistent with Grpc.Core when a null value is returned
                throw new RpcException(new Status(StatusCode.Cancelled, "No message returned from method."));
            }

            var responseBodyWriter = httpContext.Response.BodyWriter;
            await responseBodyWriter.WriteMessageAsync(response, serverCallContext, Method.ResponseMarshaller.ContextualSerializer, canFlush : false);

            GrpcEventSource.Log.MessageSent();
        }
Exemplo n.º 9
0
        protected override async Task HandleCallAsyncCore(HttpContext httpContext, HttpContextServerCallContext serverCallContext)
        {
            // Disable request body data rate for client streaming
            DisableMinRequestBodyDataRateAndMaxRequestBodySize(httpContext);

            TResponse?response = null;

            if (_pipelineInvoker == null)
            {
                GrpcActivatorHandle <TService> serviceHandle = default;
                try
                {
                    serviceHandle = ServiceActivator.Create(httpContext.RequestServices);
                    response      = await _invoker(
                        serviceHandle.Instance,
                        new HttpContextStreamReader <TRequest>(serverCallContext, Method.RequestMarshaller.ContextualDeserializer),
                        serverCallContext);
                }
                finally
                {
                    if (serviceHandle.Instance != null)
                    {
                        ServiceActivator.Release(serviceHandle);
                    }
                }
            }
            else
            {
                response = await _pipelineInvoker(
                    new HttpContextStreamReader <TRequest>(serverCallContext, Method.RequestMarshaller.ContextualDeserializer),
                    serverCallContext);
            }

            if (response == null)
            {
                // This is consistent with Grpc.Core when a null value is returned
                throw new RpcException(new Status(StatusCode.Cancelled, "No message returned from method."));
            }

            var responseBodyWriter = httpContext.Response.BodyWriter;
            await responseBodyWriter.WriteMessageAsync(response, serverCallContext, Method.ResponseMarshaller.ContextualSerializer, canFlush : false);

            GrpcEventSource.Log.MessageSent();
        }
        protected override async Task HandleCallAsyncCore(HttpContext httpContext, HttpContextServerCallContext serverCallContext)
        {
            // Disable request body data rate for client streaming
            DisableMinRequestBodyDataRate(httpContext);

            TResponse?response = null;

            if (_pipelineInvoker == null)
            {
                var      activator = httpContext.RequestServices.GetRequiredService <IGrpcServiceActivator <TService> >();
                TService?service   = null;
                try
                {
                    service  = activator.Create();
                    response = await _invoker(
                        service,
                        new HttpContextStreamReader <TRequest>(serverCallContext, Method.RequestMarshaller.Deserializer),
                        serverCallContext);
                }
                finally
                {
                    if (service != null)
                    {
                        activator.Release(service);
                    }
                }
            }
            else
            {
                response = await _pipelineInvoker(
                    new HttpContextStreamReader <TRequest>(serverCallContext, Method.RequestMarshaller.Deserializer),
                    serverCallContext);
            }

            if (response == null)
            {
                // This is consistent with Grpc.Core when a null value is returned
                throw new RpcException(new Status(StatusCode.Cancelled, "No message returned from method."));
            }

            var responseBodyWriter = httpContext.Response.BodyWriter;
            await responseBodyWriter.WriteMessageAsync(response, serverCallContext, Method.ResponseMarshaller.Serializer, canFlush : false);
        }
Exemplo n.º 11
0
        /* Send synchronously with timeout */
        private async Task <TResponse> SendMessageWithResponseAsync <TStruct, TResponse>(TStruct message, int timeout = 1000, CancellationToken token = default)
            where TStruct : IMessage <MessageType>, new()
            where TResponse : struct, IMessage <MessageType>
        {
            /* Start timeout. */
            Stopwatch watch = new Stopwatch();

            watch.Start();

            /* Setup response. */
            TResponse?response = null;

            void ReceiveMessage(ref NetMessage <TResponse> netMessage)
            {
                response = netMessage.Message;
            }

            _simpleHost.MessageHandler.AddOrOverrideHandler <TResponse>(ReceiveMessage);

            /* Send message. */
            var data = new Message <MessageType, TStruct>(message).Serialize();

            Server.Send(data, DeliveryMethod.ReliableOrdered);

            /* Wait loop. */
            while (watch.ElapsedMilliseconds < timeout)
            {
                if (token.IsCancellationRequested)
                {
                    throw new Exception("Task was cancelled.");
                }

                // Return response if available.
                if (response != null)
                {
                    return(response.Value);
                }

                await Task.Delay(1, token);
            }

            throw new Exception("Timeout to receive response has expired.");
        }
        public async Task <TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate <TResponse> next)
        {
            TResponse?result = default(TResponse);

            try
            {
                _context.BeginTransaction();

                result = await next();

                _context.CommitTransaction();
            }
            catch (Exception)
            {
                _context.RollbackTransaction();
                throw;
            }

            return(result);
        }
Exemplo n.º 13
0
        public async Task <TResponse?> Put <TData, TResponse>(string url, TData data) where TResponse : class
        {
            await SetAuthorizationHeader();

            TResponse?responseData = null;

            try
            {
                var response = await _client.PutAsJsonAsync(url, data);

                var stringContent = await response.Content.ReadAsStringAsync();

                responseData = JsonSerializer.Deserialize <TResponse>(stringContent, _serializerOptions);
            }
            catch (HttpRequestException exception)
            {
                RedirectToLoginIfUnauthorized(exception);
            }

            return(responseData);
        }
Exemplo n.º 14
0
        /// <exception cref="System.ApiException"></exception>
        public static async Task <TResponse?> SendAsync <TResource, TResponse>(this HttpClient httpClient, ApiRequest <TResource> request) where TResource : ApiResource where TResponse : class
        {
            using HttpRequestMessage requestMessage = request.ToHttpRequestMessage();

            if (request is FileUpdateRequest <TResource> fileUpdateRequest)
            {
                requestMessage.Content = BuildMultipartContent(fileUpdateRequest);
            }

            using HttpResponseMessage responseMessage = await httpClient.SendCoreAsync(requestMessage, request).ConfigureAwait(false);

            await ThrowIfNotSuccessedAsync(responseMessage).ConfigureAwait(false);

            if (typeof(TResponse) == _emptyResponseType)
            {
                return((TResponse)(object)EmptyResponse.Value);
            }
            else
            {
                TResponse?response = await responseMessage.DeSerializeJsonAsync <TResponse>().ConfigureAwait(false);

                return(response);
            }
        }
    /// <summary>
    /// Attempts to handle a service method.
    /// </summary>
    protected async Task <HttpResponseMessage?> TryHandleServiceMethodAsync <TRequest, TResponse>(HttpMethodMapping <TRequest, TResponse> mapping, HttpRequestMessage httpRequest, Func <TRequest, CancellationToken, Task <ServiceResult <TResponse> > > invokeMethodAsync, CancellationToken cancellationToken)
        where TRequest : ServiceDto, new()
        where TResponse : ServiceDto, new()
    {
        if (mapping == null)
        {
            throw new ArgumentNullException(nameof(mapping));
        }
        if (httpRequest == null)
        {
            throw new ArgumentNullException(nameof(httpRequest));
        }
        if (invokeMethodAsync == null)
        {
            throw new ArgumentNullException(nameof(invokeMethodAsync));
        }
        if (httpRequest.RequestUri == null)
        {
            throw new ArgumentException("RequestUri must be specified.", nameof(httpRequest));
        }

        if (httpRequest.Method != mapping.HttpMethod)
        {
            return(null);
        }

        var pathParameters = TryMatchHttpRoute(httpRequest.RequestUri, m_rootPath + mapping.Path);

        if (pathParameters == null)
        {
            return(null);
        }

        var context = new ServiceHttpContext();

        ServiceHttpContext.SetContext(httpRequest, context);

        var aspectHttpResponse = await AdaptTask(RequestReceivedAsync(httpRequest, cancellationToken)).ConfigureAwait(true);

        if (aspectHttpResponse != null)
        {
            return(aspectHttpResponse);
        }

        ServiceErrorDto?error = null;

        object?requestBody = null;

        if (mapping.RequestBodyType != null)
        {
            try
            {
                var serializer    = GetHttpContentSerializer(mapping.RequestBodyType);
                var requestResult = await AdaptTask(serializer.ReadHttpContentAsync(mapping.RequestBodyType, httpRequest.Content, cancellationToken)).ConfigureAwait(true);

                if (requestResult.IsFailure)
                {
                    error = requestResult.Error;
                }
                else
                {
                    requestBody = requestResult.Value;
                }
            }
            catch (Exception exception) when(ShouldCreateErrorFromException(exception))
            {
                // cancellation can cause the wrong exception
                cancellationToken.ThrowIfCancellationRequested();

                // error reading request body
                error = CreateErrorFromException(exception);
            }
        }

        TResponse?response = null;

        if (error == null)
        {
            var request = mapping.CreateRequest(requestBody);

            var uriParameters = new Dictionary <string, string?>(StringComparer.OrdinalIgnoreCase);
            foreach (var queryParameter in ParseQueryString(httpRequest.RequestUri.Query))
            {
                uriParameters[queryParameter.Key] = queryParameter.Value[0];
            }
            foreach (var pathParameter in pathParameters)
            {
                uriParameters[pathParameter.Key] = pathParameter.Value;
            }
            request = mapping.SetUriParameters(request, uriParameters);
            request = mapping.SetRequestHeaders(request, HttpServiceUtility.CreateDictionaryFromHeaders(httpRequest.Headers, httpRequest.Content?.Headers) !);

            context.Request = request;

            if (!m_skipRequestValidation && !request.Validate(out var requestErrorMessage))
            {
                error = ServiceErrors.CreateInvalidRequest(requestErrorMessage);
            }
            else
            {
                var methodResult = await invokeMethodAsync(request, cancellationToken).ConfigureAwait(true);

                if (methodResult.IsFailure)
                {
                    error = methodResult.Error;
                }
                else
                {
                    response = methodResult.Value;

                    if (!m_skipResponseValidation && !response.Validate(out var responseErrorMessage))
                    {
                        error    = ServiceErrors.CreateInvalidResponse(responseErrorMessage);
                        response = null;
                    }
                }
            }

            context.Result = error != null?ServiceResult.Failure(error) : ServiceResult.Success <ServiceDto>(response !);
        }

        HttpResponseMessage httpResponse;

        if (error == null)
        {
            var responseMappingGroups = mapping.ResponseMappings
                                        .GroupBy(x => x.MatchesResponse(response !))
                                        .Where(x => x.Key != false)
                                        .OrderByDescending(x => x.Key)
                                        .ToList();
            if (responseMappingGroups.Count >= 1 && responseMappingGroups[0].Count() == 1)
            {
                var responseMapping = responseMappingGroups[0].Single();
                httpResponse = new HttpResponseMessage(responseMapping.StatusCode);

                var responseHeaders = mapping.GetResponseHeaders(response !);
                var headersResult   = HttpServiceUtility.TryAddNonContentHeaders(httpResponse.Headers, responseHeaders);
                if (headersResult.IsFailure)
                {
                    throw new InvalidOperationException(headersResult.Error !.Message);
                }

                if (responseMapping.ResponseBodyType != null)
                {
                    var serializer = GetHttpContentSerializer(responseMapping.ResponseBodyType);
                    var mediaType  = responseMapping.ResponseBodyContentType ?? responseHeaders?.GetContentType() ?? GetAcceptedMediaType(httpRequest, serializer);
                    httpResponse.Content = serializer.CreateHttpContent(responseMapping.GetResponseBody(response !) !, mediaType);
                    if (m_disableChunkedTransfer)
                    {
                        await httpResponse.Content.LoadIntoBufferAsync().ConfigureAwait(false);
                    }
                }
            }
            else
            {
                throw new InvalidOperationException($"Found {responseMappingGroups.Sum(x => x.Count())} valid HTTP responses for {typeof(TResponse).Name}: {response}");
            }
        }
        else
        {
            var statusCode = error.Code == null ? HttpStatusCode.InternalServerError :
                             (TryGetCustomHttpStatusCode(error.Code) ?? HttpServiceErrors.TryGetHttpStatusCode(error.Code) ?? HttpStatusCode.InternalServerError);
            httpResponse = new HttpResponseMessage(statusCode);
            if (statusCode != HttpStatusCode.NoContent && statusCode != HttpStatusCode.NotModified)
            {
                var mediaType = GetAcceptedMediaType(httpRequest, m_contentSerializer);
                httpResponse.Content = m_contentSerializer.CreateHttpContent(error, mediaType);
                if (m_disableChunkedTransfer)
                {
                    await httpResponse.Content.LoadIntoBufferAsync().ConfigureAwait(false);
                }
            }
        }

        httpResponse.RequestMessage = httpRequest;
        await AdaptTask(ResponseReadyAsync(httpResponse, cancellationToken)).ConfigureAwait(true);

        return(httpResponse);
    }
Exemplo n.º 16
0
 public HttpIntegrationException(string message, int statusCode = 400, TResponse?response = null, Exception?inner = null)
     : base(message, inner)
 {
     HttpResponse   = response;
     HttpStatusCode = statusCode;
 }
Exemplo n.º 17
0
 public CommandResponse(TResponse?result)
 {
     Result = result;
 }
Exemplo n.º 18
0
 /// <summary>
 /// Call to indicate whether the current exception should be considered handled and the specified response should be returned.
 /// </summary>
 /// <param name="response">Set the response that will be returned.</param>
 public void SetHandled(TResponse response)
 {
     Handled  = true;
     Response = response;
 }
Exemplo n.º 19
0
 /// <inheritdoc />
 public async Task Execute(TRequest request, CancellationToken cancellationToken)
 {
     Response = await Next(request, cancellationToken);
 }
Exemplo n.º 20
0
 private void AddResponse(TResponse response)
 {
     _response = response;
 }
        private async Task <bool> MoveNextCore(CancellationToken cancellationToken)
        {
            CancellationTokenSource?cts = null;

            try
            {
                // Linking tokens is expensive. Only create a linked token if the token passed in requires it
                if (cancellationToken.CanBeCanceled)
                {
                    cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, _call.CancellationToken);
                    cancellationToken = cts.Token;
                }
                else
                {
                    cancellationToken = _call.CancellationToken;
                }

                cancellationToken.ThrowIfCancellationRequested();

                if (_httpResponse == null)
                {
                    Debug.Assert(_call.SendTask != null);
                    await _call.SendTask.ConfigureAwait(false);

                    Debug.Assert(_call.HttpResponse != null);
                    _httpResponse = _call.HttpResponse;
                }
                if (_responseStream == null)
                {
                    try
                    {
                        _responseStream = await _httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);
                    }
                    catch (ObjectDisposedException)
                    {
                        // The response was disposed while waiting for the content stream to start.
                        // This will happen if there is no content stream (e.g. a streaming call finishes with no messages).
                        if (_call.ResponseFinished)
                        {
                            // Call status will have been set before dispose.
                            var status = await _call.CallTask.ConfigureAwait(false);

                            if (status.StatusCode != StatusCode.OK)
                            {
                                throw new RpcException(status);
                            }

                            // Return false to indicate that the stream is complete without a message.
                            return(false);
                        }

                        throw;
                    }
                }

                Current = await _responseStream.ReadStreamedMessageAsync(
                    _call.Logger,
                    _call.Method.ResponseMarshaller.ContextualDeserializer,
                    GrpcProtocolHelpers.GetGrpcEncoding(_httpResponse),
                    _call.Channel.ReceiveMaxMessageSize,
                    _call.Channel.CompressionProviders,
                    cancellationToken).ConfigureAwait(false);

                if (Current == null)
                {
                    // No more content in response so mark as finished
                    _call.FinishResponse(throwOnFail: true);
                    return(false);
                }

                GrpcEventSource.Log.MessageReceived();
                return(true);
            }
            catch (OperationCanceledException) when(!_call.Channel.ThrowOperationCanceledExceptionOnCancellation)
            {
                throw _call.CreateCanceledStatusException();
            }
            finally
            {
                cts?.Dispose();
            }
        }