public async Task <DateTime?> FetchSince(DateTime cursor)
        {
            using (_logger.Scope("Fetching all new incidents since {Cursor}.", cursor))
            {
                var incidents = (await _incidentApiClient.GetIncidents(GetRecentIncidentsQuery(cursor)))
                                // The incident API trims the milliseconds from any filter.
                                // Therefore, a query asking for incidents newer than '2018-06-29T00:00:00.5Z' will return an incident from '2018-06-29T00:00:00.25Z'
                                // We must perform a check on the CreateDate ourselves to verify that no old incidents are returned.
                                .Where(i => i.CreateDate > cursor)
                                .ToList();

                _logger.LogInformation("Found {IncidentCount} incidents to parse.", incidents.Count);
                var parsedIncidents = incidents
                                      .SelectMany(_aggregateIncidentParser.ParseIncident)
                                      .ToList();

                _logger.LogInformation("Parsed {ParsedIncidentCount} incidents.", parsedIncidents.Count);
                foreach (var parsedIncident in parsedIncidents.OrderBy(i => i.StartTime))
                {
                    using (_logger.Scope("Creating incident for parsed incident with ID {ParsedIncidentID} affecting {ParsedIncidentPath} at {ParsedIncidentStartTime} with status {ParsedIncidentStatus}.",
                                         parsedIncident.Id, parsedIncident.AffectedComponentPath, parsedIncident.StartTime, parsedIncident.AffectedComponentStatus))
                    {
                        await _incidentFactory.CreateAsync(parsedIncident);
                    }
                }

                return(incidents.Any() ? incidents.Max(i => i.CreateDate) : (DateTime?)null);
            }
        }
Ejemplo n.º 2
0
        public async Task <TAggregationEntity> GetAsync(ParsedIncident input)
        {
            TAggregationEntity aggregationEntity = null;

            var possiblePath = _aggregationPathProvider.Get(input);
            // Find an aggregation to link to
            var possibleAggregationsQuery = _table
                                            .CreateQuery <TAggregationEntity>()
                                            .Where(e =>
                                                   // The aggregation must affect the same path
                                                   e.AffectedComponentPath == possiblePath &&
                                                   // The aggregation must begin before or at the same time
                                                   e.StartTime <= input.StartTime);

            // The aggregation must cover the same time period
            if (input.IsActive)
            {
                // An active input can only be linked to an active aggregation
                possibleAggregationsQuery = possibleAggregationsQuery
                                            .Where(e => e.IsActive);
            }
            else
            {
                // An inactive input can be linked to an active aggregation or an inactive aggregation that ends after it
                possibleAggregationsQuery = possibleAggregationsQuery
                                            .Where(e =>
                                                   e.IsActive ||
                                                   e.EndTime >= input.EndTime);
            }

            var possibleAggregations = possibleAggregationsQuery
                                       .ToList();

            _logger.LogInformation("Found {AggregationCount} possible aggregations to link entity to with path {AffectedComponentPath}.", possibleAggregations.Count(), possiblePath);
            foreach (var possibleAggregation in possibleAggregations)
            {
                if (await _strategy.CanBeAggregatedByAsync(input, possibleAggregation))
                {
                    _logger.LogInformation("Linking entity to aggregation.");
                    aggregationEntity = possibleAggregation;
                    break;
                }
            }

            if (aggregationEntity == null)
            {
                _logger.LogInformation("Could not find existing aggregation to link to, creating new aggregation to link entity to.");
                aggregationEntity = await _aggregationFactory.CreateAsync(input);

                _logger.LogInformation("Created new aggregation {AggregationRowKey} to link entity to.", aggregationEntity.RowKey);
            }

            return(aggregationEntity);
        }