Beispiel #1
0
        protected override Task <IReadOnlyCollection <RunDeletionInfo> > GetRunDeletionInfoAsync(
            IReadOnlyCollection <Guid> runIds,
            CancellationToken cancellationToken)
        {
            if (runIds.Count == 0)
            {
                return(Task.FromResult <IReadOnlyCollection <RunDeletionInfo> >(null));
            }

            var runs = new List <Run>(runIds.Count);

            using (var scope = _repositoryFactory.BeginRepositoryScope())
            {
                if (runIds.Count == 1)
                {
                    runs.Add(scope.CreateRepository <IRunRepository>().Find(runIds.First()));
                }
                else
                {
                    runs.AddRange(scope.CreateRepository <IRunRepository>().FindByIds(runIds));
                }

                cancellationToken.ThrowIfCancellationRequested();

                return(Task.FromResult <IReadOnlyCollection <RunDeletionInfo> >(
                           runs.Where(r => !(r is null)).Select(r => new RunDeletionInfo
                {
                    RunId = r.Id,
                    ScenarioIds = r.Scenarios?.Select(x => x.ScenarioId).ToArray() ?? Array.Empty <Guid>()
                }).ToArray()));
            }
        }
Beispiel #2
0
        public void ProcessData(ScenarioCampaignFailureOutput data, Run run, Scenario scenario)
        {
            if (!_saveData)
            {
                PreGenerateReport(data.Data, run, scenario);
                return;
            }

            try
            {
                _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForInformationMessage(0,
                                                                                                     0, $"Start insert of campaign failures. ScenarioId: {data.ScenarioId} Count: {data.Data.Count}"));
                using (var internalScope = _repositoryFactory.BeginRepositoryScope())
                {
                    var scenarioCampaignFailureRepository = internalScope.CreateRepository <IScenarioCampaignFailureRepository>();
                    scenarioCampaignFailureRepository.AddRange(data.Data, false);
                    scenarioCampaignFailureRepository.SaveChanges();
                }
                _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForInformationMessage(0,
                                                                                                     0, $"Complete insert of campaign failures. ScenarioId: {data.ScenarioId} Count: {data.Data.Count}"));
            }
            catch (Exception e)
            {
                _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForException(0, 0, $"Error while processing scenario campaign failures. ScenarioId: {scenario.Id}", e));
                throw;
            }

            PreGenerateReport(data.Data, run, scenario);
        }
Beispiel #3
0
        // Cannot put this collection into the immutable lookups as there's
        // currently no repository method to get all by date and a list of sales areas.
        private IReadOnlyCollection <Programme> LoadProgrammesToSmooth(
            DateTimeRange dateTimeRange,
            string salesAreaName)
        {
            using var scope = _repositoryFactory.BeginRepositoryScope();
            var repo = scope.CreateRepository <IProgrammeRepository>();

            return(repo
                   .Search(dateTimeRange.Start, dateTimeRange.End, salesAreaName)
                   .ToList());
        }
Beispiel #4
0
        /// <summary>Prepares the related data.</summary>
        /// <param name="source">The source.</param>
        protected override void PrepareRelatedData(IReadOnlyCollection <Recommendation> source)
        {
            using (var innerScope = _repositoryFactory.BeginRepositoryScope())
            {
                var campaignsRepository      = innerScope.CreateRepository <ICampaignRepository>();
                var demographicRepository    = innerScope.CreateRepository <IDemographicRepository>();
                var productRepository        = innerScope.CreateRepository <IProductRepository>();
                var clashRepository          = innerScope.CreateRepository <IClashRepository>();
                var salesAreaRepository      = innerScope.CreateRepository <ISalesAreaRepository>();
                var tenantSettingsRepository = innerScope.CreateRepository <ITenantSettingsRepository>();

                var campaignIds     = new HashSet <string>();
                var productRefs     = new HashSet <string>();
                var demographicRefs = new HashSet <string>();

                foreach (var recommendation in source)
                {
                    _ = campaignIds.Add(recommendation.ExternalCampaignNumber);
                    _ = productRefs.Add(recommendation.Product);
                    _ = demographicRefs.Add(recommendation.Demographic);
                }

                _campaigns    = campaignsRepository.FindByRefs(campaignIds.ToList()).ToDictionary(x => x.ExternalId);
                _products     = productRepository.FindByExternal(productRefs.ToList()).ToDictionary(x => x.Externalidentifier);
                _demographics = demographicRepository.GetByExternalRef(demographicRefs.ToList())
                                .ToDictionary(x => x.ExternalRef);
                _clashes        = clashRepository.GetAll().ToDictionary(r => r.Externalref);
                _salesAreas     = salesAreaRepository.GetAll().ToDictionary(x => x.Name);
                _tenantSettings = tenantSettingsRepository.Get();
            }
        }
Beispiel #5
0
        public void ProcessData(SpotsReqmOutput data, Run run, Scenario scenario)
        {
            try
            {
                _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForInformationMessage(0,
                                                                                                     0, $"Start insert of recommendations. ScenarioId: {data.ScenarioId} Count: {data.Recommendations.Count}"));

                using (var innerScope = _repositoryFactory.BeginRepositoryScope())
                {
                    var recommendationBatchRepository = innerScope.CreateRepository <IRecommendationRepository>();
                    recommendationBatchRepository.Insert(data.Recommendations, false);
                    recommendationBatchRepository.SaveChanges();
                }

                _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForInformationMessage(0,
                                                                                                     0, $"End insert of recommendations. ScenarioId: {data.ScenarioId}"));
            }
            catch (Exception e)
            {
                _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForException(0, 0, $"Error while processing scenario recommendations. ScenarioId: {scenario.Id}", e));
                throw;
            }

            // do not generate report for scenario with smooth
            if (run.Smooth)
            {
                return;
            }

            var fileName = ReportFileNameHelper.RecommendationResult(run, scenario);

            PreGenerateReport(data.Recommendations, fileName, scenario.Id);
        }
Beispiel #6
0
        /// <summary>
        /// Deletes SpotPlacement docs for dead spots, not modified for more than N days
        /// </summary>
        /// <returns></returns>
        private List <SystemTaskResult> DeleteSpotPlacements(TimeSpan spotPlacementRetention)
        {
            List <SystemTaskResult> results = new List <SystemTaskResult>();

            if (spotPlacementRetention.Ticks != 0)
            {
                try
                {
                    using (var scope = _repositoryFactory.BeginRepositoryScope())
                    {
                        _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForInformationMessage(0, 0, string.Format("Deleting spot placements (Days Old={0})", spotPlacementRetention.TotalDays)));
                        var spotPlacementRepository = scope.CreateRepository <ISpotPlacementRepository>();

                        DateTime modifiedBefore = DateTime.UtcNow.Subtract(spotPlacementRetention);
                        spotPlacementRepository.DeleteBefore(modifiedBefore);
                        _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForInformationMessage(0, 0, "Deleted spot placements"));
                    }
                }
                catch (System.Exception exception)
                {
                    results.Add(new SystemTaskResult(SystemTaskResult.ResultTypes.Error, this.Id, string.Format("Error deleting spot placements: {0}", exception.Message)));
                }
            }
            return(results);
        }
Beispiel #7
0
        public void ProcessScenarioCampaignMetrics(Guid runId, Guid scenarioId, IEnumerable <Recommendation> scenarioRecommendations)
        {
            try
            {
                var scenarioCampaignMetrics = new ScenarioCampaignMetric
                {
                    Id      = scenarioId,
                    Metrics = GenerateCampaignKPIs(runId, scenarioId, scenarioRecommendations)
                };

                _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForInformationMessage(0,
                                                                                                     0, $"Start insert of scenario campaign metrics. ScenarioId: {scenarioId} Count: {scenarioCampaignMetrics.Metrics.Count}"));

                using (var innerScope = _repositoryFactory.BeginRepositoryScope())
                {
                    var scenarioCampaignMetricRepository = innerScope.CreateRepository <IScenarioCampaignMetricRepository>();
                    scenarioCampaignMetricRepository.AddOrUpdate(scenarioCampaignMetrics);
                    scenarioCampaignMetricRepository.SaveChanges();
                }

                _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForInformationMessage(0,
                                                                                                     0, $"End insert of scenario campaign metrics. ScenarioId: {scenarioId} Count: {scenarioCampaignMetrics.Metrics.Count}"));
            }
            catch (Exception e)
            {
                _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForException(0, 0, $"Error while processing scenario campaign metrics. ScenarioId: {scenarioId}", e));
            }
        }
Beispiel #8
0
        /// <summary>
        /// Updates the TaskInstance status
        /// </summary>
        /// <param name="id"></param>
        /// <param name="repositoryFactory"></param>
        /// <param name="status"></param>
        /// <param name="timeCompleted"></param>
        public static void UpdateTaskInstanceStatus(Guid id, IRepositoryFactory repositoryFactory, TaskInstanceStatues?status = null, DateTime?timeCompleted = null, DateTime?timeLastActive = null)
        {
            using (MachineLock.Create($"xggameplan.TaskExecutor.UpdateTaskInstanceStatus.{id}", TimeSpan.FromSeconds(60)))
                using (var scope = repositoryFactory.BeginRepositoryScope())
                {
                    var taskInstanceRepository = scope.CreateRepository <ITaskInstanceRepository>();

                    var taskInstance = taskInstanceRepository.Get(id);
                    if (status != null)
                    {
                        taskInstance.Status = status.Value;
                    }

                    if (timeCompleted != null)
                    {
                        taskInstance.TimeCompleted = timeCompleted.Value;
                    }

                    if (timeLastActive != null)
                    {
                        taskInstance.TimeLastActive = timeLastActive.Value;
                    }

                    taskInstanceRepository.Update(taskInstance);
                    taskInstanceRepository.SaveChanges();
                }
        }
