DbJSonLoader.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. using AutoMapper;
  2. using Edge.Core.Configuration;
  3. using Edge.Core.Core.database;
  4. using Edge.Core.Database;
  5. using Edge.Core.Database.Configuration.Models;
  6. using Edge.Core.Domain.FccMachineInfo.Output;
  7. using Edge.Core.Parser.BinaryParser;
  8. using Edge.Core.Processor.Communicator;
  9. using Edge.Core.Processor.Dispatcher.Attributes;
  10. using Microsoft.Extensions.DependencyInjection;
  11. using Microsoft.Extensions.Logging;
  12. using Microsoft.Extensions.Logging.Abstractions;
  13. using System;
  14. using System.Collections.Generic;
  15. using System.IO;
  16. using System.Linq;
  17. using System.Reflection;
  18. using System.Text;
  19. using System.Text.Json;
  20. using System.Threading.Tasks;
  21. namespace Edge.Core.Processor.Dispatcher
  22. {
  23. public class DbJSonLoader : IProcessorLoader, IProcessorMetaConfigAccessor
  24. {
  25. protected IServiceProvider services;
  26. protected static ILogger mainLogger = NullLogger.Instance;
  27. private Dictionary<IProcessor, ProcessorMetaConfig> processorInstanceAndMetaConfigDic
  28. = new Dictionary<IProcessor, ProcessorMetaConfig>();
  29. public DbJSonLoader(IServiceProvider services)
  30. {
  31. this.services = services;
  32. var loggerFactory = services.GetRequiredService<ILoggerFactory>();
  33. mainLogger = loggerFactory.CreateLogger("Main");
  34. }
  35. protected virtual IEnumerable<ProcessorMetaConfig> LoadProcessorMetaConfigs()
  36. {
  37. List<ProcessorMetaConfig> processorMetaConfigs = new List<ProcessorMetaConfig>();
  38. MysqlDbContext mysqlDbContext = new MysqlDbContext();
  39. List<Domain.FccMachineInfo.FccMachineInfo> fccMachineInfos = mysqlDbContext.FccMachineInfos.ToList();
  40. foreach (var item in fccMachineInfos)
  41. {
  42. int port = item.Port;
  43. ProcessorMetaConfig processorMetaConfig = new ProcessorMetaConfig();
  44. processorMetaConfig.Id = 16;
  45. processorMetaConfig.Name = "HengshanPaymentTerminal.HengshanPayTerminal.Hengs_938d2e2bd48b45ba_8";
  46. processorMetaConfig.Description = "";
  47. processorMetaConfig.Type = ProcessorTypeEnum.DeviceProcessor;
  48. ProcessorMetaPartsConfig hengshanPayTermHandler = new ProcessorMetaPartsConfig();
  49. hengshanPayTermHandler.Id = 38;
  50. hengshanPayTermHandler.Type = ProcessorMetaPartsTypeEnum.DeviceHandler;
  51. hengshanPayTermHandler.FullTypeString = "HengshanPaymentTerminal.HengshanPayTermHandler, HengshanPaymentTerminal, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
  52. hengshanPayTermHandler.ParametersJsonArrayStr = @"[{""pumpIds"":""1,2,3,4"",""pumpSubAddresses"":[{""PumpId"":1,""SubAddress"":1},{""PumpId"":2,""SubAddress"":2},{""PumpId"":3,""SubAddress"":3},{""PumpId"":4,""SubAddress"":4}],""pumpNozzleLogicIds"":[{""PumpId"":1,""LogicIds"":""1""},{""PumpId"":2,""LogicIds"":""1""},{""PumpId"":3,""LogicIds"":""1""},{""PumpId"":4,""LogicIds"":""1""}],""pumpSiteNozzleNos"":[{""PumpId"":1,""SiteNozzleNos"":""1""},{""PumpId"":2,""SiteNozzleNos"":""2""},{""PumpId"":3,""SiteNozzleNos"":""3""},{""PumpId"":4,""SiteNozzleNos"":""4""}],""nozzleLogicIds"":[{""NozzleNo"":1,""LogicId"":1},{""NozzleNo"":2,""LogicId"":1},{""NozzleNo"":3,""LogicId"":1},{""NozzleNo"":4,""LogicId"":1}]}]";
  53. ProcessorMetaPartsConfig generDeviceProcessor = new ProcessorMetaPartsConfig();
  54. generDeviceProcessor.Id = 40;
  55. generDeviceProcessor.Type = ProcessorMetaPartsTypeEnum.DeviceProcessor;
  56. generDeviceProcessor.FullTypeString = "Edge.Core.Processor.GenericDeviceProcessor`2, Edge.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
  57. generDeviceProcessor.ParametersJsonArrayStr = "[]";
  58. ProcessorMetaPartsConfig tcpServerCommunicator = new ProcessorMetaPartsConfig();
  59. tcpServerCommunicator.Id = 41;
  60. tcpServerCommunicator.Type = ProcessorMetaPartsTypeEnum.Communicator;
  61. tcpServerCommunicator.FullTypeString = "Edge.Core.Processor.Communicator.TcpServerCommunicator`1, Edge.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
  62. tcpServerCommunicator.ParametersJsonArrayStr = @"[" + port + @", 30, ""enabled"", ""enabled"", ""2""]";
  63. List<ProcessorMetaPartsConfig> processorMetaPartsConfigs = new List<ProcessorMetaPartsConfig>();
  64. processorMetaPartsConfigs.Add(hengshanPayTermHandler);
  65. processorMetaPartsConfigs.Add(generDeviceProcessor);
  66. processorMetaPartsConfigs.Add(tcpServerCommunicator);
  67. processorMetaConfig.Parts = processorMetaPartsConfigs;
  68. processorMetaConfig.Activated = true;
  69. processorMetaConfigs.Add(processorMetaConfig);
  70. }
  71. return processorMetaConfigs;
  72. //string json = @"[
  73. // {
  74. // ""Id"": 16,
  75. // ""Name"": ""HengshanPaymentTerminal.HengshanPayTerminal.Hengs_938d2e2bd48b45ba_8"",
  76. // ""Description"": """",
  77. // ""Type"": 0,
  78. // ""Parts"": [
  79. // {
  80. // ""Id"": 38,
  81. // ""Type"": 1,
  82. // ""FullTypeString"": ""HengshanPaymentTerminal.HengshanPayTermHandler, HengshanPaymentTerminal, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"",
  83. // ""ParametersJsonArrayStr"": ""[{\""pumpIds\"":\""1,2,3,4\"",\""pumpSubAddresses\"":[{\""PumpId\"":1,\""SubAddress\"":1},{\""PumpId\"":2,\""SubAddress\"":2},{\""PumpId\"":3,\""SubAddress\"":3},{\""PumpId\"":4,\""SubAddress\"":4}],\""pumpNozzleLogicIds\"":[{\""PumpId\"":1,\""LogicIds\"":\""1\""},{\""PumpId\"":2,\""LogicIds\"":\""1\""},{\""PumpId\"":3,\""LogicIds\"":\""1\""},{\""PumpId\"":4,\""LogicIds\"":\""1\""}],\""pumpSiteNozzleNos\"":[{\""PumpId\"":1,\""SiteNozzleNos\"":\""1\""},{\""PumpId\"":2,\""SiteNozzleNos\"":\""2\""},{\""PumpId\"":3,\""SiteNozzleNos\"":\""3\""},{\""PumpId\"":4,\""SiteNozzleNos\"":\""4\""}],\""nozzleLogicIds\"":[{\""NozzleNo\"":1,\""LogicId\"":1},{\""NozzleNo\"":2,\""LogicId\"":1},{\""NozzleNo\"":3,\""LogicId\"":1},{\""NozzleNo\"":4,\""LogicId\"":1}]}]""
  84. // },
  85. // {
  86. // ""Id"": 40,
  87. // ""Type"": 0,
  88. // ""FullTypeString"": ""Edge.Core.Processor.GenericDeviceProcessor`2, Edge.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"",
  89. // ""ParametersJsonArrayStr"": ""[]""
  90. // },
  91. // {
  92. // ""Id"": 41,
  93. // ""Type"": 5,
  94. // ""FullTypeString"": ""Edge.Core.Processor.Communicator.TcpServerCommunicator`1, Edge.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"",
  95. // ""ParametersJsonArrayStr"": ""[23456, 30, \""enabled\"", \""enabled\"", \""2\""]""
  96. // }
  97. // ],
  98. // ""Activated"": true
  99. // }
  100. //]";
  101. //IEnumerable<ProcessorMetaConfig> configs = JsonSerializer.Deserialize<IEnumerable<ProcessorMetaConfig>>(json);
  102. //return configs;
  103. //using (var scope = this.services.CreateScope())
  104. //{
  105. //var dbContext = scope.ServiceProvider.GetRequiredService<SqliteDbContext>();
  106. //var mapper = services.GetRequiredService<IMapper>();
  107. //var processorMetaConfigs =
  108. //mapper.Map<IEnumerable<ProcessorMetaConfig>>(
  109. // dbContext.ProcessorMetaConfigs.Include(i => i.Parts).OrderByDescending(mc => mc.TimeStamp));
  110. //}
  111. // now only for App
  112. //var systemInternalComponentEndPointTypes = new List<Type>();
  113. //foreach (var loadedAss in ObjectInstanceCreator.CurrentDomainAssemblies)
  114. //{
  115. // try
  116. // {
  117. // systemInternalComponentEndPointTypes.AddRange(loadedAss.GetTypes().Where(t =>
  118. // // if already loaded via db metaconfig, then don't load again even IsSystemInternalComponent
  119. // !processorMetaConfigs.SelectMany(mc => mc.Parts).Any(p => p.FullTypeString != t.AssemblyQualifiedName) &&
  120. // !t.IsInterface && !t.IsAbstract &&
  121. // (
  122. // //t.GetInterfaces().Any(ti =>ti.Name == typeof(IDeviceHandler<,>).Name)
  123. // //||
  124. // typeof(IAppProcessor).IsAssignableFrom(t)
  125. // ) &&
  126. // t.GetCustomAttributes<MetaPartsDescriptor>().Any(att => att.IsSystemInternalComponent)
  127. // )
  128. // );
  129. // }
  130. // catch
  131. // { }
  132. //}
  133. //var processorMetaConfigFromAir = systemInternalComponentEndPointTypes.Select(t => new ProcessorMetaConfig()
  134. //{
  135. // Id = new Random().Next(1000, int.MaxValue),
  136. // Activated = true,
  137. // Description = "SystemInternalComponent",
  138. // Name = "SystemInternalComponent_" + t.Name,
  139. // Type = ProcessorTypeEnum.AppProcessor,
  140. // Parts = new List<ProcessorMetaPartsConfig>()
  141. // {
  142. // new ProcessorMetaPartsConfig()
  143. // {
  144. // Id = new Random().Next(1000, int.MaxValue),
  145. // FullTypeString = t.AssemblyQualifiedName,
  146. // Type = ProcessorMetaPartsTypeEnum.App,
  147. // ParametersJsonArrayStr = "["+
  148. // t.GetCustomAttributes<MetaPartsDescriptor>().First(att=>att.IsSystemInternalComponent).DefaultCtorParamsJsonStrings.Aggregate((acc,n)=>acc+","+n)+"]",
  149. // }
  150. // }
  151. //});
  152. //return processorMetaConfigs.Concat(processorMetaConfigFromAir);
  153. }
  154. public IEnumerable<ProcessorInstanceOperatingResult> CreateAll()
  155. {
  156. this.processorInstanceAndMetaConfigDic.Clear();
  157. mainLogger.LogInformation("Use DbJSonLoader for Processor Meta Config.");
  158. mainLogger.LogInformation("==============Instantiate Processors (by DbJSonLoader)==============");
  159. Console.WriteLine();
  160. Console.WriteLine("==============Instantiate Processors (by DbJSonLoader)==============");
  161. var processorMetaConfigs = this.LoadProcessorMetaConfigs().Where(c => c.Activated);
  162. if (processorMetaConfigs == null || !processorMetaConfigs.Any())
  163. {
  164. //mainLogger.LogInformation("Found IDeviceHandler or IAppProcessor type: " + t.FullName + " but there's no meta config defined for it, will skip it");
  165. mainLogger.LogInformation("Found empty MetaConfig in db");
  166. mainLogger.LogInformation("==============Instantiate Processors End==============");
  167. Console.WriteLine("==============Instantiate Processors End==============");
  168. return Enumerable.Empty<ProcessorInstanceOperatingResult>();
  169. }
  170. var createResults = new List<ProcessorInstanceOperatingResult>();
  171. processorMetaConfigs.ToList().ForEach(mc =>
  172. {
  173. mainLogger.LogInformation("constructing [id:" + mc.Id + "]: " + mc.Name + ", type: " + mc.Type);// + ", from: " + t.Assembly.FullName + ", assemblyPath: " + t.Assembly.Location);
  174. Console.WriteLine("[id:" + mc.Id + "]: " + mc.Name);// + " from: " + t.Assembly.GetName().Name);
  175. try
  176. {
  177. var p = ObjectInstanceCreator.CreateProcessor<IProcessor>(mc, new object[] { this.services });
  178. createResults.Add(new ProcessorInstanceOperatingResult()
  179. {
  180. Succeed = true,
  181. ProcessorInstance = p,
  182. HostVersion = Assembly.GetAssembly(p.GetType()).GetName().Version.ToString(),
  183. CoreVersion = Assembly.GetAssembly(typeof(IProcessor)).GetName().Version.ToString(),
  184. MetaConfig = mc,
  185. });
  186. this.processorInstanceAndMetaConfigDic.Add(p, mc);
  187. }
  188. catch (Exception exxxxx)
  189. {
  190. createResults.Add(new ProcessorInstanceOperatingResult()
  191. {
  192. Succeed = false,
  193. MetaConfig = mc,
  194. CoreVersion = Assembly.GetAssembly(typeof(IProcessor)).GetName().Version.ToString(),
  195. FailedReason = exxxxx.ToString()
  196. });
  197. mainLogger.LogError(" - Failed for instantiate: " + "[id:" + mc.Id + "]: " + mc.Name + ", type: " + mc.Type
  198. //+ ", from: " + t.Assembly.FullName + ", assemblyPath: " + t.Assembly.Location
  199. + Environment.NewLine + " " + exxxxx.ToString());
  200. Console.BackgroundColor = ConsoleColor.Red;
  201. Console.ForegroundColor = ConsoleColor.Black;
  202. Console.WriteLine(" - Failed for instantiate: " + "[id:" + mc.Id + "]: " + mc.Name + Environment.NewLine + " " + exxxxx.ToString().Substring(0, 90) + "...");
  203. Console.ResetColor();
  204. }
  205. });
  206. mainLogger.LogInformation("==============Instantiate Processors End==============");
  207. Console.WriteLine("==============Instantiate Processors End==============");
  208. return createResults;
  209. }
  210. public IProcessor Create(string configName)
  211. {
  212. if (string.IsNullOrEmpty(configName)) throw new ArgumentException(nameof(configName));
  213. //ignore the IsActivated
  214. var processorMetaConfig = this.LoadProcessorMetaConfigs().First(mc => mc.Name == configName);
  215. var p = ObjectInstanceCreator.CreateProcessor<IProcessor>(processorMetaConfig, new object[] { this.services });
  216. return p;
  217. }
  218. public async Task<ProcessorMetaPartsConfig> GetMetaPartsMetaConfigAsync(
  219. IProcessor processor, ProcessorMetaPartsTypeEnum metaPartsType)
  220. {
  221. if (!this.processorInstanceAndMetaConfigDic.TryGetValue(processor, out ProcessorMetaConfig pMetaConfig))
  222. return null;
  223. using (var scope = this.services.CreateScope())
  224. {
  225. return null;
  226. }
  227. }
  228. public async Task<ProcessorMetaPartsConfig> UpdateMetaPartsMetaConfigAsync(
  229. IProcessor processor, ProcessorMetaPartsTypeEnum metaPartsType, object[] parameters)
  230. {
  231. if (!this.processorInstanceAndMetaConfigDic.TryGetValue(processor, out ProcessorMetaConfig pMetaConfig))
  232. return null;
  233. using (var scope = this.services.CreateScope())
  234. {
  235. return null;
  236. }
  237. }
  238. public async Task<bool> RemoveMetaPartsMetaConfigAsync(IProcessor processor, int processorMetaPartsConfigId)
  239. {
  240. if (!this.processorInstanceAndMetaConfigDic.TryGetValue(processor, out ProcessorMetaConfig pMetaConfig))
  241. return false;
  242. using (var scope = this.services.CreateScope())
  243. {
  244. return false;
  245. }
  246. }
  247. public async Task<IEnumerable<ProcessorMetaConfig>> GetMetaConfigAsync()
  248. {
  249. return await this.GetMetaConfigAsync(null);
  250. }
  251. /// <summary>
  252. /// Get the meta configs by its linked sourceEndpointFullTypeStr with *sql likes* input parameter.
  253. /// </summary>
  254. /// <param name="sourceEndpointFullTypeStr"></param>
  255. /// <returns></returns>
  256. public async Task<IEnumerable<ProcessorMetaConfig>> GetMetaConfigAsync(string sourceEndpointFullTypeStr)
  257. {
  258. return null;
  259. }
  260. public async Task<ProcessorMetaConfig> UpsertMetaConfigAsync(ProcessorMetaConfig metaConfig)
  261. {
  262. return null;
  263. }
  264. public async Task<bool> RemoveMetaConfigAsync(int metaConfigId)
  265. {
  266. return false;
  267. }
  268. }
  269. }