Ejemplo n.º 1
0
        private static object ManagedServiceExec(
            ServiceExecFn serviceExec,
            object service, IRequestContext requestContext, object dto)
        {
            try
            {
                InjectRequestContext(service, requestContext);

                try
                {
                    //Executes the service and returns the result
                    var response = serviceExec(requestContext, dto);
                    return(response);
                }
                finally
                {
                    if (EndpointHost.AppHost != null)
                    {
                        //Gets disposed by AppHost or ContainerAdapter if set
                        EndpointHost.AppHost.Release(service);
                    }
                    else
                    {
                        using (service as IDisposable) {}
                    }
                }
            }
            catch (TargetInvocationException tex)
            {
                //Mono invokes using reflection
                throw tex.InnerException ?? tex;
            }
        }
Ejemplo n.º 2
0
        private object ManagedServiceExec(ServiceExecFn serviceExec, IService service, IRequest request, object requestDto)
        {
            try
            {
                InjectRequestContext(service, request);

                try
                {
                    request.Dto = requestDto;

                    requestDto  = appHost.OnPreExecuteServiceFilter(service, requestDto, request, request.Response);
                    request.Dto = requestDto;

                    //Executes the service and returns the result
                    var response = serviceExec(request, requestDto);

                    response = appHost.OnPostExecuteServiceFilter(service, response, request, request.Response);

                    return(response);
                }
                finally
                {
                    //Gets disposed by AppHost or ContainerAdapter if set
                    appHost.Release(service);
                }
            }
            catch (TargetInvocationException tex)
            {
                //Mono invokes using reflection
                throw tex.InnerException ?? tex;
            }
        }
