Exemplo n.º 1
0
        /// <summary>
        /// 远程调用。
        /// </summary>
        /// <typeparam name="T">返回类型。</typeparam>
        /// <param name="parameters">参数字典。</param>
        /// <param name="serviceId">服务Id。</param>
        /// <returns>调用结果。</returns>
        protected async Task <T> InvokeAsync <T>(IDictionary <string, object> parameters, string serviceId)
        {
            if (_endPoint == null)
            {
                throw new RpcException($"无法解析服务Id:{serviceId}的地址信息。");
            }

            var message = await _remoteInvokeService.InvokeAsync(new RemoteInvokeContext
            {
                InvokeMessage = new RemoteInvokeMessage
                {
                    Parameters = parameters,
                    ServiceId  = serviceId
                }
            }, _endPoint);

            if (message == null)
            {
                return(default(T));
            }

            var result = _typeConvertibleService.Convert(message.Result, typeof(T));

            return((T)result);
        }
Exemplo n.º 2
0
        /// <summary>
        /// 远程调用。
        /// </summary>
        /// <typeparam name="T">返回类型。</typeparam>
        /// <param name="parameters">参数字典。</param>
        /// <param name="serviceId">服务Id。</param>
        /// <returns>调用结果。</returns>
        protected async Task <T> Invoke <T>(IDictionary <string, object> parameters, string serviceId)
        {
            object result  = default(T);
            var    command = await _commandProvider.GetCommand(serviceId);

            RemoteInvokeResultMessage message;
            var decodeJOject = typeof(T) == UtilityType.ObjectType;

            if (!command.RequestCacheEnabled || decodeJOject)
            {
                var v = typeof(T).FullName;
                message = await _breakeRemoteInvokeService.InvokeAsync(parameters, serviceId, _serviceKey, decodeJOject);

                if (message == null)
                {
                    var invoker = _serviceProvider.GetInstances <IClusterInvoker>(command.Strategy.ToString());
                    return(await invoker.Invoke <T>(parameters, serviceId, _serviceKey, typeof(T) == UtilityType.ObjectType));
                }
            }
            else
            {
                var invocation = GetInvocation(parameters, serviceId, typeof(T));
                await _interceptor.Intercept(invocation);

                message = invocation.ReturnValue is RemoteInvokeResultMessage
                    ? invocation.ReturnValue as RemoteInvokeResultMessage : null;
                result = invocation.ReturnValue;
            }

            if (message != null)
            {
                result = _typeConvertibleService.Convert(message.Result, typeof(T));
            }
            return((T)result);
        }
Exemplo n.º 3
0
        public async Task <T> Invoke <T>(IDictionary <string, object> parameters, string serviceId, string serviceKey)
        {
            var command         = _serviceCommandProvider.GetCommand(serviceId);
            var injectionResult = await _serviceCommandProvider.Run(command.Injection, command.InjectionNamespaces);

            if (injectionResult is Boolean)
            {
                if ((bool)injectionResult)
                {
                    var entries = _serviceEntryManager.GetEntries().ToList();
                    var entry   = entries.Where(p => p.Descriptor.Id == serviceId).FirstOrDefault();
                    var message = await entry.Func(serviceKey, parameters);

                    object result = default(T);
                    if (message == null && message is Task <T> )
                    {
                        result = _typeConvertibleService.Convert((message as Task <T>).Result, typeof(T));
                    }
                    return((T)result);
                }
            }
            else
            {
                var result = injectionResult;
                if (injectionResult is Task <T> )
                {
                    result = _typeConvertibleService.Convert((injectionResult as Task <T>).Result, typeof(T));
                }
                return((T)result);
            }
            return(default(T));
        }