Beispiel #9
0
        /// <summary>
        /// Creates run from template
        /// </summary>
        /// <param name="templateRun"></param>
        /// <param name="runRepository"></param>
        /// <returns></returns>
        private Run CreateRunFromTemplate(Run templateRun, IRunRepository runRepository)
        {
            using (var scope = _repositoryFactory.BeginRepositoryScope())
            {
                // Get sales areas for the run
                var salesAreaRepository = scope.CreateRepository <ISalesAreaRepository>();

                var salesAreas = RunManager.GetSalesAreas(templateRun, salesAreaRepository.GetAll());

                // Set the default run start date time using today's date and time from template run, use it as the starting point to try and
                // find some schedule data.
                DateTime startingDateTime = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, DateTime.UtcNow.Day, templateRun.StartDate.Hour, templateRun.StartDate.Minute, templateRun.StartDate.Second, templateRun.StartDate.Millisecond, templateRun.StartDate.Kind);

                // Clone template run, reset it, set date range
                Run cloneRun = (Run)templateRun.Clone();
                cloneRun.Id                     = Guid.NewGuid();
                cloneRun.Description            = $"Deployment Test ({GetVersion().Version})";
                cloneRun.CreatedDateTime        = DateTime.UtcNow;
                cloneRun.ExecuteStartedDateTime = null;
                cloneRun.LastModifiedDateTime   = cloneRun.CreatedDateTime;
                cloneRun.IsLocked               = false;
                cloneRun.Scenarios.ForEach(scenario => scenario.ResetToPendingStatus());
                cloneRun.StartDate = GetRunStartDate(startingDateTime, salesAreas, 90);
                if (cloneRun.StartDate == DateTime.MaxValue)
                {
                    throw new Exception("Unable to determine start date for test run due to insufficient data");
                }
                cloneRun.EndDate = cloneRun.StartDate.AddDays(1);
                cloneRun.Real    = false;  // Flag that it's not a real run

                // Clear IDs so that we can assign new ones
                //IdUpdater.ClearIds(cloneRun);
                cloneRun.Id       = Guid.Empty;
                cloneRun.CustomId = 0;

                // Set new IDs
                IdUpdater.SetIds(cloneRun, _identityGeneratorResolver);

                // Save run
                runRepository.Add(cloneRun);
                runRepository.SaveChanges();
                return(cloneRun);
            }
        }
Beispiel #10
0
        public List <SystemTaskResult> Execute()
        {
            IReadOnlyCollection <Run> GetRunsToDeleteForLastNDays(DateTime minCreatedDate)
            {
                using (var scope = _repositoryFactory.BeginRepositoryScope())
                {
                    var runRepository = scope.CreateRepository <IRunRepository>();

                    return(runRepository.GetAll()
                           .Where(r => r.CreatedDateTime.Year > 2000 && r.CreatedDateTime < minCreatedDate)
                           .OrderBy(r => r.CreatedDateTime)
                           .ToList());
                }
            }

            DateTime minCreated            = DateTime.UtcNow.Subtract(_runRetention);
            IReadOnlyCollection <Run> runs = GetRunsToDeleteForLastNDays(minCreated);

            var results = new List <SystemTaskResult>();

            foreach (var run in runs)
            {
                _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForInformationMessage(0, 0,
                                                                                                     $"Deleting run {run.Id} ({run.Description})"
                                                                                                     ));

                try
                {
                    Run.ValidateForDelete(run);

                    _runManager.DeleteRun(run.Id);

                    _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForRunDeleted(0, 0, run.Id, null));
                    _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForInformationMessage(0, 0,
                                                                                                         $"Deleted run {run.Id} ({run.Description})"
                                                                                                         ));
                }
                catch (Exception exception)
                {
                    results.Add(
                        new SystemTaskResult(SystemTaskResult.ResultTypes.Error, Id,
                                             $"Error deleting run {run.Id} ({run.Description}): {exception.Message}"
                                             )
                        );
                }
            }

            return(results);
        }
        /// <summary>Prepares the related data.</summary>
        /// <param name="source">The source.</param>
        protected override void PrepareRelatedData(IReadOnlyCollection <Recommendation> source)
        {
            var campaignExternalIds = source
                                      .Select(x => x.ExternalCampaignNumber)
                                      .Distinct()
                                      .Where(x => !string.IsNullOrWhiteSpace(x));

            using (var repositoryScope = _repositoryFactory.BeginRepositoryScope())
                using (var dbContext = _dbContextFactory.Create())
                {
                    var salesAreaRepository   = repositoryScope.CreateRepository <ISalesAreaRepository>();
                    var demographicRepository = repositoryScope.CreateRepository <IDemographicRepository>();
                    var clashRepository       = repositoryScope.CreateRepository <IClashRepository>();
                    var productRepository     = repositoryScope.CreateRepository <IProductRepository>();

                    _salesAreas   = salesAreaRepository.GetAll().ToDictionary(x => x.Name);
                    _demographics = demographicRepository.GetAll().ToDictionary(x => x.ExternalRef);
                    _clashes      = clashRepository.GetAll().ToDictionary(x => x.Externalref);

                    _productLinks =
                        (from campaignWithProductRelations in dbContext.Specific.View <CampaignWithProductRelations>()
                         join campaign in dbContext.Query <CampaignEntity>()
                         .Include(x => x.SalesAreaCampaignTargets)
                         .ThenInclude(x => x.SalesAreaGroup)
                         on campaignWithProductRelations.CampaignId equals campaign.Id
                         join productJoin in dbContext.Query <ProductEntity>() on campaignWithProductRelations.ProductId equals productJoin.Uid into pJoin
                         from product in pJoin.DefaultIfEmpty()
                         join agencyJoin in dbContext.Query <AgencyEntity>() on campaignWithProductRelations.AgencyId equals agencyJoin.Id into agJoin
                         from agency in agJoin.DefaultIfEmpty()
                         where campaignExternalIds.Contains(campaign.ExternalId)
                         select new ProductLinkSql
                    {
                        Campaign = campaign,
                        Product = product,
                        Agency = agency
                    })
                        .AsNoTracking()
                        .ToDictionary(x => x.Campaign.ExternalId, x => new ProductLinkDomain
                    {
                        Campaign = _mapper.Map <Campaign>(x.Campaign, opts => opts.UseEntityCache(_salesAreaByIdCache)),
                        Product  = x.Product is null ? null : new Product
                        {
                            Externalidentifier = x.Product.Externalidentifier,
                            Name       = x.Product.Name,
                            AgencyName = x.Agency?.Name,
                            ClashCode  = x.Product.ClashCode
                        }
                    });
Beispiel #12
0
        public List <SystemTestResult> Execute(SystemTestCategories systemTestCategory)
        {
            var results = new List <SystemTestResult>();
            int hoursSinceRunStarted        = 24;
            int scenarioCompleteTimeoutMins = 120;

            try
            {
                using (var scope = _repositoryFactory.BeginRepositoryScope())
                {
                    var runRepository = scope.CreateRepository <IRunRepository>();

                    // Get any runs started in last N hours
                    int countFailedRuns = 0;
                    var runs            = runRepository.GetAll().Where(r => r.FirstScenarioStartedDateTime != null && r.FirstScenarioStartedDateTime >= DateTime.UtcNow.AddHours(-hoursSinceRunStarted)).OrderBy(r => r.CreatedDateTime);

                    // Check runs
                    foreach (var run in runs)
                    {
                        // Count up failures
                        countFailedRuns += run.Scenarios.Where(s => s.Status == ScenarioStatuses.CompletedError).ToList().Count;

                        try
                        {
                            ISystemTest runOutputTest = new RunOutputTest(run, _category, _repositoryFactory, scenarioCompleteTimeoutMins);
                            results.AddRange(runOutputTest.Execute(systemTestCategory));
                        }
                        catch { };      // Ignore
                    }

                    if (!runs.Any())
                    {
                        results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Warning, _category, string.Format("No runs were started in the last {0} hours", hoursSinceRunStarted), ""));
                    }
                    else if (countFailedRuns == 0)
                    {
                        results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Information, _category, string.Format("No failed runs in the last {0} hours", hoursSinceRunStarted), ""));
                    }
                }
            }
            catch (System.Exception exception)
            {
                results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, string.Format("Error checking run history: {0}", exception.Message), ""));
            }
            return(results);
        }
Beispiel #13
0
        /// <summary>
        /// Execute run notification HTTP tests
        /// </summary>
        /// <returns></returns>
        private List <SystemTestResult> ExecuteRunNotificationHTTPTests()
        {
            var results = new List <SystemTestResult>();

            using (var scope = _repositoryFactory.BeginRepositoryScope())
            {
                var tenantSettingsRepository = scope.CreateRepository <ITenantSettingsRepository>();
                var tenantSettings           = tenantSettingsRepository.Get();

                // Find RunEventSettings for the scenario completed event
                var runEventSettings = tenantSettings.RunEventSettings.Find(res => res.EventType == RunEvents.RunScenarioCompleted);
                if (runEventSettings != null && runEventSettings.HTTP != null)   // HTTP notification is configured
                {
                    try
                    {
                        // Create a run in memory with ScenarioIds that won't exist in external system
                        var runRepository = scope.CreateRepository <IRunRepository>();
                        var templateRun   = runRepository.GetAll().Where(r => r.Scenarios.Any()).FirstOrDefault();
                        if (templateRun == null)   // No existing runs
                        {
                            results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Warning, _category, "Unable to test HTTP notification for run scenario completed because there is no run to use. Please check that the notification is configured correctly otherwise output data will not be picked up and processed by the external system.", ""));
                        }
                        else   // Existing run, clone it
                        {
                            var run = (Run)templateRun.Clone();
                            run.Id = Guid.NewGuid();
                            run.Scenarios.ForEach(scenario => scenario.Id = Guid.NewGuid());

                            // Execute notification
                            HTTPTNotification httpNotification = new HTTPTNotification();
                            httpNotification.RunCompleted(run, run.Scenarios[0], true, runEventSettings.HTTP);
                        }
                    }
                    catch (System.Exception exception)
                    {
                        results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, string.Format("Error calling HTTP notification for run scenario completed: {0}. The output data for runs will never be picked up and processed by the external system.", exception.Message), ""));
                    }
                }
                else    // Notification not set up
                {
                    results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, "There is no HTTP notification configured for when a scenario run is completed. The output data for runs will never be picked up and processed by the external system.", ""));
                }
            }
            return(results);
        }
        public static PivotRecommendations Pivot(
            this IReadOnlyCollection <Recommendation> recommendations,
            IRepositoryFactory repositoryFactory)
        {
            using var scope = repositoryFactory.BeginRepositoryScope();
            var breakRepository     = scope.CreateRepository <IBreakRepository>();
            var programmeRepository = scope.CreateRepository <IProgrammeRepository>();

            IReadOnlyDictionary <string, Break> allBreaks = breakRepository
                                                            .GetAll()
                                                            .ToDictionary(b => b.ExternalBreakRef);

            IReadOnlyDictionary <string, Programme> allProgrammes = programmeRepository
                                                                    .GetAll()
                                                                    .ToDictionary(p => p.ExternalReference);

            return(new PivotRecommendations(
                       recommendations.OrderBy(r => r.ExternalBreakNo).ToList(),
                       allBreaks,
                       allProgrammes));
        }
