public void WriteCsvMinuteInterval_over_timeout_raises_WriteCsvException()
        {
            var csvWriter      = new CsvWriter();
            var minuteInterval = 30;
            //confirm file was written
            var      maxTrys      = 5;
            DateTime?lastWroteCsv = null;

            IPowerService powerService = Mock.Create <IPowerService>();

            Mock.Arrange(() => powerService.GetTradesAsync(_testDateTime)).Returns(() => new Task <IEnumerable <PowerTrade> >(() =>
            {
                var waitTimepan = new TimeSpan(0, 0, _timeOut.Seconds + 2);
                var stopwatch   = new Stopwatch();
                stopwatch.Start();
                while (stopwatch.ElapsedMilliseconds < waitTimepan.TotalMilliseconds)
                {
                    Thread.Sleep(0);
                }
                return(_powerTrades);
            }));

            //first try five times no error should be thrown it will be logged and a retry allowed
            for (int i = 1; i <= maxTrys; i++)
            {
                Assert.DoesNotThrow(() => lastWroteCsv = csvWriter.WriteCsvMinuteInterval(_fileFolder, _fileName, _fileDateFormat, _fileSuffix, _delimiter, _columnOneName, _columnTwoName,
                                                                                          _dataDateFormat, minuteInterval, _testDateTime, powerService, _timeOut, lastWroteCsv));
            }
            //final time is over maximum number of retries so should throw an exception
            Assert.Throws <WriteCsvException>(() => lastWroteCsv = csvWriter.WriteCsvMinuteInterval(_fileFolder, _fileName, _fileDateFormat, _fileSuffix, _delimiter, _columnOneName, _columnTwoName,
                                                                                                    _dataDateFormat, minuteInterval, _testDateTime, powerService, _timeOut, lastWroteCsv));
        }
        //Confirm the WriteCvException is being logged in the correct format
        public void WriteCsvMinuteInterval_PowerServiceException_is_caught_and_logged()
        {
            var csvWriter      = new CsvWriter();
            var minuteInterval = 30;
            //confirm file was written
            var      logFileName  = "PositionAggregatorLogFile.txt";
            var      maxTrys      = 5;
            DateTime?lastWroteCsv = null;

            File.Delete(logFileName);
            IPowerService powerService = Mock.Create <IPowerService>();

            Mock.Arrange(() => powerService.GetTradesAsync(_testDateTime)).Throws <PowerServiceException>("Power Service Exception");
            //first try five times and confirm log file is written correctly
            for (int i = 1; i <= maxTrys; i++)
            {
                lastWroteCsv = csvWriter.WriteCsvMinuteInterval(_fileFolder, _fileName, _fileDateFormat, _fileSuffix, _delimiter, _columnOneName, _columnTwoName,
                                                                _dataDateFormat, minuteInterval, _testDateTime, powerService, _timeOut, lastWroteCsv);
            }
            //confirm the log file has been written
            Assert.IsTrue(File.Exists(logFileName));
            var assembly           = Assembly.GetExecutingAssembly();
            var resourceName       = "TDomain.PositionAggregatorLogFile.txt";
            var logFileExampleText = "";

            using (StreamReader reader = new StreamReader(assembly.GetManifestResourceStream(resourceName)))
            {
                logFileExampleText = reader.ReadToEnd();
            }
            var logFileText = File.ReadAllText(logFileName);

            //confirm the log file has been written correctly.  contents will differ due to timing of runs so realistically good enough to just check the lengths
            Assert.AreEqual(logFileExampleText.Length, logFileText.Length);
        }
        //Write the csv file if the current time is at the minute Interval and no other file has been written by the process.  Otherwise write the file.
        public DateTime?WriteCsvMinuteInterval(string fileFolder, string fileName, string fileDateFormat, string fileSuffix, string delimiter, string columnOneName,
                                               string columnTwoName, string dataDateFormat, int minuteInterval, DateTime?asAt, IPowerService powerService, TimeSpan timeout, DateTime?lastWroteCsv, bool overwriteExisting = true)
        {
            //use at parameter to override what time the method believes it is.  This is useful for testing.
            //using Universal time means do not have to worry about clocks changing
            DateTime nowDateTime = asAt ?? DateTime.Now.ToUniversalTime();

            //if null then this is a first run so write the file if
            if (lastWroteCsv == null || (nowDateTime.Minute % minuteInterval == 0 &&
                                         (nowDateTime.Day != lastWroteCsv.Value.Day || nowDateTime.Hour != lastWroteCsv.Value.Hour || nowDateTime.Minute != lastWroteCsv.Value.Minute)))
            {
                try
                {
                    var writeFile  = GetFullFileName(fileFolder, fileName, fileDateFormat, fileSuffix, nowDateTime);
                    var fileExists = File.Exists(writeFile);
                    if (overwriteExisting == true || (!fileExists))
                    {
                        _tryWriteCsv++;
                        var tradesTask = powerService.GetTradesAsync(nowDateTime);
                        if (!tradesTask.Wait(timeout))
                        {
                            var exceptionMessage =
                                "The operation to retrieve power trades has timed out.  Timeout value used was " +
                                timeout.Seconds + " seconds.  The date parameter passed was " +
                                nowDateTime.ToString("R");
                            throw new WriteCsvException(exceptionMessage);
                        }
                        var trades   = tradesTask.Result;
                        var position = new Position(trades, nowDateTime);
                        WriteCsv(writeFile, delimiter, columnOneName, columnTwoName, dataDateFormat, position);
                        _tryWriteCsv = 0;
                        return(nowDateTime);
                    }
                }
                catch (Exception ex)
                    when(ex is PowerServiceException || ex is WriteCsvException || ex is AggregateException)
                    {
                        //Will retry the procedure a specified number of times when the above errors are called because they are potentially recoverable
                        if (_tryWriteCsv <= _maxTryWriteCsv)
                        {
                            //log and allow retry on next timer interval
                            var exceptionMessages = ex.GetExceptionMessages();
                            var errorMessage      =
                                "An error has occured trying to write the csv file.  This is attempt number " + _tryWriteCsv +
                                ".  A maximum of " + _maxTryWriteCsv + " attempts will be made to write the file " +
                                ".  Detailed information is below.\r\n\r\n"
                                + exceptionMessages;
                            _logger.Error(ex, errorMessage);
                        }
                        else
                        {
                            throw;
                        }
                    }
            }
            // by default assume csv not written
            return(lastWroteCsv);
        }