Exemplo n.º 4
0
        /// <summary>
        /// 远程调用。
        /// </summary>
        /// <typeparam name="T">返回类型。</typeparam>
        /// <param name="parameters">参数字典。</param>
        /// <param name="serviceId">服务Id。</param>
        /// <returns>调用结果。</returns>
        protected async Task <T> Invoke <T>(IDictionary <string, object> parameters, string serviceId)
        {
            object result  = default(T);
            var    vt      = _commandProvider.GetCommand(serviceId);
            var    command = vt.IsCompletedSuccessfully ? vt.Result : await vt;
            RemoteInvokeResultMessage message = null;
            var         decodeJOject          = typeof(T) == TypeHelper.ObjectType;
            IInvocation invocation            = null;
            var         existsInterceptor     = _interceptors.Any();
            var         serviceRoute          = await _serviceRouteProvider.Locate(serviceId);

            if ((serviceRoute == null || !serviceRoute.ServiceDescriptor.ExistIntercept()) || decodeJOject)
            {
                message = await _breakeRemoteInvokeService.InvokeAsync(parameters, serviceId, _serviceKey,
                                                                       decodeJOject);

                if (message == null)
                {
                    if (command.FallBackName != null &&
                        _serviceProvider.IsRegistered <IFallbackInvoker>(command.FallBackName) &&
                        command.Strategy == StrategyType.FallBack)
                    {
                        var invoker = _serviceProvider.GetInstances <IFallbackInvoker>(command.FallBackName);
                        return(await invoker.Invoke <T>(parameters, serviceId, _serviceKey));
                    }
                    else
                    {
                        var invoker = _serviceProvider.GetInstances <IClusterInvoker>(command.Strategy.ToString());
                        return(await invoker.Invoke <T>(parameters, serviceId, _serviceKey,
                                                        typeof(T) == TypeHelper.ObjectType));
                    }
                }
            }
            else
            {
                invocation = invocation == null?GetInvocation(parameters, serviceId, typeof(T)) : invocation;

                foreach (var interceptor in _interceptors)
                {
                    var interceptReuslt = await Intercept(interceptor, invocation);

                    message = interceptReuslt.Item1;
                    result  = interceptReuslt.Item2 == null ? default(T) : interceptReuslt.Item2;
                }
            }

            if (message != null)
            {
                if (message.Result == null)
                {
                    result = message.Result;
                }
                else
                {
                    result = _typeConvertibleService.Convert(message.Result, typeof(T));
                }
            }

            return((T)result);
        }
        /// <summary>
        /// 远程调用。
        /// </summary>
        /// <typeparam name="T">返回类型。</typeparam>
        /// <param name="parameters">参数字典。</param>
        /// <param name="serviceId">服务Id。</param>
        /// <returns>调用结果。</returns>
        protected async Task <T> Invoke <T>(IDictionary <string, object> parameters, string serviceId)
        {
            object result  = default(T);
            var    command = await _commandProvider.GetCommand(serviceId);

            RemoteInvokeResultMessage message = null;
            var         decodeJOject          = typeof(T) == UtilityType.ObjectType;
            IInvocation invocation            = null;
            var         existsInterceptor     = _interceptors.Any();

            if ((!command.RequestCacheEnabled || decodeJOject) && !existsInterceptor)
            {
                message = await _breakeRemoteInvokeService.InvokeAsync(parameters, serviceId, _serviceKey, decodeJOject);

                if (message == null)
                {
                    if (command.FallBackName != null && _serviceProvider.IsRegistered <IFallbackInvoker>(command.FallBackName) && command.Strategy == StrategyType.FallBack)
                    {
                        var invoker = _serviceProvider.GetInstances <IFallbackInvoker>(command.FallBackName);
                        return(await invoker.Invoke <T>(parameters, serviceId, _serviceKey));
                    }
                    else
                    {
                        var invoker = _serviceProvider.GetInstances <IClusterInvoker>(command.Strategy.ToString());
                        return(await invoker.Invoke <T>(parameters, serviceId, _serviceKey, typeof(T) == UtilityType.ObjectType));
                    }
                }
            }
            if (command.RequestCacheEnabled && !decodeJOject)
            {
                invocation = GetCacheInvocation(parameters, serviceId, typeof(T));
                var interceptReuslt = await Intercept(_cacheInterceptor, invocation);

                message = interceptReuslt.Item1;
                result  = interceptReuslt.Item2 == null ? default(T) : interceptReuslt.Item2;
            }
            if (existsInterceptor)
            {
                invocation = invocation == null?GetInvocation(parameters, serviceId, typeof(T)) : invocation;

                foreach (var interceptor in _interceptors)
                {
                    var interceptReuslt = await Intercept(interceptor, invocation);

                    message = interceptReuslt.Item1;
                    result  = interceptReuslt.Item2 == null ? default(T) : interceptReuslt.Item2;
                }
            }
            if (message != null)
            {
                result = _typeConvertibleService.Convert(message.Result, typeof(T));
            }
            return((T)result);
        }
        private async Task <HttpResultMessage <object> > RemoteExecuteAsync(ServiceEntry entry, HttpMessage httpMessage)
        {
            HttpResultMessage <object> resultMessage = new HttpResultMessage <object>();
            var provider = _concurrent.GetValueOrDefault(httpMessage.RoutePath);
            var list     = new List <object>();

            if (provider.Item1 == null)
            {
                provider.Item2 = ServiceLocator.GetService <IServiceProxyFactory>().CreateProxy(httpMessage.ServiceKey, entry.Type);
                provider.Item3 = provider.Item2.GetType().GetTypeInfo().DeclaredMethods.Where(p => p.Name == entry.MethodName).FirstOrDefault();;
                provider.Item1 = FastInvoke.GetMethodInvoker(provider.Item3);
                _concurrent.GetOrAdd(httpMessage.RoutePath, ValueTuple.Create <FastInvokeHandler, object, MethodInfo>(provider.Item1, provider.Item2, provider.Item3));
            }
            foreach (var parameterInfo in provider.Item3.GetParameters())
            {
                var value         = httpMessage.Parameters[parameterInfo.Name];
                var parameterType = parameterInfo.ParameterType;
                var parameter     = _typeConvertibleService.Convert(value, parameterType);
                list.Add(parameter);
            }
            try
            {
                var methodResult = provider.Item1(provider.Item2, list.ToArray());

                var task = methodResult as Task;
                if (task == null)
                {
                    resultMessage.Data = methodResult;
                }
                else
                {
                    await task;
                    var   taskType = task.GetType().GetTypeInfo();
                    if (taskType.IsGenericType)
                    {
                        resultMessage.Data = taskType.GetProperty("Result").GetValue(task);
                    }
                }
                resultMessage.IsSucceed  = resultMessage.Data != null;
                resultMessage.StatusCode = resultMessage.IsSucceed ? StatusCode.OK : StatusCode.RequestError; //StatusCode.Success : (int)StatusCode.RequestError;
            }
            catch (Exception exception)
            {
                if (_logger.IsEnabled(LogLevel.Error))
                {
                    _logger.LogError(exception, "执行远程调用逻辑时候发生了错误。");
                }
                if (exception is CPlatformException)
                {
                    resultMessage.StatusCode = ((CPlatformException)exception).ExceptionCode;
                }
                else
                {
                    resultMessage.StatusCode = StatusCode.UnKnownError;
                }
                resultMessage.Message   = GetExceptionMessage(exception);
                resultMessage.IsSucceed = false;
            }
            return(resultMessage);
        }
