Beispiel #1
0
 public Task <JimuRemoteCallResultData> InvokeAsync(RemoteCallerContext context)
 {
     if (_options != null && context.Service.ServiceDescriptor.EnableAuthorization)
     {
         var hasRight = false;
         var empid    = 0;
         if (context.PayLoad != null && context.PayLoad.Items != null && context.PayLoad.Items.Count > 0)
         {
             empid = Convert.ToInt32(context.PayLoad.Items["userid"]);
         }
         var url = context.Service.ServiceDescriptor.RoutePath;
         //                using (var cnn = new MySqlConnection(_options.ConnectionString))
         //                {
         //                    cnn.Open();
         //                    var sql = $@"
         //select count(0)
         //from {DbNameHelper.Instance.SystemDb}.SysRoleMenuPoint rmp
         //join {DbNameHelper.Instance.SystemDb}.SysErpPostRole epr on epr.RoleId = rmp.RoleId
         //join {DbNameHelper.Instance.SystemDb}.SysMenuPoint mp on mp.Code = rmp.PointCode and mp.MenuCode = rmp.MenuCode and mp.Url = @url
         //join {DbNameHelper.Instance.ErpDb}.bas_emp emp on emp.empid = @empid and emp.postid = epr.PostId
         //";
         //                    hasRight = cnn.QueryFirst<int>(sql, new { empid, url }) > 0;
         //                }
         if (!hasRight)
         {
             var result = new JimuRemoteCallResultData
             {
                 ErrorMsg  = "Unauthorized",
                 ErrorCode = "401"
             };
             return(Task.FromResult(result));
         }
     }
     return(_next(context));
 }
Beispiel #2
0
        private async Task OnReceived(IChannelHandlerContext channel, JimuTransportMsg message)
        {
            _logger.Debug($"begin handling msg: {message.Id}");
            //TaskCompletionSource<TransportMessage> task;
            if (message.ContentType == typeof(JimuRemoteCallData).FullName)
            {
                IResponse response    = new DotNettyResponse(channel, _logger);
                var       thisContext = new ServiceInvokerContext(message, _serviceEntryContainer, response, _logger, _serviceInvokeAddress);
                Guid      operationId = Guid.Empty;

                var lastInvoke = new RequestDel(async context =>
                {
                    JimuRemoteCallResultData resultMessage = new JimuRemoteCallResultData();
                    if (context.ServiceEntry == null)
                    {
                        resultMessage.ExceptionMessage = $"can not find service {context.RemoteInvokeMessage.ServiceId}";
                        _jimuApm.WriteServiceInvokeAfter(operationId, thisContext, resultMessage);
                        await response.WriteAsync(message.Id, resultMessage);
                    }
                    else if (context.ServiceEntry.Descriptor.WaitExecution)
                    {
                        await LocalServiceExecuteAsync(context.ServiceEntry, context.RemoteInvokeMessage, resultMessage);
                        _jimuApm.WriteServiceInvokeAfter(operationId, thisContext, resultMessage);
                        await response.WriteAsync(message.Id, resultMessage);
                    }
                    else
                    {
                        await response.WriteAsync(message.Id, resultMessage);
                        await Task.Factory.StartNew(async() =>
                        {
                            await LocalServiceExecuteAsync(context.ServiceEntry, context.RemoteInvokeMessage, resultMessage);
                            _jimuApm.WriteServiceInvokeAfter(operationId, thisContext, resultMessage);
                        });
                    }
                });

                foreach (var middleware in _middlewares)
                {
                    lastInvoke = middleware(lastInvoke);
                }
                try
                {
                    _jimuApm.WriteServiceInvokeBefore(thisContext);
                    await lastInvoke(thisContext);
                }
                catch (Exception ex)
                {
                    JimuRemoteCallResultData resultMessage = new JimuRemoteCallResultData();
                    resultMessage.ErrorCode        = "500";
                    resultMessage.ExceptionMessage = ex.ToStackTraceString();
                    _logger.Error("throw exception when excuting local service: \r\n " + JimuHelper.Serialize <string>(message), ex);
                    await response.WriteAsync(message.Id, resultMessage);
                }
            }
            else
            {
                _logger.Debug($"msg: {message.Id}, message type is not an  JimuRemoteCallData.");
            }
        }
