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)); }
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."); } }
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)); }
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; })); }
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); } }
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); }
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."); } }
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); } }
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)); }
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(); } }
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 }); } }