Beispiel #15
0
        public IHttpActionResult Post([FromBody] List <CreateProgramme> programs)
        {
            if (programs == null || !programs.Any() || !ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            ValidatePrograms(programs);

            var programmeList = _mapper.Map <IEnumerable <Programme> >(programs)
                                .OrderBy(x => x.StartDateTime)
                                .SequentiallyCount <Programme>(new ProgrammePrgtNoSequenceCounter())
                                .ToList();

            _programmeRepository.Add(programmeList);

            // group by date and channels
            programmeList.GroupBy(s => new { s.StartDateTime.Date, s.SalesArea }).ForEach(grp =>
            {
                using (MachineLock.Create(string.Format("xggameplan.scheduleday.{0}.{1}", grp.Key.SalesArea, grp.Key.Date), new TimeSpan(0, 10, 0)))
                {
                    using (var scope = _repositoryFactory.BeginRepositoryScope())
                    {
                        var scheduleRepository = scope.CreateRepository <IScheduleRepository>();
                        var schedule           = scheduleRepository.GetOrCreateSchedule(grp.Key.SalesArea, grp.Key.Date);

                        if (schedule.Programmes is null)
                        {
                            schedule.Programmes = new List <Programme>();
                        }

                        schedule.Programmes.AddRange(grp);
                        scheduleRepository.Add(schedule);
                        scheduleRepository.SaveChanges();
                    }
                }
            });

            return(Ok());
        }
Beispiel #16
0
        public void ProcessData(ScenarioCampaignResult data, Run run, Scenario scenario)
        {
            var scenarioId = data.Id;

            if (!_saveData)
            {
                const string campaignLevelReportFacility = "XGSCRC";

                var facility = _facilityRepository.GetByCode(campaignLevelReportFacility);

                if (facility is null || facility.Enabled == false)
                {
                    PreGenerateReport(data.Items, run, scenario);
                }

                return;
            }

            try
            {
                _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForInformationMessage(0,
                                                                                                     0, $"Start insert of scenario campaigns. ScenarioId: {scenarioId} Count: {data.Items.Count}"));
                using (var innerScope = _repositoryFactory.BeginRepositoryScope())
                {
                    var scenarioCampaignResultRepository = innerScope.CreateRepository <IScenarioCampaignResultRepository>();
                    scenarioCampaignResultRepository.AddOrUpdate(data);
                    scenarioCampaignResultRepository.SaveChanges();
                }
                _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForInformationMessage(0,
                                                                                                     0, $"End insert of scenario campaigns. ScenarioId: {scenarioId} Count: {data.Items.Count}"));
            }
            catch (Exception e)
            {
                _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForException(0, 0, $"Error while processing scenario campaign results. ScenarioId: {scenarioId}", e));
                throw;
            }

            PreGenerateReport(data.Items, run, scenario);
        }
Beispiel #17
0
        public void ProcessData(Failures data, Run run, Scenario scenario)
        {
            try
            {
                _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForInformationMessage(0,
                                                                                                     0, $"Failures has been generated. ScenarioId: {data.Id}, Count: {data.Items.Count}"));

                using (var innerScope = _repositoryFactory.BeginRepositoryScope())
                {
                    var failuresRepository = innerScope.CreateRepository <IFailuresRepository>();
                    failuresRepository.Add(data);
                    failuresRepository.SaveChanges();
                }

                _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForInformationMessage(0,
                                                                                                     0, $"Failures has been saved to the db. ScenarioId: {data.Id}"));
            }
            catch (Exception e)
            {
                _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForException(0, 0, "Error while processing failures", e));
                throw;
            }
        }
Beispiel #18
0
        public List <SystemTestResult> Execute(SystemTestCategories systemTestCategory)
        {
            var results = new List <SystemTestResult>();

            try
            {
                using (var scope = _repositoryFactory.BeginRepositoryScope())
                {
                    // Get list of AutoBooks
                    var autoBookRepository = scope.CreateRepository <IAutoBookRepository>();
                    var autoBooks          = autoBookRepository.GetAll();

                    // Check AutoBook provisioning settings
                    results.AddRange(ExecuteProvisioningTests(autoBooks.ToList()));

                    // Warn if no AutoBooks exist
                    if (autoBookRepository.GetAll().ToList().Count == 0)
                    {
                        if (!_autoBooks.Settings.AutoProvisioning)
                        {
                            results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, "No AutoBook data exists and auto-provisioning is disabled. It will not be possible to execute any runs.", ""));
                        }
                    }
                    else
                    {
                        // Check connectivity to each AutoBook
                        int countWorkingAutoBooks = 0;
                        int countFreeAutoBooks    = 0;

                        foreach (var autoBook in autoBooks)
                        {
                            try
                            {
                                IAutoBook autoBookInterface = _autoBooks.GetInterface(autoBook);
                                var       autoBookStatus    = autoBookInterface.GetStatus();
                                if (AutoBook.IsWorkingStatus(autoBookStatus))
                                {
                                    countWorkingAutoBooks++;
                                    if (autoBookStatus == AutoBookStatuses.Idle)
                                    {
                                        countFreeAutoBooks++;
                                    }
                                }
                                else if (autoBookStatus == AutoBookStatuses.Fatal_Error)
                                {
                                    if (!_autoBooks.Settings.AutoProvisioning)
                                    {
                                        results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Warning, _category, string.Format("AutoBook {0} has indicated that is has encountered a fatal error. It cannot be used for any runs while it is in this state. Please manually restart it.", autoBook.Id), ""));
                                    }
                                }
                            }
                            catch
                            {
                                if (autoBook.Status != AutoBookStatuses.Provisioning)    // Ignore error if Provisioning
                                {
                                    results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Warning, _category, string.Format("Error testing connection to AutoBook {0} ({1})", autoBook.Id, autoBook.Api), ""));
                                }
                            }
                        }

                        if (countWorkingAutoBooks == 0)
                        {
                            if (!_autoBooks.Settings.AutoProvisioning)
                            {
                                results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, "There are no working AutoBooks. It will not be possible to start any runs.", ""));
                            }
                        }
                        else if (countFreeAutoBooks == 0)
                        {
                            results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Warning, _category, string.Format("All {0} working AutoBooks are currently executing a run. It will not be possible to start any runs until existing runs have completed.", countWorkingAutoBooks), ""));
                        }
                        else if (results.Count == 0)
                        {
                            results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Information, _category, string.Format("AutoBook test OK ({0} working AutoBooks)", countWorkingAutoBooks), ""));
                        }
                    }
                }
            }
            catch (System.Exception exception)
            {
                results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, string.Format("Error checking AutoBooks: {0}", exception.Message), ""));
            }
            return(results);
        }
        private async Task <bool> WaitForRunCompletedAsync(Guid runId)
        {
            var isRunCompleted = false;

            do
            {
                using (var scope = _repositoryFactory.BeginRepositoryScope())
                {
                    var runRepository = scope.CreateRepository <IRunRepository>();
                    _run = runRepository.Find(runId);
                    if (_run is null)
                    {
                        return(false);
                    }

                    BroadcastScenarioSteps(scope, _run.TotalSteps + GetAdditionalSteps(scope));

                    if (_run.RunStatus == RunStatus.Complete || _run.RunStatus == RunStatus.Errors)
                    {
                        isRunCompleted = true;
                    }
                    else
                    {
                        await Task.Delay(5000).ConfigureAwait(false);
                    }
                }
            } while (!isRunCompleted);

            return(true);

            int GetAdditionalSteps(IRepositoryScope scope)
            {
                int additionalSteps = 0;

                var tenantRepository = scope.CreateRepository <ITenantSettingsRepository>();

                if (tenantRepository != null)
                {
                    var tenantSetting   = tenantRepository.Get();
                    var runEventSetting = tenantSetting.RunEventSettings.FirstOrDefault();
                    if (runEventSetting != null)
                    {
                        additionalSteps += runEventSetting.Email.Enabled ? 1 : 0;
                        additionalSteps += runEventSetting.HTTP.Enabled ? 1 : 0;
                    }
                }

                return(additionalSteps);
            }

            void BroadcastScenarioSteps(IRepositoryScope scope, int totalSteps)
            {
                var pipelineRepository = scope.CreateRepository <IPipelineAuditEventRepository>();

                if (pipelineRepository != null)
                {
                    var allPipelinEventsForRun = pipelineRepository.GetAllByRunId(_run.Id);

                    _run.Scenarios.ForEach(scenario =>
                    {
                        var count = pipelineRepository.GetAllByScenarioId(scenario.Id).Count();
                        count    += allPipelinEventsForRun
                                    .Where(pipelineAuditEvent => pipelineAuditEvent.ScenarioId == Guid.Empty)
                                    .Count();

                        _runManager.BroadcastScenario(
                            scenario.Id,
                            scenario.Status,
                            count > 0 ? count : 1,
                            totalSteps);
                    });
                }
            }
        }