Ejemplo n.º 3
0
        private void AddToRequestExecMap(Type requestType, Type serviceType, ServiceExecFn handlerFn)
        {
            if (requestExecMap.ContainsKey(requestType))
            {
                throw new AmbiguousMatchException(
                          string.Format(
                              "Could not register Request '{0}' with service '{1}' as it has already been assigned to another service.\n"
                              + "Each Request DTO can only be handled by 1 service.",
                              requestType.FullName, serviceType.FullName));
            }

            requestExecMap.Add(requestType, handlerFn);

            var requestAttrs = requestType.AllAttributes <RestrictAttribute>();

            if (requestAttrs.Length > 0)
            {
                requestServiceAttrs[requestType] = requestAttrs[0];
            }
            else
            {
                var serviceAttrs = serviceType.AllAttributes <RestrictAttribute>();
                if (serviceAttrs.Length > 0)
                {
                    requestServiceAttrs[requestType] = serviceAttrs[0];
                }
            }
        }
        public void RegisterService(Type serviceType, ITypeFactory serviceFactoryFn)
        {
            if (!Service.IsServiceType(serviceType))
            {
                throw new ArgumentException($"{serviceType.FullName} is not a service type that implements IService.");
            }

            if (!serviceActionMap.TryGetValue(serviceType, out Dictionary <Type, List <ActionContext> > actionMap))
            {
                var serviceExecDef = typeof(ServiceExec <>).MakeGenericType(serviceType);
                var iserviceExec   = (IServiceExec)serviceExecDef.CreateInstance();
                iserviceExec.Reset(AppHost);
                actionMap = iserviceExec.ActionMap;
                foreach (var requestType in actionMap.Keys)
                {
                    ServiceExecFn handlerFn = (req, dto) =>
                    {
                        var service = (serviceFactoryFn ?? typeFactory).CreateInstance(req, serviceType) as IService;

                        ServiceExecFn serviceExec = (reqCtx, requestDto) =>
                                                    iserviceExec.Execute(reqCtx, service, requestDto);

                        return(ManagedServiceExec(serviceExec, service, req, dto));
                    };
                    AddToRequestExecMap(requestType, serviceType, handlerFn);
                    foreach (var item in actionMap[requestType])
                    {
                        AppHost.Metadata.Add(serviceType, requestType, item.ResponseType);

                        if (Logger.IsDebugEnabled)
                        {
                            Logger.DebugFormat("Registering {0} service '{1}' with request '{2}'",
                                               item.ResponseType != null ? "Reply" : "OneWay", serviceType.GetOperationName(), requestType.GetOperationName());
                        }
                    }

                    RegisterRestPaths(requestType);
                    if (typeof(IRequiresRequestStream).IsAssignableFrom(requestType))
                    {
                        this.RequestTypeFactoryMap[requestType] = req =>
                        {
                            var restPath = req.GetRoute();
                            var request  = restPath != null
                                ? RestHandler.CreateRequest(req, restPath, req.GetRequestParams(), requestType.CreateInstance())
                                : KeyValueDataContractDeserializer.Instance.Parse(req.QueryString, requestType);

                            var rawReq = (IRequiresRequestStream)request;
                            rawReq.RequestStream = req.InputStream;
                            return(rawReq);
                        };
                    }
                }
                serviceActionMap[serviceType] = actionMap;
                AppHost.Container.RegisterAutoWiredType(serviceType);
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// 注册action
        /// </summary>
        /// <param name="servicePath"></param>
        /// <param name="serviceName"></param>
        /// <param name="serviceType"></param>
        /// <param name="mi"></param>
        /// <param name="serviceFactoryFn"></param>
        public void RegisterGServiceMethodExecutor(string servicePath, string serviceName, Type serviceType, MethodInfo mi, ITypeFactory serviceFactoryFn)
        {
            //构造执行方法
            var serviceMethodExecFn = BuildServiceMethodExecutor(mi, serviceType);
            //返回类型
            var responseType = mi.ReturnType;
            //是否是异步的
            bool isAsync = responseType.FullName.StartsWith("System.Threading.Tasks.Task`1");

            if (isAsync)
            {
                responseType = responseType.GetGenericArguments()[0];//如果是异步的 返回类型是拿 泛型的定义
            }
            if (responseType == typeof(void))
            {
                responseType = null;//判断是否没有返回类型
            }
            ServiceExecFn handlerFn = null;

            if (isAsync)
            {
                //如果是异步的
                Func <object, object> getResult = mi.ReturnType.GetProperty("Result").CreateGetter();
                handlerFn = (requestContext, dto) =>
                {
                    var           service     = serviceFactoryFn.CreateInstance(serviceType);
                    ServiceExecFn serviceExec = (reqCtx, req) => serviceMethodExecFn(req, service);
                    return(ManagedAsyncServiceMethodExec(serviceExec, service, requestContext, dto, responseType, getResult));
                };
            }
            else
            {
                //同步
                handlerFn = (requestContext, dto) =>
                {
                    var           service     = serviceFactoryFn.CreateInstance(serviceType);
                    ServiceExecFn serviceExec = (reqCtx, req) => serviceMethodExecFn(req, service);
                    try
                    {
                        return(ManagedServiceMethodExec(serviceExec, service, requestContext, dto, responseType));
                    }
                    finally
                    {
                    }
                };
            }

            AddToMethodExecMap(servicePath, mi, serviceType, handlerFn);
        }
        public void Register <TReq>(Func <IService <TReq> > invoker)
        {
            var           requestType = typeof(TReq);
            ServiceExecFn handlerFn   = (requestContext, dto) => {
                var service = invoker();

                InjectRequestContext(service, requestContext);

                return(ServiceExec <TReq> .Execute(
                           service, (TReq)dto,
                           requestContext != null?requestContext.EndpointAttributes : EndpointAttributes.None));
            };

            requestExecMap.Add(requestType, handlerFn);
        }
Ejemplo n.º 7
0
        public void RegisterNServiceExecutor(Type requestType, Type serviceType, ITypeFactory serviceFactoryFn)
        {
            var serviceExecDef = typeof(NServiceRequestExec <,>).MakeGenericType(serviceType, requestType);
            var iserviceExec   = (INServiceExec)serviceExecDef.CreateInstance();

            ServiceExecFn handlerFn = (requestContext, dto) => {
                var service = serviceFactoryFn.CreateInstance(serviceType);

                ServiceExecFn serviceExec = (reqCtx, req) =>
                                            iserviceExec.Execute(reqCtx, service, req);

                return(ManagedServiceExec(serviceExec, service, requestContext, dto));
            };

            AddToRequestExecMap(requestType, serviceType, handlerFn);
        }
Ejemplo n.º 8
0
        public void RegisterGServiceExecutor(Type requestType, Type serviceType, ITypeFactory serviceFactoryFn)
        {
            var typeFactoryFn = CallServiceExecuteGeneric(requestType, serviceType);

            ServiceExecFn handlerFn = (requestContext, dto) => {
                var service = serviceFactoryFn.CreateInstance(serviceType);

                var endpointAttrs = requestContext != null
                    ? requestContext.EndpointAttributes
                    : EndpointAttributes.None;

                ServiceExecFn serviceExec = (reqCtx, req) =>
                                            typeFactoryFn(req, service, endpointAttrs);

                return(ManagedServiceExec(serviceExec, service, requestContext, dto));
            };

            AddToRequestExecMap(requestType, serviceType, handlerFn);
        }
Ejemplo n.º 9
0
        private object ManagedServiceExec(ServiceExecFn serviceExec, IService service, IRequest request, object requestDto)
        {
            try
            {
                InjectRequestContext(service, request);

                object response = null;
                try
                {
                    requestDto = appHost.OnPreExecuteServiceFilter(service, requestDto, request, request.Response);

                    if (request.Dto == null) // Don't override existing batched DTO[]
                    {
                        request.Dto = requestDto;
                    }

                    //Executes the service and returns the result
                    response = serviceExec(request, requestDto);

                    response = appHost.OnPostExecuteServiceFilter(service, response, request, request.Response);

                    return(response);
                }
                finally
                {
                    //Gets disposed by AppHost or ContainerAdapter if set
                    var taskResponse = response as Task;
                    if (taskResponse != null)
                    {
                        taskResponse.ContinueWith(task => appHost.Release(service));
                    }
                    else
                    {
                        appHost.Release(service);
                    }
                }
            }
            catch (TargetInvocationException tex)
            {
                //Mono invokes using reflection
                throw tex.InnerException ?? tex;
            }
        }
Ejemplo n.º 10
0
        public void RegisterServiceExecutor(Type requestType, Type serviceType, ITypeFactory serviceFactoryFn)
        {
            ResetServiceExecCachesIfNeeded(serviceType, requestType);

            var serviceExecDef = typeof(ServiceRequestExec <,>).MakeGenericType(serviceType, requestType);
            var iserviceExec   = (IServiceExec)serviceExecDef.CreateInstance();

            ServiceExecFn handlerFn = (req, dto) =>
            {
                var service = serviceFactoryFn.CreateInstance(serviceType);

                ServiceExecFn serviceExec = (reqCtx, requestDto) =>
                                            iserviceExec.Execute(reqCtx, service, requestDto);

                return(ManagedServiceExec(serviceExec, (IService)service, req, dto));
            };

            AddToRequestExecMap(requestType, serviceType, handlerFn);
        }
Ejemplo n.º 11
0
        private void AddToRequestExecMap(Type requestType, Type serviceType, ServiceExecFn handlerFn)
        {
            try
            {
                requestExecMap.Add(requestType, handlerFn);
            }
            catch (ArgumentException)
            {
                throw new AmbiguousMatchException(
                          string.Format(
                              "Could not register the service '{0}' as another service with the definition of type 'IService<{1}>' already exists.",
                              serviceType.FullName, requestType.Name));
            }

            var serviceAttrs = requestType.GetCustomAttributes(typeof(ServiceAttribute), false);

            if (serviceAttrs.Length > 0)
            {
                requestServiceAttrs.Add(requestType, (ServiceAttribute)serviceAttrs[0]);
            }
        }
Ejemplo n.º 12
0
        public Task <object> ExecuteAsync(object requestDto, IRequest request)
        {
            var requestType = requestDto.GetType();

            if (appHost.Config.EnableAccessRestrictions)
            {
                AssertServiceRestrictions(requestType,
                                          request != null ? request.RequestAttributes : RequestAttributes.None);
            }

            ServiceExecFn handlerFn = GetService(requestType);
            var           response  = handlerFn(request, requestDto);

            var taskResponse = response as Task;

            if (taskResponse != null)
            {
                return(taskResponse.ContinueWith(x => x.GetResult()));
            }

            return(response.AsTaskResult());
        }
Ejemplo n.º 13
0
        private static ServiceExecFn CreateAutoBatchServiceExec(ServiceExecFn handlerFn)
        {
            return((req, dtos) =>
            {
                var dtosList = ((IEnumerable)dtos).Map(x => x);
                if (dtosList.Count == 0)
                {
                    return TypeConstants.EmptyObjectArray;
                }

                var firstDto = dtosList[0];

                req.Items[Keywords.AutoBatchIndex] = 0;

                var firstResponse = handlerFn(req, firstDto);
                if (firstResponse is Exception)
                {
                    req.SetAutoBatchCompletedHeader(0);
                    return firstResponse;
                }

                //sync
                if (!(firstResponse is Task asyncResponse))
                {
                    var ret = firstResponse != null
                        ? (object[])Array.CreateInstance(firstResponse.GetType(), dtosList.Count)
                        : new object[dtosList.Count];

                    ret[0] = firstResponse; //don't re-execute first request
                    for (var i = 1; i < dtosList.Count; i++)
                    {
                        var dto = dtosList[i];
                        req.Items[Keywords.AutoBatchIndex] = i;
                        var response = handlerFn(req, dto);
                        //short-circuit on first error
                        if (response is Exception)
                        {
                            req.SetAutoBatchCompletedHeader(i);
                            return response;
                        }

                        ret[i] = response;
                    }
                    req.Items.Remove(Keywords.AutoBatchIndex);
                    req.SetAutoBatchCompletedHeader(dtosList.Count);
                    return ret;
                }

                //async
                var asyncResponses = new Task[dtosList.Count];
                Task firstAsyncError = null;

                //execute each async service sequentially
                var task = dtosList.EachAsync((dto, i) =>
                {
                    //short-circuit on first error and don't exec any more handlers
                    if (firstAsyncError != null)
                    {
                        return firstAsyncError;
                    }

                    req.Items[Keywords.AutoBatchIndex] = i;

                    asyncResponses[i] = i == 0
                        ? asyncResponse //don't re-execute first request
                        : (Task)handlerFn(req, dto);

                    var asyncResult = asyncResponses[i].GetResult();
                    if (asyncResult is Exception)
                    {
                        req.SetAutoBatchCompletedHeader(i);
                        return firstAsyncError = asyncResponses[i];
                    }
                    return asyncResponses[i];
                });
                var batchResponse = HostContext.Async.ContinueWith(req, task, x => {
                    if (firstAsyncError != null)
                    {
                        return (object)firstAsyncError;
                    }
                    req.Items.Remove(Keywords.AutoBatchIndex);
                    req.SetAutoBatchCompletedHeader(dtosList.Count);
                    return (object)asyncResponses;
                }); //return error or completed responses

                return batchResponse;
            });
        }
Ejemplo n.º 14
0
        /// <summary>
        /// 加入到operationExecMap集合 key为:servicePath
        /// </summary>
        /// <param name="servicePath"></param>
        /// <param name="methodInfo"></param>
        /// <param name="serviceType"></param>
        /// <param name="handlerFn"></param>
        private void AddToMethodExecMap(string servicePath, MethodInfo methodInfo, Type serviceType, ServiceExecFn handlerFn)
        {
            if (!operationExecMap.ContainsKey(servicePath))
            {
                operationExecMap[servicePath] = new Dictionary <string, ServiceExecFn>();
            }

            //同一个servicePath(指的是二级目录) 如果有多个同样名称的方法 会报错
            if (operationExecMap[servicePath].ContainsKey(methodInfo.Name.ToLower()))
            {
                throw new AmbiguousMatchException(
                          string.Format(
                              "Could not register method name '{0}' with service '{1}' as it has already been registered.\n"
                              + "Each method name can only be registered once by a service, method name overloading is not allowed by AntServiceStack.",
                              methodInfo.Name, serviceType.FullName));
            }

            operationExecMap[servicePath].Add(methodInfo.Name.ToLower(), handlerFn);

            // RestrictAttribute attributes are only annotated on methods of service implementation
            MethodInfo methodInfoImpl = serviceType.GetMethod(methodInfo.Name, BindingFlags.Public | BindingFlags.Instance);

            //查看是否有限制条件(比如是否限制只能localhost访问之类的)
            var serviceAttrs = methodInfoImpl.GetCustomAttributes(typeof(RestrictAttribute), false);

            if (serviceAttrs.Length > 0)
            {
                operationServiceAttrs.Add(methodInfo.Name.ToLower(), (RestrictAttribute)serviceAttrs[0]);
            }
        }
Ejemplo n.º 15
0
        private static ServiceExecFn CreateAutoBatchServiceExec(ServiceExecFn handlerFn)
        {
            return((req, dtos) =>
            {
                var dtosList = ((IEnumerable)dtos).Map(x => x);
                if (dtosList.Count == 0)
                {
                    return new object[0];
                }

                var firstDto = dtosList[0];

                var firstResponse = handlerFn(req, firstDto);
                if (firstResponse is Exception)
                {
                    req.SetAutoBatchCompletedHeader(0);
                    return firstResponse;
                }

                var asyncResponse = firstResponse as Task;

                //sync
                if (asyncResponse == null)
                {
                    var ret = firstResponse != null
                        ? (object[])Array.CreateInstance(firstResponse.GetType(), dtosList.Count)
                        : new object[dtosList.Count];

                    ret[0] = firstResponse; //don't re-execute first request
                    for (var i = 1; i < dtosList.Count; i++)
                    {
                        var dto = dtosList[i];
                        var response = handlerFn(req, dto);
                        //short-circuit on first error
                        if (response is Exception)
                        {
                            req.SetAutoBatchCompletedHeader(i);
                            return response;
                        }

                        ret[i] = response;
                    }
                    req.SetAutoBatchCompletedHeader(dtosList.Count);
                    return ret;
                }

                //async
                var asyncResponses = new Task[dtosList.Count];
                Task firstAsyncError = null;

                //execute each async service sequentially
                return dtosList.EachAsync((dto, i) =>
                {
                    //short-circuit on first error and don't exec any more handlers
                    if (firstAsyncError != null)
                    {
                        return firstAsyncError;
                    }

                    asyncResponses[i] = i == 0
                        ? asyncResponse //don't re-execute first request
                        : (Task)handlerFn(req, dto);

                    if (asyncResponses[i].GetResult() is Exception)
                    {
                        req.SetAutoBatchCompletedHeader(i);
                        return firstAsyncError = asyncResponses[i];
                    }
                    return asyncResponses[i];
                })
                .ContinueWith(x => {
                    if (firstAsyncError != null)
                    {
                        return (object)firstAsyncError;
                    }

                    req.SetAutoBatchCompletedHeader(dtosList.Count);
                    return (object)asyncResponses;
                }); //return error or completed responses
            });
        }
Ejemplo n.º 16
0
        private static ServiceExecFn CreateAutoBatchServiceExec(ServiceExecFn handlerFn)
        {
            return (req, dtos) => 
            {
                var dtosList = ((IEnumerable) dtos).Map(x => x);
                if (dtosList.Count == 0)
                    return new object[0];

                var firstDto = dtosList[0];

                var firstResponse = handlerFn(req, firstDto);
                if (firstResponse is Exception)
                {
                    req.SetAutoBatchCompletedHeader(0);
                    return firstResponse;
                }

                var asyncResponse = firstResponse as Task;

                //sync
                if (asyncResponse == null) 
                {
                    var ret = firstResponse != null
                        ? (object[])Array.CreateInstance(firstResponse.GetType(), dtosList.Count)
                        : new object[dtosList.Count];

                    ret[0] = firstResponse; //don't re-execute first request
                    for (var i = 1; i < dtosList.Count; i++)
                    {
                        var dto = dtosList[i];
                        var response = handlerFn(req, dto);
                        //short-circuit on first error
                        if (response is Exception)
                        {
                            req.SetAutoBatchCompletedHeader(i);
                            return response;
                        }

                        ret[i] = response;
                    }
                    req.SetAutoBatchCompletedHeader(dtosList.Count);
                    return ret;
                }

                //async
                var asyncResponses = new Task[dtosList.Count];
                Task firstAsyncError = null;

                //execute each async service sequentially
                return dtosList.EachAsync((dto, i) =>
                {
                    //short-circuit on first error and don't exec any more handlers
                    if (firstAsyncError != null)
                        return firstAsyncError;

                    asyncResponses[i] = i == 0
                        ? asyncResponse //don't re-execute first request
                        : (Task) handlerFn(req, dto);

                    var asyncResult = asyncResponses[i].GetResult();
                    if (asyncResult is Exception)
                    {
                        req.SetAutoBatchCompletedHeader(i);
                        return firstAsyncError = asyncResponses[i];
                    }
                    return asyncResponses[i];
                })
                .ContinueWith(x => {
                    if (firstAsyncError != null)
                        return (object)firstAsyncError;

                    req.SetAutoBatchCompletedHeader(dtosList.Count);
                    return (object) asyncResponses;
                }); //return error or completed responses
            };
        }
Ejemplo n.º 17
0
        private object ManagedServiceExec(ServiceExecFn serviceExec, IService service, IRequest request, object requestDto)
        {
            try
            {
                InjectRequestContext(service, request);

                object response = null;
                try
                {
                    requestDto = appHost.OnPreExecuteServiceFilter(service, requestDto, request, request.Response);

                    if (request.Dto == null) // Don't override existing batched DTO[]
                        request.Dto = requestDto; 

                    //Executes the service and returns the result
                    response = serviceExec(request, requestDto);

                    response = appHost.OnPostExecuteServiceFilter(service, response, request, request.Response);

                    return response;
                }
                finally
                {
                    //Gets disposed by AppHost or ContainerAdapter if set
                    var taskResponse = response as Task;
                    if (taskResponse != null)
                    {
                        taskResponse.ContinueWith(task => appHost.Release(service));
                    }
                    else
                    {
                        appHost.Release(service);
                    }
                }
            }
            catch (TargetInvocationException tex)
            {
                //Mono invokes using reflection
                throw tex.InnerException ?? tex;
            }
        }
Ejemplo n.º 18
0
        private void AddToRequestExecMap(Type requestType, Type serviceType, ServiceExecFn handlerFn)
        {
            if (requestExecMap.ContainsKey(requestType))
            {
                throw new AmbiguousMatchException(
                    string.Format(
                    "Could not register Request '{0}' with service '{1}' as it has already been assigned to another service.\n"
                    + "Each Request DTO can only be handled by 1 service.",
                    requestType.FullName, serviceType.FullName));
            }

            requestExecMap.Add(requestType, handlerFn);

            var requestAttrs = requestType.AllAttributes<RestrictAttribute>();
            if (requestAttrs.Length > 0)
            {
                requestServiceAttrs[requestType] = requestAttrs[0];
            }
            else
            {
                var serviceAttrs = serviceType.AllAttributes<RestrictAttribute>();
                if (serviceAttrs.Length > 0)
                {
                    requestServiceAttrs[requestType] = serviceAttrs[0];
                }
            }
        }
Ejemplo n.º 19
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) { }
                }
            }
        }
Ejemplo n.º 20
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.º 21
0
        private object ManagedServiceExec(ServiceExecFn serviceExec, IService service, IRequest request, object requestDto)
        {
            try
            {
                InjectRequestContext(service, request);

                try
                {
                    request.Dto = requestDto;

                    requestDto = appHost.OnPreExecuteServiceFilter(service, requestDto, request, request.Response);
                    request.Dto = requestDto;

                    //Executes the service and returns the result
                    var response = serviceExec(request, requestDto);

                    response = appHost.OnPostExecuteServiceFilter(service, response, request, request.Response);

                    return response;
                }
                finally
                {
                    //Gets disposed by AppHost or ContainerAdapter if set
                    appHost.Release(service);
                }
            }
            catch (TargetInvocationException tex)
            {
                //Mono invokes using reflection
                throw tex.InnerException ?? tex;
            }
        }