コード例 #1
0
ファイル: ServiceProxyBase.cs プロジェクト: shanyipeng/KissU
        /// <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);
        }
コード例 #2
0
        /// <summary>
        /// 解析服务地址。
        /// </summary>
        /// <param name="serviceId">服务Id。</param>
        /// <returns>服务地址模型。</returns>
        /// 1.从字典中拿到serviceroute对象
        /// 2.从字典中拿到服务描述符集合
        /// 3.获取或添加serviceroute
        /// 4.添加服务id到白名单
        /// 5.根据服务描述符得到地址并判断地址是否是可用的(地址应该是多个)
        /// 6.添加到集合中
        /// 7.拿到服务命今
        /// 8.根据负载分流策略拿到一个选择器
        /// 9.返回addressmodel
        public async ValueTask <AddressModel> Resolver(string serviceId, string item)
        {
            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug($"准备为服务id:{serviceId},解析可用地址。");
            }

            var serviceRouteTask = _serviceRouteProvider.Locate(serviceId);
            var serviceRoute     = serviceRouteTask.IsCompletedSuccessfully ? serviceRouteTask.Result : await serviceRouteTask;

            if (serviceRoute == null)
            {
                if (_logger.IsEnabled(LogLevel.Warning))
                {
                    _logger.LogWarning($"根据服务id:{serviceId},找不到相关服务信息。");
                }
                return(null);
            }
            _serviceHeartbeatManager.AddWhitelist(serviceId);
            var address = new List <AddressModel>();

            foreach (var addressModel in serviceRoute.Address)
            {
                _healthCheckService.Monitor(addressModel);
                var task = _healthCheckService.IsHealth(addressModel);
                if (!(task.IsCompletedSuccessfully ? task.Result : await task))
                {
                    continue;
                }
                address.Add(addressModel);
            }

            if (address.Count == 0)
            {
                if (_logger.IsEnabled(LogLevel.Warning))
                {
                    _logger.LogWarning($"根据服务id:{serviceId},找不到可用的地址。");
                }
                return(null);
            }

            if (_logger.IsEnabled(LogLevel.Information))
            {
                _logger.LogInformation($"根据服务id:{serviceId},找到以下可用地址:{string.Join(",", address.Select(i => i.ToString()))}。");
            }
            var vtCommand       = _commandProvider.GetCommand(serviceId);
            var command         = vtCommand.IsCompletedSuccessfully ? vtCommand.Result : await vtCommand;
            var addressSelector = _addressSelectors[command.ShuntStrategy.ToString()];

            var vt = addressSelector.SelectAsync(new AddressSelectContext
            {
                Descriptor = serviceRoute.ServiceDescriptor,
                Address    = address,
                Item       = item
            });

            return(vt.IsCompletedSuccessfully ? vt.Result : await vt);
        }
コード例 #3
0
        public async Task Intercept(IInvocation invocation)
        {
            var route = await _serviceRouteProvider.Locate(invocation.ServiceId);

            var cacheMetadata = route.ServiceDescriptor.GetIntercept("Log");

            if (cacheMetadata != null)
            {
                var watch = Stopwatch.StartNew();
                await invocation.Proceed();

                var result = invocation.ReturnValue;
            }
        }
コード例 #4
0
        public async Task Intercept(IInvocation invocation)
        {
            var route = await _serviceRouteProvider.Locate(invocation.ServiceId);

            var cacheMetadata = route.ServiceDescriptor.GetCacheIntercept("Cache");

            if (cacheMetadata != null)
            {
                var keyValues = _interceptorProvider.GetCacheKeyVaule(invocation.Arguments);
                var cacheKey  = keyValues == null ? cacheMetadata.Key :
                                string.Format(cacheMetadata.Key ?? "", keyValues);
                var l2CacheKey = keyValues == null ? cacheMetadata.L2Key :
                                 string.Format(cacheMetadata.L2Key ?? "", keyValues);
                await CacheIntercept(cacheMetadata, cacheKey, keyValues, invocation, l2CacheKey, cacheMetadata.EnableL2Cache);
            }
        }
コード例 #5
0
ファイル: PermissionDomainService.cs プロジェクト: ligg/hero
        public async Task <bool> Check(long userId, string serviceId)
        {
            var servcieRoute = await _serviceRouteProvider.Locate(serviceId);

            if (servcieRoute.ServiceDescriptor.GetMetadata <bool>("AllowPermission"))
            {
                return(true);
            }

            var checkPermissionResult = await _userDomainService.CheckPermission(userId, serviceId) || await _userGroupDomainService.CheckPermission(userId, serviceId);

            if (!checkPermissionResult)
            {
                var actionName = servcieRoute.ServiceDescriptor.GroupName().IsNullOrEmpty() ? servcieRoute.ServiceDescriptor.RoutePath : servcieRoute.ServiceDescriptor.GroupName();
                throw new AuthException($"您没有访问{actionName}的权限");
            }
            return(true);
        }