Beispiel #20
0
        public List <SystemMessage> Validate(Run run)
        {
            var messages = new List <SystemMessage>();

            using (var scope = _repositoryFactory.BeginRepositoryScope())
            {
                var repositories = scope.CreateRepositories(
                    typeof(ISalesAreaRepository),
                    typeof(ICampaignRepository),
                    typeof(IAutoBookInstanceConfigurationRepository),
                    typeof(IDemographicRepository),
                    typeof(IScheduleRepository),
                    typeof(ISmoothConfigurationRepository)
                    );
                var salesAreaRepository = repositories.Get <ISalesAreaRepository>();
                var campaignRepository  = repositories.Get <ICampaignRepository>();
                var autoBookInstanceConfigurationRepository = repositories.Get <IAutoBookInstanceConfigurationRepository>();
                var demographicRepository         = repositories.Get <IDemographicRepository>();
                var scheduleRepository            = repositories.Get <IScheduleRepository>();
                var smoothConfigurationRepository = repositories.Get <ISmoothConfigurationRepository>();

                // Validate run details, first check that run is well formed and
                // carry on if it pass this first method check
                messages.AddRange(ValidateRunDetailsForStartRun(run));
                if (messages.Count != 0)
                {
                    return(messages);
                }

                // Get Sales areas for run and list of sales area names from
                // run.SalesAreaPriorities NOT set to 'Exclude'
                var runSalesAreas     = new List <SalesArea>();
                var runSalesAreaNames = new List <string>();
                if (run.SalesAreaPriorities.Any())
                {
                    runSalesAreas     = salesAreaRepository.FindByNames(run.SalesAreaPriorities.Where(s => s.Priority != SalesAreaPriorityType.Exclude).Select(s => s.SalesArea).ToList());
                    runSalesAreaNames = salesAreaRepository.GetListOfNames(runSalesAreas);
                }
                else
                {
                    // If there are NO entries in run.SalesAreaPriorities then
                    // get all sales are names from the repository of sales areas
                    runSalesAreaNames = salesAreaRepository.GetListOfNames(salesAreaRepository.GetAll().ToList());
                }

                // check that there are some sales areas from one of the two
                // sources above
                if (!runSalesAreaNames.Any())
                {
                    messages.Add(FormatSystemMessage(SystemMessage.SalesAreaDataMissing));

                    // only carry on with the run validation if there are some
                    // sales areas
                    return(messages);
                }

                bool isOptimiserNeeded = run.Optimisation || run.RightSizer || run.ISR;

                var allAutoBookInstanceConfigurations = autoBookInstanceConfigurationRepository.GetAll().ToList();
                if (!allAutoBookInstanceConfigurations.Any())
                {
                    allAutoBookInstanceConfigurations = _autoBooks.CreateDefaultInstanceConfigurations();
                }

                var allCampaigns = campaignRepository.GetAllFlat().ToList();
                var runCampaigns = RunManager.GetRunCampaigns(run, allCampaigns);
                var demographics = demographicRepository.GetAll().ToList();

                // Validate RatingsData
                if (_featureManager.IsEnabled(nameof(ProductFeature.NineValidationRatingPredictions)))
                {
                    var demographicsGameplan = demographics.Where(g => g.Gameplan).Select(x => x.ExternalRef).ToList();

                    var noOfRatingPredictionsPerScheduleDayAreaDemo = _tenantSettingsRepository.Get()?.NoOfRatingsPerSalesDayDemo ?? 96;
                    messages.AddRange(ValidateMissingRatingsForStartRun(run.StartDate, run.EndDate, runSalesAreaNames, demographicsGameplan, noOfRatingPredictionsPerScheduleDayAreaDemo));
                }

                if (isOptimiserNeeded && allAutoBookInstanceConfigurations.Count > 1)   //single instance?
                {
                    // Get number of breaks
                    int breaks = RunManager.GetBreakCountEstimate(run, runSalesAreas, _repositoryFactory);

                    messages.AddRange(ValidateAutoBookResourcesForStartRun(run, allAutoBookInstanceConfigurations, runSalesAreas.Count, runCampaigns.Count, demographics.Count, breaks));
                }

                // Validate ISR settings
                messages.AddRange(ValidateISRSettingsForStartRun(run, runSalesAreas));

                // Validate RS settings
                messages.AddRange(ValidateRSSettingsForStartRun(run, runSalesAreas));

                // Validate Optimisation settings
                messages.AddRange(ValidateOptimisationSettingsForStartRun(run));

                // Validate Smooth configuration
                messages.AddRange(ValidateSmoothConfiguration(run, smoothConfigurationRepository));

                // Validate against existing runs
                messages.AddRange(ValidateExistingRunsForStartRun());

                // Validate schedule data (Breaks, spots, campaigns etc)
                messages.AddRange(ValidateScheduleDataForStartRun(run, runCampaigns, runSalesAreas, demographics.Count));

                // Validate demographics
                messages.AddRange(ValidateDemographicsForStartRun(demographics));

                // Validate output files, can't process output files if data is missing
                messages.AddRange(ValidateOutputFilesForStartRun(run));

                // Validate universes
                messages.AddRange(ValidateUniversesForStartRun(run, runSalesAreas));
            }

            return(messages);
        }
        private ProcessBreakEfficiencyOutput ProcessFileInternal(Guid scenarioId, string folder)
        {
            var    output = new ProcessBreakEfficiencyOutput();
            string breakEfficiencyFile = FileHelpers.GetPathToFileIfExists(folder, FileName);

            if (String.IsNullOrEmpty(breakEfficiencyFile))
            {
                return(output);
            }

            _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForInformationMessage(0,
                                                                                                 0, $"Processing output file {breakEfficiencyFile}"));

            var demographicsById  = Demographic.IndexListById(_dataSnapshot.AllDemographics.Value);
            var salesAreasIndexed = SalesArea.IndexListByCustomId(_dataSnapshot.AllSalesAreas.Value);

            // Create memory cache of Schedule documents
            var      schedules           = new List <ScheduleIndexed <Break, int> >();
            string   lastScheduleDateKey = "";
            int      count           = 0;
            int      countUpdated    = 0;
            int      countNotUpdated = 0;
            DateTime nextYield       = DateTime.MinValue;

            // Process CSV in order of sales area + schedule date + schedule
            // time, allows us to keep as few Break/Schedule documents in memory
            var importSettings = CSVImportSettings.GetImportSettings(breakEfficiencyFile, typeof(BreakEfficiencyHeaderMap), typeof(BreakEfficiencyIndexMap));

            IBreakEfficiencyImportRepository breakEfficiencyImportRepository = new CSVBreakEfficiencyImportRepository(importSettings);
            IScheduleRepository scheduleRepository = null;

            var lazyScopeCreator = new Func <Lazy <IRepositoryScope> >(() => new Lazy <IRepositoryScope>(() => _repositoryFactory.BeginRepositoryScope()));
            var lazyScope        = lazyScopeCreator();

            try
            {
                foreach (BreakEfficiencyImport breakEfficiencyImport in breakEfficiencyImportRepository.GetAll()
                         .OrderBy(be => be.sare_no).ThenBy(be => be.brek_sched_date).ThenBy(be => be.brek_nom_time))
                {
                    count++;
                    bool   breakUpdated    = false;
                    string scheduleDateKey = string.Format("{0}{1}{2}", breakEfficiencyImport.sare_no, (Char)9,
                                                           breakEfficiencyImport.brek_sched_date);

                    try
                    {
                        // Save changes if different sales area + schedule date
                        if (!String.IsNullOrEmpty(lastScheduleDateKey) && scheduleDateKey != lastScheduleDateKey) // No longer need previous Break/Schedule docs
                        {
                            if (scheduleRepository != null)
                            {
                                schedules.ForEach(scheduleIndexed => scheduleRepository.Add(scheduleIndexed.Schedule));
                                scheduleRepository.SaveChanges();
                            }

                            scheduleRepository = null;
                            lazyScope.Value.Dispose();
                            lazyScope = lazyScopeCreator();

                            // Clear data that we no longer need
                            schedules.Clear();
                        }

                        if (scheduleRepository == null)
                        {
                            scheduleRepository = lazyScope.Value.CreateRepository <IScheduleRepository>();
                        }

                        SalesArea salesArea = salesAreasIndexed.ContainsKey(breakEfficiencyImport.sare_no)
                            ? salesAreasIndexed[breakEfficiencyImport.sare_no]
                            : null;

                        // Load breaks if necessary
                        LoadBreaks(salesArea, breakEfficiencyImport, schedules, scheduleRepository);

                        // Update break efficiency
                        if (UpdateBreakEfficiency(salesArea, breakEfficiencyImport, schedules,
                                                  demographicsById))
                        {
                            breakUpdated = true;
                        }
                    }
                    catch (System.Exception exception)
                    {
                        // Log exception, continue
                        _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForException(0, 0,
                                                                                                    string.Format("Error processing break efficiency for break no {0} (Record {1})",
                                                                                                                  breakEfficiencyImport.break_no, count), exception));
                    }
                    finally
                    {
                        lastScheduleDateKey = scheduleDateKey;
                        if (breakUpdated)
                        {
                            countUpdated++;
                        }
                        else
                        {
                            countNotUpdated++;
                        }

                        DoYield(false, ref nextYield);
                    }
                }

                // Save changed
                if (scheduleRepository != null)
                {
                    schedules.ForEach(scheduleIndexed => scheduleRepository.Add(scheduleIndexed.Schedule));
                    scheduleRepository.SaveChanges();
                }
            }
            finally
            {
                if (scheduleRepository != null)
                {
                    lazyScope.Value.Dispose();
                }
            }

            if (countUpdated > 0 && countNotUpdated == 0)   // Success, log info event
            {
                _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForInformationMessage(0, 0, string.Format("Updated {0} break efficiencies (Not updated={1})", countUpdated, countNotUpdated)));
            }
            else          // Some updates failed, log warning event
            {
                _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForWarningMessage(0, 0, string.Format("Updated {0} break efficiencies (Not updated={1})", countUpdated, countNotUpdated)));
            }

            _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForInformationMessage(0,
                                                                                                 0, $"Processed output file {breakEfficiencyFile}"));

            return(output);
        }
