public string Apply(IDocumentStore store) { #pragma warning disable 618 store.Conventions.DefaultQueryingConsistency = ConsistencyOptions.AlwaysWaitForNonStaleResultsAsOfLastWrite; #pragma warning restore 618 var stats = new MigrationStats(); int retrievedResults; var currentPage = 0; List <string> toBeDeleted = new List <string>(); do { using (var session = store.OpenSession()) { var failedMessages = session.Advanced.LoadStartingWith <FailedMessage>( $"FailedMessages/", start: PageSize * currentPage++, pageSize: PageSize); foreach (var failedMessage in failedMessages) { stats += MigrateFromTemporaryCollection(failedMessage, session, toBeDeleted); } session.SaveChanges(); retrievedResults = failedMessages.Length; } } while (retrievedResults > 0); foreach (var key in toBeDeleted) { store.DatabaseCommands.Delete(key, null); stats.Deleted++; } return($"Found {stats.FoundProblem} issue(s) in {stats.Checked} Failed Message document(s). Created {stats.Created} new document(s). Deleted {stats.Deleted} old document(s)."); }
private MigrationStats MigrateFromTemporaryCollection(FailedMessage originalFailedMessage, IDocumentSession session, List <string> toBeDeleted) { var stats = new MigrationStats(); if (originalFailedMessage.ProcessingAttempts.Any(x => x.MessageMetadata.ContainsKey(SplitFromUniqueMessageIdHeader))) { return(stats); } var originalStatus = originalFailedMessage.Status; stats.Checked = 1; var processingAttempts = originalFailedMessage.ProcessingAttempts .Select((a, i) => new ProcessingAttemptRecord(a, i)) .ToArray(); //Split the original FailedMessage into separate documents based on new unique message id var failedMessages = processingAttempts .GroupBy(p => p.UniqueMessageId) .Select(g => new FailedMessage { Id = FailedMessage.MakeDocumentId(g.Key), UniqueMessageId = g.Key, ProcessingAttempts = g.OrderBy(a => a.Index).Select(a => a.Attempt).ToList(), Status = FailedMessageStatus.Unresolved }).ToList(); //Do nothing if we don't split the document if (failedMessages.Count == 1) { return(stats); } stats.FoundProblem++; if (failedMessages.All(f => f.UniqueMessageId != originalFailedMessage.UniqueMessageId)) { toBeDeleted.Add(session.Advanced.GetDocumentId(originalFailedMessage)); } else { var failedMessageCopy = failedMessages.Single(f => f.UniqueMessageId == originalFailedMessage.UniqueMessageId); failedMessages.Remove(failedMessageCopy); failedMessages.Add(originalFailedMessage); originalFailedMessage.ProcessingAttempts = failedMessageCopy.ProcessingAttempts; originalFailedMessage.Status = failedMessageCopy.Status; } failedMessages.ForEach(failedMessage => { var lastAttempt = failedMessage.ProcessingAttempts.Last(); var messageType = GetMessageType(lastAttempt) ?? "Unknown Message Type"; failedMessage.FailureGroups = CreateFailureGroups(messageType, lastAttempt).ToList(); if (failedMessage.UniqueMessageId == originalFailedMessage.UniqueMessageId) { return; } foreach (var processingAttempt in failedMessage.ProcessingAttempts) { processingAttempt.MessageMetadata[SplitFromUniqueMessageIdHeader] = originalFailedMessage.UniqueMessageId; processingAttempt.MessageMetadata[OriginalStatusHeader] = originalStatus; } session.Store(failedMessage); stats.Created++; }); return(stats); }