Exemplo n.º 7
0
        private ServiceEntry Create(MethodInfo method)
        {
            var serviceId = _serviceIdGenerator.GenerateServiceId(method);

            var serviceDescriptor = new ServiceDescriptor
            {
                Id = serviceId,
            };
            var descriptorAttributes = method.GetCustomAttributes <ServiceDescriptorAttribute>();

            foreach (var descriptorAttribute in descriptorAttributes)
            {
                descriptorAttribute.Apply(serviceDescriptor);
            }
            return(new ServiceEntry
            {
                Descriptor = serviceDescriptor,
                Attributes = method.GetCustomAttributes().ToList(),
                Func = (key, parameters) =>
                {
                    var instance = _serviceProvider.GetInstances(key, method.DeclaringType);
                    var list = new List <object>();
                    foreach (var parameterInfo in method.GetParameters())
                    {
                        var value = parameters[parameterInfo.Name];
                        var parameterType = parameterInfo.ParameterType;
                        var parameter = _typeConvertibleService.Convert(value, parameterType);
                        list.Add(parameter);
                    }
                    var result = method.Invoke(instance, list.ToArray());
                    return Task.FromResult(result);
                }
            });
        }
Exemplo n.º 8
0
        private ServiceEntry Create(string serviceId, MethodBase implementationMethod)
        {
            var type = implementationMethod.DeclaringType;

            return(new ServiceEntry
            {
                Descriptor = new ServiceDescriptor
                {
                    Id = serviceId
                },
                Func = parameters =>
                {
                    var instance = _serviceFactory.Create(type);

                    var list = new List <object>();
                    foreach (var parameterInfo in implementationMethod.GetParameters())
                    {
                        var value = parameters[parameterInfo.Name];
                        var parameterType = parameterInfo.ParameterType;

                        var parameter = _typeConvertibleService.Convert(value, parameterType);
                        list.Add(parameter);
                    }

                    var result = implementationMethod.Invoke(instance, list.ToArray());

                    return result;
                }
            });
        }
        public async Task <T> Invoke <T>(IDictionary <string, object> parameters, string serviceId)
        {
            var context = new RemoteInvokeContext()
            {
                ServiceId  = serviceId,
                Parameters = parameters
            };
            RemoteInvokeResultMessage message;

            try
            {
                message = await _remoteServiceInvoker.InvokeAsync(context);
            }
            catch (Exception e)
            {
                //todo:log
                throw;
            }

            if (message == null)
            {
                return(default(T));
            }
            var result = _typeConvertibleService.Convert(message.Result, typeof(T));

            return((T)result);
        }
        public void Validate(ParameterInfo parameterInfo, object value)
        {
            Check.NotNull(parameterInfo, nameof(parameterInfo));
            if (value != null)
            {
                var parameterType         = parameterInfo.ParameterType;
                var parameter             = _typeConvertibleService.Convert(value, parameterType);
                var customAttributes      = parameterInfo.GetCustomAttributes(true);
                var customValidAttributes = customAttributes
                                            .Where(ca => ca.GetType() != typeof(ValidateAttribute))
                                            .OfType <ValidationAttribute>()
                                            .ToList();
                var validationContext = new ValidationContext(parameter);
                var validationResults = new List <ValidationResult>();
                var isObjValid        = Validator.TryValidateObject(parameter, validationContext,
                                                                    validationResults,
                                                                    true);

                var isValueValid = Validator.TryValidateValue(parameter, validationContext,
                                                              validationResults, customValidAttributes);

                if (isObjValid && isValueValid)
                {
                    return;
                }

                throw new ValidateException(validationResults.Select(p => p.ErrorMessage).First());
            }
        }
Exemplo n.º 11
0
        private ServiceEntry Create(MethodInfo method, string serviceName, string routeTemplate)
        {
            var serviceId         = _serviceIdGenerator.GenerateServiceId(method);
            var attributes        = method.GetCustomAttributes().ToList();
            var serviceDescriptor = new ServiceDescriptor
            {
                Id        = serviceId,
                RoutePath = RoutePatternParser.Parse(routeTemplate, serviceName, method.Name)
            };

            var descriptorAttributes = method.GetCustomAttributes <ServiceDescriptorAttribute>();

            foreach (var descriptorAttribute in descriptorAttributes)
            {
                descriptorAttribute.Apply(serviceDescriptor);
            }
            var authorization = attributes.Where(p => p is AuthorizationFilterAttribute).FirstOrDefault();

            if (authorization != null)
            {
                serviceDescriptor.EnableAuthorization(true);
            }
            if (authorization != null)
            {
                serviceDescriptor.AuthType(((authorization as AuthorizationAttribute)?.AuthType)
                                           ?? AuthorizationType.AppSecret);
            }
            var fastInvoker = GetHandler(serviceId, method);

            return(new ServiceEntry
            {
                Descriptor = serviceDescriptor,
                RoutePath = serviceDescriptor.RoutePath,
                MethodName = method.Name,
                Type = method.DeclaringType,
                Attributes = attributes,
                Func = (key, parameters) =>
                {
                    var instance = _serviceProvider.GetInstances(key, method.DeclaringType);
                    var list = new List <object>();

                    foreach (var parameterInfo in method.GetParameters())
                    {
                        //加入是否有默认值的判断,有默认值,并且用户没传,取默认值
                        if (parameterInfo.HasDefaultValue && !parameters.ContainsKey(parameterInfo.Name))
                        {
                            list.Add(parameterInfo.DefaultValue);
                            continue;
                        }
                        var value = parameters[parameterInfo.Name];
                        var parameterType = parameterInfo.ParameterType;
                        var parameter = _typeConvertibleService.Convert(value, parameterType);
                        list.Add(parameter);
                    }
                    var result = fastInvoker(instance, list.ToArray());
                    return Task.FromResult(result);
                }
            });
        }
        public async Task <T> Invoke <T>(IDictionary <string, object> parameters, string serviceId, string _serviceKey, bool decodeJOject)
        {
            var time   = 0;
            T   result = default(T);
            RemoteInvokeResultMessage message = null;
            var command = await _commandProvider.GetCommand(serviceId);

            do
            {
                message = await _breakeRemoteInvokeService.InvokeAsync(parameters, serviceId, _serviceKey, decodeJOject, true);

                if (message != null)
                {
                    if (message.StatusCode == StatusCode.Success)
                    {
                        if (message.Result != null)
                        {
                            result = (T)_typeConvertibleService.Convert(message.Result, typeof(T));
                        }
                        else
                        {
                            result = default(T);
                        }
                    }
                    else if (message.IsFailedRemoteInvokeCalled())
                    {
                        continue;
                    }
                    else if (message.IsSucceedRemoteInvokeCalled())
                    {
                        throw message.GetExceptionByStatusCode();
                    }
                }
            } while ((message == null || !message.IsSucceedRemoteInvokeCalled()) && ++time < command.FailoverCluster);
            if (message == null)
            {
                throw new CPlatformException($"{serviceId}远程服务调用失败,暂不存在可用的服务实例");
            }
            if (message.StatusCode != StatusCode.Success)
            {
                throw message.GetExceptionByStatusCode();
            }
            return(result);
        }