Beispiel #22
0
        /// <summary>
        /// Starts run. Uploads input data and then instructs AutoBook instance to start
        /// </summary>
        /// <param name="autoBookInterface"></param>
        /// <param name="autoBook"></param>
        public void UploadInputFilesStartAutoBookRun(IAutoBook autoBookInterface, AutoBook autoBook)
        {
            using var scope = _repositoryFactory.BeginRepositoryScope();
            var runRepository      = scope.CreateRepository <IRunRepository>();
            var autoBookRepository = scope.CreateRepository <IAutoBookRepository>();

            bool startedRun = false;

            try
            {
                // Update scenario status to Starting, Scenario.StartedDateTime has already been set
                RunManager.UpdateScenarioStatuses(_repositoryFactory, _auditEventRepository, RunId,
                                                  new List <Guid>()
                {
                    ScenarioId
                }, new List <ScenarioStatuses>()
                {
                    ScenarioStatuses.Starting
                });

                // Get run
                var run = runRepository.Find(RunId);

                // Record which run/scenario is being processed
                //IAutoBookRepository autoBookRepository = (IAutoBookRepository)repositories[typeof(IAutoBookRepository)];
                //AutoBook localAutoBook = autoBookRepository.Find(autoBook.Id);
                lock (autoBook)
                {
                    autoBook.Status         = AutoBookStatuses.In_Progress;
                    autoBook.LastRunStarted = DateTime.UtcNow;
                    autoBook.Locked         = true;
                    autoBook.Task           = new AutoBookTask()
                    {
                        RunId      = RunId,
                        ScenarioId = ScenarioId
                    };
                }

                autoBookRepository.Update(autoBook);
                autoBookRepository.SaveChanges(); // Force save

                // Upload input data
                _autoBookInputHandler.Handle(run, ScenarioId);

                // Instruct AutoBook to start processing
                bool loggedNotifyFinished = false;
                try
                {
                    _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForGameplanPipelineStart(0, 0,
                                                                                                            PipelineEventIDs.STARTED_NOTIFYING_AUTOBOOK_API, RunId, ScenarioId, autoBook.Id, null));

                    GetAutoBookStatusModel autoBookStatusModel = autoBookInterface.StartAutoBookRun(RunId, ScenarioId);

                    _pipelineAuditEventRepository.Add(PipelineEventHelper.CreatePipelineAuditEvent(AuditEventTypes.GamePlanRun,
                                                                                                   PipelineEventIDs.STARTED_NOTIFYING_AUTOBOOK_API, RunId, ScenarioId, null));

                    if (autoBookStatusModel.Status == AutoBookStatuses.In_Progress) // Task_Error or Fatal_Error
                    {
                        _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForGameplanPipelineEnd(0, 0,
                                                                                                              PipelineEventIDs.FINISHED_NOTIFYING_AUTOBOOK_API, RunId, ScenarioId, autoBook.Id,
                                                                                                              null, null, null));

                        _pipelineAuditEventRepository.Add(PipelineEventHelper.CreatePipelineAuditEvent(AuditEventTypes.GamePlanRun,
                                                                                                       PipelineEventIDs.FINISHED_NOTIFYING_AUTOBOOK_API, RunId, ScenarioId, null));

                        loggedNotifyFinished = true;
                    }
                    else
                    {
                        _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForGameplanPipelineEnd(0, 0,
                                                                                                              PipelineEventIDs.FINISHED_NOTIFYING_AUTOBOOK_API, RunId, ScenarioId, autoBook.Id,
                                                                                                              null,
                                                                                                              String.Format(
                                                                                                                  "AutoBook API unexpectedly returned status {0} when instructing it to start run",
                                                                                                                  autoBookStatusModel.ToString()), null));

                        _pipelineAuditEventRepository.Add(PipelineEventHelper.CreatePipelineAuditEvent(AuditEventTypes.GamePlanRun,
                                                                                                       PipelineEventIDs.FINISHED_NOTIFYING_AUTOBOOK_API, RunId, ScenarioId,
                                                                                                       $"AutoBook API unexpectedly returned status {autoBookStatusModel.ToString()} " +
                                                                                                       "when instructing it to start run"));

                        loggedNotifyFinished = true;
                        throw new Exception(String.Format(
                                                "AutoBook returned status {0} when starting run (AutoBookID={1})",
                                                autoBookStatusModel.Status, autoBook.Id));
                    }
                }
                catch (System.Exception exception)
                {
                    if (!loggedNotifyFinished)
                    {
                        _auditEventRepository.Insert(AuditEventFactory.CreateAuditEventForGameplanPipelineEnd(0, 0,
                                                                                                              PipelineEventIDs.FINISHED_NOTIFYING_AUTOBOOK_API, RunId, ScenarioId, autoBook.Id,
                                                                                                              null, exception.Message, exception));

                        _pipelineAuditEventRepository.Add(PipelineEventHelper.CreatePipelineAuditEvent(AuditEventTypes.GamePlanRun,
                                                                                                       PipelineEventIDs.FINISHED_NOTIFYING_AUTOBOOK_API, RunId, ScenarioId, exception.Message));
                    }

                    throw;
                }
                finally
                {
                    _pipelineAuditEventRepository.SaveChanges();
                }

                // Flag as InProgress
                RunManager.UpdateScenarioStatuses(_repositoryFactory, _auditEventRepository, RunId,
                                                  new List <Guid>()
                {
                    ScenarioId
                }, new List <ScenarioStatuses>()
                {
                    ScenarioStatuses.InProgress
                });
                startedRun = true;
            }
            catch
            {
                throw;
            }
            finally
            {
                // Clean up failure
                if (!startedRun)
                {
                    // Reset to free, unlocks AutoBook instance so that it can be re-used
                    autoBookInterface.ResetFree();
                    autoBookRepository.SaveChanges();
                    _pipelineAuditEventRepository.SaveChanges();
                }
            }
        }
Beispiel #23
0
        public List <SystemTestResult> Execute(SystemTestCategories systemTestCategory)
        {
            var results = new List <SystemTestResult>();

            try
            {
                using (var scope = _repositoryFactory.BeginRepositoryScope())
                {
                    var repositoryList = scope.CreateRepositories(
                        typeof(IBreakRepository),
                        typeof(ICampaignRepository),
                        typeof(IClashRepository),
                        typeof(IProductRepository),
                        typeof(IProgrammeRepository),
                        typeof(IProgrammeDictionaryRepository),
                        typeof(IRatingsScheduleRepository),
                        typeof(IScheduleRepository),
                        typeof(ISpotRepository)
                        );

                    var breakRepository               = repositoryList.Get <IBreakRepository>();
                    var campaignRepository            = repositoryList.Get <ICampaignRepository>();
                    var clashRepository               = repositoryList.Get <IClashRepository>();
                    var productRepository             = repositoryList.Get <IProductRepository>();
                    var programmeRepository           = repositoryList.Get <IProgrammeRepository>();
                    var programmeDictionaryRepository = repositoryList.Get <IProgrammeDictionaryRepository>();
                    var ratingsScheduleRepository     = repositoryList.Get <IRatingsScheduleRepository>();
                    var scheduleRepository            = repositoryList.Get <IScheduleRepository>();
                    var spotRepository = repositoryList.Get <ISpotRepository>();

                    if (breakRepository.CountAll == 0)
                    {
                        results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, "No Break data exists. It will cause runs to fail.", ""));
                    }
                    if (campaignRepository.CountAll == 0)
                    {
                        results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, "No Campaign data exists. It will cause runs to fail.", ""));
                    }
                    if (clashRepository.CountAll == 0)
                    {
                        results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, "No Clash data exists. It will cause runs to fail.", ""));
                    }
                    if (productRepository.CountAll == 0)
                    {
                        results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, "No Product data exists. It will cause runs to fail.", ""));
                    }
                    if (programmeRepository.CountAll == 0)
                    {
                        results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, "No Programme data exists. It will cause runs to fail.", ""));
                    }
                    if (programmeDictionaryRepository.CountAll == 0)
                    {
                        results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, "No Programme Dictionary data exists. It will cause runs to fail.", ""));
                    }
                    if (ratingsScheduleRepository.CountAll == 0)
                    {
                        results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, "No Ratings Schedule data exists. It will cause runs to fail.", ""));
                    }
                    if (scheduleRepository.CountAll == 0)
                    {
                        results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, "No Schedule data exists. It will cause runs to fail.", ""));
                    }
                    if (spotRepository.CountAll == 0)
                    {
                        results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, "No Spot data exists. It will cause runs to fail.", ""));
                    }
                }
            }
            catch (System.Exception exception)
            {
                results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, string.Format("Error checking schedule data: {0}", exception.Message), ""));
            }
            finally
            {
                if (!results.Where(r => r.ResultType == SystemTestResult.ResultTypes.Error).Any())
                {
                    results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Information, _category, "Schedule data test OK. Please be aware that only basic tests were performed.", ""));
                }
            }
            return(results);
        }
