コード例 #1
0
        /// <summary>
        /// Composes a component history array.
        /// </summary>
        /// <param name="cache">Extended cache object.</param>
        /// <param name="componentId">Component identifier.</param>
        /// <param name="componentName">Component name.</param>
        /// <returns>Complete component history object.</returns>
        public static async Task <InfrastructureComponentSummaryWithHistory[]> GetInfrastructureHistory(this IInfrastructureScoreCache cache, string componentId, string componentName)
        {
            var today = DateTimeOffset.UtcNow.Date;
            var infrastructureCategory = GetCategory(componentId);
            var components             = new List <InfrastructureComponentSummaryWithHistory>();

            foreach (var date in Enumerable.Range(-30, 31).Select(i => today.AddDays(i)))
            {
                var currentSummary = await cache.GetCountersSummary(componentId, date);

                var component = new InfrastructureComponentSummaryWithHistory
                {
                    Date      = date,
                    Component = new InfrastructureComponent(componentId)
                    {
                        Category = infrastructureCategory,
                        Name     = componentName,
                    },
                    Current = currentSummary,
                };

                components.Add(component);
            }

            return(components.ToArray());
        }
コード例 #2
0
        /// <summary>
        /// Returns infrastructure history for requested component.
        /// </summary>
        /// <param name="componentId">Component identifier.</param>
        /// <param name="date">The date to get details for.</param>
        /// <returns>Component details.</returns>
        public async Task <InfrastructureComponentSummaryWithHistory> GetDetails(string componentId, DateTime date)
        {
            // 1. get audit which represents the "date".
            var audit = await this.db.Set <AuditEntity>()
                        .Include(i => i.InfrastructureComponent)
                        .AsNoTracking()
                        .Where(i => i.Date.Date == date.Date && i.ComponentId == componentId)
                        .OrderByDescending(i => i.Date)
                        .FirstOrDefaultAsync();

            // 1.1. try to get InfrastructureComponent if no audit fo a requested date
            string componentName;

            if (audit == null)
            {
                var component = await this.db.Set <InfrastructureComponentEntity>()
                                .AsNoTracking()
                                .FirstOrDefaultAsync(i => i.ComponentId == componentId);

                if (component == null)
                {
                    throw new JosekiException($"Unknown componentId: {componentId}");
                }

                componentName = component.ComponentName;
            }
            else
            {
                componentName = audit.InfrastructureComponent.ComponentName;
            }

            // 2. prepare history for the last month
            var today            = DateTime.UtcNow.Date;
            var componentHistory = new List <ScoreHistoryItem>();

            foreach (var summaryDate in Enumerable.Range(-30, 31).Select(i => today.AddDays(i)))
            {
                var historyItem = await this.cache.GetCountersSummary(componentId, summaryDate);

                componentHistory.Add(new ScoreHistoryItem(summaryDate, historyItem.Score));
            }

            // 3. when the history is ready, calculate summary for the requested date.
            var currentSummary = await this.cache.GetCountersSummary(componentId, date.Date);

            var componentDetails = new InfrastructureComponentSummaryWithHistory
            {
                Date      = date,
                Component = new InfrastructureComponent(componentId)
                {
                    Category = InfraScoreExtensions.GetCategory(componentId),
                    Name     = componentName,
                },
                Current      = currentSummary,
                ScoreHistory = componentHistory.OrderBy(i => i.RecordedAt).ToArray(),
            };

            // if no audit for a given date - return result
            if (audit == null)
            {
                componentDetails.Checks            = new Check[0];
                componentDetails.CategorySummaries = new CheckCategorySummary[0];
                return(componentDetails);
            }

            // 4. Get all the check details
            var checkResults = await this.db.Set <CheckResultEntity>()
                               .AsNoTracking()
                               .Include(i => i.Check)
                               .Where(i => i.AuditId == audit.Id)
                               .Select(i => new
            {
                i.ComponentId,
                i.Check.CheckId,
                i.Check.Severity,
                i.Check.Category,
                i.Check.Description,
                i.Value,
                i.Message,
            })
                               .ToArrayAsync();

            var checks = new List <Check>();

            foreach (var entity in checkResults)
            {
                CheckResult checkResult;
                switch (entity.Value)
                {
                case CheckValue.Failed:
                    if (entity.Severity == CheckSeverity.Critical || entity.Severity == CheckSeverity.High)
                    {
                        checkResult = CheckResult.Failed;
                    }
                    else
                    {
                        checkResult = CheckResult.Warning;
                    }

                    break;

                case CheckValue.Succeeded:
                    checkResult = CheckResult.Success;
                    break;

                default:
                    checkResult = CheckResult.NoData;
                    break;
                }

                var message = entity.Message ?? entity.Description;
                var(collection, resource, tags) = ParseCollectionAndResource(entity.ComponentId);
                resource.Owner = await this.ownershipCache.GetOwner(entity.ComponentId);

                var check = new Check(
                    date,
                    collection,
                    resource,
                    entity.Category,
                    new CheckControl(entity.CheckId, message),
                    checkResult)
                {
                    Tags = tags,
                };
                checks.Add(check);
            }

            componentDetails.Checks = checks.ToArray();

            // 5. enrich with category descriptions
            var scannerType = audit.InfrastructureComponent.ScannerId.Split('/').First();
            var categories  = checks
                              .Select(i => i.Category)
                              .Distinct()
                              .Select(i => new { Id = $"{scannerType}.{i.Replace(" ", string.Empty)}".ToLowerInvariant(), Category = i })
                              .ToDictionary(i => i.Id, j => j.Category);
            var ids = categories.Keys.ToArray();

            var docs = await this.docsHandler.GetItemsByIds(ids);

            componentDetails.CategorySummaries = docs
                                                 .Select(i => new CheckCategorySummary {
                Description = i.Content, Category = categories[i.Id]
            })
                                                 .ToArray();

            return(componentDetails);
        }