Beispiel #4
0
 public async Task <IEnumerable <PowerDataCommon.domain.PowerTrade> > ReadDataAsync(DateTime tenor)
 {
     try
     {
         return(_dtoConverter.TranslateToDomainObject(await _powerService.GetTradesAsync(tenor).ConfigureAwait(false)));
     }
     catch (PowerServiceException pex)
     {
         log.Value.Error(pex);
     }
     return(Enumerable.Empty <PowerDataCommon.domain.PowerTrade>());
 }
Beispiel #5
0
        private async Task <IEnumerable <PowerTrade> > GetTradesAsync(DateTime dateTime)
        {
            try
            {
                var result = await _powerService.GetTradesAsync(dateTime);

                return(result);
            }
            catch (Exception e)
            {
                //Ensure that as much information as possible is obtained from service
                Log.Error(e, "Error obtaining trades from Power Service");
                throw;
            }
        }
        public async Task <ReadOnlyCollection <PowerTrade> > GetPowerTradeAsync()
        {
            int retries = 0, maxRetries = 3;

            _log.Info("Attempting to Retrieving power trades");
            while (retries < maxRetries)
            {
                try
                {
                    var results = await _powerService.GetTradesAsync(DateTime.Now);

                    _log.Info($"Power trades successfully retrieved in the {retries + 1} attempt");
                    if (results != null)
                    {
                        var powerTradesReadOnlyList = results.ToList().AsReadOnly();
                        _log.Info($"Received {powerTradesReadOnlyList.Count} trades");
                        return(powerTradesReadOnlyList);
                    }
                }
                catch (PowerServiceException serviceException)
                {
                    _log.Error(serviceException.ToString());

                    _log.Error($"Power service failed to retrieve the Power Trades at attempt No:{retries+1}");

                    retries++;

                    if (retries >= maxRetries)
                    {
                        _log.Error("Max retries reached");
                    }
                    else
                    {
                        _log.Error("Sourcing the data once again after 2 seconds");
                        await Task.Delay(2000);
                    }
                }
            }
            return(null);
        }
        //Confirm the WriteCvException is being logged in the correct format
        public void WriteCsvMinuteInterval_PowerServiceException_raised_sequentially_over_maximum_trys_throws_error()
        {
            var minuteInterval = 30;
            var asAt           = _testDateTime.AddMinutes(29);
            //confirm file was written
            var      maxTrys      = 5;
            var      csvWriter    = new CsvWriter();
            DateTime?lastWroteCsv = null;

            IPowerService powerService = Mock.Create <IPowerService>();

            Mock.Arrange(() => powerService.GetTradesAsync(_testDateTime)).Throws <AggregateException>("Power Service exception");
            //first try five times no error should be thrown it will be logged and a retry allowed
            for (int i = 1; i <= maxTrys; i++)
            {
                Assert.DoesNotThrow(() => lastWroteCsv = csvWriter.WriteCsvMinuteInterval(_fileFolder, _fileName, _fileDateFormat, _fileSuffix, _delimiter, _columnOneName, _columnTwoName,
                                                                                          _dataDateFormat, minuteInterval, _testDateTime, powerService, _timeOut, lastWroteCsv));
            }
            //final time is over maximum number of retries so should throw an exception
            Assert.Throws <AggregateException>(() => lastWroteCsv = csvWriter.WriteCsvMinuteInterval(_fileFolder, _fileName, _fileDateFormat, _fileSuffix, _delimiter, _columnOneName, _columnTwoName,
                                                                                                     _dataDateFormat, minuteInterval, _testDateTime, powerService, _timeOut, lastWroteCsv));
        }