Beispiel #24
0
        public List <SystemTestResult> Execute(SystemTestCategories systemTestCategory)
        {
            var results = new List <SystemTestResult>();

            try
            {
                using (var scope = _repositoryFactory.BeginRepositoryScope())
                {
                    var repositoryList = scope.CreateRepositories(
                        typeof(IFunctionalAreaRepository),
                        typeof(IISRSettingsRepository),
                        typeof(IRSSettingsRepository),
                        typeof(ILanguageRepository),
                        typeof(IMetadataRepository),
                        typeof(ISalesAreaRepository),
                        typeof(IOutputFileRepository),
                        typeof(IUniverseRepository),
                        typeof(IEmailAuditEventSettingsRepository),
                        typeof(IAutoBookInstanceConfigurationRepository),
                        typeof(IAutoBookSettingsRepository),
                        typeof(ISmoothFailureMessageRepository),
                        typeof(IDemographicRepository),
                        typeof(IProgrammeClassificationRepository),
                        typeof(IProgrammeCategoryHierarchyRepository));

                    var functionalAreaRepository = repositoryList.Get <IFunctionalAreaRepository>();
                    var languageRepository       = repositoryList.Get <ILanguageRepository>();
                    var metadataRepository       = repositoryList.Get <IMetadataRepository>();
                    var salesAreaRepository      = repositoryList.Get <ISalesAreaRepository>();
                    var outputFileRepository     = repositoryList.Get <IOutputFileRepository>();
                    var isrSettingsRepository    = repositoryList.Get <IISRSettingsRepository>();
                    var rsSettingsRepository     = repositoryList.Get <IRSSettingsRepository>();
                    var universeRepository       = repositoryList.Get <IUniverseRepository>();
                    var autoBookInstanceConfigurationRepository = repositoryList.Get <IAutoBookInstanceConfigurationRepository>();
                    var autoBookSettingsRepository        = repositoryList.Get <IAutoBookSettingsRepository>();
                    var smoothFailureMessageRepository    = repositoryList.Get <ISmoothFailureMessageRepository>();
                    var demographicRepository             = repositoryList.Get <IDemographicRepository>();
                    var programmeClassificationRepository = repositoryList.Get <IProgrammeClassificationRepository>();
                    var programmeCategoryRepository       = repositoryList.Get <IProgrammeCategoryHierarchyRepository>();

                    var salesAreas = salesAreaRepository.GetAll().ToList();

                    /*
                     * if (demographicRepository.GetAll().ToList().Count == 0)
                     * {
                     *  results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, "No Demographic data exists. It will cause runs to fail."));
                     * }
                     */
                    if (demographicRepository.CountAll == 0)
                    {
                        results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, "No Demographic data exists. It will cause runs to fail.", ""));
                    }
                    if (metadataRepository.GetByKey(MetaDataKeys.BreakTypes).Count == 0)
                    {
                        results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, "No Break Types data exists. It will cause runs to fail.", ""));
                    }
                    if (functionalAreaRepository.GetAll().ToList().Count == 0)
                    {
                        results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, "No Functional Area data exists. It will cause errors displaying Failure data when the run is complete.", ""));
                    }
                    if (languageRepository.GetAll().ToList().Count == 0)
                    {
                        results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, "No Language data exists.", ""));
                    }
                    if (salesAreaRepository.GetAll().ToList().Count == 0)
                    {
                        results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, "No Sales Area data exists. It will cause runs to fail.", ""));
                    }
                    if (outputFileRepository.GetAll().ToList().Count == 0)
                    {
                        results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, "No Output File data exists. It will cause runs to fail. It is needed for processing output files.", ""));
                    }

                    var isrSettingsList = isrSettingsRepository.GetAll();
                    if (isrSettingsList.Count == 0)
                    {
                        results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, "No ISR Settings data exists. It will cause runs to fail if ISR is requested.", ""));
                    }
                    else if (isrSettingsList.Count < salesAreas.Count)
                    {
                        results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, "ISR Settings data is missing for some sales areas. It will cause runs to fail if ISR is requested.", ""));
                    }

                    var rsSettingsList = rsSettingsRepository.GetAll();
                    if (rsSettingsList.Count == 0)
                    {
                        results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, "No Right Sizer Settings data exists. It will cause runs to fail if Right Sizer is requested.", ""));
                    }
                    else if (rsSettingsList.Count < salesAreas.Count)
                    {
                        results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, "Right Sizer Settings data is missing for some sales areas. It will cause runs to fail if Right Sizer is requested.", ""));
                    }

                    if (universeRepository.GetAll().ToList().Count == 0)
                    {
                        results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, "No Universe data exists. It will cause runs to fail.", ""));
                    }

                    if (programmeClassificationRepository.CountAll == 0)
                    {
                        results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, "No Programme Classificiation data exists. It will cause runs to fail.", ""));        // Not mandatory
                    }

                    if (programmeCategoryRepository.GetAll().ToList().Count == 0)
                    {
                        results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, "No Programme Category Hierarchy data exists. It will cause runs to fail.", ""));
                    }

                    // Test internal users
                    //results.AddRange(TestInternalUsers());
                }
            }
            catch (System.Exception exception)
            {
                results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, String.Format("Error checking static data: {0}", exception.Message), ""));
            }
            finally
            {
                if (!results.Where(r => r.ResultType == SystemTestResult.ResultTypes.Error).Any())
                {
                    results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Information, _category, "Static data test OK", ""));
                }
            }
            return(results);
        }
        /// <summary>
        /// Posts message to MS Teams channel
        /// </summary>
        /// <param name="auditEvent"></param>
        /// <param name="auditEventType"></param>
        /// <param name="postMessageSettings"></param>
        public void PostMessage(AuditEvent auditEvent, AuditEventType auditEventType, MSTeamsPostMessageSettings postMessageSettings)
        {
            AuditEventValueTypeRepository auditEventValueTypeRepository = new AuditEventValueTypeRepository();

            //Get Message value
            AuditEventValue auditEventValueMessage              = auditEvent.GetValueByValueTypeId(AuditEventValueTypes.Message);
            AuditEventValue auditEventValueRunId                = auditEvent.GetValueByValueTypeId(AuditEventValueTypes.GamePlanRunID);
            AuditEventValue auditEventValueScenarioId           = auditEvent.GetValueByValueTypeId(AuditEventValueTypes.GamePlanScenarioID);
            AuditEventValue auditEventValueAutoBookId           = auditEvent.GetValueByValueTypeId(AuditEventValueTypes.GamePlanAutoBookID);
            AuditEventValue auditEventValuePipelineErrorMessage = auditEvent.GetValueByValueTypeId(AuditEventValueTypes.GamePlanPipelineEventErrorMessage);

            // Determine if sub event is set
            string subEvent = "";

            foreach (int valueTypeId in new int[] { AuditEventValueTypes.GamePlanPipelineEventID, AuditEventValueTypes.GamePlanAutoBookEventID })
            {
                subEvent = GetValueDescription(auditEvent, valueTypeId, auditEventValueTypeRepository, _valueConverters);
                if (!String.IsNullOrEmpty(subEvent))
                {
                    break;
                }
            }

            StringBuilder title = new StringBuilder(auditEventType.Description);

            if (!String.IsNullOrEmpty(subEvent))
            {
                title.Append(string.Format(" - {0}", subEvent));
            }

            // Set Run/Scenario details
            Run           run     = null;
            StringBuilder message = new StringBuilder(title.ToString());

            if (auditEventValueRunId != null || auditEventValueScenarioId != null)
            {
                using (var scope = _repositoryFactory.BeginRepositoryScope())
                {
                    var runRepository = scope.CreateRepository <IRunRepository>();
                    run = (auditEventValueRunId != null ? runRepository.Find((Guid)auditEventValueRunId.Value) : runRepository.FindByScenarioId((Guid)auditEventValueScenarioId.Value));

                    message.Append(message.Length == 0 ? "" : "; ");
                    message.Append(string.Format("Description: {0}; Run ID: {1}", run.Description, MSTeamsMessageFormatter.FormatHyperlink(run.Id.ToString(), WebLinkFactory.GetRunDetailsURL(_frontendUrl, run.Id))));

                    if (auditEventValueScenarioId != null)
                    {
                        message.Append(message.Length == 0 ? "" : "; ");
                        message.Append(string.Format("Scenario ID: {0}", MSTeamsMessageFormatter.FormatHyperlink(auditEventValueScenarioId.Value.ToString(), WebLinkFactory.GetOptimiserReportURL(_frontendUrl, run.Id, (Guid)auditEventValueScenarioId.Value))));
                    }
                }
            }

            // Set AutoBook details
            if (auditEventValueAutoBookId != null)
            {
                message.Append(message.Length == 0 ? "" : "; ");
                message.Append(string.Format("AutoBook ID: {0}", MSTeamsMessageFormatter.FormatHyperlink(auditEventValueAutoBookId.Value.ToString(), WebLinkFactory.GetAutoBookURL(_frontendUrl, (Guid)auditEventValueAutoBookId.Value))));
            }

            // Set pipeline error
            if (auditEventValuePipelineErrorMessage != null)
            {
                message.Append(message.Length == 0 ? "" : "; ");
                message.Append(string.Format("Error: {0}", auditEventValuePipelineErrorMessage.Value.ToString()));
            }

            // Set message
            if (auditEventValueMessage != null)
            {
                message.Append(message.Length == 0 ? "" : "; ");
                message.Append(string.Format("Message: {0}", auditEventValueMessage.Value.ToString()));
            }

            // Post message
            _msTeamsREST.PostSimpleMessage(postMessageSettings.Url, "", message.ToString());
        }