コード例 #6
0
        public async Task <IDictionary <string, object> > Check(long userId, string serviceId)
        {
            var permissionResult = new Dictionary <string, object>();
            var servcieRoute     = await _serviceRouteProvider.Locate(serviceId);

            var isPermission = false;

            if (servcieRoute.ServiceDescriptor.GetMetadata <bool>("AllowPermission"))
            {
                isPermission = true;
            }
            var actionName = servcieRoute.ServiceDescriptor.GroupName().IsNullOrEmpty()
                ? servcieRoute.ServiceDescriptor.RoutePath
                : servcieRoute.ServiceDescriptor.GroupName();

            if (!isPermission)
            {
                isPermission = await _userDomainService.CheckPermission(userId, serviceId);

                if (!isPermission)
                {
                    throw new AuthException($"您没有{actionName}的权限", StatusCode.UnAuthorized);
                }
            }
            permissionResult.Add("isPermission", isPermission);
            var operations = await _operationDomainService.GetOperationsByServiceId(serviceId);

            if (operations.Any())
            {
                var dataPermission = await _userDomainService.GetDataPermissions(userId, operations.First().PermissionId);

                permissionResult.Add(ClaimTypes.DataPermission, dataPermission.DataPermissionType);
                permissionResult.Add(ClaimTypes.DataPermissionOrgIds, dataPermission.DataPermissionOrgIds);
                permissionResult.Add(ClaimTypes.IsAllOrg, dataPermission.DataPermissionType == DataPermissionType.AllOrg);
            }
            else
            {
                permissionResult.Add(ClaimTypes.DataPermission, DataPermissionType.AllOrg);
                permissionResult.Add(ClaimTypes.IsAllOrg, true);
            }

            return(permissionResult);
        }
コード例 #7
0
        private async Task OnAuthorization(ServiceEntry entry, RemoteInvokeMessage remoteInvokeMessage,
                                           RemoteInvokeResultMessage resultMessage, CancellationTokenSource cancelTokenSource)
        {
            if (entry.Descriptor.EnableAuthorization() && entry.Descriptor.AuthType() == AuthorizationType.AppSecret.ToString())
            {
                var route = await _serviceRouteProvider.Locate(entry.Descriptor.Id);

                var routeContext = new ServiceRouteContext()
                {
                    Route         = route,
                    InvokeMessage = remoteInvokeMessage,
                    ResultMessage = resultMessage,
                };
                _authorizationFilter.ExecuteAuthorizationFilterAsync(routeContext, cancelTokenSource.Token);
                if (!string.IsNullOrEmpty(resultMessage.ExceptionMessage))
                {
                    cancelTokenSource.Cancel();
                }
            }
        }
コード例 #8
0
        /// <summary>
        /// 解析服务地址。
        /// </summary>
        /// <param name="serviceId">服务Id。</param>
        /// <returns>服务地址模型。</returns>
        /// 1.从字典中拿到serviceroute对象
        /// 2.从字典中拿到服务描述符集合
        /// 3.获取或添加serviceroute
        /// 4.添加服务id到白名单
        /// 5.根据服务描述符得到地址并判断地址是否是可用的(地址应该是多个)
        /// 6.添加到集合中
        /// 7.拿到服务命今
        /// 8.根据负载分流策略拿到一个选择器
        /// 9.返回addressmodel
        public async Task <AddressModel> Resolver(string serviceId, string item)
        {
            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug($"准备为服务id:{serviceId},解析可用地址。");
            }

            var isFailoverInvoke = IsFailoverInvoke();
            var serviceRoute     = await _serviceRouteProvider.Locate(serviceId, !isFailoverInvoke);

            if (serviceRoute == null)
            {
                throw new CPlatformException($"根据服务id:{serviceId},找不到相关服务信息。【fromCache:{!isFailoverInvoke}】");
            }
            var address = await GetHealthAddress(serviceRoute);

            if (!address.Any())
            {
                throw new CPlatformException($"根据服务id:{serviceId},找不到可用的服务提供者的地址");
            }

            _serviceHeartbeatManager.AddWhitelist(serviceId);

            var command = await _commandProvider.GetCommand(serviceId);

            var addressSelector = _addressSelectors[command.ShuntStrategy.ToString()];

            var selectAddress = await addressSelector.SelectAsync(new AddressSelectContext
            {
                Descriptor = serviceRoute.ServiceDescriptor,
                Address    = address,
                Item       = item
            });

            return(selectAddress);
        }