Exemplo n.º 13
0
        /// <summary>
        /// 异步远程调用
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="parameters">参数字典</param>
        /// <param name="serviceId">服务Id</param>
        /// <returns>调用结果</returns>
        // ReSharper disable once UnusedMember.Global
        protected async Task <T> InvokeAsync <T>(IDictionary <string, object> parameters, string serviceId)
        {
            var message = await _remoteInvokeService.InvokeAsync(new RemoteInvokeContext
            {
                InvokeMessage = new RemoteInvokeMessage
                {
                    Parameters = parameters,
                    ServiceId  = serviceId
                }
            });

            if (message == null)
            {
                return(default(T));
            }

            var result = _typeConvertibleService.Convert(message.Result, typeof(T));

            return((T)result);
        }
Exemplo n.º 14
0
        private Task <T> GetInvokeResult <T>(RemoteInvokeResultMessage message)
        {
            return(Task.Run(() =>
            {
                object result = default(T);
                if (message.StatusCode == StatusCode.Success)
                {
                    if (message.Result != null)
                    {
                        result = _typeConvertibleService.Convert(message.Result, typeof(T));
                    }
                }
                else
                {
                    throw message.GetExceptionByStatusCode();
                }

                return (T)result;
            }));
        }
Exemplo n.º 15
0
        public async Task OnActionExecuting(ActionExecutingContext filterContext)
        {
            filterContext.Context.Response.OnStarting(async() =>
            {
                var options          = AppConfig.Options;
                var transferContract = filterContext.Route.ServiceDescriptor.GetTransferContract();
                if (transferContract != null)
                {
                    var option = options.Where(p => p.Name == transferContract.Name).FirstOrDefault();
                    if (option != null)
                    {
                        var routePath = string.IsNullOrEmpty(option.RoutePath) ? transferContract.RoutePath : option.RoutePath;

                        var address      = new StringBuilder(option.Endpoint);
                        address          = address.Append(routePath);
                        var serviceEntry = _serviceEntryLocate.Locate(filterContext.Message);
                        if (serviceEntry != null)
                        {
                            var parameters = new Dictionary <string, object>();
                            foreach (var parameterInfo in serviceEntry.Parameters)
                            {
                                var value         = filterContext.Message.Parameters[parameterInfo.Name];
                                var parameterType = parameterInfo.ParameterType;
                                var parameter     = _typeConvertibleService.Convert(value, parameterType);
                                parameters.Add(parameterInfo.Name, _typeConvertibleService.Convert(value, parameterType));
                            }
                            try
                            {
                                var result = await ServiceLocator.GetService <ITransportClient>(transferContract.Type.ToString()).SendAsync(address.ToString(),
                                                                                                                                            parameters, filterContext.Context);
                                await new MessageSender(_serializer, filterContext.Context).SendAndFlushAsync(result, GetContentType(transferContract.Type));
                            }
                            catch (Exception ex)
                            {
                                var i = 0;
                            }
                        }
                    }
                }
            });
        }
Exemplo n.º 16
0
        private void SetSampleParameterValue(ITypeConvertibleService typeConvertibleService, object parameter,
                                             ParameterDescriptor parameterDescriptor, List <object> list)
        {
            var dict =
                (IDictionary <string, object>)typeConvertibleService.Convert(parameter,
                                                                             typeof(IDictionary <string, object>));
            var parameterVal = parameterDescriptor.ParameterInfo.GetDefaultValue();

            if (dict.ContainsKey(parameterDescriptor.Name))
            {
                parameterVal = dict[parameterDescriptor.Name];
            }

            list.Add(parameterVal);
        }
Exemplo n.º 17
0
        private ServiceEntry Create(MethodInfo method, MethodBase implementationMethod)
        {
            var serviceId = _serviceIdGenerator.GenerateServiceId(method);

            var serviceDescriptor = new ServiceDescriptor
            {
                Id = serviceId
            };

            var descriptorAttributes = method.GetCustomAttributes <RpcServiceDescriptorAttribute>();

            foreach (var descriptorAttribute in descriptorAttributes)
            {
                descriptorAttribute.Apply(serviceDescriptor);
            }

            return(new ServiceEntry
            {
                Descriptor = serviceDescriptor,
                Func = async(parameters) =>
                {
                    Stopwatch watch = new Stopwatch();
                    watch.Start();
                    var serviceScopeFactory = _serviceProvider.GetService <IServiceScopeFactory>();
                    using (var scope = serviceScopeFactory.CreateScope())
                    {
                        var instance = scope.ServiceProvider.GetService(method.DeclaringType);

                        var list = new List <object>(implementationMethod.GetParameters().Length);
                        foreach (var parameterInfo in implementationMethod.GetParameters())
                        {
                            var value = parameters[parameterInfo.Name];
                            var parameterType = parameterInfo.ParameterType;

                            var parameter = _typeConvertibleService.Convert(value, parameterType);
                            list.Add(parameter);
                        }

                        var result = implementationMethod.Invoke(instance, list.ToArray());
                        watch.Stop();
                        _logger.LogInformation($"执行耗时:{watch.ElapsedMilliseconds}/ms");
                        Task <ActionResult> task = result as Task <ActionResult>;

                        return await task;
                    }
                }
            });
        }
