private void UpdateSignalMessagesForNotification(IEnumerable <SignalMessage> signalMessages, SendingProcessingMode sendingPMode) { if (!signalMessages.Any()) { Logger.Trace("No SignalMessages present to be notified"); return; } // Improvement: I think it will be safer if we retrieve the sending-pmodes of the related usermessages ourselves here // instead of relying on the SendingPMode that is available in the AS4Message object (which is set by another Step in the queue). IEnumerable <Receipt> receipts = signalMessages.OfType <Receipt>(); bool notifyReceipts = sendingPMode?.ReceiptHandling?.NotifyMessageProducer ?? false; if (!notifyReceipts) { Logger.Debug($"No Receipts will be notified since the SendingPMode {sendingPMode?.Id} ReceiptHandling.NotifyMessageProducer = false"); } RetryReliability retryReceipts = sendingPMode?.ReceiptHandling?.Reliability; if (retryReceipts?.IsEnabled == false) { Logger.Trace( "Will not insert RetryReliability for Receipt(s) so it can be retried during delivery " + $"since the ReceivingPMode {sendingPMode?.Id} ReceiptHandling.Reliability.IsEnabled = false"); } if (notifyReceipts) { UpdateSignalMessages(sendingPMode, receipts, retryReceipts); } UpdateReferencedUserMessagesStatus(receipts, OutStatus.Ack); IEnumerable <Error> errors = signalMessages.OfType <Error>(); bool notifyErrors = sendingPMode?.ErrorHandling?.NotifyMessageProducer ?? false; if (!notifyErrors) { Logger.Debug($"No Errors will be notified since the SendingPMode {sendingPMode?.Id} Errorhandling.NotifyMessageProducer = false"); } RetryReliability retryErrors = sendingPMode?.ErrorHandling?.Reliability; if (retryErrors?.IsEnabled == false) { Logger.Trace( "Will not insert RetryReliability for Error(s) so it can be retried during notification " + $"since the SendingPMode {sendingPMode?.Id} ErrorHandling.Reliability.IsEnabled = false"); } if (notifyErrors) { UpdateSignalMessages(sendingPMode, errors, retryErrors); } UpdateReferencedUserMessagesStatus(errors, OutStatus.Nack); }
private void UpdateUserMessagesForDelivery(IEnumerable <UserMessage> userMessages, ReceivingProcessingMode receivingPMode) { if (userMessages.Any() == false) { Logger.Trace("No UserMessages present to be delivered"); return; } string receivingPModeId = receivingPMode?.Id; string receivingPModeString = AS4XmlSerializer.ToString(receivingPMode); var xs = _repository .GetInMessagesData(userMessages.Select(um => um.MessageId), im => im.Id) .Zip(userMessages, Tuple.Create); foreach ((long id, UserMessage userMessage) in xs) { _repository.UpdateInMessage( userMessage.MessageId, message => { message.SetPModeInformation(receivingPModeId, receivingPModeString); if (UserMessageNeedsToBeDelivered(receivingPMode, userMessage) && message.Intermediary == false) { message.Operation = Operation.ToBeDelivered; RetryReliability reliability = receivingPMode?.MessageHandling?.DeliverInformation?.Reliability; if (reliability?.IsEnabled ?? false) { var r = Entities.RetryReliability.CreateForInMessage( refToInMessageId: id, maxRetryCount: reliability.RetryCount, retryInterval: reliability.RetryInterval.AsTimeSpan(), type: RetryType.Delivery); Logger.Debug( $"Insert RetryReliability for UserMessage InMessage {r.RefToInMessageId} with {{" + $"MaxRetryCount={r.MaxRetryCount}, RetryInterval={r.RetryInterval}}}"); _repository.InsertRetryReliability(r); } else { Logger.Trace( "Will not insert RetryReliability for UserMessage(s) so it can be retried during delivery " + $"since the ReceivingPMode {receivingPMode?.Id} MessageHandling.Deliver.Reliability.IsEnabled = false"); } Logger.Debug($"Update InMessage UserMessage {userMessage.MessageId} with Operation={message.Operation}"); } }); } }
private void UpdateSignalMessages <TSignal>( SendingProcessingMode sendingPMode, IEnumerable <TSignal> signalMessages, RetryReliability reliability) where TSignal : SignalMessage { string[] signalsToNotify = signalMessages.Where(r => r.IsDuplicate == false) .Select(s => s.MessageId) .ToArray(); if (!signalsToNotify.Any()) { return; } string ebmsMessageType = typeof(TSignal).Name; _repository.UpdateInMessages( m => signalsToNotify.Contains(m.EbmsMessageId) && m.Intermediary == false, m => { m.Operation = Operation.ToBeNotified; m.SetPModeInformation(sendingPMode); Logger.Debug($"Update InMessage {ebmsMessageType} {m.EbmsMessageId} with Operation={m.Operation} according to SendingPMode {sendingPMode.Id}"); }); bool isRetryEnabled = reliability?.IsEnabled ?? false; if (isRetryEnabled) { IEnumerable <long> ids = _repository.GetInMessagesData(signalsToNotify, m => m.Id); foreach (long id in ids) { var r = Entities.RetryReliability.CreateForInMessage( refToInMessageId: id, maxRetryCount: reliability.RetryCount, retryInterval: reliability.RetryInterval.AsTimeSpan(), type: RetryType.Notification); Logger.Debug( $"Insert RetryReliability for SignalMessage InMessage {id} with {{" + $"MaxRetryCount={r.MaxRetryCount}, " + $"RetryInterval={r.RetryInterval}}}"); _repository.InsertRetryReliability(r); } } }
private static SendingProcessingMode NotifySendingPMode(string url) { var notifyMethod = new Method { Type = "HTTP", Parameters = new List <Parameter> { new Parameter { Name = "location", Value = url } } }; var reliability = new RetryReliability { IsEnabled = true, RetryCount = 1, RetryInterval = "00:00:01" }; return(new SendingProcessingMode { Id = "notify-sending-pmode", ReceiptHandling = { NotifyMessageProducer = true, NotifyMethod = notifyMethod, Reliability = reliability }, ErrorHandling = { NotifyMessageProducer = true, NotifyMethod = notifyMethod, Reliability = reliability }, ExceptionHandling = { NotifyMessageProducer = true, NotifyMethod = notifyMethod, Reliability = reliability } }); }
/// <summary> /// Insert a <see cref="RetryReliability"/> record for an stored <see cref="OutException"/> record. /// </summary> /// <param name="referenced">The referenced exception record.</param> /// <param name="reliability">Reliability to populate the record with retry information.</param> public void InsertRelatedRetryReliability(OutException referenced, RetryReliability reliability) { if (referenced == null) { throw new ArgumentNullException(nameof(referenced)); } if (referenced.Id <= 0) { throw new InvalidOperationException( "Requires to have a stored OutException to insert a referenced RetryReliability record"); } if (reliability != null && reliability.IsEnabled) { var r = Entities.RetryReliability.CreateForOutException( refToOutExceptionId: referenced.Id, maxRetryCount: reliability.RetryCount, retryInterval: reliability.RetryInterval.AsTimeSpan(), type: RetryType.Notification); _repository.InsertRetryReliability(r); } }