Beispiel #3
0
        public Task WriteAsync(string messageId, JimuRemoteCallResultData resultMessage)
        {
            _logger.Debug($"finish handling msg: {messageId}");
            var data = _serializer.Serialize <string>(new JimuTransportMsg(messageId, resultMessage));

            //_httpResponse.
            return(_httpResponse.WriteAsync(data));
        }
        Task InvokeService(RemoteCallerContext context)
        {
            try
            {
                var pureToken = context.RemoteInvokeMessage.Token;
                if (pureToken != null && pureToken.Trim().StartsWith("Bearer "))
                {
                    pureToken = pureToken.Trim().Substring(6).Trim();
                }
                var payload    = JWT.Decode(pureToken, Encoding.ASCII.GetBytes(_options.SecretKey), JwsAlgorithm.HS256);
                var payloadObj = JimuHelper.Deserialize(payload, typeof(IDictionary <string, object>)) as IDictionary <string, object>;
                if (_options.ValidateLifetime)
                {
                    //var exp = payloadObj["exp"];
                    if (payloadObj == null || ((Int64)payloadObj["exp"]).ToDate() < DateTime.Now)
                    {
                        var result = new JimuRemoteCallResultData
                        {
                            ErrorMsg  = "Token is Expired",
                            ErrorCode = "401"
                        };
                        return(context.Response.WriteAsync(context.TransportMessage.Id, result));
                    }
                }
                var serviceRoles = context.ServiceEntry.Descriptor.Roles;
                if (!string.IsNullOrEmpty(serviceRoles))
                {
                    var serviceRoleArr = serviceRoles.Split(',');
                    var roles          = payloadObj != null && payloadObj.ContainsKey("roles") ? payloadObj["roles"] + "" : "";
                    var authorize      = roles.Split(',').Any(role => serviceRoleArr.Any(x => x.Equals(role, StringComparison.InvariantCultureIgnoreCase)));
                    if (!authorize)
                    {
                        var result = new JimuRemoteCallResultData
                        {
                            ErrorMsg  = "Unauthorized",
                            ErrorCode = "401"
                        };
                        return(context.Response.WriteAsync(context.TransportMessage.Id, result));
                    }
                }
                context.RemoteInvokeMessage.Payload = new JimuPayload {
                    Items = payloadObj
                };
            }
            catch (Exception ex)
            {
                var result = new JimuRemoteCallResultData
                {
                    ErrorMsg  = $"Token is incorrect, exception is { ex.Message}",
                    ErrorCode = "401"
                };
                return(context.Response.WriteAsync(context.TransportMessage.Id, result));
            }

            return(_next(context));
        }
Beispiel #5
0
        public async Task <JimuRemoteCallResultData> InvokeAsync(JimuServiceRoute service, IDictionary <string, object> paras,
                                                                 string token)
        {
            if (paras == null)
            {
                paras = new ConcurrentDictionary <string, object>();
            }
            var address = await _addressSelector.GetAddressAsyn(service);

            if (_retryTimes < 0)
            {
                _retryTimes = service.Address.Count;
            }
            JimuRemoteCallResultData result = null;
            var retryPolicy = Policy.Handle <TransportException>()
                              .RetryAsync(_retryTimes,
                                          async(ex, count) =>
            {
                address = await _addressSelector.GetAddressAsyn(service);
                _logger.Debug(
                    $"FaultHandling,retry times: {count},serviceId: {service.ServiceDescriptor.Id},Address: {address.Code},RemoteServiceCaller excute retry by Polly for exception {ex.Message}");
            });
            var fallbackPolicy = Policy <JimuRemoteCallResultData> .Handle <TransportException>()
                                 .FallbackAsync(new JimuRemoteCallResultData()
            {
                ErrorCode = "500", ErrorMsg = "error occur when communicate with server. server maybe have been down."
            })
                                 .WrapAsync(retryPolicy);

            return(await fallbackPolicy.ExecuteAsync(async() =>
            {
                var client = _transportClientFactory.CreateClient(address);
                if (client == null)
                {
                    return new JimuRemoteCallResultData
                    {
                        ErrorCode = "400",
                        ErrorMsg = "Server unavailable!"
                    }
                }
                ;
                _logger.Debug($"invoke: serviceId:{service.ServiceDescriptor.Id}, parameters count: {paras.Count()}, token:{token}");
                //Polly.Policy.Handle<>()

                result = await client.SendAsync(new JimuRemoteCallData
                {
                    Parameters = paras,
                    ServiceId = service.ServiceDescriptor.Id,
                    Token = token,
                    Descriptor = service.ServiceDescriptor
                });
                return result;
            }));
        }