Exemplo n.º 18
0
        private ServiceEntry Create(MethodInfo method, MethodReflector implementationMethod)
        {
            var serviceId = _serviceIdGenerator.GenerateServiceId(method);

            var serviceDescriptor = new ServiceDescriptor
            {
                Id = serviceId
            };

            var descriptorAttributes = method.GetCustomAttributes <RpcServiceDescriptorAttribute>();

            foreach (var descriptorAttribute in descriptorAttributes)
            {
                descriptorAttribute.Apply(serviceDescriptor);
            }
            return(new ServiceEntry
            {
                Descriptor = serviceDescriptor,
                Func = parameters =>
                {
                    var serviceScopeFactory = _serviceProvider.GetRequiredService <IServiceScopeFactory>();
                    using (var scope = serviceScopeFactory.CreateScope())
                    {
                        var instance = scope.ServiceProvider.GetRequiredService(method.DeclaringType);

                        var list = new List <object>();
                        foreach (var parameterInfo in method.GetParameters())
                        {
                            if (parameterInfo.HasDefaultValue && !parameters.ContainsKey(parameterInfo.Name))
                            {
                                list.Add(parameterInfo.DefaultValue);
                                continue;
                            }
                            var value = parameters[parameterInfo.Name];
                            var parameterType = parameterInfo.ParameterType;

                            var parameter = _typeConvertibleService.Convert(value, parameterType);
                            list.Add(parameter);
                        }

                        var result = implementationMethod.Invoke(instance, list.ToArray());

                        return Task.FromResult(result);
                    }
                }
            });
        }
Exemplo n.º 19
0
        /// <summary>
        /// 远程调用。
        /// </summary>
        /// <typeparam name="T">返回类型。</typeparam>
        /// <param name="parameters">参数字典。</param>
        /// <param name="serviceId">服务Id。</param>
        /// <returns>调用结果。</returns>
        protected async Task <T> Invoke <T>(IDictionary <string, object> parameters, string serviceId)
        {
            var message = await _breakeRemoteInvokeService.InvokeAsync(parameters, serviceId, _serviceKey);

            if (message == null)
            {
                var command = _commandProvider.GetCommand(serviceId);
                var invoker = _serviceProvider.GetInstances <IClusterInvoker>(command.Strategy.ToString());
                return(await invoker.Invoke <T>(parameters, serviceId, _serviceKey));
            }
            if (message == null)
            {
                return(default(T));
            }
            var result = _typeConvertibleService.Convert(message.Result, typeof(T));

            return((T)result);
        }
        public async Task <T> Invoke <T>(IDictionary <string, object> parameters, string serviceId, string _serviceKey, bool decodeJOject)
        {
            var time   = 0;
            T   result = default(T);
            RemoteInvokeResultMessage message = null;
            var command = await _commandProvider.GetCommand(serviceId);

            do
            {
                message = await _breakeRemoteInvokeService.InvokeAsync(parameters, serviceId, _serviceKey, decodeJOject);

                if (message != null && message.Result != null)
                {
                    result = (T)_typeConvertibleService.Convert(message.Result, typeof(T));
                }
            } while (message == null && ++time < command.FailoverCluster);
            return(result);
        }
Exemplo n.º 21
0
        private ServiceEntry Create(MethodInfo method, string serviceName, string routeTemplate)
        {
            var serviceId         = _serviceIdGenerator.GenerateServiceId(method);
            var attributes        = method.GetCustomAttributes().ToList();
            var serviceDescriptor = new ServiceDescriptor
            {
                Id        = serviceId,
                RoutePath = RoutePatternParser.Parse(routeTemplate, serviceName, method.Name)
            };

            var descriptorAttributes = method.GetCustomAttributes <ServiceDescriptorAttribute>();

            foreach (var descriptorAttribute in descriptorAttributes)
            {
                descriptorAttribute.Apply(serviceDescriptor);
            }
            serviceDescriptor.EnableAuthorization(!serviceDescriptor.EnableAuthorization()
                ? attributes.Any(p => p is AuthorizationFilterAttribute) :
                                                  serviceDescriptor.EnableAuthorization());
            var fastInvoker = FastInvoke.GetMethodInvoker(method);

            return(new ServiceEntry
            {
                Descriptor = serviceDescriptor,
                Attributes = attributes,
                Func = (key, parameters) =>
                {
                    var instance = _serviceProvider.GetInstances(key, method.DeclaringType);
                    var list = new List <object>();

                    foreach (var parameterInfo in method.GetParameters())
                    {
                        var value = parameters[parameterInfo.Name];
                        var parameterType = parameterInfo.ParameterType;
                        var parameter = _typeConvertibleService.Convert(value, parameterType);
                        list.Add(parameter);
                    }
                    var result = fastInvoker(instance, list.ToArray()); //method.Invoke(instance, list.ToArray());
                    return Task.FromResult(result);
                }
            });
        }
        public StringContent HttpRouteRpc(List <dynamic> proxys, Uri urlPath, HttpRequestHeaders headers)
        {
            foreach (var proxy in proxys)
            {
                Type type = proxy.GetType();
                if (!urlPath.Query.Contains("scheme=rpc"))
                {
                    continue;
                }

                var predicate = urlPath.AbsolutePath.Split('/');
                var absName   = predicate[predicate.Length - 1];
                var absPars   = predicate[predicate.Length - 2];

                if (!type.GetMethods().Any(methodInfo => methodInfo.Name.Contains(absName)))
                {
                    continue;
                }

                var method = type.GetMethod(absName);
                if (method != null)
                {
                    var parameters = method.GetParameters();
                    var parType    = parameters[0].ParameterType; // only one parameter
                    var par        = _typeConvertibleService.Convert(absPars, parType);

                    var relayScriptor = new RelayScriptor {
                        InvokeType = type, InvokeParameter = new dynamic[] { par }
                    };

                    var result = method.Invoke(
                        Activator.CreateInstance(relayScriptor.InvokeType, _remoteInvokeService, _typeConvertibleService),
                        relayScriptor.InvokeParameter);

                    var strResult = JsonConvert.SerializeObject(result);
                    return(new StringContent(strResult));
                }
            }

            return(null);
        }
