Exemplo n.º 1
0
        private async Task<InvocationResponse<TResponse>> MakeInvokeRequestAsyncWithResponse<TRequest, TResponse>(
            InvocationRequest<TRequest> request,
            bool useRaw,
            CancellationToken cancellationToken = default)
        {
            Any serializedData = null;
            if (request.Body != null)
            {
                if (useRaw)
                {
                    // User has passed in raw bytes
                    var requestBytes = (byte[])(object)(request.Body);
                    serializedData = new Any { Value = ByteString.CopyFrom(requestBytes), TypeUrl = typeof(byte[]).FullName };
                }
                else
                {
                    serializedData = TypeConverters.ToAny(request.Body, this.jsonSerializerOptions);
                }
            }

            try
            {
                var invokeResponse = new InvocationResponse<TResponse>();
                Autogenerated.InvokeServiceRequest invokeRequest;
                CallOptions callOptions;
                (invokeRequest, callOptions) = this.MakeInvokeRequestAsync(request.AppId, request.MethodName, serializedData, request.HttpExtension, cancellationToken);
                var grpcCall = client.InvokeServiceAsync(invokeRequest, callOptions);

                var response = await grpcCall.ResponseAsync;
                var responseHeaders = await grpcCall.ResponseHeadersAsync;
                var trailers = grpcCall.GetTrailers();
                var grpcStatus = grpcCall.GetStatus();

                var headers = grpcCall.ResponseHeadersAsync.Result.ToDictionary(kv => kv.Key, kv => kv.ValueBytes);

                if (useRaw)
                {
                    // User wants to receive raw bytes
                    var responseBytes = new byte[response.Data.Value.Length];
                    response.Data.Value?.CopyTo(responseBytes, 0);
                    invokeResponse.Body = (TResponse)(response.Data.Value.IsEmpty ? default : (object)(responseBytes));
                }
                else
                {
                    invokeResponse.Body = response.Data.Value.IsEmpty ? default : TypeConverters.FromAny<TResponse>(response.Data, this.jsonSerializerOptions);
                }
                invokeResponse.Headers = headers;
                invokeResponse.Trailers = grpcCall.GetTrailers().ToDictionary(kv => kv.Key, kv => kv.ValueBytes);

                if (headers.TryGetValue(DaprHttpStatusHeader, out var httpStatus))
                {
                    invokeResponse.HttpStatusCode = (HttpStatusCode)System.Enum.Parse(typeof(HttpStatusCode), Encoding.UTF8.GetString(httpStatus, 0, httpStatus.Length));
                    invokeResponse.ContentType = Constants.ContentTypeApplicationJson;
                }
                else
                {
                    // Response is grpc
                    invokeResponse.GrpcStatusInfo = new GrpcStatusInfo(grpcStatus.StatusCode, grpcStatus.Detail);
                    invokeResponse.ContentType = Constants.ContentTypeApplicationGrpc;
                }
                return invokeResponse;

            }
            catch (RpcException ex)
            {
                var invokeErrorResponse = new InvocationResponse<byte[]>();
                var entry = ex.Trailers.Get(GrpcStatusDetails);
                if (entry != null)
                {
                    var status = Google.Rpc.Status.Parser.ParseFrom(entry.ValueBytes);
                    foreach (var detail in status.Details)
                    {
                        if (Google.Protobuf.WellKnownTypes.Any.GetTypeName(detail.TypeUrl) == GrpcErrorInfoDetail)
                        {
                            var rpcError = detail.Unpack<Google.Rpc.ErrorInfo>();
                            var grpcStatusCode = (StatusCode)status.Code;

                            string innerHttpErrorCode = null;
                            string innerHttpErrorMessage = null;
                            rpcError.Metadata.TryGetValue(DaprErrorInfoHttpCodeMetadata, out innerHttpErrorCode);
                            rpcError.Metadata.TryGetValue(DaprErrorInfoHttpErrorMetadata, out innerHttpErrorMessage);
                            if(innerHttpErrorCode != null || innerHttpErrorMessage != null)
                            {
                                // Response returned by Http server
                                invokeErrorResponse.HttpStatusCode = (HttpStatusCode)(Convert.ToInt32(innerHttpErrorCode));
                                invokeErrorResponse.Body = Encoding.UTF8.GetBytes(innerHttpErrorMessage);
                            }
                            else
                            {
                                // Response returned by gRPC server
                                invokeErrorResponse.GrpcStatusInfo = new GrpcStatusInfo(grpcStatusCode, status.Message);
                            }
                            break;
                        }
                    }
                }
                throw new InvocationException($"Exception while invoking {request.MethodName} on appId:{request.AppId}", ex, invokeErrorResponse);
            }
        }
 /// <summary>
 /// The constructor.
 /// </summary>
 public InvocationException(string message, Exception innerException, InvocationResponse <byte[]> response)
     : base(message, innerException)
 {
     this.Response = response;
 }