public async Task <DateTime?> FetchSince(DateTime cursor)
        {
            using (_logger.Scope("Processing manual status changes."))
            {
                var manualChangesQuery = _table
                                         .CreateQuery <ManualStatusChangeEntity>();

                // Table storage throws on queries with DateTime values that are too low.
                // If we are fetching manual changes for the first time, don't filter on the timestamp.
                if (cursor > DateTime.MinValue)
                {
                    manualChangesQuery = manualChangesQuery.Where(c => c.Timestamp > new DateTimeOffset(cursor, TimeSpan.Zero));
                }

                var manualChanges = manualChangesQuery.ToList();

                _logger.LogInformation("Processing {ManualChangesCount} manual status changes.", manualChanges.Count());
                foreach (var manualChange in manualChanges.OrderBy(m => m.Timestamp))
                {
                    await _handler.Handle(_table, manualChange);
                }

                return(manualChanges.Any() ? manualChanges.Max(c => c.Timestamp.UtcDateTime) : (DateTime?)null);
            }
        }
示例#2
0
 public static IQueryable <TEntity> GetActiveEntities <TEntity>(this ITableWrapper table)
     where TEntity : ComponentAffectingEntity, new()
 {
     return(table
            .CreateQuery <TEntity>()
            .Where(e => e.IsActive));
 }
示例#3
0
 public static IQueryable <TChild> GetChildEntities <TChild, TParent>(this ITableWrapper table, TParent entity)
     where TChild : ITableEntity, IChildEntity <TParent>, new()
     where TParent : ITableEntity
 {
     return(table
            .CreateQuery <TChild>()
            .Where(e => e.ParentRowKey == entity.RowKey));
 }
示例#4
0
 public IEnumerable <Event> Export(DateTime cursor)
 {
     return(_table
            .CreateQuery <EventEntity>()
            .Where(e => e.IsActive || (e.EndTime >= cursor - _eventVisibilityPeriod))
            .ToList()
            .Select(_exporter.Export)
            .Where(e => e != null)
            .ToList());
 }
示例#5
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);
        }