Exemplo n.º 23
0
        private static string GetHashKey(object[] parameterValues, ParameterDescriptor parameterDescriptor, int index,
                                         ITypeConvertibleService typeConvertibleService)
        {
            string hashKey;

            if (parameterDescriptor.IsSample)
            {
                var propVal = parameterValues[index];
                if (propVal == null)
                {
                    throw new LmsException("hashKey指定的值不允许为空");
                }

                hashKey = propVal.ToString();
            }
            else
            {
                var parameterValue =
                    typeConvertibleService.Convert(parameterValues[index], parameterDescriptor.Type);
                var hashKeyProp = parameterDescriptor.Type
                                  .GetProperties().First();
                var hashKeyProviderProps = parameterDescriptor.Type
                                           .GetProperties()
                                           .Where(p => p.GetCustomAttributes().OfType <IHashKeyProvider>().Any());
                if (hashKeyProviderProps.Any())
                {
                    hashKeyProp = hashKeyProviderProps.First();
                }

                var propValue = hashKeyProp.GetValue(parameterValue);
                if (propValue == null)
                {
                    throw new LmsException("hashKey指定的属性的值不允许为空");
                }

                hashKey = propValue.ToString();
            }

            return(hashKey);
        }
Exemplo n.º 24
0
        /// <summary>
        /// 从容器中实例化对象,并调用对应方法
        /// </summary>
        /// <param name="method"></param>
        /// <param name="implementationMethod"></param>
        /// <returns>通过容器实例化ServiceEntity实体进行实例化,并调用相应的方法</returns>
        private ServiceEntity Create(MethodInfo method, MethodBase implementationMethod)
        {
            var serviceId         = _serviceIdGenerator.GenerateServiceId(method);
            var serviceDescriptor = new ServiceDescriptor {
                Id = serviceId
            };

            return(new ServiceEntity
            {
                Descriptor = serviceDescriptor,
                Func = async parameters =>
                {
                    // 从Microsoft.Extensions.DependencyInjection获取当前范围
                    var serviceScopeFactory = _serviceProvider.GetRequiredService <IServiceScopeFactory>();

                    if (parameters.Any(p => p.Key.Equals("token")))
                    {
                        if (!_authorization.ValidateClientAuthentication(parameters.First(l => l.Key.Equals("token")).Value.ToString()))
                        {
                            return Task.FromResult("{\"error\":\"failure token\"}");
                        }
                    }

                    using (var scope = serviceScopeFactory.CreateScope())
                    {
                        var par = implementationMethod.GetParameters()
                                  .Select(parameterInfo => _typeConvertibleService.Convert(parameters[parameterInfo.Name], parameterInfo.ParameterType))
                                  .ToArray();
                        var invoke = implementationMethod.Invoke(scope.ServiceProvider.GetRequiredService(method.DeclaringType), par);
                        var fullName = invoke.GetType().FullName;
                        if (fullName != null && fullName.Contains(typeof(Task).FullName ?? throw new InvalidOperationException()))
                        {
                            return Task.FromResult(((dynamic)invoke).Result);
                        }

                        return Task.FromResult(invoke);
                    }
                }
            });
Exemplo n.º 25
0
        private async Task RemoteExecuteAsync(ServiceEntry entry, HttpMessage httpMessage, HttpResultMessage <object> resultMessage)
        {
            var provider = _concurrent.GetValueOrDefault(httpMessage.RoutePath);
            var list     = new List <object>();

            if (provider.Item1 == null)
            {
                provider.Item2 = ServiceLocator.GetService <IServiceProxyFactory>().CreateProxy(httpMessage.ServiceKey, entry.Type);
                provider.Item3 = provider.Item2.GetType().GetTypeInfo().DeclaredMethods.Where(p => p.Name == entry.MethodName).FirstOrDefault();;
                provider.Item1 = FastInvoke.GetMethodInvoker(provider.Item3);
                _concurrent.GetOrAdd(httpMessage.RoutePath, ValueTuple.Create <FastInvokeHandler, object, MethodInfo>(provider.Item1, provider.Item2, provider.Item3));
            }
            foreach (var parameterInfo in provider.Item3.GetParameters())
            {
                var value         = httpMessage.Parameters[parameterInfo.Name];
                var parameterType = parameterInfo.ParameterType;
                var parameter     = _typeConvertibleService.Convert(value, parameterType);
                list.Add(parameter);
            }
            var methodResult = provider.Item1(provider.Item2, list.ToArray());

            var task = methodResult as Task;

            if (task == null)
            {
                resultMessage.Entity    = methodResult;
                resultMessage.IsSucceed = resultMessage.Entity != null;
            }
            else
            {
                await task;
                var   taskType = task.GetType().GetTypeInfo();
                if (taskType.IsGenericType)
                {
                    resultMessage.Entity = taskType.GetProperty("Result").GetValue(task);
                }
                resultMessage.IsSucceed = resultMessage.Entity != null;
            }
        }
Exemplo n.º 26
0
        public async Task <T> Invoke <T>(IDictionary <string, object> parameters, string serviceId, string _serviceKey, bool decodeJOject)
        {
            var time   = 0;
            T   result = default(T);
            RemoteInvokeResultMessage message = null;
            var vtCommand = _commandProvider.GetCommand(serviceId);
            var command   = vtCommand.IsCompletedSuccessfully ? vtCommand.Result : await vtCommand;

            do
            {
                message = await _breakeRemoteInvokeService.InvokeAsync(parameters, serviceId, _serviceKey, decodeJOject);

                if (message != null && message.Result != null)
                {
                    if (message.StatusCode != StatusCode.Success && time >= command.FailoverCluster)
                    {
                        throw new CPlatformException(message.ExceptionMessage, message.StatusCode);
                    }
                    result = (T)_typeConvertibleService.Convert(message.Result, typeof(T));
                }
            } while ((message == null || message.StatusCode == StatusCode.ServiceUnavailability) && ++time < command.FailoverCluster);
            return(result);
        }
        // 此方法严重依赖于Microsoft.Extensions.DependencyInjection库,需要拆分
        // 通过容器实例化ServiceEntity实体
        private ServiceEntity Create(MethodInfo method, MethodBase implementationMethod)
        {
            var serviceId         = _serviceIdGenerator.GenerateServiceId(method);
            var serviceDescriptor = new ServiceDescriptor {
                Id = serviceId
            };

            return(new ServiceEntity
            {
                Descriptor = serviceDescriptor,
                Func = parameters =>
                {
                    // 从Microsoft.Extensions.DependencyInjection获取当前范围
                    var serviceScopeFactory = _serviceProvider.GetRequiredService <IServiceScopeFactory>();

                    using (var scope = serviceScopeFactory.CreateScope())
                    {
                        var instance = scope.ServiceProvider.GetRequiredService(method.DeclaringType);

                        var list = new List <object>();
                        foreach (var parameterInfo in implementationMethod.GetParameters())
                        {
                            list.Add(
                                _typeConvertibleService.Convert(
                                    parameters[parameterInfo.Name],
                                    parameterInfo.ParameterType)
                                );
                        }

                        return Task.FromResult(implementationMethod.Invoke(
                                                   instance,
                                                   list.ToArray()
                                                   ));
                    }
                }
            });
        }
Exemplo n.º 28
0
        private ServiceEntry Create(MethodInfo method, string serviceName, string routeTemplate)
        {
            var serviceId         = _serviceIdGenerator.GenerateServiceId(method);
            var attributes        = method.GetCustomAttributes().ToList();
            var serviceDescriptor = new ServiceDescriptor
            {
                Id        = serviceId,
                RoutePath = RoutePatternParser.Parse(routeTemplate, serviceName, method.Name)
            };
            var           httpMethodAttributes = attributes.Where(p => p is HttpMethodAttribute).Select(p => p as HttpMethodAttribute).ToList();
            var           httpMethods          = new List <string>();
            StringBuilder httpMethod           = new StringBuilder();

            foreach (var attribute in httpMethodAttributes)
            {
                httpMethods.AddRange(attribute.HttpMethods);
                if (attribute.IsRegisterMetadata)
                {
                    httpMethod.AppendJoin(',', attribute.HttpMethods).Append(",");
                }
            }
            if (httpMethod.Length > 0)
            {
                httpMethod.Length = httpMethod.Length - 1;
                serviceDescriptor.HttpMethod(httpMethod.ToString());
            }
            var authorization = attributes.Where(p => p is AuthorizationFilterAttribute).FirstOrDefault();

            if (authorization != null)
            {
                serviceDescriptor.EnableAuthorization(true);
            }
            if (authorization != null)
            {
                serviceDescriptor.AuthType(((authorization as AuthorizationAttribute)?.AuthType)
                                           ?? AuthorizationType.AppSecret);
            }
            else
            {
                serviceDescriptor.EnableAuthorization(true);
                serviceDescriptor.AuthType(AuthorizationType.JWT);
            }

            var descriptorAttributes = method.GetCustomAttributes <ServiceDescriptorAttribute>();

            foreach (var descriptorAttribute in descriptorAttributes)
            {
                descriptorAttribute.Apply(serviceDescriptor);
            }
            var fastInvoker = GetHandler(serviceId, method);

            return(new ServiceEntry
            {
                Descriptor = serviceDescriptor,
                RoutePath = serviceDescriptor.RoutePath,
                Methods = httpMethods,
                MethodName = method.Name,
                Type = method.DeclaringType,
                Attributes = attributes,
                Func = (key, parameters) =>
                {
                    object instance = null;
                    if (AppConfig.ServerOptions.IsModulePerLifetimeScope)
                    {
                        instance = _serviceProvider.GetInstancePerLifetimeScope(key, method.DeclaringType);
                    }
                    else
                    {
                        instance = _serviceProvider.GetInstances(key, method.DeclaringType);
                    }
                    var list = new List <object>();

                    foreach (var parameterInfo in method.GetParameters())
                    {
                        //加入是否有默认值的判断,有默认值,并且用户没传,取默认值
                        if (parameterInfo.HasDefaultValue && !parameters.ContainsKey(parameterInfo.Name))
                        {
                            list.Add(parameterInfo.DefaultValue);
                            continue;
                        }
                        var value = parameters[parameterInfo.Name];
                        var parameterType = parameterInfo.ParameterType;
                        var parameter = _typeConvertibleService.Convert(value, parameterType);
                        list.Add(parameter);
                    }
                    var result = fastInvoker(instance, list.ToArray());
                    return Task.FromResult(result);
                }
            });
        }
        private ServiceEntry Create(MethodInfo method, string serviceName, string routeTemplate)
        {
            var serviceId         = _serviceIdGenerator.GenerateServiceId(method);
            var attributes        = method.GetCustomAttributes().ToList();
            var serviceDescriptor = new ServiceDescriptor
            {
                Id        = serviceId,
                RoutePath = RoutePatternParser.Parse(routeTemplate, serviceName, method.Name)
            };

            serviceDescriptor = SetPorts(serviceDescriptor);
            serviceDescriptor.EnableAuthorization(true);
            serviceDescriptor.AuthType(AuthorizationType.JWT);

            var descriptorAttributes = method.GetCustomAttributes <ServiceDescriptorAttribute>();

            foreach (var descriptorAttribute in descriptorAttributes)
            {
                descriptorAttribute.Apply(serviceDescriptor);
            }
            //var authorization = attributes.Where(p => p is AuthorizationFilterAttribute).FirstOrDefault();
            //if (authorization != null)
            //{
            //    serviceDescriptor.EnableAuthorization(true);
            //    serviceDescriptor.AuthType(((authorization as AuthorizationAttribute)?.AuthType)
            //        ?? AuthorizationType.AppSecret);
            //}
            var fastInvoker = GetHandler(serviceId, method);

            return(new ServiceEntry
            {
                Descriptor = serviceDescriptor,
                RoutePath = serviceDescriptor.RoutePath,
                MethodName = method.Name,
                Type = method.DeclaringType,
                Attributes = attributes,
                Func = (key, parameters) =>
                {
                    var instance = _serviceProvider.GetInstances(key, method.DeclaringType);
                    var list = new List <object>();

                    foreach (var parameterInfo in method.GetParameters())
                    {
                        if (parameterInfo.HasDefaultValue && !parameters.ContainsKey(parameterInfo.Name))
                        {
                            list.Add(parameterInfo.DefaultValue);
                            continue;
                        }
                        var value = parameters[parameterInfo.Name];
                        var parameterType = parameterInfo.ParameterType;
                        var parameter = _typeConvertibleService.Convert(value, parameterType);
                        list.Add(parameter);
                    }

                    if (parameters.ContainsKey("payload"))
                    {
                        if (RpcContext.GetContext().GetAttachment("payload") == null)
                        {
                            var serializer = ServiceLocator.GetService <ISerializer <string> >();
                            var payloadString = serializer.Serialize(parameters["payload"], true);
                            RpcContext.GetContext().SetAttachment("payload", payloadString);
                        }
                    }

                    var result = fastInvoker(instance, list.ToArray());
                    return Task.FromResult(result);
                }
            });
        }
        private ServiceEntry Create(MethodInfo method, string serviceName, string routeTemplate, bool routeIsReWriteByServiceRoute = false)
        {
            var serviceId         = _serviceIdGenerator.GenerateServiceId(method);
            var attributes        = method.GetCustomAttributes().ToList();
            var serviceDescriptor = new ServiceDescriptor
            {
                Id        = serviceId,
                RoutePath = RoutePatternParser.Parse(routeTemplate, serviceName, method.Name, routeIsReWriteByServiceRoute)
            };
            var httpMethodAttributes = attributes.Where(p => p is HttpMethodAttribute).Select(p => p as HttpMethodAttribute).ToList();
            var httpMethods          = new List <string>();

            foreach (var httpAttribute in httpMethodAttributes)
            {
                httpMethods.AddRange(httpAttribute.HttpMethods);
            }
            if (!httpMethods.Any())
            {
                var paramTypes = GetParamTypes(method);
                if (paramTypes.All(p => p.Value.IsValueType || p.Value == typeof(string) || p.Value.IsEnum))
                {
                    httpMethods.Add(HttpMethod.GET.ToString());
                }
                else
                {
                    httpMethods.Add(HttpMethod.POST.ToString());
                }
            }
            serviceDescriptor.HttpMethod(httpMethods);
            var authorization = attributes.Where(p => p is AuthorizationFilterAttribute).FirstOrDefault();

            if (authorization != null)
            {
                serviceDescriptor.EnableAuthorization(true);
            }
            if (authorization != null)
            {
                serviceDescriptor.AuthType(((authorization as AuthorizationAttribute)?.AuthType)
                                           ?? AuthorizationType.AppSecret);
            }
            else
            {
                serviceDescriptor.EnableAuthorization(true);
                serviceDescriptor.AuthType(AuthorizationType.JWT);
            }

            var descriptorAttributes = method.GetCustomAttributes <ServiceDescriptorAttribute>();

            foreach (var descriptorAttribute in descriptorAttributes)
            {
                descriptorAttribute.Apply(serviceDescriptor);
            }
            var fastInvoker = GetHandler(serviceId, method);

            return(new ServiceEntry
            {
                Descriptor = serviceDescriptor,
                RoutePath = serviceDescriptor.RoutePath,
                Methods = httpMethods,
                MethodName = method.Name,
                Type = method.DeclaringType,
                Attributes = attributes,
                ParamTypes = GetParamTypes(method),
                CacheKeys = GetCackeKeys(method),
                Func = (key, parameters) =>
                {
                    object instance = null;
                    if (AppConfig.ServerOptions.IsModulePerLifetimeScope)
                    {
                        instance = _serviceProvider.GetInstancePerLifetimeScope(key, method.DeclaringType);
                    }
                    else
                    {
                        instance = _serviceProvider.GetInstances(key, method.DeclaringType);
                    }
                    var list = new List <object>();

                    foreach (var parameterInfo in method.GetParameters())
                    {
                        if (parameters.ContainsKey(parameterInfo.Name))
                        {
                            var value = parameters[parameterInfo.Name];
                            var parameterType = parameterInfo.ParameterType;
                            var parameter = _typeConvertibleService.Convert(value, parameterType);
                            list.Add(parameter);
                        }
                        //加入是否有默认值的判断,有默认值,并且用户没传,取默认值
                        else if (parameterInfo.HasDefaultValue && !parameters.ContainsKey(parameterInfo.Name))
                        {
                            list.Add(parameterInfo.DefaultValue);
                        }
                        else
                        {
                            list.Add(null);
                        }
                    }
                    var result = fastInvoker(instance, list.ToArray());
                    return Task.FromResult(result);
                }
            });
        }