bool GetFailedMessage(MyContext c, out FailedMessage failure, Predicate<FailedMessage> condition = null)
 {
     if (!TryGet("/api/errors/" + c.UniqueMessageId, out failure, condition))
     {
         return false;
     }
     return true;
 }
Exemple #2
0
        private void Store(string uniqueMessageId, FailedMessage.ProcessingAttempt processingAttempt, List <FailedMessage.FailureGroup> groups)
        {
            var documentId = FailedMessage.MakeDocumentId(uniqueMessageId);

            store.DatabaseCommands.Patch(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 PreSplitScenario(FailedMessageStatus originalStatus)
 {
     UniqueMessageId             = DeterministicGuid.MakeId(MessageId, ReplyToAddress).ToString();
     OriginalFailedMessageStatus = originalStatus;
     FailedMessage = new FailedMessage()
     {
         Id = FailedMessage.MakeDocumentId(UniqueMessageId),
         UniqueMessageId    = UniqueMessageId,
         ProcessingAttempts = new List <FailedMessage.ProcessingAttempt>(),
         Status             = originalStatus,
         FailureGroups      = new List <FailedMessage.FailureGroup>()
     };
 }
            public void ProcessingAlwaysFailsForMessage(TransportMessage message, Exception e)
            {
                try
                {
                    var destination     = message.Headers["ServiceControl.TargetEndpointAddress"];
                    var messageUniqueId = message.Headers["ServiceControl.Retry.UniqueMessageId"];
                    Log.Warn($"Failed to send '{messageUniqueId}' message to '{destination}' for retry. Attempting to revert message status to unresolved so it can be tried again.", e);

                    using (var session = store.OpenSession())
                    {
                        var failedMessage = session.Load <FailedMessage>(FailedMessage.MakeDocumentId(messageUniqueId));
                        if (failedMessage != null)
                        {
                            failedMessage.Status = FailedMessageStatus.Unresolved;
                        }

                        var failedMessageRetry = session.Load <FailedMessageRetry>(FailedMessageRetry.MakeDocumentId(messageUniqueId));
                        if (failedMessageRetry != null)
                        {
                            session.Delete(failedMessageRetry);
                        }

                        session.SaveChanges();
                    }
                    string reason;
                    try
                    {
                        reason = e.GetBaseException().Message;
                    }
                    catch (Exception)
                    {
                        reason = "Failed to retrieve reason!";
                    }
                    domainEvents.Raise(new MessagesSubmittedForRetryFailed
                    {
                        Reason          = reason,
                        FailedMessageId = messageUniqueId,
                        Destination     = destination
                    });
                }
                catch (Exception ex)
                {
                    // If something goes wrong here we just ignore, not the end of the world!
                    Log.Error("A failure occurred when trying to handle a retry failure.", ex);
                }
                finally
                {
                    executeOnFailure();
                }
            }
        public void Enrich(FailedMessage message, ImportFailedMessage source)
        {
            var classifications = new List<FailedMessage.FailureGroup>();

            foreach (var classifier in Classifiers)
            {
                var classification = classifier.ClassifyFailure(source.FailureDetails);
                if (classification == null)
                    continue;

                classifications.Add(new FailedMessage.FailureGroup
                {
                    Id = DeterministicGuid.MakeId(classifier.Name, classification).ToString(),
                    Title = classification,
                    Type = classifier.Name
                });
            }

            message.FailureGroups = classifications;
        }
        void StageMessage(FailedMessage message, string stagingId)
        {
            message.Status = FailedMessageStatus.RetryIssued;

            var attempt = message.ProcessingAttempts.Last();

            var headersToRetryWith = attempt.Headers.Where(kv => !KeysToRemoveWhenRetryingAMessage.Contains(kv.Key))
                .ToDictionary(kv => kv.Key, kv => kv.Value);

            headersToRetryWith["ServiceControl.TargetEndpointAddress"] = attempt.FailureDetails.AddressOfFailingEndpoint;
            headersToRetryWith["ServiceControl.Retry.UniqueMessageId"] = message.UniqueMessageId;
            headersToRetryWith["ServiceControl.Retry.StagingId"] = stagingId;

            var transportMessage = new TransportMessage(message.Id, headersToRetryWith)
            {
                CorrelationId = attempt.CorrelationId,
                Recoverable = attempt.Recoverable,
                MessageIntent = attempt.MessageIntent
            };

            Stream stream;
            if (bodyStorage.TryFetch(attempt.MessageId, out stream))
            {
                using (stream)
                {
                    transportMessage.Body = ReadFully(stream);
                }
            }

            if (!String.IsNullOrWhiteSpace(attempt.ReplyToAddress))
            {
                transportMessage.ReplyToAddress = Address.Parse(attempt.ReplyToAddress);
            }

            sender.Send(transportMessage, AdvancedDequeuer.Address);
        }