123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304 |
- using Edge.Core.Configuration;
- using Microsoft.Extensions.DependencyInjection;
- using Microsoft.Extensions.Logging;
- using Microsoft.Extensions.Logging.Abstractions;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Text.RegularExpressions;
- using System.Threading.Tasks;
- namespace Edge.Core.Processor.Dispatcher
- {
- public class LegacySettingsXmlFileLoader : IProcessorLoader
- {
- protected IServiceProvider services;
- protected static ILogger mainLogger = NullLogger.Instance;
- public LegacySettingsXmlFileLoader(IServiceProvider services)
- {
- this.services = services;
- var loggerFactory = services.GetRequiredService<ILoggerFactory>();
- mainLogger = loggerFactory.CreateLogger("Main");
- }
- public IEnumerable<ProcessorInstanceOperatingResult> CreateAll()
- {
- mainLogger.LogInformation("Use LegacySettingsXmlFileLoader for Processor Meta Config.");
- Console.WriteLine("Use LegacySettingsXmlFileLoader for Processor Meta Config.");
- var configurator = this.services.GetRequiredService<Configurator>();
- var processorConfigs = configurator.DeviceProcessorConfiguration.Processor.OrderBy(pc => pc.Name).ToList();
- mainLogger.LogInformation("==============Instantiate Processors (total: " + processorConfigs.Count() + ")==============");
- Console.WriteLine();
- Console.WriteLine("==============Instantiate Processors (total: " + processorConfigs.Count() + ")==============");
- //List<IProcessor> processorInstances = new List<IProcessor>();
- var createResults = new List<ProcessorInstanceOperatingResult>();
- for (int i = 0; i < processorConfigs.Count; i++)
- {
- var pc = processorConfigs[i];
- try
- {
- mainLogger.LogInformation("[" + i + "]: " + pc.Name + ", " + pc.DeviceProcessorType);
- Console.WriteLine("[" + i + "]: " + pc.Name + ", " + pc.DeviceProcessorType);
- var parameters = pc.Parameter;//.Cast<DeviceProcessorParameter>();
- foreach (var para in parameters)
- {
- mainLogger.LogInformation(" " + para.Name + " : " + para.Value);
- //Console.WriteLine(" " + para.Name + " : " + para.Value);
- }
- var processorInstance =
- ConstructComplexType_Xml_String(pc.DeviceProcessorType, pc.ConstructorArg, parameters, services) as IProcessor;
- processorInstance.MetaConfigName = pc.Name;
- createResults.Add(new ProcessorInstanceOperatingResult()
- {
- MetaConfig = new ProcessorMetaConfig()
- {
- Name = pc.Name,
- Activated = true,
- SourceEndpointFullTypeStr = pc.DeviceProcessorType,
- Type = processorInstance is IAppProcessor ? ProcessorTypeEnum.AppProcessor : ProcessorTypeEnum.DeviceProcessor,
- Description = "Current using Legacy Settings XmlFile mode, so this is a fake ProcessorMetaConfig"
- },
- //Description = "Legacy Settings XmlFile mode for instantiate a processor, and succeed",
- Succeed = true,
- ProcessorInstance = processorInstance,
- //MetaConfig = mc,
- });
- }
- catch (Exception eee)
- {
- createResults.Add(new ProcessorInstanceOperatingResult()
- {
- MetaConfig = new ProcessorMetaConfig()
- {
- Name = pc.Name,
- Activated = true,
- SourceEndpointFullTypeStr = pc.DeviceProcessorType,
- Description = "Current using Legacy Settings XmlFile mode, so this is a fake ProcessorMetaConfig"
- },
- //Description = "Legacy Settings XmlFile mode for instantiate a processor, but failed",
- Succeed = false,
- //MetaConfig = mc,
- FailedReason = eee.ToString()
- });
- mainLogger.LogError(" - Failed for instantiate: " + pc.Name + Environment.NewLine + " " + eee.ToString());
- Console.BackgroundColor = ConsoleColor.Red;
- Console.ForegroundColor = ConsoleColor.Black;
- Console.WriteLine(" - Failed for instantiate: " + pc.Name + Environment.NewLine + " " + eee.ToString().Substring(0, 90) + "...");
- Console.ResetColor();
- }
- }
- mainLogger.LogInformation("==============Instantiate Processors End==============");
- Console.WriteLine("==============Instantiate Processors End==============");
- return createResults;
- }
- public IProcessor Create(string configName)
- {
- if (string.IsNullOrEmpty(configName)) throw new ArgumentException(nameof(configName));
- var configurator = this.services.GetRequiredService<Configurator>();
- var processorConfig = configurator.DeviceProcessorConfiguration.Processor.First(settingsXmlConfig => settingsXmlConfig.Name == configName);
- var p =
- ConstructComplexType_Xml_String(
- processorConfig.DeviceProcessorType,
- processorConfig.ConstructorArg,
- processorConfig.Parameter, services) as IProcessor;
- p.MetaConfigName = processorConfig.Name;
- return p;
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="typeFullyQualifiedNameString">nameSpace.ClassA, AssemblyFileName</param>
- /// <param name="constrStrFromConfig"></param>
- /// <param name="parameters"></param>
- /// <param name="services"></param>
- /// <returns></returns>
- protected virtual dynamic ConstructComplexType_Xml_String(string typeFullyQualifiedNameString, string constrStrFromConfig, IEnumerable<ProcessorParameter> parameters, IServiceProvider services)
- {
- Type processorType = Type.GetType(typeFullyQualifiedNameString);
- if (processorType == null)
- {
- var fallbackToVersion2NameString = Fallback_Version2_ResolveType_Compatbility(typeFullyQualifiedNameString);
- processorType = Type.GetType(fallbackToVersion2NameString);
- if (processorType == null)
- throw new ArgumentException("Could not resolve type: " + typeFullyQualifiedNameString);
- else
- typeFullyQualifiedNameString = fallbackToVersion2NameString;
- }
- if (string.IsNullOrEmpty(constrStrFromConfig))
- {
- try
- {
- //now only support injecting one parameter.
- var injectingCtor = processorType.GetConstructors().FirstOrDefault(c => c.GetParameters().Length == 1);
- if (injectingCtor != null
- && injectingCtor.GetParameters().First().ParameterType == typeof(IServiceProvider))
- {
- mainLogger.LogTrace("Constructing instance(with 1 param ctor and empty param from config) with type: " + processorType.Name);
- mainLogger.LogTrace(" - ctor parameter with name: " + injectingCtor.GetParameters().First().Name + " is type IServiceProvider, will injecting");
- var injectedInstance = Activator.CreateInstance(processorType, new object[] { services });
- mainLogger.LogTrace(" Done constructing instance(with 1 param ctor and empty param from config) with type: " + processorType.Name);
- return injectedInstance;
- }
- mainLogger.LogTrace("Constructing instance(with empty param ctor and empty param from config) with type: " + processorType.Name);
- var parameterlessInstance = Activator.CreateInstance(processorType);
- mainLogger.LogTrace(" Done constructing instance(with empty param ctor and empty param from config) with type: " + processorType.Name);
- return parameterlessInstance;
- }
- catch (Exception exxx)
- {
- //mainLogger.LogError();
- throw new InvalidOperationException("CreateInstance(with empty ctor) for: "
- + typeFullyQualifiedNameString + " failed, " + Environment.NewLine + " exception detail: " + exxx);
- }
- }
- else
- {
- List<object> cArgsFromConfig = new List<object>();
- var constructorArgStrings = constrStrFromConfig.Replace("\r", "").Replace("\n", "").Split(',').Select(s => s.Trim()).ToArray();
- for (int i = 0; i < constructorArgStrings.Length; i++)
- {
- var argStr = constructorArgStrings[i];
- try
- {
- if (!argStr.StartsWith("ref:"))
- {
- cArgsFromConfig.Add(readPrimitiveParameterValue(argStr));
- }
- else if (argStr.StartsWith("ref:"))
- {
- var refTo = argStr.Substring(4);
- // quick ref
- if (refTo.Contains(':'))
- {
- var quickRefValuePart = refTo.Split(':').Last();
- cArgsFromConfig.Add(readPrimitiveParameterValue(quickRefValuePart));
- }
- else
- {
- var refParameter = parameters.First(p => p.Name == refTo);
- if (!refParameter.Complex)
- {
- cArgsFromConfig.Add(readPrimitiveParameterValue(refParameter.Value));
- }
- else
- {
- var complexArg = ConstructComplexType_Xml_String(refParameter.Value, refParameter.ConstructorArg, parameters, services);
- cArgsFromConfig.Add(complexArg);
- }
- }
- }
- }
- catch (Exception exxx)
- {
- throw new InvalidOperationException("failed for parse constructor arg[" + i + "]: " + argStr
- + " " + Environment.NewLine + " for type: " + processorType.Name
- + " " + Environment.NewLine + " detail: " + exxx);
- }
- //else if (argStr.StartsWith("refIdArray("))
- //{
- // var idsString = argStr.Skip("refIdArray(".Length).TakeWhile(p => p != ')')
- // .Select(c => c.ToString()).Aggregate((acc, n) => acc + n);
- // var output = processors.Where(p => idsString.Trim().Split('|').ToList().Contains(p.Id.ToString()));
- // cArgs.Add(output);
- //}
- }
- //var cc = deviceProcessorType.GetConstructors();
- try
- {
- mainLogger.LogTrace("Constructing instance(with multiple param ctor and "
- + cArgsFromConfig.Count + " param from config) with type: " + processorType.Name);
- //now only support injecting one parameter.
- var injectingCtor = processorType.GetConstructors().FirstOrDefault(c => c.GetParameters().Length == cArgsFromConfig.Count + 1);
- //for(int c=0;c<injectingCtors.Count())
- //{
- if (injectingCtor != null)
- {
- var ctParams = injectingCtor.GetParameters();
- for (int i = 0; i < ctParams.Length; i++)
- {
- var param = ctParams[i];
- if (param.ParameterType == typeof(IServiceProvider))
- {
- mainLogger.LogTrace(" - ctor parameter with name: " + ctParams[i].Name + " is type IServiceProvider, will injecting");
- cArgsFromConfig.Insert(i, services);
- }
- }
- }
- //}
- var s = Activator.CreateInstance(processorType, cArgsFromConfig.ToArray());
- mainLogger.LogTrace(" Done constructing instance with type: " + processorType.Name);
- return s;
- }
- catch (Exception exxx)
- {
- throw new InvalidOperationException("CreateInstance(with ctor args: "
- + cArgsFromConfig.Select(c => c.ToString()).Aggregate((acc, n) => acc + ", " + n) + ") for: " + processorType.Name + " failed, \r\n exception detail: " + exxx);
- }
- }
- }
- protected virtual object readPrimitiveParameterValue(string valueStr)
- {
- if (valueStr.StartsWith("ref:")) throw new ArgumentException("ONLY can read primitive parameter value");
- if (valueStr == "") return "";
- if (valueStr.StartsWith("'")) return valueStr.Substring(1, valueStr.Length - 2);
- int intResult = -1;
- var intParseResult = int.TryParse(valueStr, out intResult);
- if (intParseResult) return intResult;
- else return valueStr;
- }
- /// <summary>
- /// version 3 combind DeviceProcessor, Communicator, Parser, Common into one project and namespace also adjusted.
- /// it'll break the old setting.xml, so here try to recover it by overwirte the old namespace and assembly name.
- /// </summary>
- /// <param name="version2TypeFullyQualifiedNameString"></param>
- /// <returns></returns>
- internal static string Fallback_Version2_ResolveType_Compatbility(string version2TypeFullyQualifiedNameString)
- {
- if (Regex.IsMatch(version2TypeFullyQualifiedNameString,
- "^\\s{0,}(DeviceProcessor|Communicator)(\\..+)(\\1)\\s{0,}$"))
- {
- /* the old one likes(the content between the ""):
- * deviceProcessorType="DeviceProcessor.GenericDeviceProcessor`2[[System.Byte[]], [ProGauge_StartItaliana_Probe.MessageEntity.MessageBase, ProGauge_StartItaliana_Probe]], DeviceProcessor"
- * deviceProcessorType="DeviceProcessor.HalfDuplexActivePollingDeviceProcessor`2[[System.Byte[]], [OPW_VaporRecoveryOnlineWatch_DataCollector.DataCollectorMessageBase,OPW_VaporRecoveryOnlineWatch_DataCollector]], DeviceProcessor"
- * name="deviceHandlerType" value="ProGauge_StartItaliana_Probe.Handler,ProGauge_StartItaliana_Probe"
- * name="deviceHandlerType" value="LanTian_Pump_664_Or_886.PumpGroupHandler,LanTian_Pump_664_Or_886"
- * name="communicatorType" value="Communicator.ComPortCommunicator`1[[ProGauge_StartItaliana_Probe.MessageEntity.MessageBase,ProGauge_StartItaliana_Probe]],Communicator"
- * name="communicatorType" value="Communicator.TcpClientCommunicator`1[[VeederRoot_ATG_Console.MessageEntity.MessageBaseGeneric,VeederRoot_ATG_Console]],Communicator"
- */
- version2TypeFullyQualifiedNameString = version2TypeFullyQualifiedNameString.Replace(" ", "");
- return version2TypeFullyQualifiedNameString
- .Replace("DeviceProcessor.", "Edge.Core.Processor.")
- .Replace(",DeviceProcessor", ",Edge.Core")
- .Replace("Communicator.", "Edge.Core.Processor.Communicator.")
- .Replace(",Communicator", ",Edge.Core");
- }
- else if (Regex.IsMatch(version2TypeFullyQualifiedNameString,
- "(DeviceProcessor|Communicator|Parser|Common),\\sCulture=\\w+?,\\sPublicKeyToken=\\w+"))
- {
- /* the old one likes: DeviceProcessor, Culture=neutral, PublicKeyToken=null */
- return version2TypeFullyQualifiedNameString
- .Replace("DeviceProcessor", "Edge.Core")
- .Replace("Communicator", "Edge.Core")
- .Replace("Parser", "Edge.Core")
- .Replace("Common", "Edge.Core");
- }
- else
- return version2TypeFullyQualifiedNameString;
- }
- }
- }
|