Beispiel #6
0
 public async Task WriteAsync(string messageId, JimuRemoteCallResultData resultMessage)
 {
     try
     {
         _logger.Debug($"finish handling msg: {messageId}");
         var data   = _serializer.Serialize <byte[]>(new JimuTransportMsg(messageId, resultMessage));
         var buffer = Unpooled.Buffer(data.Length, data.Length);
         buffer.WriteBytes(data);
         await _channel.WriteAndFlushAsync(buffer);
     }
     catch (Exception ex)
     {
         _logger.Error("throw exception when response msg: " + messageId, ex);
     }
 }
Beispiel #7
0
        public async Task Invoke(HttpContext context)
        {
            using (var sr = new StreamReader(context.Request.Body))
            {
                var body = sr.ReadToEnd();
                _logger.Debug($"received msg is: {body}");
                _message = (JimuTransportMsg)_typeConvert.Convert(body, typeof(JimuTransportMsg));
            }

            _logger.Debug($"begin handling msg: {_message.Id}");
            IResponse response    = new HttpResponse(context.Response, _serializer, _logger);
            var       thisContext = new RemoteCallerContext(_message, _serviceEntryContainer, response, _logger);
            var       lastInvoke  = new RequestDel(async ctx =>
            {
                JimuRemoteCallResultData resultMessage = new JimuRemoteCallResultData();

                if (ctx.ServiceEntry == null)
                {
                    resultMessage.ExceptionMessage = $"can not find service {ctx.RemoteInvokeMessage.ServiceId}";
                    await response.WriteAsync(_message.Id, resultMessage);
                }
                else if (ctx.ServiceEntry.Descriptor.WaitExecution)
                {
                    await LocalServiceExecuteAsync(ctx.ServiceEntry, ctx.RemoteInvokeMessage, resultMessage);
                    await response.WriteAsync(_message.Id, resultMessage);
                }
                else
                {
                    await response.WriteAsync(_message.Id, resultMessage);
                    await Task.Factory.StartNew(async() =>
                    {
                        await LocalServiceExecuteAsync(ctx.ServiceEntry, ctx.RemoteInvokeMessage, resultMessage);
                    });
                }
            });


            foreach (var middleware in _middlewares)
            {
                lastInvoke = middleware(lastInvoke);
            }

            await lastInvoke(thisContext);

            //await _next(context);
        }
