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}");
            }
        }
Пример #2
0
        /// <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));
        }
Пример #3
0
        /// <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;
        }
Пример #4
0
        /// <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;
        }
Пример #5
0
        /// <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);
        }
Пример #7
0
        /// <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);
        }
Пример #8
0
        /// <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);
            }
        }
Пример #10
0
        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);
        }
Пример #11
0
            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));
        }
Пример #14
0
 /// <summary>
 /// Start sending the <see cref="NotifyMessage"/>
 /// </summary>
 /// <param name="notifyMessage"></param>
 public Task <SendResult> SendAsync(NotifyMessageEnvelope notifyMessage)
 {
     throw new SaboteurException("Sabotage 'Notify' Send");
 }
Пример #15
0
 /// <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));
 }