コード例 #3
0
        /// <summary>
        /// Composes an infrastructure overview object for a requested date and provided audits.
        /// </summary>
        /// <param name="cache">Extended cache object.</param>
        /// <param name="date">The date to calculate overview for.</param>
        /// <param name="audits">List of audits to include into overview.</param>
        /// <returns>Complete infrastructure-overview object.</returns>
        public static async Task <InfrastructureOverview> GetInfrastructureOverview(this IInfrastructureScoreCache cache, DateTime date, Audit[] audits)
        {
            // 0. if no audits - return stub
            if (audits.Length == 0)
            {
                return(new InfrastructureOverview
                {
                    Overall = new InfrastructureComponentSummaryWithHistory
                    {
                        Component = new InfrastructureComponent(Audit.OverallId)
                        {
                            Category = InfrastructureCategory.Overall,
                            Name = Audit.OverallName,
                        },
                        Date = date,
                        ScoreHistory = new ScoreHistoryItem[0],
                        Current = new CountersSummary(),
                    },
                    Components = new InfrastructureComponentSummaryWithHistory[0],
                });
            }

            // 1. Calculate Overall data first, as it reloads caches for component audits automatically
            var overallHistory = new List <ScoreHistoryItem>();

            foreach (var dateTime in audits.Select(i => i.Date.Date).Distinct())
            {
                var historyItem = await cache.GetCountersSummary(Audit.OverallId, dateTime);

                overallHistory.Add(new ScoreHistoryItem(dateTime, historyItem.Score));
            }

            var overall = new InfrastructureComponentSummaryWithHistory
            {
                Component = new InfrastructureComponent(Audit.OverallId)
                {
                    Category = InfrastructureCategory.Overall,
                    Name     = Audit.OverallName,
                },
                Date         = date,
                ScoreHistory = overallHistory.OrderBy(i => i.RecordedAt).ToArray(),
                Current      = await cache.GetCountersSummary(Audit.OverallId, date),
            };

            // 2. Calculate each component data
            // The code expects that each date has only unique component-identifiers
            // Thus, iterating only over requested date - gives unique components
            var today      = DateTime.UtcNow.Date;
            var month      = Enumerable.Range(-30, 31).Select(i => today.AddDays(i)).ToArray();
            var components = new List <InfrastructureComponentSummaryWithHistory>();

            foreach (var audit in audits.Where(i => i.Date.Date == date.Date))
            {
                // first, get counters for each date during last month
                var componentHistory = new List <ScoreHistoryItem>();
                foreach (var summaryDate in month)
                {
                    var historyItem = await cache.GetCountersSummary(audit.ComponentId, summaryDate);

                    componentHistory.Add(new ScoreHistoryItem(summaryDate, historyItem.Score));
                }

                // when the history is ready, calculate summary for the requested date.
                var currentSummary = await cache.GetCountersSummary(audit.ComponentId, audit.Date);

                var component = new InfrastructureComponentSummaryWithHistory
                {
                    Date      = date,
                    Component = new InfrastructureComponent(audit.ComponentId)
                    {
                        Category = GetCategory(audit.ComponentId),
                        Name     = audit.ComponentName,
                    },
                    Current      = currentSummary,
                    ScoreHistory = componentHistory.OrderBy(i => i.RecordedAt).ToArray(),
                };

                components.Add(component);
            }

            return(new InfrastructureOverview
            {
                Overall = overall,
                Components = components.ToArray(),
            });
        }