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); } }
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); } }
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."); } } }
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); } } }