Ejemplo n.º 1
0
        /// <summary>
        /// 构造异步的执行action
        /// </summary>
        /// <param name="serviceExec"></param>
        /// <param name="service"></param>
        /// <param name="requestContext"></param>
        /// <param name="dto"></param>
        /// <param name="responseType"></param>
        /// <param name="getResult"></param>
        /// <returns></returns>
        private static Task <object> ManagedAsyncServiceMethodExec(
            ServiceExecFn serviceExec,
            object service, IRequestContext requestContext, object dto, Type responseType, Func <object, object> getResult)
        {
            Stopwatch stopwatch   = new Stopwatch();
            var       httpRequest = requestContext != null?requestContext.Get <IHttpRequest>() : null;

            var httpResponse = requestContext != null?requestContext.Get <IHttpResponse>() : null;

            string identity = null;

            if (EndpointHost.ServiceManager != null && EndpointHost.MetadataMap != null && httpRequest != null)
            {
                identity = EndpointHost.Config.MetadataMap[httpRequest.ServicePath].GetOperationByOpName(httpRequest.OperationName).Key;
            }

            Task serviceTask = null;

            try
            {
                InjectRequestContext(service, requestContext);

                if (EndpointHost.Config != null && EndpointHost.Config.PreExecuteServiceFilter != null)
                {
                    EndpointHost.Config.PreExecuteServiceFilter(service, httpRequest, httpResponse);
                }

                //Executes the async service and returns the task
                stopwatch.Start();
                try
                {
                    serviceTask = serviceExec(requestContext, dto) as Task;
                }
                catch (Exception)
                {
                    object startTimeObject;
                    if (httpRequest.Items.TryGetValue(ServiceCatConstants.SOA2AsyncServiceStartTimeKey, out startTimeObject))
                    {
                        var startTime = (DateTime)startTimeObject;
                    }
                    throw;
                }
                finally
                {
                }

                if (serviceTask == null) // null task
                {
                    throw new InvalidOperationException(ServiceUtils.AsyncOperationReturnedNullTask);
                }

                if (serviceTask.Status == TaskStatus.Created)
                {
                    throw new InvalidAsynchronousStateException("Service task status is invalid: TaskStatus.Created");
                }
            }
            catch (Exception ex)
            {
                TaskCompletionSource <object> tcs = new TaskCompletionSource <object>();
                try
                {
                    if (stopwatch.IsRunning)
                    {
                        stopwatch.Stop();
                    }
                    var response = ErrorUtils.CreateServiceErrorResponse(httpRequest, ex, responseType);
                    if (httpResponse != null)
                    {
                        httpResponse.ResponseObject = response;
                        if (httpResponse.ExecutionResult != null)
                        {
                            httpResponse.ExecutionResult.ExceptionCaught        = ex;
                            httpResponse.ExecutionResult.ServiceExceptionThrown = true;
                            httpResponse.ExecutionResult.ServiceExecutionTime   = stopwatch.ElapsedMilliseconds;
                        }
                    }
                    tcs.TrySetResult(response);
                }
                catch (Exception ex1)
                {
                    tcs.TrySetException(ex1);
                }

                return(tcs.Task);
            }

            return(serviceTask.ContinueWith(t =>
            {
                try
                {
                    Exception taskException = t.Exception;

                    stopwatch.Stop();

                    if (taskException != null) // handler service exception
                    {
                        Exception ex = taskException.InnerException ?? taskException;
                        var responseObject = ErrorUtils.CreateServiceErrorResponse(httpRequest, ex, responseType);

                        if (httpResponse != null)
                        {
                            if (httpResponse.ExecutionResult != null)
                            {
                                httpResponse.ExecutionResult.ExceptionCaught = ex;
                                // Mark service execution throws exception
                                httpResponse.ExecutionResult.ServiceExceptionThrown = true;
                                httpResponse.ExecutionResult.ServiceExecutionTime = stopwatch.ElapsedMilliseconds;
                            }
                            httpResponse.ResponseObject = responseObject;
                        }
                        return responseObject;
                    }

                    object response = getResult(serviceTask); // get the real response
                    if (response == null)                     // null response, create service error response
                    {
                        var ex = new InvalidOperationException("Null response returned by service call");
                        var responseObject = ErrorUtils.CreateServiceErrorResponse(httpRequest, ex, responseType);
                        if (httpResponse != null)
                        {
                            httpResponse.ResponseObject = responseObject;
                            if (httpResponse.ExecutionResult != null)
                            {
                                httpResponse.ExecutionResult.ExceptionCaught = ex;
                                httpResponse.ExecutionResult.ServiceExceptionThrown = true;
                                httpResponse.ExecutionResult.ServiceExecutionTime = stopwatch.ElapsedMilliseconds;
                            }
                        }
                        return responseObject;
                    }

                    if (EndpointHost.Config != null && EndpointHost.Config.PostExecuteServiceFilter != null)
                    {
                        EndpointHost.Config.PostExecuteServiceFilter(service, httpRequest, httpResponse);
                    }

                    IHasResponseStatus hasResponseStatus = response as IHasResponseStatus;
                    if (hasResponseStatus != null && hasResponseStatus.ResponseStatus != null &&
                        hasResponseStatus.ResponseStatus.Ack == AckCodeType.Failure)
                    {
                        if (hasResponseStatus.ResponseStatus.Errors.Count > 0)
                        {
                            ErrorUtils.LogError("Internal handled Service Error", httpRequest, hasResponseStatus.ResponseStatus, false, "FXD300003");
                        }
                        else
                        {
                            ErrorUtils.LogError("Internal handled Service Error. But no error data in ResponseStatus.Errors. QA please fire bug to dev and let dev fix it.",
                                                httpRequest, hasResponseStatus.ResponseStatus, true, "FXD300028");
                        }
                    }
                    if (httpResponse != null)
                    {
                        httpResponse.ResponseObject = response;
                        if (httpResponse.ExecutionResult != null)
                        {
                            httpResponse.ExecutionResult.ServiceExecutionTime = stopwatch.ElapsedMilliseconds;
                        }
                    }
                    return response;
                }
                catch (Exception ex) // catch unexpected framework exception
                {
                    var responseObject = ErrorUtils.CreateFrameworkErrorResponse(httpRequest, ex, responseType);
                    if (httpResponse != null)
                    {
                        httpResponse.ResponseObject = responseObject;
                        if (httpResponse.ExecutionResult != null)
                        {
                            httpResponse.ExecutionResult.ExceptionCaught = ex;
                            // Mark framework excution throws exception
                            httpResponse.ExecutionResult.FrameworkExceptionThrown = true;
                            httpResponse.ExecutionResult.ServiceExecutionTime = stopwatch.ElapsedMilliseconds;
                        }
                    }
                    return responseObject;
                }
                finally
                {
                    if (EndpointHost.AppHost != null)
                    {
                        //Gets disposed by AppHost or ContainerAdapter if set
                        EndpointHost.AppHost.Release(service);
                    }
                    else
                    {
                        using (service as IDisposable) { }
                    }
                }
            }));
        }