Beispiel #26
0
        public MailMessage CreateEmail(AuditEvent auditEvent)
        {
            // Determine if we need to generate email
            if (!Handles(auditEvent))
            {
                return(null);
            }

            using (var scope = _repositoryFactory.BeginRepositoryScope())
            {
                EmailAuditEventSettings emailAuditEventSettings = _emailAuditEventSettingsList.Find(s => s.EventTypeId == auditEvent.EventTypeID);

                AuditEventValueTypeRepository auditEventValueTypeRepository = new AuditEventValueTypeRepository();

                // Determine if sub event is set
                string subEvent = "";
                foreach (int valueTypeId in new int[] { AuditEventValueTypes.GamePlanPipelineEventID, AuditEventValueTypes.GamePlanAutoBookEventID })
                {
                    subEvent = GetValueDescription(auditEvent, valueTypeId, auditEventValueTypeRepository, _valueConverters);
                    if (!String.IsNullOrEmpty(subEvent))
                    {
                        break;
                    }
                }

                // Get run details, check if specific scenario specified
                var             runRepository             = scope.CreateRepository <IRunRepository>();
                AuditEventValue runIdAuditEventValue      = auditEvent.GetValueByValueTypeId(AuditEventValueTypes.GamePlanRunID);
                AuditEventValue scenarioIdAuditEventValue = auditEvent.GetValueByValueTypeId(AuditEventValueTypes.GamePlanScenarioID);
                Run             run = runRepository.Find((Guid)runIdAuditEventValue.Value);

                AuditEventType auditEventType = new AuditEventTypeRepository().GetByID(auditEvent.EventTypeID);
                MailMessage    mail           = new MailMessage();
                if (!String.IsNullOrEmpty(subEvent))   // No pipeline event
                {
                    mail.Subject = string.Format("[{0}] {1}: {2}: {3}", _environmentId, Globals.ProductName, auditEventType.Description, subEvent);
                }
                else
                {
                    mail.Subject = string.Format("[{0}] {1}: {2}", _environmentId, Globals.ProductName, auditEventType.Description);
                }

                // Indicate if run failed in subject, bit of a hack as we have to check the message string
                if (auditEvent.EventTypeID == AuditEventTypes.GamePlanRunCompleted)
                {
                    string message = GetValueDescription(auditEvent, AuditEventValueTypes.Message, auditEventValueTypeRepository, _valueConverters);
                    if (!String.IsNullOrEmpty(message) && message.ToLower().Contains("errors"))
                    {
                        mail.Subject = mail.Subject + string.Format(" ({0})", message);
                    }
                }

                // Load scenarios
                var scenarioRepository = scope.CreateRepository <IScenarioRepository>();

                var             scenarioIds = run.Scenarios.Select(e => e.Id).Distinct().ToArray();
                List <Scenario> scenarios   = scenarioRepository.FindByIds(scenarioIds).ToList();

                mail.Sender = new MailAddress(emailAuditEventSettings.NotificationSettings.SenderAddress, emailAuditEventSettings.NotificationSettings.SenderAddress);
                mail.From   = new MailAddress(emailAuditEventSettings.NotificationSettings.SenderAddress, emailAuditEventSettings.NotificationSettings.SenderAddress);
                mail.Body   = scenarioIdAuditEventValue == null?GetBody(auditEvent, auditEventType, run, scenarios, subEvent, auditEventValueTypeRepository) : GetBody(auditEvent, auditEventType, run, (Guid)scenarioIdAuditEventValue.Value, scenarios.First(s => s.Id == (Guid)scenarioIdAuditEventValue.Value), subEvent, auditEventValueTypeRepository);

                mail.IsBodyHtml = mail.Body.ToLower().Contains("<html>") && (mail.Body.ToLower().Contains("<head>") || mail.Body.ToLower().Contains("<head/>"));

                // Check if specific email address indicated in audit event

                List <AuditEventValue> recipientAuditEventValues = new List <AuditEventValue>();
                AuditEventValue        recipientAuditEventValue  = auditEvent.GetValueByValueTypeId(AuditEventValueTypes.RecipientEmailAddress);
                if (recipientAuditEventValue != null)
                {
                    recipientAuditEventValues.Add(recipientAuditEventValue);
                }
                if (recipientAuditEventValues.Count == 0)
                {
                    for (int index = 0; index < emailAuditEventSettings.NotificationSettings.RecipientAddresses.Count; index++)
                    {
                        mail.To.Add(new MailAddress(emailAuditEventSettings.NotificationSettings.RecipientAddresses[index], emailAuditEventSettings.NotificationSettings.RecipientAddresses[index]));
                    }
                }
                else
                {
                    foreach (AuditEventValue auditEventValue in recipientAuditEventValues)
                    {
                        mail.To.Add(new MailAddress(auditEventValue.Value.ToString()));
                    }
                }
                if (emailAuditEventSettings.NotificationSettings.CCAddresses != null)
                {
                    emailAuditEventSettings.NotificationSettings.CCAddresses.ForEach(address => mail.CC.Add(new MailAddress(address, address)));
                }

                /*
                 * foreach (AuditEventValue auditEventValue in auditEvent.Values.Where(item => item.TypeID == AuditEventValueTypes.EmailAttachment))
                 * {
                 *  mail.Attachments.Add(new Attachment(auditEventValue.Value.ToString()));
                 * }
                 */
                return(mail);
            }
        }
        /// <summary>
        /// Posts message to MS Teams channel
        /// </summary>
        /// <param name="auditEvent"></param>
        /// <param name="auditEventType"></param>
        /// <param name="postMessageSettings"></param>
        public void PostMessage(AuditEvent auditEvent, AuditEventType auditEventType, MSTeamsPostMessageSettings postMessageSettings)
        {
            AuditEventValueTypeRepository auditEventValueTypeRepository = new AuditEventValueTypeRepository();

            //Get Message value
            AuditEventValue auditEventValueMessage    = auditEvent.GetValueByValueTypeId(AuditEventValueTypes.Message);
            AuditEventValue auditEventValueRunId      = auditEvent.GetValueByValueTypeId(AuditEventValueTypes.GamePlanRunID);
            AuditEventValue auditEventValueScenarioId = auditEvent.GetValueByValueTypeId(AuditEventValueTypes.GamePlanScenarioID);
            AuditEventValue auditEventValueAutoBookId = auditEvent.GetValueByValueTypeId(AuditEventValueTypes.GamePlanAutoBookID);

            // Determine if sub event is set
            string subEvent = "";

            foreach (int valueTypeId in new int[] { AuditEventValueTypes.GamePlanPipelineEventID, AuditEventValueTypes.GamePlanAutoBookEventID })
            {
                subEvent = GetValueDescription(auditEvent, valueTypeId, auditEventValueTypeRepository, _valueConverters);
                if (!String.IsNullOrEmpty(subEvent))
                {
                    break;
                }
            }

            List <string> detailsTextList = new List <string>();
            List <string> detailsUrlList  = new List <string>();

            StringBuilder title = new StringBuilder(auditEventType.Description);

            if (!String.IsNullOrEmpty(subEvent))
            {
                title.Append(string.Format(" - {0}", subEvent));
            }

            // Set Run/Scenario details
            Run           run     = null;
            StringBuilder message = new StringBuilder("");

            if (auditEventValueRunId != null || auditEventValueScenarioId != null)
            {
                using (var scope = _repositoryFactory.BeginRepositoryScope())
                {
                    var runRepository = scope.CreateRepository <IRunRepository>();
                    run = (auditEventValueRunId != null ? runRepository.Find((Guid)auditEventValueRunId.Value) : runRepository.FindByScenarioId((Guid)auditEventValueScenarioId.Value));

                    if (auditEventValueScenarioId == null)
                    {
                        // Set URL
                        detailsUrlList.Add(WebLinkFactory.GetRunDetailsURL(_frontendUrl, run.Id));
                        detailsTextList.Add("Run Details");
                    }
                    else
                    {
                        detailsUrlList.Add(WebLinkFactory.GetRunDetailsURL(_frontendUrl, run.Id));
                        detailsTextList.Add("Run Details");

                        // Set URL
                        detailsUrlList.Add(WebLinkFactory.GetOptimiserReportURL(_frontendUrl, run.Id, (Guid)auditEventValueScenarioId.Value));
                        detailsTextList.Add("Scenario Details");
                    }
                }
            }

            // Set AutoBook details
            if (auditEventValueAutoBookId != null)
            {
                detailsUrlList.Add(WebLinkFactory.GetAutoBookURL(_frontendUrl, (Guid)auditEventValueAutoBookId.Value));
                detailsTextList.Add("AutoBook Details");
            }

            DataTable dataTable = GetValuesDataTable(auditEvent, run, auditEventType, subEvent, auditEventValueTypeRepository, _valueConverters);

            foreach (DataRow dataRow in dataTable.Rows)
            {
                message.Append(message.Length == 0 ? "" : "; ");        //message.Append(message.Length == 0 ? "" : "<BR/>");
                message.Append(string.Format("{0}: {1}", dataRow[0].ToString(), dataRow[1].ToString()));
            }

            // Post message
            _msTeamsREST.PostMessageCard(postMessageSettings.Url, "Title", title.ToString(), message.ToString(), detailsTextList, detailsUrlList);
        }
Beispiel #28
0
        public void Execute(DateTimeRange period, IEnumerable <SalesArea> salesAreas, CancellationToken cancellationToken = default)
        {
            if (!salesAreas.Any())
            {
                _logger.LogWarning("No sales areas were passed to the calculator.");
                return;
            }

            var salesAreaNames = salesAreas
                                 .Select(sa => sa.Name)
                                 .ToList();

            _logger.LogInformation($"Recalculating break availability for {LogAsString.Log(period.Start)} to {LogAsString.Log(period.End)}");

            var allSpotsSubsetForAllSalesAreasForRunPeriodCollection =
                GetAllSpotSubsetsForAllSalesAreasForPeriod(period, salesAreaNames);

            if (allSpotsSubsetForAllSalesAreasForRunPeriodCollection.Count == 0)
            {
                _logger.LogWarning(
                    $"Did not find any spots for the sales areas {string.Join("; ", salesAreaNames)} between {LogAsString.Log(period.Start)} to {LogAsString.Log(period.End)}"
                    );

                return;
            }

            var datesToProcess = GetDatesToProcess(period);

            var salesAreasToProcessInParallel = new ParallelOptions
            {
                MaxDegreeOfParallelism = Math.Max(Environment.ProcessorCount, 1)
            };

            var daysToProcessInParallel = new ParallelOptions
            {
                MaxDegreeOfParallelism = Math.Max(Environment.ProcessorCount / 2, 1)
            };

            _ = Parallel.ForEach(salesAreaNames, salesAreasToProcessInParallel, salesAreaName =>
            {
                _logger.LogInformation($"Calculating break availability and optimiser availability for sales area {salesAreaName}");

                var spotSubsetForSalesAreaCollection = ImmutableList.CreateRange(
                    allSpotsSubsetForAllSalesAreasForRunPeriodCollection
                    .Where(s => s.SalesArea == salesAreaName));

                var programmeSubsetForSalesAreaForRunPeriodCollection =
                    GetProgrammesSubsetForPeriodForSalesArea(period, salesAreaName);

                _ = Parallel.ForEach(datesToProcess, daysToProcessInParallel, date =>
                {
                    var programmesForUtcDate = programmeSubsetForSalesAreaForRunPeriodCollection
                                               .Where(prog => prog.StartDateTime.Date == date.Date)
                                               .ToImmutableList();

                    if (programmesForUtcDate.Count == 0)
                    {
                        _logger.LogWarning($"No programmes found for sales area {salesAreaName} on {LogAsString.Log(date.Date)}");
                        return;
                    }

                    _logger.LogInformation(
                        $"Found {LogAsString.Log(programmesForUtcDate.Count)} programmes " +
                        $"for sales area {salesAreaName} on {LogAsString.Log(date.Date)}. " +
                        $"(Programme Ids: {String.Join(",", programmesForUtcDate.Select(p => p.ProgrammeId))})"
                        );

                    var anyProgrammesSpanningMidnight = programmesForUtcDate
                                                        .Any(p => p.StartDateTime.Add(p.Duration.ToTimeSpan()) >= date.Date.AddDays(1));

                    Func <ISpotForBreakAvailCalculation, bool> condition;

                    if (anyProgrammesSpanningMidnight)
                    {
                        condition = spot =>
                                    spot.StartDateTime.Date == date.Date ||
                                    spot.StartDateTime.Date == date.Date.AddDays(1);
                    }
                    else
                    {
                        condition = spot => spot.StartDateTime.Date == date.Date;
                    }

                    var spotsForUtcDate = spotSubsetForSalesAreaCollection
                                          .Where(condition)
                                          .ToList();

                    if (spotsForUtcDate.Count > 0)
                    {
                        _logger.LogInformation(
                            $"Found {LogAsString.Log(spotsForUtcDate.Count)} spots " +
                            $"for sales area {salesAreaName} on {LogAsString.Log(date.Date)}"
                            );
                    }
                    else
                    {
                        _logger.LogWarning($"No spots found for sales area {salesAreaName} on {LogAsString.Log(date.Date)}");
                    }

                    using (var scope = _repositoryFactory.BeginRepositoryScope())
                    {
                        var breakRepository = scope.CreateRepository <IBreakRepository>()
                                              ?? throw new NullReferenceException($"An instance of {nameof(IBreakRepository)} was not found.");

                        var dateTo = anyProgrammesSpanningMidnight
                            ? date.Date.AddDays(2).AddSeconds(-1)
                            : date.Date.AddDays(1).AddSeconds(-1);

                        var breaksForUtcDate = breakRepository.Search(
                            date.Date,
                            dateTo,
                            salesAreaName
                            ).ToList();

                        if (breaksForUtcDate.Count == 0)
                        {
                            _logger.LogWarning($"No breaks found for sales area {salesAreaName} on {LogAsString.Log(date.Date)}");
                            return;
                        }

                        _logger.LogInformation(
                            $"Found {LogAsString.Log(breaksForUtcDate.Count)} break(s) for sales area {salesAreaName} " +
                            $"on {LogAsString.Log(date.Date)}. " +
                            $"[Break Ext. Refs: {breaksForUtcDate.ReducePropertyToCsv(x => x.ExternalBreakRef)}]"
                            );

                        var scheduleRepository = scope.CreateRepository <IScheduleRepository>()
                                                 ?? throw new NullReferenceException($"An instance of {nameof(IScheduleRepository)} was not found.");

                        Schedule scheduleForUtcDate = GetScheduleForUtcDate(
                            salesAreaName,
                            date,
                            scheduleRepository);

                        CalculateBreaksAvailsForUtcDate(
                            salesAreaName,
                            programmesForUtcDate,
                            spotsForUtcDate,
                            breaksForUtcDate,
                            scheduleForUtcDate,
                            breakRepository,
                            scheduleRepository);

                        if (anyProgrammesSpanningMidnight)
                        {
                            var programmesSpanningMidnight = programmesForUtcDate
                                                             .Where(p => p.StartDateTime.Add(p.Duration.ToTimeSpan()) >= date.Date)
                                                             .ToList();

                            CopyUpdatedPostMidnightBreakAvails(
                                salesAreaName,
                                date.AddDays(1),
                                programmesSpanningMidnight,
                                breaksForUtcDate,
                                breakRepository,
                                scheduleRepository);
                        }

                        breakRepository.SaveChanges();
                        scheduleRepository.SaveChanges();
                    }
                });
            });
        }
