private static void Client_OnRequest(HttpRequestMessage request, RpcContext rpcContext) { var rpcId = string.Empty; var requestHeader = TracingContextData.GetRequestHeader(); if (requestHeader == null) { requestHeader = TracingContextData.GetDefaultRequestHeader(); TracingContextData.SetRequestHeader(requestHeader); //HttpContentData.SetSubRpcID(modelHeader.RpcID + ".0"); //rpcId = requestHeader.RpcID + ".0"; } //else //{ // rpcId = Util.VersionIncr(TracingContextData.GetSubRpcID()); //} rpcId = Util.VersionIncr(TracingContextData.GetSubRpcID()); TracingContextData.SetSubRpcID(rpcId); rpcContext.Items[TraceIDKey] = requestHeader.TraceID; rpcContext.Items[RpcIDKey] = rpcId; //post/put content is ObjectContent var oc = request.Content as ObjectContent; if (oc != null) { var reqModel = oc.Value as IRequestModel<Header>; if (reqModel != null) { if (reqModel.Header == null) { reqModel.Header = new Header(); } reqModel.Header.TraceID = requestHeader.TraceID; reqModel.Header.RpcID = rpcId; } } }
public Task <int> GetUserId(string userName) { var xid = RpcContext.GetContext().GetAttachment("xid"); return(Task.FromResult(1)); }
public async Task OnReceived(IMessageSender sender, string messageId, HttpContext context, IEnumerable <IActionFilter> actionFilters) { var serviceRoute = context.Items["route"] as ServiceRoute; var path = (context.Items["path"] ?? HttpUtility.UrlDecode(GetRoutePath(context.Request.Path.ToString()))) as string; if (serviceRoute == null) { serviceRoute = await _serviceRouteProvider.GetRouteByPathRegex(path); } IDictionary <string, object> parameters = context.Request.Query.ToDictionary(p => p.Key, p => (object)p.Value.ToString()); object serviceKey = null; foreach (var key in _serviceKeys) { parameters.Remove(key, out object value); if (value != null) { serviceKey = value; break; } } if (String.Compare(serviceRoute.ServiceDescriptor.RoutePath, path, true) != 0) { var @params = RouteTemplateSegmenter.Segment(serviceRoute.ServiceDescriptor.RoutePath, path); foreach (var param in @params) { parameters.Add(param.Key, param.Value); } } var httpMessage = new HttpMessage { Parameters = parameters, RoutePath = serviceRoute.ServiceDescriptor.RoutePath, ServiceKey = serviceKey?.ToString() }; if (context.Request.HasFormContentType) { var collection = await GetFormCollection(context.Request); httpMessage.Parameters.Add("form", collection); if (!await OnActionExecuting(new ActionExecutingContext { Context = context, Route = serviceRoute, Message = httpMessage }, sender, messageId, actionFilters)) { return; } httpMessage.Attachments = RpcContext.GetContext().GetContextParameters(); await Received(sender, new TransportMessage(messageId, httpMessage)); } else { StreamReader streamReader = new StreamReader(context.Request.Body); var data = await streamReader.ReadToEndAsync(); if (context.Request.Method != "GET") { var bodyParams = _serializer.Deserialize <string, IDictionary <string, object> >(data) ?? new Dictionary <string, object>(); foreach (var param in bodyParams) { httpMessage.Parameters.Add(param.Key, param.Value); } if (!await OnActionExecuting(new ActionExecutingContext { Context = context, Route = serviceRoute, Message = httpMessage }, sender, messageId, actionFilters)) { return; } httpMessage.Attachments = RpcContext.GetContext().GetContextParameters(); await Received(sender, new TransportMessage(messageId, httpMessage)); } else { if (!await OnActionExecuting(new ActionExecutingContext { Context = context, Route = serviceRoute, Message = httpMessage }, sender, messageId, actionFilters)) { return; } httpMessage.Attachments = RpcContext.GetContext().GetContextParameters(); await Received(sender, new TransportMessage(messageId, httpMessage)); } } await OnActionExecuted(context, httpMessage, actionFilters); }
/// <summary> /// 将list模型转换成datatable。类属性名 保存为ColumnName,类属性名资源保存为Caption /// 此处list直接读取属性,并按照属性读取资源,本地化后存为Excel,此处提供了datetime的最小值转换为空的操作, /// 若有更多转换操作,需要先组织好数据, 再利用该函数进行转换 /// 注意:如果T是动态类型,需要业务自己保证 值均为字符串,否则导出excel后格式有可能不正确 /// </summary> /// <typeparam name="T">模型类型</typeparam> /// <param name="modelsList">模型list</param> /// <param name="needResource">是否需要进行列头资源文件转换,默认不转换,一般从Execl上来的都需要转换</param> /// <param name="context">rpccontext用于资源文件转换</param> /// <param name="includeCols">列在此集合内</param> /// <param name="noIncludeCols">列不在此集合内</param> /// <returns>datatable</returns> public static DataTable ToDataTable <T>(this List <T> modelsList, bool needResource = false, RpcContext context = null, IEnumerable <string> includeCols = null, IEnumerable <string> noIncludeCols = null) where T : class { const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance; var type = typeof(T); if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IDictionary <,>)) { throw new NotImplementedException(); } DataTable dataTable = new DataTable(); if (needResource) { dataTable.TableName = context.R(typeof(T).Name) ?? typeof(T).Name; } else { dataTable.TableName = typeof(T).Name; } // 对 dynamic 转Datatable的处理 // 此处为定制功能,不支持字符串以外类型,如果使用,需要业务自己保证 值均为字符串 var numberStr = "$number$"; if (type == typeof(object) && modelsList.Count > 0 && modelsList[0] is IDictionary <string, object> ) { var keys = ((IDictionary <string, object>)modelsList[0]).Keys; foreach (var p in keys) { if ((includeCols?.Contains(p) ?? true) && (!(noIncludeCols?.Contains(p) ?? false))) { var sRealName = p; DataColumn col; if (p.EndsWith(numberStr)) { sRealName = p.Substring(0, p.Length - numberStr.Length); col = new DataColumn(p, typeof(decimal)); col.Caption = sRealName; } else { col = new DataColumn(p, typeof(string)); } if (needResource) { var fieldResource = context.R(sRealName); if (!string.IsNullOrEmpty(fieldResource)) { col.Caption = fieldResource; } } dataTable.Columns.Add(col); } } // 增加数据到DataTable里 modelsList.ForEach(x => { decimal dOut = 0; var row = dataTable.NewRow(); foreach (DataColumn col in dataTable.Columns) { var pVal = ((IDictionary <string, object>)x)[col.ColumnName]?.ToString(); if (col.DataType == typeof(decimal)) { decimal.TryParse(pVal, out dOut); row[col.ColumnName] = dOut; } else { row[col.ColumnName] = pVal; } } var itemArray = row.ItemArray; if (!itemArray.All(t => t == null || string.IsNullOrEmpty(t.ToString().Trim()))) { dataTable.Rows.Add(row); } }); } else { var objFieldNames = typeof(T).GetProperties(flags); foreach (var p in objFieldNames) { if ((includeCols?.Contains(p.Name) ?? true) && (!(noIncludeCols?.Contains(p.Name) ?? false))) { var t = p.PropertyType; // 对 Nullable<> 类型做处理, 模型内对 int? datetime? 进行支持 if (p.PropertyType.IsGenericType) { t = p.PropertyType.GetGenericArguments().FirstOrDefault(); t = (t == null) ? typeof(string) : t; } DataColumn col = new DataColumn(p.Name, t); if (needResource) { var fieldResource = context.R(p.Name); if (!string.IsNullOrEmpty(fieldResource)) { col.Caption = fieldResource; } } dataTable.Columns.Add(col); } } // 增加数据到DataTable里 modelsList.ForEach(x => { var row = dataTable.NewRow(); foreach (DataColumn col in dataTable.Columns) { var p = objFieldNames.FirstOrDefault(y => y.Name == col.ColumnName); if (p == null) { continue; } var pVal = p.GetValue(x); if (p.PropertyType == typeof(DateTime) && IsNullDateTime(pVal)) { row[col.ColumnName] = DBNull.Value; } else { row[col.ColumnName] = pVal ?? DBNull.Value; } } var itemArray = row.ItemArray; if (!itemArray.All(t => t == null || string.IsNullOrEmpty(t.ToString().Trim()))) { dataTable.Rows.Add(row); } }); } return(dataTable); }
public async Task <RemoteResultMessage> Invoke(RemoteInvokeMessage remoteInvokeMessage, GovernanceOptions governanceOptions, string hashKey = null) { var serviceRoute = _serviceRouteCache.GetServiceRoute(remoteInvokeMessage.ServiceId); if (serviceRoute == null) { throw new LmsException($"通过{remoteInvokeMessage.ServiceId}找不到服务路由", StatusCode.NotFindServiceRoute); } if (!serviceRoute.Addresses.Any(p => p.Enabled)) { throw new NotFindServiceRouteAddressException($"通过{remoteInvokeMessage.ServiceId}找不到可用的服务提供者"); } var addressSelector = EngineContext.Current.ResolveNamed <IAddressSelector>(governanceOptions.ShuntStrategy.ToString()); var selectedAddress = addressSelector.Select(new AddressSelectContext(remoteInvokeMessage.ServiceId, serviceRoute.Addresses, hashKey)); bool isInvakeSuccess = true; var sp = Stopwatch.StartNew(); try { _remoteServiceSupervisor.Monitor((remoteInvokeMessage.ServiceId, selectedAddress), governanceOptions); var client = await _transportClientFactory.GetClient(selectedAddress); //RpcContext.GetContext().SetAttachment("localAddress", NetUtil.GetRpcAddressModel().ToString()); RpcContext.GetContext().SetAttachment("remoteAddress", selectedAddress.ToString()); return(await client.SendAsync(remoteInvokeMessage, governanceOptions.ExecutionTimeout)); } catch (IOException ex) { Logger.LogError($"服务提供者{selectedAddress}不可用,IO异常,原因:{ex.Message}"); _healthCheck.RemoveAddress(selectedAddress); isInvakeSuccess = false; throw new CommunicatonException(ex.Message, ex.InnerException); } catch (ConnectException ex) { Logger.LogError($"与服务提供者{selectedAddress}链接异常,原因:{ex.Message}"); MarkAddressFail(governanceOptions, selectedAddress); isInvakeSuccess = false; throw new CommunicatonException(ex.Message, ex.InnerException); } catch (ChannelException ex) { Logger.LogError($"与服务提供者{selectedAddress}通信异常,原因:{ex.Message}"); MarkAddressFail(governanceOptions, selectedAddress); isInvakeSuccess = false; throw new CommunicatonException(ex.Message, ex.InnerException); } catch (TimeoutException ex) { Logger.LogError($"与服务提供者{selectedAddress}执行超时,原因:{ex.Message}"); MarkAddressFail(governanceOptions, selectedAddress, true); isInvakeSuccess = false; throw; } finally { sp.Stop(); if (isInvakeSuccess) { _remoteServiceSupervisor.ExecSuccess((remoteInvokeMessage.ServiceId, selectedAddress), sp.Elapsed.TotalMilliseconds); } else { _remoteServiceSupervisor.ExceFail((remoteInvokeMessage.ServiceId, selectedAddress), sp.Elapsed.TotalMilliseconds); } } }
public virtual string datetime(RpcContext ctx) { return(""); }
public virtual void bidirection(RpcContext ctx) { }
public virtual void timeout(int secs, RpcContext ctx) { }
/// <summary> /// 执行。 /// </summary> /// <param name="sender">消息发送者。</param> /// <param name="message">调用消息。</param> public async Task ExecuteAsync(IMessageSender sender, TransportMessage message) { if (_logger.IsEnabled(LogLevel.Trace)) { _logger.LogTrace("服务提供者接收到消息。"); } if (!message.IsInvokeMessage()) { return; } RemoteInvokeMessage remoteInvokeMessage; try { remoteInvokeMessage = message.GetContent <RemoteInvokeMessage>(); } catch (Exception exception) { _logger.LogError(exception, "将接收到的消息反序列化成 TransportMessage<RemoteInvokeMessage> 时发送了错误。"); return; } var entry = _serviceEntryLocate.Locate(remoteInvokeMessage); if (entry == null) { if (_logger.IsEnabled(LogLevel.Error)) { _logger.LogError($"根据服务Id:{remoteInvokeMessage.ServiceId},找不到服务条目。"); } return; } if (remoteInvokeMessage.Attachments != null) { foreach (var attachment in remoteInvokeMessage.Attachments) { RpcContext.GetContext().SetAttachment(attachment.Key, attachment.Value); } } if (_logger.IsEnabled(LogLevel.Debug)) { _logger.LogDebug("准备执行本地逻辑。"); } var resultMessage = new RemoteInvokeResultMessage(); //是否需要等待执行。 if (entry.Descriptor.WaitExecution()) { //执行本地代码。 await LocalExecuteAsync(entry, remoteInvokeMessage, resultMessage); //向客户端发送调用结果。 await SendRemoteInvokeResult(sender, message.Id, resultMessage); } else { //通知客户端已接收到消息。 await SendRemoteInvokeResult(sender, message.Id, resultMessage); //确保新起一个线程执行,不堵塞当前线程。 await Task.Factory.StartNew(async() => { //执行本地代码。 await LocalExecuteAsync(entry, remoteInvokeMessage, resultMessage); }, TaskCreationOptions.LongRunning); } }
private void WirteDiagnosticBefore(TransportMessage message) { if (!AppConfig.ServerOptions.DisableDiagnostic) { var remoteInvokeMessage = message.GetContent <RemoteInvokeMessage>(); remoteInvokeMessage.Attachments.TryGetValue("TraceId", out object traceId); _diagnosticListener.WriteTransportBefore(TransportType.Rpc, new TransportEventData(new DiagnosticMessage { Content = message.Content, ContentType = message.ContentType, Id = message.Id, MessageName = remoteInvokeMessage.ServiceId }, remoteInvokeMessage.DecodeJOject ? RpcMethod.Json_Rpc.ToString() : RpcMethod.Proxy_Rpc.ToString(), traceId?.ToString(), RpcContext.GetContext().GetAttachment("RemoteAddress")?.ToString())); } var parameters = RpcContext.GetContext().GetContextParameters(); parameters.TryRemove("RemoteAddress", out object value); RpcContext.GetContext().SetContextParameters(parameters); }
/// <summary> /// Call the incoming Rpc request method and gives the appropriate response /// </summary> /// <param name="request">Rpc request</param> /// <returns>An Rpc response for the request</returns> public async Task <RpcResponse?> InvokeRequestAsync(RpcRequest request) { if (request == null) { throw new ArgumentNullException(nameof(request)); } this.logger.InvokingRequest(request.Id); RpcContext routeContext = this.contextAccessor.Get(); RpcInvokeContext?invokeContext = null; if (this.serverConfig.Value.OnInvokeStart != null) { invokeContext = new RpcInvokeContext(routeContext.RequestServices, request, routeContext.Path); this.serverConfig.Value.OnInvokeStart(invokeContext); } RpcResponse rpcResponse; try { IRpcMethodInfo rpcMethod; using (var requestSignature = RpcRequestSignature.Create(request)) { rpcMethod = this.rpcRequestMatcher.GetMatchingMethod(requestSignature); } bool isAuthorized = await this.authorizationHandler.IsAuthorizedAsync(rpcMethod); if (isAuthorized) { object[] realParameters = this.ParseParameters(request.Parameters, rpcMethod.Parameters); this.logger.InvokeMethod(request.Method); object?result = await this.InvokeAsync(rpcMethod, realParameters, request, routeContext.RequestServices); this.logger.InvokeMethodComplete(request.Method); if (result is IRpcMethodResult methodResult) { rpcResponse = methodResult.ToRpcResponse(request.Id); } else { rpcResponse = new RpcResponse(request.Id, result); } } else { var authError = new RpcError(RpcErrorCode.InvalidRequest, "Unauthorized"); rpcResponse = new RpcResponse(request.Id, authError); } } catch (Exception ex) { const string errorMessage = "An Rpc error occurred while trying to invoke request."; this.logger.LogException(ex, errorMessage); RpcError error; if (ex is RpcException rpcException) { error = rpcException.ToRpcError(this.serverConfig.Value.ShowServerExceptions); } else { error = new RpcError(RpcErrorCode.InternalError, errorMessage, ex); } rpcResponse = new RpcResponse(request.Id, error); } if (this.serverConfig.Value.OnInvokeEnd != null) { if (invokeContext == null) { invokeContext = new RpcInvokeContext(routeContext.RequestServices, request, routeContext.Path); } this.serverConfig.Value.OnInvokeEnd(invokeContext, rpcResponse); } if (request.Id.HasValue) { this.logger.FinishedRequest(request.Id.ToString() !); //Only give a response if there is an id return(rpcResponse); } //TODO make no id run in a non-blocking way this.logger.FinishedRequestNoId(); return(null); }
static void Main(string[] args) { IConfiguration config = new ConfigurationBuilder() .AddJsonFile("appsettings.json", true, true) .Build(); var rpcConnnectionSettings = new RpcConnectionSetting(); config.GetSection("OdooConnection").Bind(rpcConnnectionSettings); var odooConn = new RpcConnection(rpcConnnectionSettings); var rpcContext = new RpcContext(odooConn, "res.partner"); //Query Parameter rpcContext .RpcFilter .Or() .Equal("id", 1) .Equal("id", 14383); //Returns all fields if fields are not selected rpcContext .AddField("id") .AddField("name") .AddField("mobile") .AddField("phone"); var data = rpcContext.Execute(true, limit: 5); foreach (var record in data) { var id = record.GetField("id"); var name = record.GetField("name"); var mobile = record.GetField("mobile"); var phone = record.GetField("phone"); Console.WriteLine(record.GetField("id")); Console.WriteLine(record); // Update Record record.SetFieldValue("mobile", "xxx-xxx-xx"); record.Save(); } //New Record var fields = new List <RpcField> { new RpcField { FieldName = "name", Value = 1 }, new RpcField { FieldName = "website", Value = "www.odootr.com" }, }; var newRecord = new RpcRecord(odooConn, "res.partner", null, fields); newRecord.Save(); var a = rpcContext.ToXml(); Console.ReadLine(); }
void OnCreateGameObject(RpcContext <CreateGameObject> ctx) { var tracker = new Tracker(); tracker.InstanceId = ctx.Data.InstanceId; if (CompleteIfCanceled(ctx, tracker)) { return; } var instanceEntryRpc = m_AcquireEntryDataOutput.Call(this, ctx, tracker, new AcquireEntryData(ctx.Data.InstanceId)); instanceEntryRpc.Success <EntryData>((self, ctx, tracker, instanceData) => { tracker.InstanceData = instanceData; var instanceRpc = self.m_AcquireResourceOutput.Call(self, ctx, tracker, new AcquireResource(ctx.Data.Stream, instanceData)); instanceRpc.Success <SyncObjectInstance>((self, ctx, tracker, syncInstance) => { var instance = tracker.Instance = syncInstance; if (self.CompleteIfCanceled(ctx, tracker)) { return; } var objEntryRpc = self.m_AcquireEntryDataFromModelDataOutput.Call(self, ctx, tracker, new AcquireEntryDataFromModelData(tracker.InstanceData.ManifestId, new PersistentKey(typeof(SyncObject), instance.ObjectId.Value))); objEntryRpc.Success <EntryData>((self, ctx, tracker, objData) => { tracker.ObjectId = objData.Id; tracker.ObjectData = objData; var objRpc = self.m_AcquireResourceOutput.Call(self, ctx, tracker, new AcquireResource(ctx.Data.Stream, tracker.ObjectData)); objRpc.Success <SyncObject>((self, ctx, tracker, syncObject) => { tracker.Object = syncObject; if (self.CompleteIfCanceled(ctx, tracker)) { return; } var goRpc = self.m_ConvertToGameObjectOutput.Call(self, ctx, tracker, new ConvertToGameObject(ctx.Data.Stream, tracker.InstanceData, tracker.Instance, tracker.Object)); goRpc.Success <GameObject>((self, ctx, tracker, gameObject) => { // gameObject may be null at this point, but the caller will // check if the stream has been canceled anyway. Just forward. self.ClearTrackerResources(tracker); ctx.SendSuccess(gameObject); }); goRpc.Failure((self, ctx, tracker, ex) => self.CompleteRequestAsFailure(ctx, tracker, ex)); }); objRpc.Failure((self, ctx, tracker, ex) => self.CompleteRequestAsFailure(ctx, tracker, ex)); }); objEntryRpc.Failure((self, ctx, tracker, ex) => self.CompleteRequestAsFailure(ctx, tracker, ex)); }); instanceRpc.Failure((self, ctx, tracker, ex) => self.CompleteRequestAsFailure(ctx, tracker, ex)); }); instanceEntryRpc.Failure((self, ctx, tracker, ex) => self.CompleteRequestAsFailure(ctx, tracker, ex)); }
void CompleteRequestAsFailure(RpcContext <CreateGameObject> ctx, Tracker tracker, Exception ex) { ClearTrackerResources(tracker); ctx.SendFailure(ex); }
public void Set(RpcContext context) { throw new NotImplementedException(); }
private void WirteDiagnosticBefore(TransportMessage message) { if (!AppConfig.ServerOptions.DisableDiagnostic) { RpcContext.GetContext().SetAttachment("TraceId", message.Id); var diagnosticListener = new DiagnosticListener(DiagnosticListenerExtensions.DiagnosticListenerName); var remoteInvokeMessage = message.GetContent <HttpMessage>(); diagnosticListener.WriteTransportBefore(TransportType.Rest, new TransportEventData(new DiagnosticMessage { Content = message.Content, ContentType = message.ContentType, Id = message.Id, MessageName = remoteInvokeMessage.RoutePath }, TransportType.Rest.ToString(), message.Id, RpcContext.GetContext().GetAttachment("RemoteIpAddress")?.ToString())); } else { var parameters = RpcContext.GetContext().GetContextParameters(); parameters.TryRemove("RemoteIpAddress", out object value); RpcContext.GetContext().SetContextParameters(parameters); } }
public virtual string echo(string text, RpcContext ctx) { return(""); }
static void Main(string[] args) { IConfiguration config = new ConfigurationBuilder() .AddJsonFile("appsettings.json", true, true) .Build(); var rpcConnnectionSettings = new RpcConnectionSetting(); config.GetSection("OdooConnection").Bind(rpcConnnectionSettings); var odooConn = new RpcConnection(rpcConnnectionSettings); var rpcContext = new RpcContext(odooConn, "res.partner"); rpcContext .AddField("id") .AddField("name"); var data = rpcContext.Execute(false); var partner_1 = new RpcModel("res.partner", odooConn); var method_response = partner_1.CallMethod("find_or_create", new object[1] { "*****@*****.**" }); //res.partner - Write var partner = new RpcContext(odooConn, "res.partner"); partner.AddFields(new[] { "name", "phone", "email" }); var results = partner.Execute(false, order: "id desc"); //var results = partner.Execute(false, offset:1, limit:2, order: "id desc"); foreach (var result in results) { result.SetFieldValue("phone", "55-66-666"); result.Save(); } //res.partner - Create RpcRecord record = new RpcRecord(odooConn, "stock.quant", -1, new List <RpcField> { new RpcField { FieldName = "product_id" }, new RpcField { FieldName = "reserved_quantity" }, new RpcField { FieldName = "location_id" } }); record.SetFieldValue("product_id", 52); record.SetFieldValue("reserved_quantity", 333); record.SetFieldValue("location_id", 8); record.Save(); }
public virtual void heartbeat(string hello, RpcContext ctx) { }
//private static void Client_OnResponse(HttpResponseMessage response, RpcContext rpcContext) //{ // TraceLogs trace = new TraceLogs(); // trace.IsSuccess = true; // trace.IsException = false; // FillClientSR(trace, response.RequestMessage, rpcContext); // Record(trace); //} //private static void Client_OnError(Exception ex, HttpRequestMessage request, RpcContext rpcContext) //{ // TraceLogs trace = new TraceLogs(); // trace.IsSuccess = false; // trace.IsException = true; // FillClientSR(trace, request, rpcContext); // trace.Extension.Add("Exception", Util.GetFullExceptionMessage(ex)); // Record(trace); //} /// <summary> /// /// </summary> /// <param name="trace"></param> /// <param name="request"></param> /// <param name="response"></param> /// <param name="rpcContext"></param> private static void FillClientSR(TraceLogs trace, HttpRequestMessage request, HttpResponseMessage response, RpcContext rpcContext) { trace.ContextType = ContextType.Client.ToString(); //var requestHeader = TracingContextData.GetRequestHeader(); //raven Request Header var uri = request.RequestUri; //int index = uri.AbsoluteUri.IndexOf("?"); //if (index > 0) //{ // trace.ServiceMethod = uri.AbsoluteUri.Substring(0, index); //} //else //{ // trace.ServiceMethod = uri.AbsoluteUri; //} trace.MachineAddr = Util.TracingContextHelper.GetServerAddress(); trace.InvokeID = uri.AbsolutePath; trace.ServerHost = uri.Host; //trace.Extension.Add(nameof(uri.AbsolutePath), uri.AbsolutePath); trace.Extensions.Add(nameof(uri.PathAndQuery), uri.PathAndQuery); //trace.Extension.Add(nameof(uri.Host), uri.Host); trace.Extensions.Add(nameof(rpcContext.RequestModel), rpcContext.RequestModel); trace.Extensions.Add(nameof(rpcContext.ResponseModel), rpcContext.ResponseModel); trace.ResponseSize = rpcContext.ResponseSize; trace.Protocol = uri.Scheme; trace.ProtocolHeader.Add("RequestHeaders", new Dictionary<string, string> { { "Accept", request.Headers.Accept.ToString() }, { "Accept-Encoding", request.Headers.AcceptEncoding.ToString() }, { "Content-Type", request.Content?.Headers?.ContentType?.ToString() }, }); if (response != null) { trace.ProtocolHeader.Add("ResponseHeaders", new Dictionary<string, string> { { "Content-Encoding", response.Content?.Headers?.ContentEncoding?.ToString() }, { "Content-Type", response.Content?.Headers?.ContentType?.ToString() }, }); } //trace.SendSTime = rpcContext.SendStartTime; //trace.ReceiveETime = rpcContext.ReceiveEndTime; //trace.ExceptionTime = rpcContext.ExceptionTime; trace.StartTime = rpcContext.SendStartTime; if (rpcContext.ReceiveEndTime.HasValue) { trace.EndTime = rpcContext.ReceiveEndTime.Value; trace.TimeLength = (trace.EndTime - trace.StartTime).TotalMilliseconds; } else if (rpcContext.ExceptionTime.HasValue) { trace.EndTime = rpcContext.ExceptionTime.Value; trace.TimeLength = (trace.EndTime - trace.StartTime).TotalMilliseconds; } //trace.TimeLength = trace.ReceiveETime.HasValue ? (trace.ReceiveETime.Value - trace.SendSTime).TotalMilliseconds : 0D; //trace.RpcId = modelHeader.RpcID; //var reqModel = rpcContext.RequestModel as IRequestModel<Header>; //if (reqModel != null && reqModel.Header != null) //{ // trace.RpcId = rpcContext.Items[RpcIDKey].ToString(); //} //if modelHeader is null, create new traceID trace.RpcId = rpcContext.Items[RpcIDKey].ToString(); trace.TraceId = rpcContext.Items[TraceIDKey].ToString(); if (rpcContext.ResponseModel != null) { var resModel = rpcContext.ResponseModel as IResponseModel; if (resModel != null) { trace.Code = resModel.GetCode(); } //SearchKey var searchKey = rpcContext.ResponseModel as ISearchKey; if (searchKey != null) { trace.SearchKey = searchKey.GetSearchKey(); } } }
public virtual void onMessage(string message, RpcContext ctx) { }
public async Task Handler(TransactionContext context, ILmsMethodInvocation invocation) { var serviceEntry = invocation.ArgumentsDictionary["serviceEntry"] as ServiceEntry; Debug.Assert(serviceEntry != null); if (serviceEntry.IsLocal) { context.Action = ActionStage.PreTry; await executor.ConsumerParticipantExecute(context, invocation, TccMethodType.Try); context.Action = ActionStage.Trying; invocation.ReturnValue = await executor.ConsumerParticipantExecute(context, invocation, TccMethodType.Confirm); context.Action = ActionStage.Confirming; } else { if (context.Action != ActionStage.PreTry) { context.TransactionRole = TransactionRole.Participant; } var participant = executor.PreTryParticipant(context, invocation); try { await invocation.ProceedAsync(); if (participant != null) { participant.Status = ActionStage.Trying; } } catch (Exception e) { var currentTrans = LmsTransactionHolder.Instance.CurrentTransaction; foreach (var participantItem in currentTrans.Participants) { if (participantItem.Role == TransactionRole.Participant && participantItem.Status == ActionStage.Trying) { context.Action = ActionStage.Canceling; context.TransactionRole = TransactionRole.Participant; context.ParticipantId = participantItem.ParticipantId; context.ParticipantRefId = participantItem.ParticipantRefId; RpcContext.GetContext().SetTransactionContext(context); await participantItem.Invocation.ProceedAsync(); } if (participantItem.Role == TransactionRole.Consumer && participantItem.Status == ActionStage.Trying) { invocation.ReturnValue = await executor.ConsumerParticipantExecute(context, invocation, TccMethodType.Cancel); context.Action = ActionStage.Canceling; } } throw; } } }
public virtual void ping(RpcContext ctx) { }
private static DbInfo GetDbInfo(RpcContext rpcContext, string dbName) { try { // 先找用户私有化的配置 var sysInfos = rpcContext.GetUserContext()?.GetSysInfo(); if (sysInfos == null || !sysInfos.Any()) { if (!string.IsNullOrEmpty(rpcContext.Args.tk)) { logger.LogWarning("GrantDBContext.GetDbInfo.GetUserCtx.sysInfos==null"); } } var dbInfos = sysInfos?.Where(a => a.DbModelName?.ToLower() == dbName).ToList(); ConstItem dbValue = null; if (dbInfos == null || !dbInfos.Any()) { // 从配置文件做了兼容转换,等数据库tenant_database的DBModelName字段启用后就直接能取到了 dbValue = ServerSetting.GetConstValue(dbName); if (dbValue != null) { var sysId = dbValue.Value.ToLower(); dbInfos = sysInfos.Where(a => a.SysID?.ToLower() == sysId && !string.IsNullOrEmpty(a.DBIP)).ToList(); } } DbInfo info = null; if (dbInfos != null && dbInfos.Any()) { var dbInfo = dbInfos.First(); var dbType = dbInfo.DBType; DbType dType = DbTypeParser.Parser(dbType); info = new DbInfo() { DbType = dType, DbName = dbInfo.DBName, Ip = dbInfo.DBIP, Port = dbInfo.DbPort, UserName = dbInfo.DBUser, Pwd = dbInfo.DBPwd, DbContextName = dbName, }; } else { // 如果私有化的表没有,找全局的表 var dbModel = ServerSetting.GetDbModelContext(dbName); if (dbModel == null) { throw new Exception($"DataModel Info :{dbName} Is Not Found"); } DbType dType = DbTypeParser.Parser(dbModel.DbType); // 需要根据接口配置的主从来选择主从,这里先暂时全部取主,有空了在完善接口主从配置 info = new DbInfo() { DbName = dbModel.Database, DbType = dType, Ip = dbModel.Master.Ip, Port = dbModel.Master.Port, UserName = dbModel.UserName, Pwd = dbModel.PassWord, DbContextName = dbName, }; } logger.LogDebug($"获取的数据库信息是:{info?.ToString()}"); return(info); } catch (Exception e) { logger.LogCritical(e, $"GrantDBContext.GetDbInfo.Error,获取数据库{dbName}连接信息异常"); throw new BusinessException(new StatusCode(StatusCode.ServerError.code, $"无法找到用户的数据库信息,请检查租户数据库,或者Config目录下的数据库配置信息({dbName})")); } }
/// <summary> /// 将dataTable转换成T类型的实体列表 /// </summary> /// <typeparam name="T">要转换的实体类型</typeparam> /// <param name="dataTable">数据源</param> /// <param name="needResource">是否需要进行列头资源文件转换,默认不转换,一般从Execl上来的都需要转换</param> /// <param name="context">rpccontext用于资源文件转换</param> /// <param name="allowDuplicates">是否允许重复(默认允许,为否时有重复会报错)</param> /// <returns>T的列表</returns> public static List <T> ToList <T>(this DataTable dataTable, bool needResource = false, RpcContext context = null, bool allowDuplicates = true) where T : new() { var dataList = new Dictionary <string, T>(); const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance; var objFieldNames = typeof(T).GetProperties(flags).Cast <PropertyInfo>().Select(item => new { Name = item.Name, Type = Nullable.GetUnderlyingType(item.PropertyType) ?? item.PropertyType, }).ToList(); if (needResource) { foreach (var p in objFieldNames) { var fieldResource = context.R(p.Name); foreach (DataColumn col in dataTable.Columns) { // 如果实体的字段名称转换成资源名称,和模板上来的列名相同,直接把列名改成实体名称,减少循环 if (fieldResource?.ToLower().Trim() == col.ColumnName.ToLower()) { col.ColumnName = p.Name; } } } } var dtlFieldNames = dataTable.Columns.Cast <DataColumn>().Select(item => new { Name = item.ColumnName, Type = item.DataType, }).ToList(); StringBuilder key = new StringBuilder(); int idx = -1; List <int> emptyRowIndex = new List <int>(); List <int> duplicateRowIndexs = new List <int>(); foreach (DataRow dataRow in dataTable.Rows) { idx += 1; var itemArray = dataRow.ItemArray; object[] values = null; if (itemArray.Length > 2) { values = new object[itemArray.Length - 2];//有附加的两个列rowindex errormsg Array.Copy(itemArray, values, values.Length); } if (values != null) { if (itemArray.All(t => t == null || string.IsNullOrEmpty(t.ToString().Trim()))) { emptyRowIndex.Add(idx + 2); continue; } } var classObj = new T(); if (key.Length > 0) { key.Clear(); } string convertErrors = ""; foreach (var objField in objFieldNames) { PropertyInfo propertyInfos = classObj.GetType().GetProperty(objField.Name); var dtField = dtlFieldNames.Find(x => x.Name == objField.Name); var error = ""; if (dtField == null) { var k = setFieldValue(propertyInfos, classObj, null, out error); if (objField.Name != "ExcelRowIndex" && objField.Name != "ErrorMsg") // 附加内容不算 { key.Append(k); } } else { var k = setFieldValue(propertyInfos, classObj, dataRow[dtField.Name], out error); if (objField.Name != "ExcelRowIndex" && objField.Name != "ErrorMsg") { key.Append(k); } } convertErrors += error; } if (!string.IsNullOrEmpty(convertErrors)) { PropertyInfo errorPropertyInfo = classObj.GetType().GetProperty("ErrorMsg"); if (errorPropertyInfo != null) { setFieldValue(errorPropertyInfo, classObj, convertErrors, out string e); } } if (dataList.ContainsKey(key.ToString().ToLower())) { duplicateRowIndexs.Add(idx + 2); } dataList[key.ToString().ToLower()] = classObj; } StringBuilder sbError = new StringBuilder(); if (emptyRowIndex.Count > 0) { sbError.AppendLine($"Excel中包含空数据,行号{string.Join(',', emptyRowIndex)}请删除!"); } if (duplicateRowIndexs.Count > 0) { sbError.AppendLine($"Excel中包含重复数据,行号{string.Join(',', duplicateRowIndexs)}请删除!"); } if (!allowDuplicates && sbError.Length > 0) { throw new BusinessException(sbError.ToString()); } return(dataList.Values.ToList()); }
public async Task OnReceived(IMessageSender sender, HttpContext context) { var routePath = GetRoutePath(context.Request.Path.ToString()); IDictionary <string, object> parameters = context.Request.Query.ToDictionary(p => p.Key, p => (object)p.Value.ToString()); parameters.Remove("servicekey", out object serviceKey); var serviceRouteProvider = ServiceLocator.GetService <IServiceRouteProvider>(); var commandInfo = await serviceRouteProvider.GetRouteByPath(routePath); if (context.Request.HasFormContentType) { var collection = await GetFormCollection(context.Request); parameters.Add("form", collection); await Received(sender, new TransportMessage(new HttpMessage { Parameters = parameters, RoutePath = routePath, ServiceKey = serviceKey?.ToString() })); } else { StreamReader streamReader = new StreamReader(context.Request.Body); var data = await streamReader.ReadToEndAsync(); if (context.Request.Method == "POST") { var bodyParmeters = _serializer.Deserialize <string, IDictionary <string, object> >(data) ?? new Dictionary <string, object>(); if (AppConfig.SwaggerOptions.Authorization.EnableAuthorization && commandInfo.ServiceDescriptor.EnableAuthorization()) { var authorizationServerProvider = ServiceLocator.GetService <IAuthorizationServerProvider>(); var payload = authorizationServerProvider.GetPayload(context.Request.GetTokenFromHeader()); bodyParmeters.Add("payload", _serializer.Serialize(payload, true)); RpcContext.GetContext().SetAttachment("payload", _serializer.Serialize(payload, true)); } await Received(sender, new TransportMessage(new HttpMessage { Parameters = bodyParmeters, RoutePath = routePath, ServiceKey = serviceKey?.ToString() })); } else { if (AppConfig.SwaggerOptions.Authorization.EnableAuthorization && commandInfo.ServiceDescriptor.EnableAuthorization()) { var authorizationServerProvider = ServiceLocator.GetService <IAuthorizationServerProvider>(); var payload = authorizationServerProvider.GetPayload(context.Request.GetTokenFromHeader()); parameters.Add("payload", _serializer.Serialize(payload, true)); RpcContext.GetContext().SetAttachment("payload", _serializer.Serialize(payload, true)); } await Received(sender, new TransportMessage(new HttpMessage { Parameters = parameters, RoutePath = routePath, ServiceKey = serviceKey?.ToString() })); } } }
/// <summary> /// 测试 /// </summary> /// <param name="serviceProxyFactory"></param> public static void Test(IServiceProxyFactory serviceProxyFactory) { var tracingContext = ServiceLocator.GetService <ITracingContext>(); Task.Run(async() => { RpcContext.GetContext().SetAttachment("xid", 124); var userProxy = serviceProxyFactory.CreateProxy <IUserService>("User"); var asyncProxy = serviceProxyFactory.CreateProxy <IAsyncService>(); var result = await asyncProxy.AddAsync(1, 2); var user = userProxy.GetUser(new UserModel { UserId = 1, Name = "", Age = 120, Sex = 0 }).GetAwaiter().GetResult(); var e = userProxy.SetSex(Sex.Woman).GetAwaiter().GetResult(); var v = userProxy.GetUserId("").GetAwaiter().GetResult(); var fa = userProxy.GetUserName(1).GetAwaiter().GetResult(); userProxy.Try().GetAwaiter().GetResult(); var v1 = userProxy.GetUserLastSignInTime(1).Result; var things = userProxy.GetAllThings().Result; var apiResult = userProxy.GetApiResult().GetAwaiter().GetResult(); userProxy.PublishThroughEventBusAsync(new UserEvent { UserId = 1, Name = "" }).Wait(); userProxy.PublishThroughEventBusAsync(new UserEvent { UserId = 1, Name = "" }).Wait(); var r = await userProxy.GetDictionary(); var serviceProxyProvider = ServiceLocator.GetService <IServiceProxyProvider>(); do { Console.WriteLine("正在循环 1w次调用 GetUser....."); //1w次调用 var watch = Stopwatch.StartNew(); for (var i = 0; i < 10000; i++) { //var a = userProxy.GetDictionary().Result; var a = await userProxy.GetDictionary(); //var result = serviceProxyProvider.Invoke<object>(new Dictionary<string, object>(), "api/user/GetDictionary", "User").Result; } watch.Stop(); Console.WriteLine($"1w次调用结束,执行时间:{watch.ElapsedMilliseconds}ms"); Console.WriteLine("Press any key to continue, q to exit the loop..."); var key = Console.ReadLine(); if (key.ToLower() == "q") { break; } } while (true); }).Wait(); }
public void Change(string seviceKey) { RpcContext.GetContext().SetAttachment("serviceKey", seviceKey); }
public override async Task <IClusterResult <T> > DoInvoke <T>(IClientPool pool, ILoadBalance loadbalance, URL address, IList <URL> urls, IInvocation invocation) { //IResult result = null; var goodUrls = new List <URL>(); var badUrls = new List <BadUrl>(); checkInvokers(urls, invocation, address); IList <URL> selected; int forks = address.GetParameter(FORKS_KEY, DEFAULT_FORKS); int timeout = address.GetParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT); if (forks <= 0 || forks >= urls.Count) { selected = urls; } else { selected = new List <URL>(); for (int i = 0; i < forks; i++) { //在invoker列表(排除selected)后,如果没有选够,则存在重复循环问题.见select实现. var invoker = base.select(loadbalance, invocation, urls, selected); if (!selected.Contains(invoker)) {//防止重复添加invoker selected.Add(invoker); } } } RpcContext.GetContext().SetInvokers(selected); var count = new AtomicInteger(); var taskList = new Task <IResult <T> > [selected.Count]; var index = 0; foreach (var invoker in selected) { var task = Task.Run(async() => { try { var client = await pool.GetClient(invoker); try { var refer = await client.Refer(); _source.WriteConsumerBefore(refer.Instance, invoker, invocation); var resultInner = await refer.Invoke <T>(invocation); _source.WriteConsumerAfter(invoker, invocation, resultInner); await pool.Recovery(client); goodUrls.Add(invoker); return(resultInner); } catch (Exception ex) { await pool.DestoryClient(client).ConfigureAwait(false); _source.WriteConsumerError(invoker, invocation, ex); throw ex; } } catch (Exception e) { badUrls.Add(new BadUrl { Url = invoker, BadTime = DateTime.Now, CurrentException = e }); int value = count.IncrementAndGet(); if (value >= selected.Count) { return(new RpcResult <T>(e)); } } return(null); }); taskList[index++] = task; } try { var retIndex = Task.WaitAny(taskList, timeout); var ret = await taskList[retIndex]; if (ret.HasException) { Exception e = ret.Exception; throw new RpcException(e is RpcException exception ? exception.Code : 0, "Failed to forking invoke provider " + selected + ", but no luck to perform the invocation. Last error is: " + e.Message, e.InnerException != null ? e.InnerException : e); } return(new ClusterResult <T>(ret, goodUrls, badUrls, null, false)); } catch (Exception e) { var exception = new RpcException("Failed to forking invoke provider " + selected + ", but no luck to perform the invocation. Last error is: " + e.Message, e); return(new ClusterResult <T>(new RpcResult <T>(exception), goodUrls, badUrls, exception, true)); } }
private async Task <RemoteInvokeResultMessage> MonitorRemoteInvokeAsync(IDictionary <string, object> parameters, string serviceId, string serviceKey, bool decodeJOject, int requestTimeout, string item) { CancellationTokenSource source = new CancellationTokenSource(); var token = source.Token; var invokeMessage = new RemoteInvokeMessage { Parameters = parameters, ServiceId = serviceId, ServiceKey = serviceKey, DecodeJOject = decodeJOject, Attachments = RpcContext.GetContext().GetContextParameters() }; try { _serviceInvokeListenInfo.AddOrUpdate(serviceId, new ServiceInvokeListenInfo(), (k, v) => { v.RemoteServiceRequests = v.RemoteServiceRequests == null ? 1 : ++v.RemoteServiceRequests; v.FinalRemoteInvokeTime = DateTime.Now; ++v.ConcurrentRequests; return(v); }); var message = await _remoteInvokeService.InvokeAsync(new RemoteInvokeContext { Item = item, InvokeMessage = invokeMessage }, requestTimeout); _serviceInvokeListenInfo.AddOrUpdate(serviceId, new ServiceInvokeListenInfo(), (k, v) => { v.SinceFaultRemoteServiceRequests = 0; --v.ConcurrentRequests; return(v); }); return(message); } catch (Exception ex) { await ExecuteExceptionFilter(ex, invokeMessage, token); if ((ex.InnerException != null && ex.InnerException is BusinessException) || ex is BusinessException) { _serviceInvokeListenInfo.AddOrUpdate(serviceId, new ServiceInvokeListenInfo(), (k, v) => { v.SinceFaultRemoteServiceRequests = 0; --v.ConcurrentRequests; return(v); }); return(new RemoteInvokeResultMessage() { ExceptionMessage = ex.InnerException.GetExceptionMessage(), Result = null, StatusCode = ex.InnerException.GetExceptionStatusCode() }); } else { _serviceInvokeListenInfo.AddOrUpdate(serviceId, new ServiceInvokeListenInfo(), (k, v) => { ++v.FaultRemoteServiceRequests; ++v.SinceFaultRemoteServiceRequests; --v.ConcurrentRequests; return(v); }); } return(new RemoteInvokeResultMessage() { ExceptionMessage = ex.GetExceptionMessage(), Result = null, StatusCode = ex.GetExceptionStatusCode() }); } }
public override async Task <IClusterResult <T> > DoInvoke <T>(IClientPool pool, ILoadBalance loadbalance, URL address, IList <URL> urls, IInvocation invocation) { var goodUrls = new List <URL>(); var badUrls = new List <BadUrl>(); //IResult result = null; var copyinvokers = urls; checkInvokers(copyinvokers, invocation, address); //*getUrl(); int len = address.GetMethodParameter(invocation.MethodInfo.Name, RETRIES_KEY, DEFAULT_RETRIES) + 1; if (len <= 0) { len = 1; } // retry loop. RpcException le = null; // last exception. var invoked = new List <URL>(copyinvokers.Count); // invoked invokers. ISet <string> providers = new HashSet <string>(); //*len for (int i = 0; i < len; i++) { //重试时,进行重新选择,避免重试时invoker列表已发生变化. //注意:如果列表发生了变化,那么invoked判断会失效,因为invoker示例已经改变 if (i > 0) { //*checkWhetherDestroyed(); //*copyinvokers = list(invocation); //重新检查一下 checkInvokers(copyinvokers, invocation, address); } var invoker = base.select(loadbalance, invocation, copyinvokers, invoked); invoked.Add(invoker); RpcContext.GetContext().SetInvokers(invoked); try { var client = await pool.GetClient(invoker); try { var refer = await client.Refer(); _source.WriteConsumerBefore(refer.Instance, invoker, invocation); var result = await refer.Invoke <T>(invocation); _source.WriteConsumerAfter(invoker, invocation, result); await pool.Recovery(client); if (le != null) { Logger().LogWarning(le, "Although retry the method " + invocation.MethodInfo.Name + " in the service " + invocation.TargetType.FullName + " was successful by the provider " + invoker.Address + ", but there have been failed providers " + string.Join(",", providers) + " (" + providers.Count + "/" + copyinvokers.Count + ") from the registry " + address.Address + " on the consumer " + Local.HostName + " using the service version " + invocation.Version + ". Last error is: " + le.Message); } goodUrls.Add(invoker); return(new ClusterResult <T>(result, goodUrls, badUrls, le, false)); } catch (Exception ex) { await pool.DestoryClient(client).ConfigureAwait(false); _source.WriteConsumerError(invoker, invocation, ex); throw ex; } } catch (RpcException e) { if (e.Biz) { // biz exception. throw e; } le = e; } catch (Exception e) { le = new RpcException(e.Message, e); var badUrl = badUrls.FirstOrDefault(w => w.Url == invoker); if (badUrl != null) { badUrls.Remove(badUrl); } badUrls.Add(new BadUrl { Url = invoker, BadTime = DateTime.Now, CurrentException = le }); } finally { providers.Add(invoker.Address); } } var re = new RpcException(le != null ? le.Code : 0, "Failed to invoke the method " + invocation.MethodInfo.Name + " in the service " + invocation.TargetType.FullName + ". Tried " + len + " times of the providers " + string.Join(",", providers) + " (" + providers.Count + "/" + copyinvokers.Count + ") from the registry " + address //+ " on the consumer " + NetUtils.getLocalHost() + " using the service version " + invocation.Version + ". Last error is: " + (le != null ? le.Message : ""), le != null && le.InnerException != null ? le.InnerException : le); return(new ClusterResult <T>(new RpcResult <T>(re), goodUrls, badUrls, re, true)); }
private void ValuesAPIClient_OnResponse(HttpResponseMessage response, RpcContext rpcContext) { var cc = CallContext.LogicalGetData("cc"); ; }