FixAntenna/Tools/Tester/CasesConfigHandler.cs (292 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.Tester.Comparator; using Epam.FixAntenna.Tester.Logger; using Epam.FixAntenna.Tester.Stage; using Epam.FixAntenna.Tester.Updater; using System; using System.Collections.Generic; using System.IO; using System.Text; using Epam.FixAntenna.NetCore.Common.Logging; namespace Epam.FixAntenna.Tester { public sealed class CasesConfigHandler : IDefaultHandler, IDisposable { private static readonly ILog _log = LogFactory.GetLog(typeof(CasesConfigHandler)); private const string TASK = "task"; public const string LOGGER_ATTRIBUTE = "logger"; private const string TESTER_PREFIX = "Epam.FixAntenna.Tester."; private const string TRANSPORT = "transport"; private static readonly string _transportPrefix = TESTER_PREFIX + "Transport."; private static readonly string _updaterPrefix = TESTER_PREFIX + "Updater."; private static readonly string _comparatorPrefix = TESTER_PREFIX + "Comparator."; private static readonly string _logPrefix = TESTER_PREFIX + "Logger."; private static readonly string _taskPrefix = TESTER_PREFIX + "Task."; private const string CASE = "case"; private const string PARAM = "param"; private const string CLASS_NAME_ATTRIBUTE = "className"; private const string NAME_ATTRIBUTE = "name"; private const string EXPECT = "expect"; private const string SEND = "send"; private const string SEPARATOR = "separator"; private CustomConcurrentDictionary<string, object> _sessions = new CustomConcurrentDictionary<string, object>(); private Stack<string> _currentTag = new Stack<string>(); private ResultCounter _counter = new ResultCounter(); private string _caseName; private Case _currentCase; private ITransport _transport; private IDictionary<string, string> _currentParams; private string _currentParamName; private string _currentMessage = ""; private IDictionary<string, string> _currentMessageAttributes = new CustomDictionary<string, string>(); private Type _currentValidatorClass = typeof(IMessageComparator); private IMessageUpdater _currentUpdater; private Stack<ITask> _currentTask = new Stack<ITask>(); private ICaseLogger _logger; private string _currentParamValue; private string _separator; private string _fileName; public CasesConfigHandler(string fileName) { this._fileName = fileName; this._currentParams = new CustomDictionary<string, string>(); } public ResultCounter GetCounter() { return _counter; } public void StartElement(string uri, string localName, string qName, Attributes attributes) { try { _currentTag.Push(qName); ProcessStartElement(qName, attributes); } catch (Exception e) { _log.Error(e, e); throw new Exception("Unrecoverable error during the test"); } } public void EndElement(string uri, string localName, string qName) { try { ProcessEndElement(qName); _currentTag.Pop(); } catch (Exception e) { _log.Error(e, e); throw; } } private void ProcessStartElement(string qName, Attributes attributes) { if (CASE.Equals(qName)) { InitCaseStuff(attributes); } else if (TRANSPORT.Equals(qName)) { StartTransport(attributes); } else if (PARAM.Equals(qName)) { _currentParamName = attributes.GetValue(NAME_ATTRIBUTE); _currentParamValue = ""; } else if (TASK.Equals(qName)) { _log.Debug("Creating " + TASK); _currentParams = new CustomDictionary<string, string>(); _currentTask.Push( (ITask)System.Activator.CreateInstance(Type.GetType(_taskPrefix + attributes.GetValue(CLASS_NAME_ATTRIBUTE))) ); } if (SEND.Equals(qName) || EXPECT.Equals(qName)) { _currentMessageAttributes = GetProperties(attributes); } } private void ProcessEndElement(string qName) { if (CASE.Equals(qName)) { if (_currentCase.IsSuccess()) { _counter.IncSuccess(); } else { _counter.IncFailed(); } _currentCase.Close(); DisposeTasks(); } else if (PARAM.Equals(qName)) { _currentParams[_currentParamName] = _currentParamValue; } else if (TRANSPORT.Equals(qName)) { _transport.Dispose(); _transport = null; } else if (TASK.Equals(qName)) { _log.Debug("Initializing " + TASK + " with: " + PrintParams(_currentParams)); _currentTask.Peek().Init(_currentParams, _sessions); _log.Debug("Executing " + TASK); _currentTask.Peek().DoTask(); } else if (EXPECT.Equals(qName)) { IMessageComparator comparator = (IMessageComparator)System.Activator.CreateInstance(_currentValidatorClass); comparator.SetMessageSeparator(_separator); _currentCase.RunReceiveStage(new ExpectedMessage(_currentMessage.Trim(), comparator), _currentMessageAttributes); _currentMessage = ""; _currentMessageAttributes = new CustomDictionary<string, string>(); } else if (SEND.Equals(qName)) { try { _currentCase.RunSendStage(new OutgoingMessage(_currentMessage.Trim(), _currentUpdater), _currentMessageAttributes); _currentMessage = ""; _currentMessageAttributes = new CustomDictionary<string, string>(); } catch (IOException e) { _log.Error(e, e); } } } private string PrintParams(IDictionary<string, string> dictionary) { var res = new StringBuilder(); foreach (var key in dictionary.Keys) { res.AppendFormat("[{0}]: {1},", key, dictionary[key]); } return res.ToString().TrimEnd(','); } public void Characters(char[] chars, int start, int length) { if (PARAM.Equals(_currentTag.Peek())) { _currentParamValue += new string(chars, start, length); } if (EXPECT.Equals(_currentTag.Peek()) || SEND.Equals(_currentTag.Peek())) { _currentMessage += new string(chars, start, length); } } private void StartTransport(Attributes attributes) { _log.Debug("Initing transport"); _transport = (ITransport)System.Activator.CreateInstance(Type.GetType(_transportPrefix + attributes.GetValue(CLASS_NAME_ATTRIBUTE))); _transport.Init(GetProperties(attributes)); _log.Debug("Staring transport"); _transport.Open(); _log.Debug("Succussed"); if (_currentCase == null) { _currentCase = new Case("(" + _fileName + ") " + _caseName, _transport, _logger); } else { _currentCase.ReinitTransport(_transport); } } private IDictionary<string, string> GetProperties(Attributes attributes) { int length = attributes.GetLength(); IDictionary<string, string> map = new CustomDictionary<string, string>(); for (int i = 0; i < length; i++) { map[attributes.GetQName(i)] = attributes.GetValue(i); } return map; } private void InitCaseStuff(Attributes attributes) { _caseName = attributes.GetValue(NAME_ATTRIBUTE); _log.Info("Case '" + _caseName + "' initialization"); _separator = attributes.GetValue(SEPARATOR); if (string.ReferenceEquals(_separator, null)) { _separator = "#"; _log.Debug("Using default " + SEPARATOR + ":" + _separator); } else { _log.Debug("Using " + SEPARATOR + ":" + _separator); } InitLogger(attributes); InitComparator(attributes); InitUpdater(attributes); } private void InitUpdater(Attributes attributes) { _log.Debug("Initing message updater"); string updaterClass = attributes.GetValue("updater"); if (string.ReferenceEquals(updaterClass, null)) { _log.Debug("Not specified, so using default"); updaterClass = typeof(LazyUpdater).FullName; } else { updaterClass = _updaterPrefix + updaterClass; } _currentUpdater = (IMessageUpdater)System.Activator.CreateInstance(Type.GetType(updaterClass)); _currentUpdater.SetMessageSeparator(_separator); _log.Debug("Success"); } private void InitComparator(Attributes attributes) { _log.Debug("Initing comparator"); string compClass = attributes.GetValue("comparator"); if (string.ReferenceEquals(compClass, null)) { _log.Debug("Not specified, so using default value"); compClass = typeof(RegExpFlexibleComparator).FullName; } else { compClass = _comparatorPrefix + compClass; } _currentValidatorClass = Type.GetType(compClass); _log.Debug("Success"); } private void InitLogger(Attributes attributes) { _log.Debug("Initing logger"); string logClass = attributes.GetValue(LOGGER_ATTRIBUTE); if (string.ReferenceEquals(logClass, null)) { _log.Debug("Not specified, so using default"); logClass = typeof(LoggingCaseLogger).FullName; } else { logClass = _logPrefix + logClass; } _log.Debug("class:" + logClass); _logger = (ICaseLogger)System.Activator.CreateInstance(Type.GetType(logClass)); _log.Debug("Success"); } private void DisposeTasks() { while (_currentTask.Count > 0) { _currentTask.Pop().Dispose(); } } public void Dispose() { _transport?.Dispose(); _transport = null; DisposeTasks(); } } }