FixAntenna/NetCore/FixEngine/Session/Util/SessionParametersBuilder.cs (253 lines of code) (raw):

// Copyright (c) 2021 EPAM Systems // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. using Epam.FixAntenna.NetCore.Common; using Epam.FixAntenna.NetCore.Common.Logging; using Epam.FixAntenna.NetCore.Common.ResourceLoading; using Epam.FixAntenna.NetCore.Configuration; using System; using System.Collections.Generic; using System.IO; using System.Xml; namespace Epam.FixAntenna.NetCore.FixEngine.Session.Util { public class SessionParametersBuilder { private static readonly ILog Log = LogFactory.GetLog(typeof(SessionParametersBuilder)); public const string SessionTypeProp = "sessionType"; private const string AcceptorType = "acceptor"; private const string InitiatorType = "initiator"; private static IPropertiesFilter _acceptorFilter = new SessionTypeFilter(AcceptorType); private static IPropertiesFilter _initiatorFilter = new SessionTypeFilter(InitiatorType); // SessionParameters List build service /// <summary> /// Build list of SessionParameters using default configuration file. /// </summary> public static IDictionary<string, SessionParameters> BuildSessionParametersList() { var p = new Properties(Config.GlobalConfiguration.Properties); return ConstructListFromProperties(p); } /// <summary> /// Build list of SessionParameters using input file name. /// </summary> /// <param name="file"> configuration file </param> /// <returns> list of SessionParameters </returns> public static IDictionary<string, SessionParameters> BuildSessionParametersList(string file) { var properties = GetPropertiesFromFile(file); return ConstructListFromProperties(properties); } /// <summary> /// Build list of acceptor's SessionParameters using default configuration file. /// </summary> public static IDictionary<string, SessionParameters> BuildAcceptorSessionParametersList() { var p = new Properties(Config.GlobalConfiguration.Properties); return ConstructListFromProperties(p, _acceptorFilter); } /// <summary> /// Build list of initiator's SessionParameters using default configuration file. /// </summary> public static IDictionary<string, SessionParameters> BuildInitiatorSessionParametersList() { var p = new Properties(Config.GlobalConfiguration.Properties); return ConstructListFromProperties(p, _initiatorFilter); } /// <summary> /// Build list of acceptor's SessionParameters using input file name. /// </summary> /// <param name="file"> configuration file </param> /// <returns> list of SessionParameters </returns> public static IDictionary<string, SessionParameters> BuildAcceptorSessionParametersList(string file) { var properties = GetPropertiesFromFile(file); return ConstructListFromProperties(properties, _acceptorFilter); } /// <summary> /// Build list of acceptor's SessionParameters using input file name. /// </summary> /// <param name="file"> configuration file </param> /// <returns> list of SessionParameters </returns> public static IDictionary<string, SessionParameters> BuildInitiatorSessionParametersList(string file) { var properties = GetPropertiesFromFile(file); return ConstructListFromProperties(properties, _initiatorFilter); } private static IDictionary<string, SessionParameters> ConstructListFromProperties(Properties properties) { return ConstructListFromProperties(properties, new PropertiesFilterAnonymousInnerClass()); } internal class PropertiesFilterAnonymousInnerClass : IPropertiesFilter { public bool FilterSession(string sessionId, Properties props) { return true; } } private static IDictionary<string, SessionParameters> ConstructListFromProperties(Properties properties, IPropertiesFilter filter) { var sessionIdsParam = properties.GetProperty("sessionIDs"); var sessionParamsMap = new Dictionary<string, SessionParameters>(); if (string.IsNullOrWhiteSpace(sessionIdsParam)) { return sessionParamsMap; } var propertiesMap = new Dictionary<string, Properties>(); var defaultProps = GetSessionProperties(properties, Properties.DefaultSessionId); foreach (var splittedId in sessionIdsParam.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { var sessionId = splittedId.Trim(); var props = new Properties(); props.PutAll(defaultProps); props.PutAll(GetSessionProperties(properties, sessionId)); propertiesMap[sessionId] = props; } if (propertiesMap.Count == 0) { propertiesMap[string.Empty] = properties; } foreach (var mapEntry in propertiesMap) { var sessionId = mapEntry.Key; var sessionProps = mapEntry.Value; if (filter.FilterSession(sessionId, sessionProps)) { sessionParamsMap[sessionId] = ConstructFromProperties(sessionProps); } } return sessionParamsMap; } private static SessionParameters ConstructFromProperties(Properties properties, string sessionId) { var defaultProps = GetSessionProperties(properties, Properties.DefaultSessionId); var props = new Properties(); props.PutAll(defaultProps); props.PutAll(GetSessionProperties(properties, sessionId)); return ConstructFromProperties(props); } private static Properties GetSessionProperties(Properties data, string sessionId) { var pr = new Properties(); var sessionPrefix = $"sessions.{sessionId}."; var sessionPrefixLength = sessionPrefix.Length; foreach (KeyValuePair<string,string> entry in data) { if (entry.Key.StartsWith(sessionPrefix, StringComparison.OrdinalIgnoreCase)) { pr.Put(entry.Key.Substring(sessionPrefixLength), entry.Value); } } // check out the corresponding environment variables var evs = Environment.GetEnvironmentVariables(); var evPrefix = Properties.PrepareEvPrefix(sessionId); var evPrefixLength = evPrefix.Length; foreach (string evName in evs.Keys) { if (evName.StartsWith(evPrefix, StringComparison.OrdinalIgnoreCase)) { var paramName = evName.Substring(evPrefixLength); pr.Put(paramName, evs[evName].ToString()); ParamSources.Instance.Set(paramName, ParamSource.Environment, sessionId); } } pr.Put(Properties.SessionIdKey, sessionId); return pr; } /// <summary> /// Build SessionParameters using default configuration file name and session id. /// </summary> /// <param name="sessionId"> specific session id </param> /// <returns> session parameters </returns> public static SessionParameters BuildSessionParameters(string sessionId) { var properties = new Properties(Config.GlobalConfiguration.Properties); return ConstructFromProperties(properties, sessionId); } /// <summary> /// Build SessionParameters using input file name and session id. /// </summary> /// <param name="file"> configuration file </param> /// <param name="sessionId"> specific session id </param> /// <returns> session parameters </returns> public static SessionParameters BuildSessionParameters(string file, string sessionId) { var properties = GetPropertiesFromFile(file); return ConstructFromProperties(properties, sessionId); } private static Properties GetPropertiesFromFile(string file) { if (!string.IsNullOrEmpty(file)) { try { if (file.EndsWith(".xml", StringComparison.Ordinal)) { var xmlConfig = new XmlDocument(); //xmlConfig.setDelimiterParsingDisabled(true); xmlConfig.Load(file); return GetProperties(xmlConfig); } } catch (Exception e) { var s = "Unable to load config from xml: " + file; Log.Fatal(s, e); throw; } if (file.EndsWith(".properties", StringComparison.Ordinal)) { using (var inStream = ResourceLoader.DefaultLoader.LoadResource(file)) { try // load default properties { return new Properties(inStream); } catch (IOException ex) { var s = "Unable to load session properties: " + file; Log.Fatal(s, ex); throw; } } } } throw new ArgumentException("Wrong config file: " + file); } private static SessionParameters ConstructFromProperties(Properties properties) { Config config = null; try { config = (Config) Config.GlobalConfiguration.Clone(); //overload properties config.AddAllProperties(properties.ToDictionary()); } catch (Exception e) { if (Log.IsDebugEnabled) { Log.Warn("Can't clone global configuration", e); } else { Log.Warn("Can't clone global configuration. " + e.Message); } config = new Config(properties.ToDictionary()); } var @params = new SessionParameters(config); @params.FromProperties(properties.ToDictionary()); return @params; } private static Properties GetProperties(XmlDocument config) { var props = new Properties(); foreach (XmlNode node in config.DocumentElement.SelectNodes("*")) { ProcessNode("", node, props); } return props; } private static void ProcessNode(string prefix, XmlNode node, Properties props) { if (node == null) { return; } var attr = node.Attributes?["id"]; var key = attr?.Value ?? node.Name; if (node.SelectNodes("*").Count == 0) { var value = node.Value ?? node.InnerText; if (value != null) { props.Put(prefix + (prefix.Length == 0 ? "" : ".") + key, value); } } else { prefix = prefix + (prefix.Length == 0 ? "" : ".") + key; foreach (XmlNode childNode in node.SelectNodes("*")) { ProcessNode(prefix, childNode, props); } } } internal interface IPropertiesFilter { bool FilterSession(string sessionId, Properties props); } private sealed class SessionTypeFilter : IPropertiesFilter { private readonly string _sessionType; public SessionTypeFilter(string sessionType) { _sessionType = sessionType; } public bool FilterSession(string sessionId, Properties props) { var st = props.GetProperty(SessionTypeProp); return st == null || _sessionType.Equals(st, StringComparison.OrdinalIgnoreCase); } } } }