Ejemplo n.º 2
0
        private static object ManagedServiceMethodExec(
            ServiceExecFn serviceExec,
            object service, IRequestContext requestContext, object dto, Type responseType)
        {
            InjectRequestContext(service, requestContext);

            Stopwatch stopwatch   = new Stopwatch();
            var       httpRequest = requestContext != null?requestContext.Get <IHttpRequest>() : null;

            var httpResponse = requestContext != null?requestContext.Get <IHttpResponse>() : null;

            try
            {
                if (EndpointHost.Config != null && EndpointHost.Config.PreExecuteServiceFilter != null)
                {
                    EndpointHost.Config.PreExecuteServiceFilter(service, httpRequest, httpResponse);
                }

                string identity = null;
                if (EndpointHost.ServiceManager != null && EndpointHost.MetadataMap != null && httpRequest != null)
                {
                    identity = EndpointHost.Config.MetadataMap[httpRequest.ServicePath].GetOperationByOpName(httpRequest.OperationName).Key;
                }

                object response;
                //Executes the service and returns the result
                stopwatch.Start();
                try
                {
                    response = serviceExec(requestContext, dto);
                }
                catch (Exception)
                {
                    throw;
                }
                finally
                {
                }
                stopwatch.Stop();
                // Record service execution time
                if (httpResponse != null)
                {
                    httpResponse.ResponseObject = response;
                    if (httpResponse.ExecutionResult != null)
                    {
                        httpResponse.ExecutionResult.ServiceExecutionTime = stopwatch.ElapsedMilliseconds;
                    }
                }

                if (response == null) // null response
                {
                    throw new NullReferenceException("Null response returned by service call");
                }

                if (EndpointHost.Config != null && EndpointHost.Config.PostExecuteServiceFilter != null)
                {
                    EndpointHost.Config.PostExecuteServiceFilter(service, httpRequest, httpResponse);
                }

                IHasResponseStatus hasResponseStatus = response as IHasResponseStatus;
                if (hasResponseStatus != null && hasResponseStatus.ResponseStatus != null &&
                    hasResponseStatus.ResponseStatus.Ack == AckCodeType.Failure)
                {
                    if (hasResponseStatus.ResponseStatus.Errors.Count > 0)
                    {
                        ErrorUtils.LogError("Internal handled Service Error", httpRequest, hasResponseStatus.ResponseStatus, false, "FXD300003");
                    }
                    else
                    {
                        ErrorUtils.LogError("Internal handled Service Error. But no error data in ResponseStatus.Errors. QA please fire bug to dev and let dev fix it.",
                                            httpRequest, hasResponseStatus.ResponseStatus, true, "FXD300028");
                    }
                }

                return(response);
            }
            catch (Exception ex)
            {
                var errorResponse = ErrorUtils.CreateServiceErrorResponse(httpRequest, ex, responseType);
                if (httpResponse != null)
                {
                    httpResponse.ResponseObject = errorResponse;
                    if (httpResponse.ExecutionResult != null)
                    {
                        httpResponse.ExecutionResult.ExceptionCaught = ex;
                        // Mark service excution throws exception
                        httpResponse.ExecutionResult.ServiceExceptionThrown = true;
                        // take service execution time into accout even the service execution throws excetpion
                        if (stopwatch.IsRunning)
                        {
                            stopwatch.Stop();
                        }
                        httpResponse.ExecutionResult.ServiceExecutionTime = stopwatch.ElapsedMilliseconds;
                    }
                }
                return(errorResponse);
            }
            finally
            {
                if (EndpointHost.AppHost != null)
                {
                    //Gets disposed by AppHost or ContainerAdapter if set
                    EndpointHost.AppHost.Release(service);
                }
                else
                {
                    using (service as IDisposable) { }
                }
            }
        }