Beispiel #8
0
        private async Task OnReceived(IChannelHandlerContext channel, JimuTransportMsg message)
        {
            _logger.Debug($"begin handling msg: {message.Id}");
            //TaskCompletionSource<TransportMessage> task;
            if (message.ContentType == typeof(JimuRemoteCallData).FullName)
            {
                IResponse response    = new DotNettyResponse(channel, _serializer, _logger);
                var       thisContext = new RemoteCallerContext(message, _serviceEntryContainer, response, _logger);

                var lastInvoke = new RequestDel(async context =>
                {
                    JimuRemoteCallResultData resultMessage = new JimuRemoteCallResultData();
                    if (context.ServiceEntry == null)
                    {
                        resultMessage.ExceptionMessage = $"can not find service {context.RemoteInvokeMessage.ServiceId}";
                        await response.WriteAsync(message.Id, resultMessage);
                    }
                    else if (context.ServiceEntry.Descriptor.WaitExecution)
                    {
                        await LocalServiceExecuteAsync(context.ServiceEntry, context.RemoteInvokeMessage, resultMessage);
                        await response.WriteAsync(message.Id, resultMessage);
                    }
                    else
                    {
                        await response.WriteAsync(message.Id, resultMessage);
                        await Task.Factory.StartNew(async() =>
                        {
                            await LocalServiceExecuteAsync(context.ServiceEntry, context.RemoteInvokeMessage, resultMessage);
                        });
                    }
                });

                foreach (var middleware in _middlewares)
                {
                    lastInvoke = middleware(lastInvoke);
                }
                await lastInvoke(thisContext);
            }
            else
            {
                _logger.Debug($"msg: {message.Id}, message type is not an  JimuRemoteCallData.");
            }
        }
Beispiel #9
0
        public async Task WriteAsync(string messageId, JimuRemoteCallResultData resultMessage)
        {
            try
            {
                _logger.Debug($"finish handling msg: {messageId}");
                var data = JimuHelper.Serialize <byte[]>(new JimuTransportMsg(messageId, resultMessage));
                if (data.Length < 102400)
                {
                    _logger.Debug($"resp msg is: {Encoding.UTF8.GetString(data)}");
                }
                else
                {
                    _logger.Debug($"resp msg is (bigger than 100k, we don't show it)");
                }

                var buffer = Unpooled.Buffer(data.Length, data.Length);
                buffer.WriteBytes(data);
                await _channel.WriteAndFlushAsync(buffer);
            }
            catch (Exception ex)
            {
                _logger.Error("throw exception when response msg: " + messageId, ex);
            }
        }
Beispiel #10
0
        public Task Invoke(RemoteCallerContext context)
        {
            // get jwt token
            if (!string.IsNullOrEmpty(_options.TokenEndpointPath) &&
                context.ServiceEntry == null &&
                context.RemoteInvokeMessage.ServiceId == _options.GetServiceId())
            {
                if (_options.CheckCredential == null)
                {
                    throw new Exception("JwtAuthorizationOptions.CheckCredential must be provided");
                }
                JwtAuthorizationContext jwtAuthorizationContext = new JwtAuthorizationContext(_options, context.RemoteInvokeMessage);

                _options.CheckCredential(jwtAuthorizationContext);
                if (jwtAuthorizationContext.IsRejected)
                {
                    return(context.Response.WriteAsync(context.TransportMessage.Id, new JimuRemoteCallResultData
                    {
                        ErrorMsg = $"{jwtAuthorizationContext.Error}, {jwtAuthorizationContext.ErrorDescription}",
                        ErrorCode = "400"
                    }));
                }

                var payload = jwtAuthorizationContext.GetPayload();
                var token   = JWT.Encode(payload, Encoding.ASCII.GetBytes(_options.SecretKey), JwsAlgorithm.HS256);

                var result = new ExpandoObject() as IDictionary <string, object>;
                result["access_token"] = token;
                if (_options.ValidateLifetime)
                {
                    result["expired_in"] = payload["exp"];
                }

                return(context.Response.WriteAsync(context.TransportMessage.Id, new JimuRemoteCallResultData
                {
                    Result = result
                }));
            }
            // jwt authentication, alse authentication the role

            if (context.ServiceEntry != null && context.ServiceEntry.Descriptor.EnableAuthorization)
            {
                try
                {
                    var payload = JWT.Decode(context.RemoteInvokeMessage.Token, Encoding.ASCII.GetBytes(
                                                 _options.SecretKey));
                    var payloadObj = _serializer.Deserialize(payload, typeof(IDictionary <string, object>)) as IDictionary <string, object>;
                    if (_options.ValidateLifetime)
                    {
                        //var exp = payloadObj["exp"];
                        if (payloadObj == null || ((Int64)payloadObj["exp"]).ToDate() < DateTime.Now)
                        {
                            var result = new JimuRemoteCallResultData
                            {
                                ErrorMsg  = "Token is Expired",
                                ErrorCode = "401"
                            };
                            return(context.Response.WriteAsync(context.TransportMessage.Id, result));
                        }
                    }
                    var serviceRoles = context.ServiceEntry.Descriptor.Roles;
                    if (!string.IsNullOrEmpty(serviceRoles))
                    {
                        var serviceRoleArr = serviceRoles.Split(',');
                        var roles          = payloadObj != null && payloadObj.ContainsKey("roles") ? payloadObj["roles"] + "" : "";
                        var authorize      = roles.Split(',').Any(role => serviceRoleArr.Any(x => x.Equals(role, StringComparison.InvariantCultureIgnoreCase)));
                        if (!authorize)
                        {
                            var result = new JimuRemoteCallResultData
                            {
                                ErrorMsg  = "Unauthorized",
                                ErrorCode = "401"
                            };
                            return(context.Response.WriteAsync(context.TransportMessage.Id, result));
                        }
                    }
                    context.RemoteInvokeMessage.Payload = new JimuPayload {
                        Items = payloadObj
                    };
                }
                catch (Exception ex)
                {
                    var result = new JimuRemoteCallResultData
                    {
                        ErrorMsg  = $"Token is incorrect, exception is { ex.Message}",
                        ErrorCode = "401"
                    };
                    return(context.Response.WriteAsync(context.TransportMessage.Id, result));
                }
                return(_next(context));
            }
            // service can be annoymouse request

            return(_next(context));
        }
