DefaultDispatcher.cs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. using AutoMapper;
  2. using Edge.Core.Configuration;
  3. using Edge.Core.Database.Configuration.Models;
  4. using Edge.Core.Processor.Communicator;
  5. using Edge.Core.Processor.Dispatcher.Attributes;
  6. using Edge.Core.UniversalApi;
  7. using Edge.Core.UniversalApi.CommunicationProvider;
  8. using Microsoft.EntityFrameworkCore;
  9. using Microsoft.Extensions.DependencyInjection;
  10. using Microsoft.Extensions.Logging;
  11. using Microsoft.Extensions.Logging.Abstractions;
  12. using Newtonsoft.Json.Schema;
  13. using Newtonsoft.Json.Schema.Generation;
  14. using System;
  15. using System.Collections.Generic;
  16. using System.IO;
  17. using System.Linq;
  18. using System.Reflection;
  19. using System.Runtime.Loader;
  20. using System.Text;
  21. using System.Text.Json;
  22. using System.Text.Json.Serialization;
  23. using System.Text.RegularExpressions;
  24. using System.Threading.Tasks;
  25. namespace Edge.Core.Processor.Dispatcher
  26. {
  27. [UniversalApi(Name = DefaultDispatcher.OnProcessorsLifeCycleChangedEventApiName,
  28. EventDataType = typeof(OnProcessorsLifeCycleChangedEventArg),
  29. Description = "When life cycle of processors are changed, an event will fired with details for each processor.")]
  30. [UniversalApi(Name = GenericAlarm.UniversalApiEventName, EventDataType = typeof(object), Description = "Fire GenericAlarm which mostly used in Alarm UI Bar for attracting users.")]
  31. [MetaPartsDescriptor("DefaultDispatcher", "Processors' life cycle manager.",
  32. new[] { "Managment" },
  33. IsSystemInternalComponent = true)]
  34. public partial class DefaultDispatcher : IAppProcessor
  35. {
  36. public const string OnProcessorsLifeCycleChangedEventApiName = "OnProcessorsLifeCycleChanged";
  37. private List<OnProcessorsLifeCycleChangedEventArg> historyProcessorsLifeCycleChangedEvents
  38. = new List<OnProcessorsLifeCycleChangedEventArg>();
  39. public event EventHandler<OnProcessorsInstantiatedEventArg> OnProcessorInstantiated;
  40. /// <summary>
  41. /// latest instantiated processor result.
  42. /// </summary>
  43. private IEnumerable<ProcessorInstanceOperatingResult> currentProcessorInstantiatedOperatingResults;
  44. //public static EventHandler OnRequestDispatch;
  45. protected IServiceProvider services;
  46. protected static ILogger mainLogger = NullLogger.Instance;
  47. public string MetaConfigName { get; set; } = "ProcessorsDispatcher";
  48. public static string DefaultClientAcceptLanguage = "zh-cn";
  49. static DefaultDispatcher()
  50. {
  51. // replace with your license key, https://www.newtonsoft.com/jsonschema
  52. string licenseKey = "4278-fsXeHk11Z1h23Ki2z21y8tDMv43+eMW7Gcnv6caaGWz6w8Q4xrsg/Ow/moZc6GrkgjCaiq33yzr/meweRwNrPHsfqTc1rgpJu385YKKqMbJ5UKUDV1csm5ZwpMBIc1JJDbQwVZuDqUyOFqLZ31uk+10j9i8uMTPGEzLI729edmx7IklkIjo0Mjc4LCJFeHBpcnlEYXRlIjoiMjAyMS0wNy0wNFQwNjoxMjozMC43Mzc1NTE1WiIsIlR5cGUiOiJKc29uU2NoZW1hQnVzaW5lc3MifQ==";
  53. License.RegisterLicense(licenseKey);
  54. //AppDomain.CurrentDomain.TypeResolve += (s, args) =>
  55. //{
  56. // var type = ObjectInstanceCreator.DefaultSearchLocalAssemblyFileTypeResolver(args.Name);
  57. // return type?.Assembly;
  58. //};
  59. //AppDomain.CurrentDomain.AssemblyResolve += (s, args) =>
  60. //{
  61. // return ObjectInstanceCreator.DefaultSearchLocalAssemblyFileAssemblyResolver(args.Name);
  62. //};
  63. }
  64. public DefaultDispatcher(IServiceProvider services)
  65. {
  66. this.services = services;
  67. var loggerFactory = services.GetRequiredService<ILoggerFactory>();
  68. mainLogger = loggerFactory.CreateLogger("Main");
  69. ObjectInstanceCreator.mainLogger = mainLogger;
  70. mainLogger.LogInformation("AppDomain.CurrentDomain.CurrentDomainAssemblies: " +
  71. ObjectInstanceCreator.CurrentDomainAssemblies?.Select(ass => ass.FullName + " " + (!ass.IsDynamic ? ass.Location ?? "" : "")).OrderBy(o => o)
  72. .Aggregate(Environment.NewLine, (acc, n) => acc + n + Environment.NewLine) ?? "");
  73. //route this special event into this processor rather than from different processors to form an unified api entrance.
  74. this.services.GetRequiredService<UniversalApiHub>().OnUniversalGenericAlarmEventFired += async (s, a) =>
  75. {
  76. await this.services.GetRequiredService<UniversalApiHub>().FireEvent(this,
  77. GenericAlarm.UniversalApiEventName, new
  78. {
  79. Title = a.GenericAlarm.Title.LocalizedContent(DefaultClientAcceptLanguage),
  80. Category = a.GenericAlarm.Category?.LocalizedContent(DefaultClientAcceptLanguage),
  81. SubCategory = a.GenericAlarm.SubCategory?.LocalizedContent(DefaultClientAcceptLanguage),
  82. Detail = a.GenericAlarm.Detail?.LocalizedContent(DefaultClientAcceptLanguage),
  83. a.GenericAlarm.Severity,
  84. a.PersistId
  85. });
  86. };
  87. }
  88. /// <summary>
  89. ///
  90. /// </summary>
  91. /// <param name="reason"></param>
  92. /// <returns></returns>
  93. public virtual async Task<IEnumerable<ProcessorInstanceOperatingResult>> CreateProcessorsAsync(string reason, bool enableSafeBoot = false)
  94. {
  95. var processorLoader = this.services.GetRequiredService<IProcessorLoader>();
  96. var defaultDispatcherProcessorInstanceOperatingResult = new ProcessorInstanceOperatingResult()
  97. {
  98. Succeed = true,
  99. ProcessorInstance = this,
  100. //for this special AppProcessor as it's included in Edge.Core, so both version are the same
  101. HostVersion = Assembly.GetAssembly(this.GetType()).GetName().Version.ToString(),
  102. CoreVersion = Assembly.GetAssembly(this.GetType()).GetName().Version.ToString(),
  103. };
  104. if (enableSafeBoot)
  105. this.currentProcessorInstantiatedOperatingResults = new[] { defaultDispatcherProcessorInstanceOperatingResult };
  106. else
  107. this.currentProcessorInstantiatedOperatingResults =
  108. new[] { defaultDispatcherProcessorInstanceOperatingResult }.Concat(processorLoader.CreateAll()).ToList();
  109. this.OnProcessorInstantiated?.Invoke(this, new OnProcessorsInstantiatedEventArg(this.currentProcessorInstantiatedOperatingResults));
  110. var createEvtArg = new OnProcessorsLifeCycleChangedEventArg(
  111. this.currentProcessorInstantiatedOperatingResults.Select(i => ProcessorLifeCycleOperationResult.From(i)).ToList(),
  112. "ProcessorsInstantiate",
  113. reason);
  114. this.historyProcessorsLifeCycleChangedEvents.Add(createEvtArg);
  115. return this.currentProcessorInstantiatedOperatingResults;
  116. }
  117. public virtual async Task<IEnumerable<ProcessorInstanceOperatingResult>> StartProcessorsAsync(
  118. IEnumerable<IProcessor> processorInstances, string reason)
  119. {
  120. //App will call Init(...) before Start()
  121. var initOrStartResults = new List<ProcessorInstanceOperatingResult>();
  122. mainLogger.LogInformation("==============Start Processors (total: " + processorInstances.Count() + ")==============");
  123. Console.WriteLine();
  124. Console.WriteLine("==============Start Processors (total: " + processorInstances.Count() + ")==============");
  125. var pendingForStartInstances = processorInstances.ToList();
  126. // call App.Init(...), and only succeed ones will call its Start() later.
  127. processorInstances.OfType<IAppProcessor>().ToList().ForEach(app =>
  128. {
  129. try
  130. {
  131. app.Init(processorInstances);
  132. }
  133. catch (Exception eee)
  134. {
  135. //remove it for avoid call Start()
  136. pendingForStartInstances.Remove(app);
  137. initOrStartResults.Add(new ProcessorInstanceOperatingResult()
  138. {
  139. //WhatThisProcessorUsedFor = p.ProcessorDescriptor().DeviceHandlerOrApp.GetType().GetCustomAttributes<MetaPartsDescriptor>()?.FirstOrDefault()?.Description,
  140. ProcessorInstance = app,
  141. Succeed = false,
  142. FailedReason = "Call App.Init(...) exceptioned: " + eee.ToString(),
  143. //Description = $"Ordinary start a processor but failed with an unexpected fatal error",
  144. });
  145. mainLogger.LogError("Initing [" + (app.MetaConfigName ?? "") + "] failed and will skip its Start: " + eee.ToString());
  146. Console.BackgroundColor = ConsoleColor.Red;
  147. Console.ForegroundColor = ConsoleColor.Black;
  148. Console.WriteLine("Initing [" + (app.MetaConfigName ?? "") + "] failed: " + Environment.NewLine + " " + eee.ToString().Substring(0, 70) + "...");
  149. Console.ResetColor();
  150. }
  151. });
  152. for (int i = 0; i < pendingForStartInstances.Count(); i++)
  153. {
  154. var p = pendingForStartInstances.ElementAt(i);
  155. try
  156. {
  157. mainLogger.LogInformation("Starting [" + (p.MetaConfigName ?? "") + "]: ");
  158. Console.WriteLine("Starting [" + (p.MetaConfigName ?? "") + "]: ");
  159. bool r = await p.Start();
  160. if (r)
  161. {
  162. initOrStartResults.Add(new ProcessorInstanceOperatingResult()
  163. {
  164. //WhatThisProcessorUsedFor = p.ProcessorDescriptor().DeviceHandlerOrApp.GetType().GetCustomAttributes<MetaPartsDescriptor>()?.FirstOrDefault()?.Description,
  165. ProcessorInstance = p,
  166. Succeed = true,
  167. //Description = $"Ordinary start a processor and succeed.",
  168. });
  169. mainLogger.LogInformation(" Started");
  170. Console.WriteLine(" Started");
  171. }
  172. else
  173. {
  174. initOrStartResults.Add(new ProcessorInstanceOperatingResult()
  175. {
  176. //WhatThisProcessorUsedFor = p.ProcessorDescriptor().DeviceHandlerOrApp.GetType().GetCustomAttributes<MetaPartsDescriptor>()?.FirstOrDefault()?.Description,
  177. ProcessorInstance = p,
  178. Succeed = false,
  179. //Description = $"Ordinary start a processor but failed with a graceful reason",
  180. });
  181. mainLogger.LogInformation(" Failed for starting");
  182. Console.BackgroundColor = ConsoleColor.Red;
  183. Console.ForegroundColor = ConsoleColor.Black;
  184. Console.WriteLine(" !!!Failed for starting!!!");
  185. Console.ResetColor();
  186. }
  187. }
  188. catch (Exception eee)
  189. {
  190. initOrStartResults.Add(new ProcessorInstanceOperatingResult()
  191. {
  192. //WhatThisProcessorUsedFor = p.ProcessorDescriptor().DeviceHandlerOrApp.GetType().GetCustomAttributes<MetaPartsDescriptor>()?.FirstOrDefault()?.Description,
  193. ProcessorInstance = p,
  194. Succeed = false,
  195. FailedReason = eee.ToString(),
  196. //Description = $"Ordinary start a processor but failed with an unexpected fatal error",
  197. });
  198. mainLogger.LogError(" - Failed for start: [" + p.MetaConfigName + "]" + Environment.NewLine + " " + eee.ToString());
  199. Console.BackgroundColor = ConsoleColor.Red;
  200. Console.ForegroundColor = ConsoleColor.Black;
  201. Console.WriteLine(" - Failed for start: [" + p.MetaConfigName + "]" + Environment.NewLine + " " + eee.ToString().Substring(0, 70) + "...");
  202. Console.ResetColor();
  203. }
  204. }
  205. mainLogger.LogInformation("==============Start Processors End==============\r\n");
  206. Console.WriteLine("==============Start Processors End==============\r\n");
  207. var startEvtArg = new OnProcessorsLifeCycleChangedEventArg(
  208. initOrStartResults.Select(i => ProcessorLifeCycleOperationResult.From(i)).ToList(),
  209. "ProcessorsStart",
  210. reason);
  211. var universalApiHub = this.services.GetRequiredService<UniversalApiHub>();
  212. await universalApiHub.FireEvent(this, DefaultDispatcher.OnProcessorsLifeCycleChangedEventApiName, startEvtArg);
  213. this.historyProcessorsLifeCycleChangedEvents.Add(startEvtArg);
  214. return initOrStartResults;
  215. }
  216. /// <summary>
  217. /// Call Stop() on target processors, and correlated life cycle operation results will be recorded.
  218. /// </summary>
  219. /// <param name="processors"></param>
  220. /// <param name="reason"></param>
  221. /// <returns></returns>
  222. public virtual async Task<IEnumerable<ProcessorInstanceOperatingResult>> StopProcessorsAsync(
  223. IEnumerable<IProcessor> processors, string reason)
  224. {
  225. if (processors == null || !processors.Any()) return Enumerable.Empty<ProcessorInstanceOperatingResult>();
  226. var stopResults = new List<ProcessorInstanceOperatingResult>();
  227. foreach (var p in processors)
  228. {
  229. try
  230. {
  231. Console.WriteLine(" stopping " + p.MetaConfigName + "..." + " by reason: " + (reason ?? ""));
  232. mainLogger.LogInformation(" stopping " + p.MetaConfigName + " by reason: " + (reason ?? ""));
  233. bool r = await p.Stop();
  234. if (r)
  235. {
  236. stopResults.Add(new ProcessorInstanceOperatingResult()
  237. {
  238. //WhatThisProcessorUsedFor = p.ProcessorDescriptor().DeviceHandlerOrApp.GetType().GetCustomAttributes<MetaPartsDescriptor>()?.FirstOrDefault()?.Description,
  239. //ProcessorMetaConfigName = p.MetaConfigName,
  240. ProcessorInstance = p,
  241. Succeed = true,
  242. //Description = $"Ordinary stop a processor and succeed.",
  243. });
  244. Console.WriteLine(" Stopped");
  245. mainLogger.LogInformation(" Stopped");
  246. }
  247. else
  248. {
  249. stopResults.Add(new ProcessorInstanceOperatingResult()
  250. {
  251. //WhatThisProcessorUsedFor = p.ProcessorDescriptor().DeviceHandlerOrApp.GetType().GetCustomAttributes<MetaPartsDescriptor>()?.FirstOrDefault()?.Description,
  252. //ProcessorMetaConfigName = p.MetaConfigName,
  253. ProcessorInstance = p,
  254. Succeed = false,
  255. //Description = $"Ordinary stop a processor but failed with a graceful reason",
  256. });
  257. }
  258. }
  259. catch (Exception xxxx)
  260. {
  261. stopResults.Add(new ProcessorInstanceOperatingResult()
  262. {
  263. //WhatThisProcessorUsedFor = p.ProcessorDescriptor().DeviceHandlerOrApp.GetType().GetCustomAttributes<MetaPartsDescriptor>()?.FirstOrDefault()?.Description,
  264. //ProcessorMetaConfigName = p.MetaConfigName,
  265. Succeed = false,
  266. FailedReason = xxxx.ToString(),
  267. //Description = $"Ordinary stop a processor but failed with an unexpected fatal error",
  268. });
  269. Console.BackgroundColor = ConsoleColor.Red;
  270. Console.ForegroundColor = ConsoleColor.Black;
  271. Console.WriteLine(" stopping " + p.MetaConfigName + " failed.");
  272. Console.ResetColor();
  273. mainLogger.LogInformation(" stopping " + p.MetaConfigName + " failed: "
  274. + Environment.NewLine
  275. + xxxx);
  276. }
  277. }
  278. var stopEvtArg = new OnProcessorsLifeCycleChangedEventArg(
  279. stopResults.Select(i => ProcessorLifeCycleOperationResult.From(i)).ToList(),
  280. "ProcessorsStop",
  281. reason);
  282. this.historyProcessorsLifeCycleChangedEvents.Add(stopEvtArg);
  283. var universalApiHub = this.services.GetRequiredService<UniversalApiHub>();
  284. await universalApiHub.FireEvent(this, DefaultDispatcher.OnProcessorsLifeCycleChangedEventApiName,
  285. stopEvtArg);
  286. return stopResults;
  287. }
  288. [UniversalApi(Description = "Get history datas for Processors' LifeCycle Changed Event")]
  289. public Task<List<OnProcessorsLifeCycleChangedEventArg>> GetHistoryProcessorsLifeCycleChangedEvents()
  290. {
  291. return Task.FromResult(this.historyProcessorsLifeCycleChangedEvents);
  292. }
  293. [UniversalApi]
  294. public async Task<ProcessorMetaConfig> UpsertProcessorMetaConfigAsync(ProcessorMetaConfig input)
  295. {
  296. var accessor = this.services.GetService<IProcessorMetaConfigAccessor>();
  297. if (accessor == null) throw new NotSupportedException("Could not find ProcessorMetaConfigAccessor, may current ProcessorLoader does not support the MetaConfig Upsert???");
  298. return await accessor.UpsertMetaConfigAsync(input);
  299. }
  300. [UniversalApi(Description = "Get all ProcessorMetaConfigs with endPointFullTypeStr qualified with input parameter, or leave null or empty to get all")]
  301. public async Task<IEnumerable<ProcessorMetaConfig>> GetProcessorMetaConfigAsync(string sourceEndpointFullTypeStr)
  302. {
  303. var accessor = this.services.GetService<IProcessorMetaConfigAccessor>();
  304. if (accessor == null) throw new NotSupportedException("Could not find ProcessorMetaConfigAccessor, may current ProcessorLoader does not support the MetaConfig Get???");
  305. return await accessor.GetMetaConfigAsync(sourceEndpointFullTypeStr);
  306. }
  307. [UniversalApi(InputParametersExampleJson = "[121]", Description = "Remove a ProcessorMetaConfig and all its MetaPartsConfigs")]
  308. public async Task<bool> RemoveProcessorMetaConfigAsync(int metaConfigId)
  309. {
  310. var accessor = this.services.GetService<IProcessorMetaConfigAccessor>();
  311. if (accessor == null) throw new NotSupportedException("Could not find ProcessorMetaConfigAccessor, may current ProcessorLoader does not support the MetaConfig Remove???");
  312. return await accessor.RemoveMetaConfigAsync(metaConfigId);
  313. }
  314. [UniversalApi(InputParametersExampleJson = "[\"wayne dart pump configuration 1\"]",
  315. Description = "Test by constructing a Processor instance on the air from specified metaConfig, start, test and then stop it, any error will treat as test failed.")]
  316. public async Task<bool> TestProcessorMetaConfigAsync(string configName, string[] parameters)
  317. {
  318. var processorLoader = this.services.GetRequiredService<IProcessorLoader>();
  319. IProcessor p = null;
  320. try
  321. {
  322. p = processorLoader.Create(configName);
  323. if (p == null) throw new InvalidOperationException($"Test failed on constructing processor.");//: {p.MetaConfigName}");
  324. var startResult = false;
  325. try
  326. {
  327. startResult = await p.Start();
  328. if (!startResult)
  329. throw new InvalidOperationException($"Test failed on starting processor.");
  330. await p.Test(parameters);
  331. }
  332. catch (Exception eee)
  333. {
  334. throw;// new InvalidOperationException($"Test failed on pre-starting processor with error: {eee}");
  335. }
  336. }
  337. finally
  338. {
  339. if (p != null)
  340. {
  341. var stopResult = false;
  342. try
  343. {
  344. stopResult = await p.Stop();
  345. }
  346. catch (Exception eee)
  347. {
  348. throw;// new InvalidOperationException($"Test failed on pre-stop processor with error: {eee}");
  349. }
  350. if (!stopResult)
  351. throw new InvalidOperationException($"Test failed on stopping processor.");
  352. }
  353. }
  354. return true;
  355. }
  356. /// <summary>
  357. ///
  358. /// </summary>
  359. /// <param name="processorMetaPartsConfigId"></param>
  360. /// <returns>the original ParametersJsonArrayStr if no resolve method defined in target meta part type, or updated value by call the resolve method</returns>
  361. [UniversalApi]
  362. public async Task<string> ResolveProcessorMetaPartsConfigCompatibilityAsync(int processorMetaPartsConfigId)
  363. {
  364. var accessor = this.services.GetService<IProcessorMetaConfigAccessor>();
  365. if (accessor == null) throw new NotSupportedException("Could not find ProcessorMetaConfigAccessor, may current ProcessorLoader does not support the MetaConfig Get???");
  366. var allMetaConfigs = await accessor.GetMetaConfigAsync();
  367. var targetMetaPartsInfo = allMetaConfigs.SelectMany(mc => mc.Parts,
  368. (metaConfig, metaPartsConfig) => new { metaConfig, metaPartsConfig })
  369. .FirstOrDefault(p => p.metaPartsConfig.Id == processorMetaPartsConfigId);
  370. if (targetMetaPartsInfo == null) throw new ArgumentException("Could not find processorMetaPartsConfig with id: " + processorMetaPartsConfigId);
  371. if (targetMetaPartsInfo.metaPartsConfig.TryCallMetaPartsConfigCompatibilityMethodAndUpdate())
  372. {
  373. //targetMetaPartsInfo.metaConfig.Parts.First(p => p.Id == targetMetaPartsInfo.metaPartsConfig.Id)
  374. // .ParametersJsonArrayStr = reformatParamsStr;
  375. //await accessor.UpsertMetaConfigAsync(targetMetaPartsInfo.metaConfig);
  376. }
  377. return targetMetaPartsInfo.metaPartsConfig.ParametersJsonArrayStr;
  378. }
  379. [UniversalApi(Description = "Stop all exist non-system processors, and re-instantiate, re-start them again")]
  380. public async Task<IEnumerable<ProcessorLifeCycleOperationResult>> ReloadProcessorsAsync(string reason = "")
  381. {
  382. try
  383. {
  384. mainLogger.LogInformation($"Stop Non-System Processors is on requesting by reason: {reason}");
  385. Console.BackgroundColor = ConsoleColor.Yellow;
  386. Console.ForegroundColor = ConsoleColor.Black;
  387. Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff") + $"=====>Stop All Processors is on requesting by reason: {reason}");
  388. Console.ResetColor();
  389. var stopResults = await this.StopProcessorsAsync(
  390. this.currentProcessorInstantiatedOperatingResults.Where(r => r.ProcessorInstance != null)
  391. .Select(r => r.ProcessorInstance).Except(new[] { this }),
  392. reason);
  393. mainLogger.LogInformation(" Stop Non-System Processors done successfully");
  394. Console.BackgroundColor = ConsoleColor.Green;
  395. Console.ForegroundColor = ConsoleColor.Black;
  396. Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff") + "<=====Stop All Processors done successfully");
  397. Console.ResetColor();
  398. //return stopResults;
  399. }
  400. catch (Exception exx)
  401. {
  402. mainLogger.LogError("******Stop Non-System Processors got internal error!\r\n" + exx.ToString());
  403. Console.BackgroundColor = ConsoleColor.Red;
  404. Console.ForegroundColor = ConsoleColor.Black;
  405. Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff") + "******Stop All Processors got internal error: " + exx.ToString().Substring(0, 70) + "...");
  406. Console.ResetColor();
  407. throw;
  408. }
  409. try
  410. {
  411. mainLogger.LogInformation($"Create All Processors is on requesting by reason: {reason}");
  412. Console.BackgroundColor = ConsoleColor.Yellow;
  413. Console.ForegroundColor = ConsoleColor.Black;
  414. Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff") + $"=====>Create All Processors is on requesting by reason: {reason}");
  415. Console.ResetColor();
  416. var createResults = await this.CreateProcessorsAsync(reason);
  417. mainLogger.LogInformation(" Create All Processors done successfully");
  418. Console.BackgroundColor = ConsoleColor.Green;
  419. Console.ForegroundColor = ConsoleColor.Black;
  420. Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff") + "<=====Create All Processors done successfully");
  421. Console.ResetColor();
  422. //return createResults;
  423. }
  424. catch (Exception exx)
  425. {
  426. mainLogger.LogError("******Create All Processors got internal error!\r\n" + exx.ToString());
  427. Console.BackgroundColor = ConsoleColor.Red;
  428. Console.ForegroundColor = ConsoleColor.Black;
  429. Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff") + "******Create All Processors got internal error: " + exx.ToString().Substring(0, 70) + "...");
  430. Console.ResetColor();
  431. throw;
  432. }
  433. try
  434. {
  435. mainLogger.LogInformation($"Start All Processors is on requesting by reason: {reason}");
  436. Console.BackgroundColor = ConsoleColor.Yellow;
  437. Console.ForegroundColor = ConsoleColor.Black;
  438. Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff") + $"=====>Start All Processors is on requesting by reason: {reason}");
  439. Console.ResetColor();
  440. var startResults = await this.StartProcessorsAsync(
  441. this.currentProcessorInstantiatedOperatingResults.Where(r => r.Succeed).Select(r => r.ProcessorInstance),
  442. reason);
  443. mainLogger.LogInformation(" Start All Processors done successfully");
  444. Console.BackgroundColor = ConsoleColor.Green;
  445. Console.ForegroundColor = ConsoleColor.Black;
  446. Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff") + "<=====Start All Processors done successfully");
  447. Console.ResetColor();
  448. return startResults.Select(r => ProcessorLifeCycleOperationResult.From(r));
  449. }
  450. catch (Exception exx)
  451. {
  452. mainLogger.LogError("******Start All Processors got internal error!\r\n" + exx.ToString());
  453. Console.BackgroundColor = ConsoleColor.Red;
  454. Console.ForegroundColor = ConsoleColor.Black;
  455. Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff") + "******Start All Processors got internal error: " + exx.ToString().Substring(0, 70) + "...");
  456. Console.ResetColor();
  457. throw;
  458. }
  459. }
  460. /// <summary>
  461. ///
  462. /// </summary>
  463. /// <param name="apiType">localmqtt, remotemqtt, webapi</param>
  464. /// <param name="tags"></param>
  465. /// <returns></returns>
  466. [UniversalApi(InputParametersExampleJson = "[\"localMqtt\",[\"Pump\",\"ATG\"]]")]
  467. public async Task<IEnumerable<UniversalApiInfoDoc>> ShowMeApi(string apiType, string[] tags)
  468. {
  469. var communicationProvider =
  470. this.services.GetService<UniversalApiHub>()?.CommunicationProviders?.Where(p => p.GetType().Name.Contains(apiType, StringComparison.OrdinalIgnoreCase))?.FirstOrDefault();
  471. if (communicationProvider == null)
  472. return Enumerable.Empty<UniversalApiInfoDoc>();
  473. return communicationProvider.GetApiDocuments().FilterByTags(tags);
  474. }
  475. public void Init(IEnumerable<IProcessor> processors)
  476. {
  477. }
  478. public async Task<bool> Start()
  479. {
  480. try
  481. {
  482. Console.WriteLine(" Setup Universal Api communicators...");
  483. await services.GetRequiredService<UniversalApiHub>()
  484. .InitAsync(this.currentProcessorInstantiatedOperatingResults.Where(r => r.Succeed).Select(r => r.ProcessorInstance));
  485. Console.WriteLine(" Setup finished.");
  486. }
  487. catch (Exception exxx)
  488. {
  489. mainLogger.LogInformation(" Setup UniversalApiHub Failed: " + exxx);
  490. Console.BackgroundColor = ConsoleColor.Red;
  491. Console.ForegroundColor = ConsoleColor.Black;
  492. Console.WriteLine(" Setup UniversalApiHub Failed: " + exxx);
  493. Console.ResetColor();
  494. throw;
  495. }
  496. return true;
  497. }
  498. public Task<bool> Stop()
  499. {
  500. mainLogger.LogError("Stopping DefaultDispatcher processor...");
  501. Console.BackgroundColor = ConsoleColor.Red;
  502. Console.ForegroundColor = ConsoleColor.Black;
  503. Console.WriteLine(" FATAL, Stopping DefaultDispatcher will lose major functions...");
  504. Console.ResetColor();
  505. this.services.GetRequiredService<UniversalApiHub>().CommunicationProviders.ToList().ForEach(c => c.Dispose());
  506. return Task.FromResult(true);
  507. }
  508. }
  509. }