Esempio n. 1
0
        public async Task UpdateMessageAsync(EventEntity eventEntity, DateTime time, MessageType type, IComponent component)
        {
            using (_logger.Scope("Updating existing message of type {Type} for event {EventRowKey} at {Timestamp} affecting {ComponentPath}.",
                                 type, eventEntity.RowKey, time, component.Path))
            {
                var existingMessage = await _table.RetrieveAsync <MessageEntity>(MessageEntity.GetRowKey(eventEntity, time));

                if (existingMessage == null)
                {
                    _logger.LogWarning("Cannot update message that doesn't exist.");
                    return;
                }

                var existingMessageType = (MessageType)existingMessage.Type;
                if (existingMessageType != type)
                {
                    if (existingMessageType == MessageType.Manual)
                    {
                        _logger.LogInformation("Message was changed manually, cannot update.");
                    }
                    else
                    {
                        _logger.LogWarning("Cannot update message, has unexpected type {UnexpectedType}.", existingMessageType);
                    }

                    return;
                }

                var newContents = _builder.Build(type, component);
                _logger.LogInformation("Replacing contents of message with time {MessageTimestamp} and contents {OldMessageContents} with {NewMessageContents}.",
                                       existingMessage.Time, existingMessage.Contents, newContents);
                existingMessage.Contents = newContents;
                await _table.ReplaceAsync(existingMessage);
            }
        }
Esempio n. 2
0
        public async Task <IncidentEntity> CreateAsync(ParsedIncident input)
        {
            var groupEntity = await _aggregationProvider.GetAsync(input);

            var affectedPath = _pathProvider.Get(input);

            using (_logger.Scope("Creating incident for parsed incident with path {AffectedComponentPath}.", affectedPath))
            {
                var incidentEntity = new IncidentEntity(
                    input.Id,
                    groupEntity,
                    affectedPath,
                    input.AffectedComponentStatus,
                    input.StartTime,
                    input.EndTime);

                await _table.InsertOrReplaceAsync(incidentEntity);

                if (incidentEntity.AffectedComponentStatus > groupEntity.AffectedComponentStatus)
                {
                    _logger.LogInformation("Incident {IncidentRowKey} has a greater severity than incident group {GroupRowKey} it was just linked to ({NewSeverity} > {OldSeverity}), updating group's severity.",
                                           incidentEntity.RowKey, groupEntity.RowKey, (ComponentStatus)incidentEntity.AffectedComponentStatus, (ComponentStatus)groupEntity.AffectedComponentStatus);
                    groupEntity.AffectedComponentStatus = incidentEntity.AffectedComponentStatus;
                    await _table.ReplaceAsync(groupEntity);
                }

                return(incidentEntity);
            }
        }
Esempio n. 3
0
        public async Task UpdateAsync(TAggregationEntity aggregationEntity, DateTime cursor)
        {
            aggregationEntity = aggregationEntity ?? throw new ArgumentNullException(nameof(aggregationEntity));

            using (_logger.Scope("Updating aggregation {AggregationRowKey} given cursor {Cursor}.", aggregationEntity.RowKey, cursor))
            {
                if (!aggregationEntity.IsActive)
                {
                    _logger.LogInformation("Aggregation is inactive, cannot update.");
                    return;
                }

                var hasActiveOrRecentChildren = false;
                var children = _table
                               .GetChildEntities <TChildEntity, TAggregationEntity>(aggregationEntity)
                               .ToList();

                if (children.Any())
                {
                    _logger.LogInformation("Aggregation has {ChildrenCount} children. Updating each child.", children.Count);
                    foreach (var child in children)
                    {
                        await _aggregatedEntityUpdater.UpdateAsync(child, cursor);

                        hasActiveOrRecentChildren =
                            hasActiveOrRecentChildren ||
                            child.IsActive ||
                            child.EndTime > cursor - _groupEndDelay;
                    }
                }
                else
                {
                    _logger.LogInformation("Aggregation has no children and must have been created manually, cannot update.");
                    return;
                }

                if (!hasActiveOrRecentChildren)
                {
                    _logger.LogInformation("Deactivating aggregation because its children are inactive and too old.");
                    var lastEndTime = children.Max(i => i.EndTime.Value);
                    aggregationEntity.EndTime = lastEndTime;

                    await _table.ReplaceAsync(aggregationEntity);
                }
                else
                {
                    _logger.LogInformation("Aggregation has active or recent children so it will not be deactivated.");
                }
            }
        }
Esempio n. 4
0
        public async Task Handle(EditStatusEventManualChangeEntity entity)
        {
            var eventRowKey = EventEntity.GetRowKey(entity.EventAffectedComponentPath, entity.EventStartTime);
            var eventEntity = await _table.RetrieveAsync <EventEntity>(eventRowKey);

            if (eventEntity == null)
            {
                throw new ArgumentException("Cannot edit an event that does not exist.");
            }

            eventEntity.AffectedComponentStatus = entity.EventAffectedComponentStatus;
            ManualStatusChangeUtility.UpdateEventIsActive(eventEntity, entity.EventIsActive, entity.Timestamp.UtcDateTime);

            await _table.ReplaceAsync(eventEntity);
        }
        public async Task Handle(DeleteStatusMessageManualChangeEntity entity)
        {
            var eventRowKey   = EventEntity.GetRowKey(entity.EventAffectedComponentPath, entity.EventStartTime);
            var messageEntity = await _table.RetrieveAsync <MessageEntity>(MessageEntity.GetRowKey(eventRowKey, entity.MessageTimestamp));

            if (messageEntity == null)
            {
                throw new ArgumentException("Cannot delete a message that does not exist.");
            }

            messageEntity.Contents = "";
            messageEntity.Type     = (int)MessageType.Manual;

            await _table.ReplaceAsync(messageEntity);
        }
        public async Task Handle(AddStatusMessageManualChangeEntity entity)
        {
            var time = entity.Timestamp.UtcDateTime;

            var eventRowKey = EventEntity.GetRowKey(entity.EventAffectedComponentPath, entity.EventStartTime);
            var eventEntity = await _table.RetrieveAsync <EventEntity>(eventRowKey);

            if (eventEntity == null)
            {
                throw new ArgumentException("Cannot create a message for an event that does not exist.");
            }

            var messageEntity = new MessageEntity(eventEntity, time, entity.MessageContents, MessageType.Manual);

            await _table.InsertAsync(messageEntity);

            if (ManualStatusChangeUtility.UpdateEventIsActive(eventEntity, entity.EventIsActive, time))
            {
                await _table.ReplaceAsync(eventEntity);
            }
        }
        public async Task UpdateAsync(IncidentEntity entity, DateTime cursor)
        {
            using (_logger.Scope("Updating incident with ID {IncidentApiId}.", entity.IncidentApiId))
            {
                if (!entity.IsActive)
                {
                    return;
                }

                var activeIncident = await _incidentApiClient.GetIncident(entity.IncidentApiId);

                var endTime = activeIncident.MitigationData?.Date;

                if (endTime != null)
                {
                    _logger.LogInformation("Updated mitigation time of active incident to {MitigationTime}.", entity.EndTime);
                    entity.EndTime = endTime;
                    await _table.ReplaceAsync(entity);
                }
            }
        }