GoverManage.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. using System;
  2. using System.Collections.Generic;
  3. using Newtonsoft.Json;
  4. using Sers.Core.CL.MessageOrganize;
  5. using Sers.Core.Module.Api.ApiDesc;
  6. using Sers.Core.Module.Api.Data;
  7. using Sers.Core.Module.Api.RouteMap;
  8. using Sers.Core.Module.Env;
  9. using Sers.Core.Module.Message;
  10. using Sers.Core.Module.Rpc;
  11. using Sers.Gover.Base.Model;
  12. using Sers.Gover.Persistence;
  13. using Sers.Gover.RateLimit;
  14. using Sers.ServiceCenter.ApiCenter;
  15. using Sers.ServiceCenter.Entity;
  16. using Vit.Core.Module.Log;
  17. using Vit.Core.Util.ComponentModel.SsError;
  18. using Vit.Core.Util.ConfigurationManager;
  19. using Vit.Extensions;
  20. namespace Sers.Gover.Base
  21. {
  22. [JsonObject(MemberSerialization.OptIn)]
  23. public class GoverManage : ApiCenterService
  24. {
  25. #region static
  26. public static readonly GoverManage Instance = LoadFromFile();
  27. static GoverManage LoadFromFile()
  28. {
  29. var mng=new GoverManage();
  30. Persistence_ApiDesc.ApiDesc_LoadAllFromJsonFile(mng.apiStationMng);
  31. Persistence_Counter.LoadCounterFromJsonFile(mng.apiStationMng);
  32. return mng;
  33. }
  34. public static void SaveToFile()
  35. {
  36. Persistence_Counter.SaveCounterToJsonFile(Instance.apiStationMng);
  37. }
  38. #endregion
  39. public GoverManage()
  40. {
  41. //init apiLoadBalancingMng
  42. switch (ConfigurationManager.Instance.GetStringByPath("Sers.ServiceCenter.ApiRouteType"))
  43. {
  44. case "IgnoreHttpMethod": apiLoadBalancingMng = new ApiLoadBalancingMng(); break;
  45. default: apiLoadBalancingMng = new ApiLoadBalancingMng_RESTful(); break;
  46. }
  47. serviceStationMng = new ServiceStationMng();
  48. serviceStationMng.Init(this);
  49. apiStationMng = new ApiStationMng();
  50. apiStationMng.Init(this);
  51. }
  52. internal readonly ApiLoadBalancingMng apiLoadBalancingMng;
  53. [JsonProperty]
  54. internal ApiStationMng apiStationMng { get; private set; }
  55. [JsonIgnore]
  56. internal ServiceStationMng serviceStationMng { get; private set; }
  57. [JsonIgnore]
  58. public RateLimitMng rateLimitMng { get; private set; } = new RateLimitMng();
  59. public void SaveUsageInfo(EnvUsageInfo item)
  60. {
  61. serviceStationMng.SaveUsageInfo(item);
  62. }
  63. #region ServiceStation
  64. public IEnumerable<SsApiDesc> ApiDesc_GetActive()
  65. {
  66. return apiLoadBalancingMng.GetAllApiDesc();
  67. }
  68. public IEnumerable<SsApiDesc> ApiDesc_GetAll()
  69. {
  70. return apiStationMng.ApiDesc_GetAll();
  71. }
  72. #endregion
  73. #region CallApi
  74. public override void CallApiAsync(IRpcContextData rpcData, ApiMessage requestMessage, Object sender, Action<object, Vit.Core.Util.Pipelines.ByteData> callback)
  75. {
  76. try
  77. {
  78. #region (x.0)ApiScopeEvent
  79. apiScopeEventList?.ForEach(onScope =>
  80. {
  81. try
  82. {
  83. var onDispose = onScope(rpcData, requestMessage);
  84. if (onDispose != null)
  85. {
  86. callback += onDispose;
  87. }
  88. }
  89. catch (Exception ex)
  90. {
  91. Logger.Error(ex);
  92. }
  93. });
  94. #endregion
  95. #region (x.1)route 判空
  96. if (string.IsNullOrWhiteSpace(rpcData.route))
  97. {
  98. //返回api 不存在
  99. SendReply(SsError.Err_ApiNotExists);
  100. return;
  101. }
  102. #endregion
  103. #region (x.2) 服务限流 BeforeLoadBalancing
  104. var error = rateLimitMng.BeforeLoadBalancing(rpcData, requestMessage);
  105. if (null != error)
  106. {
  107. SendReply(error);
  108. return;
  109. }
  110. #endregion
  111. #region (x.3) 负载均衡,获取对应服务端
  112. var apiNode = apiLoadBalancingMng.GetCurApiNodeByLoadBalancing(rpcData, out var routeType);
  113. if (null == apiNode)
  114. {
  115. //返回api 不存在
  116. SendReply(SsError.Err_ApiNotExists);
  117. return;
  118. }
  119. #endregion
  120. #region (x.4) 服务限流 BeforeCallRemoteApi
  121. error = rateLimitMng.BeforeCallRemoteApi(rpcData, requestMessage, apiNode);
  122. if (null != error)
  123. {
  124. SendReply(error);
  125. return;
  126. }
  127. #endregion
  128. #region (x.5) BeforeCallApi
  129. try
  130. {
  131. BeforeCallApi?.Invoke(rpcData, requestMessage);
  132. }
  133. catch (Exception ex)
  134. {
  135. Logger.Error(ex);
  136. }
  137. #endregion
  138. #region (x.6) 权限校验 SsValid
  139. // 权限校验不通过,调用次数也计数
  140. // TODO:应当有其他计数
  141. //(x.x.1) rpcValidations Sers1校验
  142. if (!Sers.Core.Module.Valid.Sers1.RpcVerify1.Verify(rpcData.oriJson, apiNode.apiDesc.rpcValidations, out var validError))
  143. {
  144. SendReply(validError);
  145. return;
  146. }
  147. //(x.x.2) rpcVerify2 Sers2校验
  148. if (!Sers.Core.Module.Valid.Sers2.RpcVerify2.Verify(rpcData.oriJson, apiNode.apiDesc.rpcVerify2, out var verifyError))
  149. {
  150. SendReply(verifyError);
  151. return;
  152. }
  153. #endregion
  154. #region (x.7) RpcContextData 修正
  155. //(x.x.1) 修正route
  156. // 调用服务端 泛接口(如: "/station1/fold2/*")时,route应修正为"/station1/fold2/*",而不是原始 地址(如: "/station1/fold2/index.html")
  157. if (routeType == ERouteType.genericRoute)
  158. {
  159. rpcData.route = apiNode.apiDesc.route;
  160. requestMessage.rpcContextData_OriData = ArraySegmentByteExtensions.Null;
  161. }
  162. //(x.x.2) 修正 requestMessage
  163. if (requestMessage.rpcContextData_OriData.Count <= 0) {
  164. requestMessage.RpcContextData_OriData_Set(rpcData);
  165. }
  166. #endregion
  167. #region (x.8)服务调用
  168. apiNode.CallApiAsync(rpcData, requestMessage, sender,callback);
  169. #endregion
  170. }
  171. catch (Exception ex)
  172. {
  173. Logger.Error(ex);
  174. ApiSysError.LogSysError(rpcData, requestMessage, ex.ToSsError());
  175. SendReply(SsError.Err_SysErr);
  176. return;
  177. }
  178. void SendReply(SsError error)
  179. {
  180. //callback(sender, new ApiMessage().InitByError(error).SetSysErrToRpcData(error).Package().ByteDataToBytes().BytesToArraySegmentByte());
  181. callback(sender, new ApiMessage().InitAsApiReplyMessageByError(error).Package());
  182. }
  183. }
  184. #endregion
  185. #region ServiceStation
  186. public List<ServiceStationData> ServiceStation_GetAll()
  187. {
  188. return serviceStationMng.ServiceStation_GetAll();
  189. }
  190. public override void ServiceStation_Regist(ServiceStation serviceStation)
  191. {
  192. Logger.Info("[ApiCenterService]Regist serviceStation,stationName:" + serviceStation?.serviceStationInfo?.serviceStationName);
  193. serviceStationMng.ServiceStation_Add(serviceStation);
  194. }
  195. /// <summary>
  196. /// 更新服务站点设备硬件信息
  197. /// </summary>
  198. /// <param name="serviceStation"></param>
  199. public override bool ServiceStation_UpdateStationInfo(ServiceStation serviceStation)
  200. {
  201. Logger.Info("[ApiCenterService]ServiceStation_UpdateStationInfo,stationName:" + serviceStation?.serviceStationInfo?.serviceStationName);
  202. return serviceStationMng.ServiceStation_UpdateStationInfo(serviceStation);
  203. }
  204. public override void ServiceStation_Remove(IOrganizeConnection conn)
  205. {
  206. string connKey = ""+ conn.GetHashCode();
  207. var serviceStation = serviceStationMng.ServiceStation_Remove(connKey);
  208. if (serviceStation != null)
  209. {
  210. Logger.Info("[ApiCenterService]Remove serviceStation,stationName:" + serviceStation?.serviceStationInfo?.serviceStationName);
  211. }
  212. }
  213. public bool ServiceStation_Pause(string connKey)
  214. {
  215. var serviceStation = serviceStationMng.ServiceStation_Pause(connKey);
  216. if (serviceStation != null)
  217. {
  218. Logger.Info("[ApiCenterService]Pause serviceStation,stationName:" + serviceStation?.serviceStationInfo?.serviceStationName);
  219. }
  220. return serviceStation != null;
  221. }
  222. public bool ServiceStation_Start(string connKey)
  223. {
  224. var serviceStation = serviceStationMng.ServiceStation_Start(connKey);
  225. if (serviceStation != null)
  226. {
  227. Logger.Info("[ApiCenterService]Start serviceStation,stationName:" + serviceStation?.serviceStationInfo?.serviceStationName);
  228. }
  229. return serviceStation != null;
  230. }
  231. public bool ServiceStation_Stop(string connKey)
  232. {
  233. var serviceStation = serviceStationMng.ServiceStation_Remove(connKey);
  234. if (serviceStation != null)
  235. {
  236. Logger.Info("[ApiCenterService]Stop serviceStation,stationName:" + serviceStation?.serviceStationInfo?.serviceStationName);
  237. serviceStation.connection.Close();
  238. }
  239. return serviceStation != null;
  240. }
  241. #endregion
  242. #region ApiStation
  243. public List<ApiStationData> ApiStation_GetAll()
  244. {
  245. return apiStationMng.ApiStation_GetAll();
  246. }
  247. public bool ApiStation_Pause(string stationName)
  248. {
  249. Logger.Info("[ApiCenterService]Pause ApiStation,stationName:" + stationName);
  250. return apiStationMng.ApiStation_Pause(stationName);
  251. }
  252. public bool ApiStation_Start(string stationName)
  253. {
  254. Logger.Info("[ApiCenterService]Start ApiStation,stationName:" + stationName);
  255. return apiStationMng.ApiStation_Start(stationName);
  256. }
  257. #endregion
  258. #region ApiScopeEvent
  259. /// <summary>
  260. ///
  261. /// </summary>
  262. List<Func<IRpcContextData, ApiMessage, Action<Object, Vit.Core.Util.Pipelines.ByteData>>> apiScopeEventList = null;
  263. /// <summary>
  264. /// 在调用api前调用onScope,若onScope返回的结果(onDispose)不为空,则在api调用结束前调用onDispose
  265. /// </summary>
  266. /// <param name="apiScopeEvent"></param>
  267. public void AddApiScopeEvent(Func<IRpcContextData, ApiMessage, Action<Object, Vit.Core.Util.Pipelines.ByteData>> apiScopeEvent)
  268. {
  269. if (apiScopeEventList == null) apiScopeEventList=new List<Func<IRpcContextData, ApiMessage, Action<Object, Vit.Core.Util.Pipelines.ByteData>>>();
  270. apiScopeEventList.Add(apiScopeEvent);
  271. }
  272. #endregion
  273. }
  274. }