private static Method GetNotifyMethodBasedOnNotifyMessage( NotifyMessageEnvelope notifyMessage, SendingProcessingMode sendingPMode, ReceivingProcessingMode receivingPMode) { switch (notifyMessage.StatusCode) { case Status.Delivered: if (sendingPMode.ReceiptHandling?.NotifyMethod?.Type == null) { throw new InvalidOperationException( $"SendingPMode {sendingPMode.Id} should have a ReceiptHandling.NotifyMethod " + "with a <Type/> element indicating the notifying strategy when the NotifyMessage.StatusCode = Delivered. " + "Default strategies are: 'FILE' and 'HTTP'. See 'Notify Uploading' for more information"); } return(sendingPMode.ReceiptHandling.NotifyMethod); case Status.Error: if (sendingPMode.ErrorHandling?.NotifyMethod?.Type == null) { throw new InvalidOperationException( $"SendingPMode {sendingPMode.Id} should have a ErrorHandling.NotifyMethod " + "with a <Type/> element indicating the notifying strategy when the NotifyMessage.StatusCode = Error. " + "Default strategies are: 'FILE' and 'HTTP'. See 'Notify Uploading' for more information"); } return(sendingPMode.ErrorHandling.NotifyMethod); case Status.Exception: bool isNotifyMessageFormedBySending = sendingPMode?.Id != null; if (isNotifyMessageFormedBySending) { if (sendingPMode?.ExceptionHandling?.NotifyMethod?.Type == null) { throw new InvalidOperationException( $"SendingPMode {sendingPMode.Id} should have a ExceptionHandling.NotifyMethod " + "with a <Type/> element indicating the notifying strategy when the NotifyMessage.StatusCode = Exception. " + "This means that the NotifyMessage is an Exception occured during a outbound sending operation. " + "Default strategies are: 'FILE' and 'HTTP'. See 'Notify Uploading' for more information"); } return(sendingPMode.ExceptionHandling.NotifyMethod); } if (receivingPMode?.ExceptionHandling?.NotifyMethod?.Type == null) { throw new InvalidOperationException( $"ReceivingPMode {receivingPMode?.Id} should have a ExceptionHandling.NotifyMethod " + "with a <Type/> element indicating the notifying strategy when the NotifyMessage.StatusCode = Exception. " + "This means that the NotifyMessage is an Exception occured during an inbound receiving operation. " + "Default strategies are: 'FILE' and 'HTTP'. See 'Notify Uploading' for more information"); } return(receivingPMode.ExceptionHandling.NotifyMethod); default: throw new ArgumentOutOfRangeException($"No NotifyMethod not defined for status {notifyMessage.StatusCode}"); } }
/// <summary> /// Start sending the <see cref="NotifyMessage" /> /// </summary> /// <param name="notifyMessage"></param> public async Task <SendResult> SendAsync(NotifyMessageEnvelope notifyMessage) { if (notifyMessage == null) { throw new ArgumentNullException(nameof(notifyMessage)); } if (String.IsNullOrWhiteSpace(notifyMessage.ContentType)) { throw new InvalidOperationException( $"{nameof(HttpSender)} requires a ContentType to correctly notify the message"); } if (notifyMessage.NotifyMessage == null) { throw new InvalidOperationException( $"{nameof(HttpSender)} requires a NotifyMessage as a series of bytes to correctly notify the message"); } Logger.Info($"(Notify)[{notifyMessage.MessageInfo.MessageId}] Send Notification to {Location}"); HttpWebRequest request = await CreateHttpPostRequest(notifyMessage.ContentType, notifyMessage.NotifyMessage); HttpWebResponse response = await SendHttpPostRequest(request).ConfigureAwait(false); HttpStatusCode statusCode = response?.StatusCode ?? HttpStatusCode.InternalServerError; Logger.Debug($"POST Notification to {Location} result in: {(int) statusCode} {response?.StatusCode}"); response?.Close(); return(SendResultUtils.DetermineSendResultFromHttpResonse(statusCode)); }
/// <summary> /// Clones the message. /// </summary> /// <param name="notifyMessage">The notify message.</param> /// <param name="entityId"></param> /// <returns></returns> public void ModifyContext(NotifyMessageEnvelope notifyMessage, long?entityId = null) { if (notifyMessage == null) { throw new ArgumentNullException(nameof(notifyMessage)); } PrepareContextChange(); NotifyMessage = notifyMessage; Mode = MessagingContextMode.Notify; }
/// <summary> /// Initializes a new instance of the <see cref="MessagingContext"/> class. /// </summary> /// <param name="notifyMessage">The notify message.</param> /// <param name="receivedMessage">The referenced received message for this notify envelope.</param> public MessagingContext(NotifyMessageEnvelope notifyMessage, ReceivedMessage receivedMessage) : this(receivedMessage, MessagingContextMode.Notify) { if (notifyMessage == null) { throw new ArgumentNullException(nameof(notifyMessage)); } SubmitMessage = null; AS4Message = null; DeliverMessage = null; NotifyMessage = notifyMessage; }
/// <summary> /// Start sending the <see cref="NotifyMessage"/> /// </summary> /// <param name="notifyMessage"></param> public async Task <SendResult> SendAsync(NotifyMessageEnvelope notifyMessage) { if (notifyMessage == null) { throw new ArgumentNullException(nameof(notifyMessage)); } return(await SendMessageResult( message : notifyMessage, sending : InnerNotifySender.SendAsync, exMessage : $"(Notify)[{notifyMessage?.MessageInfo?.MessageId}] Unable to send NotifyMessage to the configured endpoint due to and exceptoin") .ConfigureAwait(false)); }
public async Task ThenNotifyMessageHasCorrectStatusCode() { // Arrange ReceivedEntityMessage receivedSignal = await CreateReceivedReceiptMessage(); // Act MessagingContext result = await ExerciseTransform(receivedSignal); // Assert NotifyMessageEnvelope notifyMessage = result.NotifyMessage; Assert.NotNull(notifyMessage); Assert.Equal(Status.Delivered, notifyMessage.StatusCode); }
/// <summary> /// Start sending the <see cref="NotifyMessage"/> /// </summary> /// <param name="notifyMessage"></param> public async Task <SendResult> SendAsync(NotifyMessageEnvelope notifyMessage) { if (notifyMessage == null) { throw new ArgumentNullException(nameof(notifyMessage)); } if (notifyMessage.MessageInfo?.MessageId == null) { throw new InvalidOperationException( $"{nameof(FileSender)} requires a MessageInfo.MessageId to correctly notify the message"); } if (notifyMessage.NotifyMessage == null) { throw new InvalidOperationException( $"{nameof(FileSender)} requires a NotifyMessage as a series of bytes to correctly notify the message"); } if (String.IsNullOrWhiteSpace(Location)) { throw new InvalidOperationException( $"{nameof(FileSender)} requires a configured location to send the notified file to, please add a " + "<Parameter name=\"location\" value=\"your-location\"/> it to the applicable element in the Receiving or SendingPMode"); } SendResult directoryResult = EnsureDirectory(Location); if (directoryResult == SendResult.FatalFail) { return(directoryResult); } string location = CombineDestinationFullName(notifyMessage.MessageInfo.MessageId, Location); Logger.Trace($"Sending NotifyMessage to {location}"); SendResult result = await TryWriteContentsToFileAsync(location, notifyMessage.NotifyMessage); if (result == SendResult.Success) { Logger.Info( $"(Notify) NotifyMessage {notifyMessage.MessageInfo.MessageId} is successfully send to \"{location}\""); } return(result); }
/// <summary> /// Transform a given <see cref="ReceivedMessage"/> to a Canonical <see cref="MessagingContext"/> instance. /// </summary> /// <param name="message">Given message to transform.</param> /// <returns></returns> public async Task <MessagingContext> TransformAsync(ReceivedMessage message) { if (message == null) { throw new ArgumentNullException(nameof(message)); } if (!(message is ReceivedEntityMessage receivedMessage)) { throw new NotSupportedException( $"Incoming message stream from {message.Origin} that must be transformed should be of type {nameof(ReceivedEntityMessage)}"); } if (receivedMessage.Entity is ExceptionEntity ex) { string ebmsMessageId = IdentifierFactory.Instance.Create(); Error error = Error.FromErrorResult( ebmsMessageId, ex.EbmsRefToMessageId, new ErrorResult(ex.Exception, ErrorAlias.Other)); NotifyMessageEnvelope notifyEnvelope = await CreateNotifyMessageEnvelopeAsync(AS4Message.Create(error), ebmsMessageId, ex.GetType()); return(new MessagingContext(notifyEnvelope, receivedMessage)); } if (receivedMessage.Entity is MessageEntity me) { var as4Transformer = new AS4MessageTransformer(); MessagingContext ctx = await as4Transformer.TransformAsync(receivedMessage); // Normally the message shouldn't have any attachments // but to be sure we should dispose them since we don't need attachments for notifying. ctx.AS4Message.CloseAttachments(); NotifyMessageEnvelope notifyEnvelope = await CreateNotifyMessageEnvelopeAsync(ctx.AS4Message, me.EbmsMessageId, me.GetType()); ctx.ModifyContext(notifyEnvelope, receivedMessage.Entity.Id); return(ctx); } throw new InvalidOperationException(); }
private async Task UpdateDatastoreAsync( NotifyMessageEnvelope notifyMessage, long?messageEntityId, SendResult result) { using (DatastoreContext context = _createContext()) { var repository = new DatastoreRepository(context); var service = new MarkForRetryService(repository); if (!messageEntityId.HasValue) { throw new InvalidOperationException( $"Unable to update notified entities of type {notifyMessage.EntityType?.FullName} because no entity id is present"); } if (notifyMessage.EntityType == typeof(InMessage)) { service.UpdateNotifyMessageForIncomingMessage(messageEntityId.Value, result); } else if (notifyMessage.EntityType == typeof(OutMessage)) { service.UpdateNotifyMessageForOutgoingMessage(messageEntityId.Value, result); } else if (notifyMessage.EntityType == typeof(InException)) { service.UpdateNotifyExceptionForIncomingMessage(messageEntityId.Value, result); } else if (notifyMessage.EntityType == typeof(OutException)) { service.UpdateNotifyExceptionForOutgoingMessage(messageEntityId.Value, result); } else { throw new InvalidOperationException( $"Unable to update notified entities of type {notifyMessage.EntityType?.FullName}." + "Please provide one of the following types in the notify message: " + "InMessage, OutMessage, InException, and OutException are supported"); } await context.SaveChangesAsync().ConfigureAwait(false); } }
private static MessagingContext CreateNotifyMessage <T>(string ebmsMessageId, Entity entity) { var envelope = new NotifyMessageEnvelope( new MessageInfo { MessageId = ebmsMessageId, RefToMessageId = ebmsMessageId }, Status.Delivered, new byte[0], "content-type", typeof(T)); var ctx = new MessagingContext( new ReceivedEntityMessage(entity), MessagingContextMode.Notify) { SendingPMode = new SendingProcessingMode { ReceiptHandling = { NotifyMethod = new Method { Type = "FILE" } }, ErrorHandling = { NotifyMethod = new Method { Type = "FILE" } }, ExceptionHandling = { NotifyMethod = new Method { Type = "FILE" } } } }; ctx.ModifyContext(envelope); return(ctx); }
public void OverrideMessageWithNotifyMessage() { // Arrange var filledNotify = new NotifyMessageEnvelope(new AS4.Model.Notify.MessageInfo(), Status.Delivered, new byte[0], "type", typeof(InMessage)); var context = new MessagingContext(filledNotify) { SendingPMode = new SendingProcessingMode(), ReceivingPMode = new ReceivingProcessingMode() }; var anonymousNotify = new NotifyMessageEnvelope(null, default(Status), null, null, typeof(InMessage)); // Act context.ModifyContext(anonymousNotify); // Assert Assert.Equal(anonymousNotify, context.NotifyMessage); Assert.NotNull(context.SendingPMode); Assert.NotNull(context.ReceivingPMode); }
/// <summary> /// Transform a given <see cref="ReceivedMessage"/> to a Canonical <see cref="MessagingContext"/> instance. /// </summary> /// <param name="message">Given message to transform.</param> /// <returns></returns> public async Task <MessagingContext> TransformAsync(ReceivedMessage message) { var receivedEntityMessage = message as ReceivedEntityMessage; if (receivedEntityMessage == null) { throw new NotSupportedException( $"Minder Notify Transformer only supports transforming instances of type {typeof(ReceivedEntityMessage)}"); } var as4Transformer = new AS4MessageTransformer(); MessagingContext context = await as4Transformer.TransformAsync(message); NotifyMessageEnvelope notifyMessage = await CreateNotifyMessageEnvelope( context.AS4Message, context.AS4Message.GetPrimaryMessageId(), receivedEntityMessage.Entity.GetType()); context.ModifyContext(notifyMessage); return(context); }
private async Task <SendResult> SendNotifyMessageAsync(Method notifyMethod, NotifyMessageEnvelope notifyMessage) { INotifySender sender = _provider.GetNotifySender(notifyMethod.Type); if (sender == null) { throw new ArgumentNullException( nameof(sender), $@"No {nameof(INotifySender)} found for NotifyMethod.Type = {notifyMethod.Type}"); } sender.Configure(notifyMethod); Task <SendResult> sendAsync = sender.SendAsync(notifyMessage); if (sendAsync == null) { throw new ArgumentNullException( nameof(sendAsync), $@"{sender.GetType().Name} returns 'null' for sending NotifyMessage"); } return(await sendAsync.ConfigureAwait(false)); }
/// <summary> /// Start sending the <see cref="NotifyMessage"/> /// </summary> /// <param name="notifyMessage"></param> public Task <SendResult> SendAsync(NotifyMessageEnvelope notifyMessage) { throw new SaboteurException("Sabotage 'Notify' Send"); }
/// <summary> /// Start sending the <see cref="NotifyMessage"/> /// </summary> /// <param name="notifyMessage"></param> public Task <SendResult> SendAsync(NotifyMessageEnvelope notifyMessage) { IsNotified = true; return(Task.FromResult(SendResult.Success)); }