public FailedMessage Build() { return(new FailedMessage { ProcessingAttempts = processingAttempts.Select(x => { var messageMetadata = new Dictionary <string, object> { { "SendingEndpoint", new Contracts.Operations.EndpointDetails() }, { "ReceivingEndpoint", new Contracts.Operations.EndpointDetails() }, }; if (messageType != null) { messageMetadata["MessageType"] = messageType; } if (contentType != null) { messageMetadata["ContentType"] = contentType; } var attempt = new FailedMessage.ProcessingAttempt { FailureDetails = new FailureDetails { Exception = new ExceptionDetails() }, MessageMetadata = messageMetadata, }; x(attempt); return attempt; }).ToList(), Status = messageStatus }); }
static string GetBody(FailedMessage.ProcessingAttempt last) { if (last.MessageMetadata.TryGetValue("Body", out var body)) { return((string)body); } return(null); }
private static string GetMessageType(FailedMessage.ProcessingAttempt processingAttempt) { object messageType; if (processingAttempt.MessageMetadata.TryGetValue("MessageType", out messageType)) { return(messageType as string); } return(null); }
Task SaveToDb(string uniqueMessageId, FailedMessage.ProcessingAttempt processingAttempt, List <FailedMessage.FailureGroup> groups) { var documentId = FailedMessage.MakeDocumentId(uniqueMessageId); return(store.AsyncDatabaseCommands.PatchAsync(documentId, new[] { new PatchRequest { Name = nameof(FailedMessage.Status), Type = PatchCommandType.Set, Value = (int)FailedMessageStatus.Unresolved }, new PatchRequest { Name = nameof(FailedMessage.ProcessingAttempts), Type = PatchCommandType.Add, Value = RavenJToken.FromObject(processingAttempt, Serializer) // Need to specify serializer here because otherwise the $type for EndpointDetails is missing and this causes EventDispatcher to blow up! }, new PatchRequest { Name = nameof(FailedMessage.FailureGroups), Type = PatchCommandType.Set, Value = RavenJToken.FromObject(groups) } }, new[] { new PatchRequest { Name = nameof(FailedMessage.UniqueMessageId), Type = PatchCommandType.Set, Value = uniqueMessageId }, new PatchRequest { Name = nameof(FailedMessage.Status), Type = PatchCommandType.Set, Value = (int)FailedMessageStatus.Unresolved }, new PatchRequest { Name = nameof(FailedMessage.ProcessingAttempts), Type = PatchCommandType.Add, Value = RavenJToken.FromObject(processingAttempt, Serializer) // Need to specify serilaizer here because otherwise the $type for EndpointDetails is missing and this causes EventDispatcher to blow up! }, new PatchRequest { Name = nameof(FailedMessage.FailureGroups), Type = PatchCommandType.Set, Value = RavenJToken.FromObject(groups) } }, JObjectMetadata )); }
public ProcessingAttemptRecord(FailedMessage.ProcessingAttempt attempt, int index) { Attempt = attempt; Index = index; var headers = new Dictionary <string, string>(attempt.Headers); UniqueMessageId = NewUniqueId(headers); IsRetry = headers.ContainsKey("ServiceControl.Retry.UniqueMessageId"); }
Task SaveToDb(string uniqueMessageId, FailedMessage.ProcessingAttempt processingAttempt, List <FailedMessage.FailureGroup> groups) { var documentId = FailedMessage.MakeDocumentId(uniqueMessageId); var attemptedAtField = nameof(FailedMessage.ProcessingAttempt.AttemptedAt); var processingAttemptsField = nameof(FailedMessage.ProcessingAttempts); var statusField = nameof(FailedMessage.Status); var failureGroupsField = nameof(FailedMessage.FailureGroups); var uniqueMessageIdField = nameof(FailedMessage.UniqueMessageId); var serializedGroups = RavenJToken.FromObject(groups); var serializedAttempt = RavenJToken.FromObject(processingAttempt, Serializer); return(store.AsyncDatabaseCommands.PatchAsync(documentId, new ScriptedPatchRequest { Script = $@"this.{statusField} = status; this.{failureGroupsField} = failureGroups; var duplicateIndex = _.findIndex(this.{processingAttemptsField}, function(a){{ return a.{attemptedAtField} === attempt.{attemptedAtField}; }}); if(duplicateIndex === -1){{ this.{processingAttemptsField} = _.union(this.{processingAttemptsField}, [attempt]); }}", Values = new Dictionary <string, object> { { "status", (int)FailedMessageStatus.Unresolved }, { "failureGroups", serializedGroups }, { "attempt", serializedAttempt } } }, new ScriptedPatchRequest { Script = $@"this.{statusField} = status; this.{failureGroupsField} = failureGroups; this.{processingAttemptsField} = [attempt]; this.{uniqueMessageIdField} = uniqueMessageId; ", Values = new Dictionary <string, object> { { "status", (int)FailedMessageStatus.Unresolved }, { "failureGroups", serializedGroups }, { "attempt", serializedAttempt }, { "uniqueMessageId", uniqueMessageId } } }, JObjectMetadata)); }
private IEnumerable <FailedMessage.FailureGroup> CreateFailureGroups(string messageType, FailedMessage.ProcessingAttempt attempt) { var failureDetails = new ClassifiableMessageDetails(messageType, attempt.FailureDetails, attempt); foreach (var classifier in classifiers) { var failureGroupTitle = classifier.ClassifyFailure(failureDetails); if (failureGroupTitle == null) { continue; } var prefix = string.Format(GroupPrefixFormat, attempt.Headers.ProcessingEndpointName()); var fullTitle = $"{prefix}{failureGroupTitle}"; yield return(new FailedMessage.FailureGroup { Id = DeterministicGuid.MakeId(classifier.Name, fullTitle).ToString(), Title = fullTitle, Type = classifier.Name }); } }
public IEnumerable <FailedMessage.FailureGroup> Enrich(string messageType, FailureDetails failureDetails, FailedMessage.ProcessingAttempt processingAttempt) { var details = new ClassifiableMessageDetails(messageType, failureDetails, processingAttempt); foreach (var classifier in classifiers) { var classification = classifier.ClassifyFailure(details); if (classification == null) { continue; } yield return(new FailedMessage.FailureGroup { Id = DeterministicGuid.MakeId(classifier.Name, classification).ToString(), Title = classification, Type = classifier.Name }); } }