コード例 #9
0
        public override async Task Intercept(ICacheInvocation invocation)
        {
            try 
            {
                var attribute =
                      invocation.Attributes.Where(p => p is InterceptMethodAttribute)
                      .Select(p => p as InterceptMethodAttribute).FirstOrDefault();
                if (attribute != null)
                {
                    if (!attribute.Key.IsNullOrEmpty() && attribute.Key.Contains("{userId}", StringComparison.OrdinalIgnoreCase))
                    {
                        var loginUser = NullSurgingSession.Instance;
                        if (loginUser == null || !loginUser.UserId.HasValue)
                        {
                            await invocation.Proceed();
                            return;
                        }
                        else
                        {
                            attribute.Key = attribute.Key.Replace("{userId}", loginUser.UserId.Value.ToString());
                        }
                    }
                    if (attribute.CorrespondingKeys != null && attribute.CorrespondingKeys.Any(p => p.Contains("{userId}", StringComparison.OrdinalIgnoreCase)))
                    {
                        var loginUser = NullSurgingSession.Instance;

                        for (var i = 0; i < attribute.CorrespondingKeys.Length; i++)
                        {
                            if (loginUser == null || !loginUser.UserId.HasValue)
                            {
                                attribute.CorrespondingKeys[i] = attribute.CorrespondingKeys[i].Replace("{userId}", "*", StringComparison.OrdinalIgnoreCase);
                            }
                            else
                            {
                                attribute.CorrespondingKeys[i] = attribute.CorrespondingKeys[i].Replace("{userId}", loginUser.UserId.Value.ToString(), StringComparison.OrdinalIgnoreCase);
                            }
                        }
                    }
                    var cacheKey = invocation.CacheKey == null ? attribute.Key :
                          string.Format(attribute.Key ?? "", invocation.CacheKey);
                    var l2CacheKey = invocation.CacheKey == null ? attribute.L2Key :
                          string.Format(attribute.L2Key ?? "", invocation.CacheKey);

                    await CacheIntercept(attribute, cacheKey, invocation, l2CacheKey, attribute.EnableL2Cache);
                }
                else
                {
                    var route = await _serviceRouteProvider.Locate(invocation.ServiceId);
                    var cacheMetadata = route.ServiceDescriptor.GetCacheIntercept("Cache");
                    if (cacheMetadata != null)
                    {
                        var keyValues = _interceptorProvider.GetCacheKeyVaule(invocation.Arguments);
                        if (!cacheMetadata.Key.IsNullOrEmpty() && cacheMetadata.Key.Contains("{userId}", StringComparison.OrdinalIgnoreCase))
                        {
                            var loginUser = NullSurgingSession.Instance;
                            if (loginUser == null || !loginUser.UserId.HasValue)
                            {
                                await invocation.Proceed();
                                return;
                            }
                            else
                            {
                                cacheMetadata.Key = cacheMetadata.Key.Replace("{userId}", loginUser.UserId.Value.ToString());
                            }
                        }
                        if (cacheMetadata.CorrespondingKeys != null && cacheMetadata.CorrespondingKeys.Any(p => p.Contains("{userId}", StringComparison.OrdinalIgnoreCase)))
                        {
                            var loginUser = NullSurgingSession.Instance;

                            for (var i = 0; i < cacheMetadata.CorrespondingKeys.Length; i++)
                            {
                                if (loginUser == null || !loginUser.UserId.HasValue)
                                {
                                    cacheMetadata.CorrespondingKeys[i] = cacheMetadata.CorrespondingKeys[i].Replace("{userId}", "*", StringComparison.OrdinalIgnoreCase);
                                }
                                else
                                {
                                    cacheMetadata.CorrespondingKeys[i] = cacheMetadata.CorrespondingKeys[i].Replace("{userId}", loginUser.UserId.Value.ToString(), StringComparison.OrdinalIgnoreCase);
                                }
                            }
                        }
                        var cacheKey = keyValues == null ? cacheMetadata.Key :
                            string.Format(cacheMetadata.Key ?? "", keyValues);
                        var l2CacheKey = keyValues == null ? cacheMetadata.L2Key :
                             string.Format(cacheMetadata.L2Key ?? "", keyValues);
                        await CacheIntercept(cacheMetadata, cacheKey, invocation, l2CacheKey, cacheMetadata.EnableL2Cache);
                    }
                    else 
                    {
                        await invocation.Proceed();
                    }
                }
            } catch (Exception ex) 
            {
                var logger = ServiceLocator.GetService<ILogger<CacheProviderInterceptor>>();
                logger.LogWarning($"使用缓存拦截失败,原因:{ex.Message}");
                await invocation.Proceed();
            }
            
        }