Beispiel #11
0
        private async Task LocalServiceExecuteAsync(JimuServiceEntry serviceEntry, JimuRemoteCallData invokeMessage, JimuRemoteCallResultData resultMessage)
        {
            try
            {
                var cancelTokenSource = new CancellationTokenSource();
                //wait OnAuthorization(serviceEntry, cancelTokenSource ,,,,)
                if (!cancelTokenSource.IsCancellationRequested)
                {
                    var result = await serviceEntry.Func(invokeMessage.Parameters, invokeMessage.Payload);

                    var task = result as Task;
                    if (task == null)
                    {
                        resultMessage.Result = result;
                    }
                    else
                    {
                        task.Wait(cancelTokenSource.Token);
                        var taskType = task.GetType().GetTypeInfo();
                        if (taskType.IsGenericType)
                        {
                            resultMessage.Result = taskType.GetProperty("Result")?.GetValue(task);
                        }
                    }
                    resultMessage.ResultType = serviceEntry.Descriptor.ReturnDesc;
                }
            }
            catch (Exception ex)
            {
                _logger.Error("throw exception when excuting local service: " + serviceEntry.Descriptor.Id, ex);
                resultMessage.ExceptionMessage = ex.ToStackTraceString();
            }
        }
Beispiel #12
0
 public static void WriteRPCExecuteAfter(this IJimuDiagnostic @this, Guid operationId, RemoteCallerContext context, JimuRemoteCallResultData resultData
                                         , [CallerMemberName] string operation = ""
                                         )
 {
     if (@this.IsEnabled(DiagnosticClientEventType.RpcExecuteAfter))
     {
         @this.Write(DiagnosticClientEventType.RpcExecuteAfter, new RPCExecuteAfterEventData(operationId, operation)
         {
             Data       = context,
             ResultData = resultData
         });
     }
 }
        public Task <JimuRemoteCallResultData> InvokeAsync(RemoteCallerContext context)
        {
            // get jwt token
            if (!string.IsNullOrEmpty(_options.TokenEndpointPath) &&
                context.Service.ServiceDescriptor.Id == _options.GetServiceId())
            {
                if (_options.CheckCredential == null)
                {
                    throw new Exception("JwtAuthorizationOptions.CheckCredential must be provided");
                }
                JwtAuthorizationContext jwtAuthorizationContext = new JwtAuthorizationContext(_options, context);

                _options.CheckCredential(jwtAuthorizationContext);
                if (jwtAuthorizationContext.IsRejected)
                {
                    return(Task.FromResult(new JimuRemoteCallResultData()
                    {
                        ErrorMsg = $"{jwtAuthorizationContext.Error}, {jwtAuthorizationContext.ErrorDescription}",
                        ErrorCode = "400"
                    }));
                }

                var payload = jwtAuthorizationContext.GetPayload();
                var token   = JWT.Encode(payload, Encoding.ASCII.GetBytes(_options.SecretKey), JwsAlgorithm.HS256);

                var result = new ExpandoObject() as IDictionary <string, object>;
                result["access_token"] = token;
                if (_options.ValidateLifetime)
                {
                    result["expired_in"] = payload["exp"];
                }

                return(Task.FromResult(new JimuRemoteCallResultData()
                {
                    Result = result
                }));
            }
            // jwt authentication, alse authentication the role

            if (context.Service != null && !context.Service.ServiceDescriptor.AllowAnonymous)
            {
                try
                {
                    var pureToken = context.Token;
                    if (pureToken != null && pureToken.Trim().StartsWith("Bearer "))
                    {
                        pureToken = pureToken.Trim().Substring(6).Trim();
                    }
                    var payload    = JWT.Decode(pureToken, Encoding.ASCII.GetBytes(_options.SecretKey), JwsAlgorithm.HS256);
                    var payloadObj = JimuHelper.Deserialize(payload, typeof(IDictionary <string, object>)) as IDictionary <string, object>;
                    if (_options.ValidateLifetime)
                    {
                        //var exp = payloadObj["exp"];
                        if (payloadObj == null || ((Int64)payloadObj["exp"]).ToDate() < DateTime.Now)
                        {
                            var result = new JimuRemoteCallResultData
                            {
                                ErrorMsg  = "Token is Expired",
                                ErrorCode = "401"
                            };
                            return(Task.FromResult(result));
                        }
                    }
                    var serviceRoles = context.Service.ServiceDescriptor.Roles;
                    if (!string.IsNullOrEmpty(serviceRoles))
                    {
                        var serviceRoleArr = serviceRoles.Split(',');
                        var roles          = payloadObj != null && payloadObj.ContainsKey("roles") ? payloadObj["roles"] + "" : "";
                        var authorize      = roles.Split(',').Any(role => serviceRoleArr.Any(x => x.Equals(role, StringComparison.InvariantCultureIgnoreCase)));
                        if (!authorize)
                        {
                            var result = new JimuRemoteCallResultData
                            {
                                ErrorMsg  = "Unauthorized",
                                ErrorCode = "401"
                            };
                            return(Task.FromResult(result));
                        }
                    }
                    if (context.Payload == null)
                    {
                        context.Payload = new JimuPayload {
                            Items = payloadObj
                        };
                    }
                    else
                    {
                        foreach (var item in payloadObj)
                        {
                            if (context.Payload.Items.ContainsKey(item.Key))
                            {
                                context.Payload.Items[item.Key] = item.Value;
                            }
                            else
                            {
                                context.Payload.Items.Add(item);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    var result = new JimuRemoteCallResultData
                    {
                        ErrorMsg  = $"Token is incorrect, exception is { ex.Message}",
                        ErrorCode = "401"
                    };
                    return(Task.FromResult(result));
                }
                return(_next(context));
            }
            // service can be annoymouse request

            return(_next(context));
        }
 public static void WriteServiceInvokeAfter(this IJimuDiagnostic @this, Guid operationId, ServiceInvokerContext context, JimuRemoteCallResultData resultData)
 {
     if (@this.IsEnabled(DiagnosticServerEventType.ServiceInvokeAfter.ToString()))
     {
         var operation = context.RemoteInvokeMessage.ServiceId;
         @this.Write(DiagnosticServerEventType.ServiceInvokeAfter, new ServiceInvokeAfterEventData(operationId, operation)
         {
             Data       = context,
             ResultData = resultData
         });
     }
 }