Beispiel #29
0
        public List <SystemTestResult> Execute(SystemTestCategories systemTestCategory)
        {
            List <SystemTestResult> results = new List <SystemTestResult>();

            try
            {
                using (var scope = _repositoryFactory.BeginRepositoryScope())
                {
                    // Get sales areas for run
                    var salesAreaRepository = scope.CreateRepository <ISalesAreaRepository>();
                    var salesAreas          = RunManagement.RunManager.GetSalesAreas(_run, salesAreaRepository.GetAll());

                    // Check scenarios
                    foreach (var scenario in _run.Scenarios)
                    {
                        // Warn of possibly crashed scenarios, running for too long
                        if (scenario.StartedDateTime != null && scenario.IsScheduledOrRunning && scenario.Status != ScenarioStatuses.Scheduled)
                        {
                            if (scenario.StartedDateTime.Value.AddMinutes(_scenarioCompleteTimeoutMins) <= DateTime.UtcNow)   // Hard-coded limit for the moment
                            {
                                results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Warning, _category, string.Format("Run {0} (RunID {1}) has a scenario (ScenarioID {2}) that was started at {3} and it is still running after {4} mins." +
                                                                                                                                "Please check if it has crashed.",
                                                                                                                                _run.Description, _run.Id, scenario.Id, scenario.StartedDateTime, _scenarioCompleteTimeoutMins), ""));
                            }
                        }

                        switch (scenario.Status)
                        {
                        case ScenarioStatuses.CompletedError:
                            //countFailedRuns++;
                            results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, string.Format("Run {0} (Run ID {1}) has a scenario (Scenario ID {2}) that completed with errors. The Optimiser Report will indicate why it failed.", _run.Description, _run.Id, scenario.Id), ""));
                            break;

                        case ScenarioStatuses.Scheduled:
                            results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, string.Format("Run {0} (Run ID {1}) has a scenario (Scenario ID {2}) that has been scheduled but not started. Please check if there is a problem with the AutoBooks.", _run.Description, _run.Id, scenario.Id), ""));
                            break;
                        }

                        // Check recommendations output data
                        results.AddRange(CheckRecommendationOutputData(_run, salesAreas, scenario));

                        // Check failures output data
                        results.AddRange(CheckFailuresOutputData(_run, salesAreas, scenario));

                        // Check scenario results output data
                        results.AddRange(CheckScenarioResultsOutputData(_run, salesAreas, scenario));
                    }

                    // Check Smooth failures output data
                    results.AddRange(CheckSmoothFailuresOutputData(_run, salesAreas));

                    // Check break efficiency output data
                    results.AddRange(CheckBreakEfficiencyOutputData(_run, salesAreas));
                }
            }
            catch (System.Exception exception)
            {
                results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, string.Format("Error checking run output (Run ID {0}): {1}", _run.Id, exception.Message), ""));
            }
            finally
            {
                if (!results.Where(r => r.ResultType == SystemTestResult.ResultTypes.Error).Any() && _run.Scenarios.Where(s => s.Status == ScenarioStatuses.CompletedSuccess).ToList().Count == _run.Scenarios.Count)
                {
                    results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Information, _category, "Run output OK", ""));
                }
            }
            return(results);
        }
Beispiel #30
0
        public List <SystemTestResult> Execute(SystemTestCategories systemTestCategory)
        {
            var results = new List <SystemTestResult>();

            try
            {
                using (var scope = _repositoryFactory.BeginRepositoryScope())
                {
                    var repositories = scope.CreateRepositories(
                        typeof(IPassRepository),
                        typeof(IRunRepository),
                        typeof(IScenarioRepository),
                        typeof(ITenantSettingsRepository)
                        );
                    var passRepository           = repositories.Get <IPassRepository>();
                    var runRepository            = repositories.Get <IRunRepository>();
                    var scenarioRepository       = repositories.Get <IScenarioRepository>();
                    var tenantSettingsRepository = repositories.Get <ITenantSettingsRepository>();

                    var librariedScenarios = scenarioRepository.GetLibraried();
                    var defaultScenarioId  = tenantSettingsRepository.Get().DefaultScenarioId;

                    // Check default scenario
                    if (defaultScenarioId == Guid.Empty)    // Not set
                    {
                        results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, "Default scenario is not set", ""));
                    }
                    else    // Set, check that it exists
                    {
                        var defaultScenario = scenarioRepository.Get(defaultScenarioId);
                        if (defaultScenario == null)
                        {
                            results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, "Default scenario does not exist", ""));
                        }
                    }

                    // Load runs & scenarios
                    var runs      = runRepository.GetAll().OrderBy(r => r.CreatedDateTime).ThenBy(r => r.Description);
                    var scenarios = scenarioRepository.GetAll().OrderBy(s => s.Id);

                    // Check runs
                    foreach (var run in runs)
                    {
                        // Check that runs for scenario exist
                        var scenarioIdsForRun = run.Scenarios.Select(s => s.Id).ToList();
                        foreach (var scenarioId in scenarioIdsForRun)
                        {
                            var scenario = scenarios.FirstOrDefault(s => s.Id == scenarioId);
                            if (scenario == null)
                            {
                                results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, string.Format("Run ID {0} has Scenario ID {1} that does not exist", run.Id, scenarioId), ""));
                            }
                            if (librariedScenarios.Any(x => x.Id == scenarioId))
                            {
                                results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, string.Format("Run ID {0} has Scenario ID {1} that is libraried", run.Id, scenarioId), ""));
                            }
                            if (scenarioId == defaultScenarioId)
                            {
                                results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, string.Format("Run ID {0} has Scenario ID {1} that is the default scenario", run.Id, scenarioId), ""));
                            }
                        }
                        if (run.Scenarios.Select(s => s.Id).Distinct().ToList().Count != run.Scenarios.Count)
                        {
                            results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, string.Format("Run ID {0} has duplicate scenarios", run.Id), ""));
                        }
                        if (run.Scenarios.Count == 0)
                        {
                            results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, string.Format("Run ID {0} has no scenarios", run.Id), ""));
                        }
                    }

                    // Check each scenario. E.g. Passes exist
                    Dictionary <int, Guid> firstScenarioByPassId = new Dictionary <int, Guid>();
                    foreach (var scenario in scenarios)
                    {
                        // Get list of Run IDs for this scenario, will be one at most
                        var runsForScenario = runs.Where(r => r.Scenarios.FindIndex(s => s.Id == scenario.Id) != -1).ToList();
                        System.Text.StringBuilder runDescriptions = new System.Text.StringBuilder("");
                        foreach (var run in runsForScenario)
                        {
                            if (runDescriptions.Length > 0)
                            {
                                runDescriptions.Append(", ");
                            }
                            runDescriptions.Append(run.Id.ToString());
                        }
                        if (runsForScenario.Count > 1)
                        {
                            results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, string.Format("Scenario ID {0} is used by multiple runs (Run IDs {1})", scenario.Id, runDescriptions.ToString()), ""));
                        }

                        // Check that all passes exist
                        var passesForScenario = passRepository.FindByIds(scenario.Passes.Select(p => p.Id));
                        foreach (var passReference in scenario.Passes)
                        {
                            // Check that pass isn't referenced by another scenario
                            if (firstScenarioByPassId.ContainsKey(passReference.Id))
                            {
                                if (runDescriptions.Length == 0)
                                {
                                    results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, string.Format("Scenario ID {0} has a Pass ID {1} that is also used by Scenario ID {2}", scenario.Id, passReference.Id, firstScenarioByPassId[passReference.Id]), ""));
                                }
                                else
                                {
                                    results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, string.Format("Scenario ID {0} has a Pass ID {1} that is also used by Scenario ID {2} (Run IDs: {3})", scenario.Id, passReference.Id, firstScenarioByPassId[passReference.Id], runDescriptions.ToString()), ""));
                                }
                            }
                            else
                            {
                                firstScenarioByPassId.Add(passReference.Id, scenario.Id);
                            }

                            var pass = passesForScenario.FirstOrDefault(p => p.Id == passReference.Id);
                            if (pass == null)
                            {
                                if (runDescriptions.Length == 0)
                                {
                                    results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, string.Format("Scenario ID {0} has a Pass ID {1} that does not exist", scenario.Id, passReference.Id), ""));
                                }
                                else
                                {
                                    results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, string.Format("Scenario ID {0} has a Pass ID {1} that does not exist (Run IDs: {2})", scenario.Id, passReference.Id, runDescriptions.ToString()), ""));
                                }
                            }
                        }
                        if (scenario.Passes.Select(p => p.Id).Distinct().ToList().Count != scenario.Passes.Count)
                        {
                            if (runDescriptions.Length == 0)
                            {
                                results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, string.Format("Scenario ID {0} has duplicate passes", scenario.Id), ""));
                            }
                            else
                            {
                                results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, string.Format("Scenario ID {0} has duplicate passes (Run IDs: {1})", scenario.Id, runDescriptions.ToString()), ""));
                            }
                        }
                        if (scenario.Passes.Count == 0)
                        {
                            if (runDescriptions.Length == 0)
                            {
                                results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, string.Format("Scenario ID {0} has no passes", scenario.Id), ""));
                            }
                            else
                            {
                                results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, string.Format("Scenario ID {0} has no passes (Run IDs: {1})", scenario.Id, runDescriptions.ToString()), ""));
                            }
                        }
                    }
                }
            }
            catch (System.Exception exception)
            {
                results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Error, _category, string.Format("Error checking Scenario/Pass library: {0}", exception.Message), ""));
            }
            finally
            {
                if (!results.Where(r => r.ResultType == SystemTestResult.ResultTypes.Error).Any())
                {
                    results.Add(new SystemTestResult(SystemTestResult.ResultTypes.Information, _category, "Scenario/Pass library OK", ""));
                }
            }
            return(results);
        }