Beispiel #8
0
        public async Task CreateReportAsync(int retryAttemps, string outputPath)
        {
            //Gets report date - date used to call PowerService
            var reportDate = _dateProvider.GetReportDate();

            //Repe
            for (int i = 0; i < retryAttemps; i++)
            {
                try
                {
                    if (log.IsInfoEnabled)
                    {
                        log.Info($"Creating report attempt {i+1} of {retryAttemps} for report date {reportDate.Date}.");
                    }

                    if (log.IsInfoEnabled)
                    {
                        log.Info("Retreving power trades.");
                    }

                    //Gets PowerTrade
                    var powerTrades = await _powerService.GetTradesAsync(reportDate);

                    if (log.IsInfoEnabled)
                    {
                        log.Info("Power trades retreived.");
                    }

                    if (log.IsInfoEnabled)
                    {
                        log.Info("Calculating interday report positions.");
                    }

                    //Calculates interDay positions.
                    var interDayPositions = powerTrades.Where(trade => trade.Date.Date == reportDate.Date)
                                            .SelectMany(trades => trades.Periods)
                                            .GroupBy(periods => periods.Period)
                                            .Select(group => new InterdayPowerReportPosition(group.Key, group.Sum(p => p.Volume)))
                                            .OrderBy(data => data.PositionId)
                                            .ToArray();

                    if (log.IsInfoEnabled)
                    {
                        log.Info("Interday positions calculated.");
                    }

                    if (log.IsInfoEnabled)
                    {
                        log.Info("Exporting report.");
                    }

                    //Exports report, using injected exporter.
                    _exporter.Export(outputPath, _dateProvider.GetExtractDateTime(), interDayPositions);

                    if (log.IsInfoEnabled)
                    {
                        log.Info("Report Exported.");
                    }

                    if (log.IsInfoEnabled)
                    {
                        log.Info("Report has been created successfully.");
                    }

                    return;
                }
                catch (Exception ex)
                {
                    log.Error(ex, "Create Report Error.");
                    //If no more attempts we can ommit delay.
                    if (i + 1 == retryAttemps)
                    {
                        log.Info("Report couldn't be created.");
                        return;
                    }
                }
                //Delays next attempt about 10 second. In the test project, delay is eliminated.
                await BackgroundScheduler.Default.Delay(TimeSpan.FromSeconds(10));
            }
        }
        public void Setup()
        {
            //Set up the power service
            var testPeriods = new PowerPeriod[]
            {
                new PowerPeriod()
                {
                    Period = 1, Volume = 1000
                },
                new PowerPeriod()
                {
                    Period = 2, Volume = 2000
                },
                new PowerPeriod()
                {
                    Period = 3, Volume = 3000
                },
                new PowerPeriod()
                {
                    Period = 4, Volume = 4000
                },
                new PowerPeriod()
                {
                    Period = 5, Volume = 5000
                },
                new PowerPeriod()
                {
                    Period = 6, Volume = 6000
                },
                new PowerPeriod()
                {
                    Period = 7, Volume = 7000
                },
                new PowerPeriod()
                {
                    Period = 8, Volume = 8000
                },
                new PowerPeriod()
                {
                    Period = 9, Volume = 9000
                },
                new PowerPeriod()
                {
                    Period = 10, Volume = 10000
                },
                new PowerPeriod()
                {
                    Period = 11, Volume = 11000
                },
                new PowerPeriod()
                {
                    Period = 12, Volume = 12000
                },
                new PowerPeriod()
                {
                    Period = 13, Volume = 13000
                },
                new PowerPeriod()
                {
                    Period = 14, Volume = 14000
                },
                new PowerPeriod()
                {
                    Period = 15, Volume = 15000
                },
                new PowerPeriod()
                {
                    Period = 16, Volume = 16000
                },
                new PowerPeriod()
                {
                    Period = 17, Volume = 17000
                },
                new PowerPeriod()
                {
                    Period = 18, Volume = 18000
                },
                new PowerPeriod()
                {
                    Period = 19, Volume = 19000
                },
                new PowerPeriod()
                {
                    Period = 20, Volume = 20000
                },
                new PowerPeriod()
                {
                    Period = 21, Volume = 21000
                },
                new PowerPeriod()
                {
                    Period = 22, Volume = 22000
                },
                new PowerPeriod()
                {
                    Period = 23, Volume = 23000
                },
                new PowerPeriod()
                {
                    Period = 24, Volume = 24000
                },
            };

            var tradeOne = Mock.Create <PowerTrade>();

            Mock.Arrange(() => tradeOne.Date).Returns(_testDateTime);
            Mock.Arrange(() => tradeOne.Periods).Returns(testPeriods);

            var tradeTwo = Mock.Create <PowerTrade>();

            Mock.Arrange(() => tradeTwo.Date).Returns(_testDateTime.AddHours(1));
            Mock.Arrange(() => tradeTwo.Periods).Returns(testPeriods);

            var tradeThree = Mock.Create <PowerTrade>();

            Mock.Arrange(() => tradeThree.Date).Returns(_testDateTime.AddHours(2));
            Mock.Arrange(() => tradeThree.Periods).Returns(testPeriods);

            _powerTrades = new List <PowerTrade>()
            {
                tradeOne, tradeTwo, tradeThree
            };
            //simulate a short call time on the PowerService.GetTradesAsync
            var powerTradesTask = new Task <IEnumerable <PowerTrade> >(() => _powerTrades);

            powerTradesTask.Start();
            powerTradesTask.Wait();
            Mock.Arrange(() => _powerService.GetTradesAsync(_testDateTime)).Returns(powerTradesTask);
            Mock.Arrange(() => _powerService.GetTrades(_testDateTime)).Returns(_powerTrades);
            //set up the expected data to be written by the csv writer
            var assembly     = Assembly.GetExecutingAssembly();
            var resourceName = "TDomain.PositionExample.csv";

            using (StreamReader reader = new StreamReader(assembly.GetManifestResourceStream(resourceName)))
            {
                _csvExampleText = reader.ReadToEnd();
            }

            if (!System.IO.Directory.Exists(_fileFolder))
            {
                Directory.CreateDirectory(_fileFolder);
            }
        }