示例#1
0
        /// <summary>
        /// Start sending the <see cref="DeliverMessage"/>
        /// </summary>
        /// <param name="envelope"></param>
        public async Task <SendResult> SendAsync(DeliverMessageEnvelope envelope)
        {
            if (envelope == null)
            {
                throw new ArgumentNullException(nameof(envelope));
            }

            if (String.IsNullOrWhiteSpace(envelope.ContentType))
            {
                throw new InvalidOperationException(
                          $"{nameof(HttpSender)} requires a ContentType to correctly deliver the message");
            }

            Logger.Info($"(Deliver)[{envelope.Message.MessageInfo.MessageId}] Send DeliverMessage to {Location}");

            HttpWebRequest request = await CreateHttpPostRequest(envelope.ContentType, envelope.SerializeMessage()).ConfigureAwait(false);

            HttpWebResponse response = await SendHttpPostRequest(request).ConfigureAwait(false);

            HttpStatusCode statusCode = response?.StatusCode ?? HttpStatusCode.InternalServerError;

            Logger.Debug($"POST DeliverMessage to {Location} result in: {(int)statusCode} {response?.StatusCode}");

            response?.Close();
            return(SendResultUtils.DetermineSendResultFromHttpResonse(statusCode));
        }
示例#2
0
        private async Task <SendResult> SendDeliverMessageAsync(
            Method deliverMethod,
            DeliverMessageEnvelope deliverMessage)
        {
            IDeliverSender sender = _messageProvider.GetDeliverSender(deliverMethod.Type);

            if (sender == null)
            {
                throw new ArgumentNullException(
                          nameof(sender),
                          $@"No {nameof(IDeliverSender)} can be found for DeliverMethod.Type = {deliverMethod?.Type}");
            }

            sender.Configure(deliverMethod);
            Task <SendResult> sendAsync = sender.SendAsync(deliverMessage);

            if (sendAsync == null)
            {
                throw new ArgumentNullException(
                          nameof(sendAsync),
                          $@"{sender.GetType().Name} returns 'null' for sending DeliverMessage");
            }

            return(await sendAsync.ConfigureAwait(false));
        }
示例#3
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 is ReceivedEntityMessage))
            {
                throw new NotSupportedException(
                          $"Minder Deliver Transformer only supports transforming instances of type {typeof(ReceivedEntityMessage)}");
            }

            var as4Transformer       = new AS4MessageTransformer();
            MessagingContext context = await as4Transformer.TransformAsync(message);

            var includeAttachments = true;
            CollaborationInfo collaborationInfo = context.ReceivingPMode?.MessagePackaging?.CollaborationInfo;

            if (collaborationInfo != null &&
                (collaborationInfo.Action?.Equals("ACT_SIMPLE_ONEWAY_SIZE", StringComparison.OrdinalIgnoreCase) ?? false) &&
                (collaborationInfo.Service?.Value?.Equals("SRV_SIMPLE_ONEWAY_SIZE", StringComparison.OrdinalIgnoreCase) ?? false))
            {
                includeAttachments = false;
            }

            DeliverMessageEnvelope deliverMessage = CreateDeliverMessageEnvelope(context.AS4Message, includeAttachments);

            context.ModifyContext(deliverMessage);

            return(context);
        }
        public async Task ThenExecuteStepFailsWithFailedSenderAsync()
        {
            // Arrange
            DeliverMessageEnvelope envelope = EmptyDeliverMessageEnvelope();
            IStep sut = CreateSendDeliverStepWithSender(new SaboteurSender());

            // Act
            await Assert.ThrowsAnyAsync <Exception>(() => sut.ExecuteAsync(new MessagingContext(envelope)));
        }
示例#5
0
        /// <summary>
        /// Modifies the MessagingContext
        /// </summary>
        /// <param name="deliverMessage">The anonymous deliver.</param>
        /// <returns></returns>
        public void ModifyContext(DeliverMessageEnvelope deliverMessage)
        {
            if (deliverMessage == null)
            {
                throw new ArgumentNullException(nameof(deliverMessage));
            }

            PrepareContextChange();
            DeliverMessage = deliverMessage;
            Mode           = MessagingContextMode.Deliver;
        }
示例#6
0
        /// <summary>
        /// Start sending the <see cref="DeliverMessage"/>
        /// </summary>
        /// <param name="envelope"></param>
        public async Task <SendResult> SendAsync(DeliverMessageEnvelope envelope)
        {
            if (envelope == null)
            {
                throw new ArgumentNullException(nameof(envelope));
            }

            return(await SendMessageResult(
                       message : envelope,
                       sending : InnerDeliverSender.SendAsync,
                       exMessage : $"(Deliver)[{envelope.Message.MessageInfo?.MessageId}] Unable to send DeliverMessage to the configured endpoint due to an exception")
                   .ConfigureAwait(false));
        }
示例#7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MessagingContext"/> class.
        /// </summary>
        /// <param name="deliverMessage">The deliver message.</param>
        public MessagingContext(DeliverMessageEnvelope deliverMessage)
        {
            if (deliverMessage == null)
            {
                throw new ArgumentNullException(nameof(deliverMessage));
            }

            SubmitMessage   = null;
            ReceivedMessage = null;
            AS4Message      = null;
            DeliverMessage  = deliverMessage;
            NotifyMessage   = null;
            Mode            = MessagingContextMode.Deliver;
        }
示例#8
0
        public async Task InsertInException_WithDeliverMessage()
        {
            var envelope =
                new DeliverMessageEnvelope(
                    new DeliverMessage {
                MessageInfo = { MessageId = _expectedId }
            },
                    "content-type",
                    Enumerable.Empty <Attachment>());

            await TestExecutionException(
                default(Operation),
                new MessagingContext(envelope),
                sut => sut.HandleExecutionException);
        }
        /// <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 entityMessage) ||
                !(entityMessage.Entity is MessageEntity me))
            {
                throw new InvalidDataException(
                          $"The message that must be transformed should be of type {nameof(ReceivedEntityMessage)} with a {nameof(MessageEntity)} as Entity");
            }

            MessagingContext context = await AS4MessageTransformer.TransformAsync(entityMessage);

            AS4Message as4Message = context.AS4Message;

            UserMessage toBeDeliveredUserMessage =
                as4Message.UserMessages.FirstOrDefault(u => u.MessageId == me.EbmsMessageId);

            if (toBeDeliveredUserMessage == null)
            {
                throw new InvalidOperationException(
                          $"No UserMessage {me.EbmsMessageId} can be found in stored record for delivering");
            }

            IEnumerable <Attachment> toBeUploadedAttachments =
                as4Message.Attachments
                .Where(a => a.MatchesAny(toBeDeliveredUserMessage.PayloadInfo))
                .ToArray();

            DeliverMessage deliverMessage =
                CreateDeliverMessage(
                    toBeDeliveredUserMessage,
                    toBeUploadedAttachments,
                    context.ReceivingPMode);

            Logger.Info($"(Deliver) Created DeliverMessage from (first) UserMessage {as4Message.FirstUserMessage.MessageId}");
            var envelope = new DeliverMessageEnvelope(
                message: deliverMessage,
                contentType: "application/xml",
                attachments: toBeUploadedAttachments);

            context.ModifyContext(envelope);
            return(context);
        }
        public async Task ThenExecuteStepSucceedsWithValidSenderAsync()
        {
            // Arrange
            DeliverMessageEnvelope envelope = EmptyDeliverMessageEnvelope();

            var spySender = new Mock <IDeliverSender>();

            spySender.Setup(s => s.SendAsync(envelope))
            .ReturnsAsync(SendResult.Success);

            IStep sut = CreateSendDeliverStepWithSender(spySender.Object);

            // Act
            await sut.ExecuteAsync(new MessagingContext(envelope) { ReceivingPMode = CreateDefaultReceivingPMode() });

            // Assert
            spySender.Verify(s => s.SendAsync(It.IsAny <DeliverMessageEnvelope>()), Times.Once);
        }
示例#11
0
        public async Task InsertOutException_IfDeliverMessage()
        {
            var context = SetupMessagingContextForOutMessage(_expectedId);

            var deliverEnvelope =
                new DeliverMessageEnvelope(
                    new DeliverMessage {
                MessageInfo = { MessageId = _expectedId }
            },
                    "content-type",
                    Enumerable.Empty <Attachment>());

            context.ModifyContext(deliverEnvelope);

            await TestHandleExecutionException(
                default(Operation),
                context,
                sut => sut.HandleExecutionException);
        }
示例#12
0
            public void OverrideMessageWithDeliverMessage()
            {
                // Arrange
                var filledNotify = new DeliverMessageEnvelope(new MessageInfo(), new byte[0], "type");
                var context      = new MessagingContext(filledNotify)
                {
                    SendingPMode   = new SendingProcessingMode(),
                    ReceivingPMode = new ReceivingProcessingMode()
                };

                var anonymousDeliver = new DeliverMessageEnvelope(new MessageInfo(), new byte[0], "type");

                // Act
                context.ModifyContext(anonymousDeliver);

                // Assert
                Assert.Equal(anonymousDeliver, context.DeliverMessage);
                Assert.NotNull(context.SendingPMode);
                Assert.NotNull(context.ReceivingPMode);
            }
示例#13
0
        /// <summary>
        /// Start sending the <see cref="DeliverMessage"/>
        /// </summary>
        /// <param name="envelope"></param>
        public async Task <SendResult> SendAsync(DeliverMessageEnvelope envelope)
        {
            if (envelope == null)
            {
                throw new ArgumentNullException(nameof(envelope));
            }

            if (envelope.Message.MessageInfo?.MessageId == null)
            {
                throw new InvalidOperationException(
                          $"{nameof(FileSender)} requires a MessageInfo.MessageId to correctly deliver the message");
            }

            if (String.IsNullOrWhiteSpace(Location))
            {
                throw new InvalidOperationException(
                          $"{nameof(FileSender)} requires a configured location to send the delivered file to, please add a "
                          + "<Parameter name=\"location\" value=\"your-location\"/> it to the MessageHandling.Deliver.DeliverMethod element in the ReceivingPMode");
            }

            SendResult directoryResult = EnsureDirectory(Location);

            if (directoryResult == SendResult.FatalFail)
            {
                return(directoryResult);
            }

            string location = CombineDestinationFullName(envelope.Message.MessageInfo.MessageId, Location);

            Logger.Trace($"Sending DeliverMessage to {location}");

            SendResult result = await TryWriteContentsToFileAsync(location, envelope.SerializeMessage());

            if (result == SendResult.Success)
            {
                Logger.Info(
                    $"(Deliver) DeliverMessage {envelope.Message.MessageInfo.MessageId} is successfully send to \"{location}\"");
            }

            return(result);
        }
        private static async Task <UploadResult> TryUploadAttachmentAsync(
            Attachment attachment,
            DeliverMessageEnvelope deliverMessage,
            IAttachmentUploader uploader)
        {
            try
            {
                Logger.Trace($"Start Uploading Attachment {attachment.Id}...");
                Task <UploadResult> uploadAsync = uploader.UploadAsync(attachment, deliverMessage.Message.MessageInfo);
                if (uploadAsync == null)
                {
                    throw new ArgumentNullException(
                              nameof(uploadAsync),
                              $@"{uploader.GetType().Name} returns 'null' for Attachment {attachment.Id}");
                }

                UploadResult attachmentResult = await uploadAsync.ConfigureAwait(false);

                attachment.ResetContentPosition();

                Payload referencedPayload =
                    deliverMessage.Message.Payloads.FirstOrDefault(attachment.Matches);

                if (referencedPayload == null)
                {
                    throw new InvalidOperationException(
                              $"No referenced <Payload/> element found in DeliverMessage to assign the upload location to with attachment Id = {attachment.Id}");
                }

                referencedPayload.Location = attachmentResult.DownloadUrl;

                Logger.Trace($"Attachment {attachment.Id} uploaded succesfully");
                return(attachmentResult);
            }
            catch (Exception exception)
            {
                Logger.Error($"Attachment {attachment.Id} cannot be uploaded because of an exception: {Environment.NewLine}" + exception);
                return(UploadResult.FatalFail);
            }
        }
        public async Task ThenExecuteMethodSucceedsWithValidUserMessageAsync()
        {
            // Arrange
            string id = Guid.NewGuid().ToString();

            GetDataStoreContext.InsertInMessage(
                CreateInMessage(id, InStatus.Received, Operation.ToBeDelivered));

            DeliverMessageEnvelope envelope = AnonymousDeliverEnvelope(id);
            IStep sut = CreateSendDeliverStepWithSender(new SpySender());

            // Act
            await sut.ExecuteAsync(new MessagingContext(envelope) { ReceivingPMode = CreateDefaultReceivingPMode() });

            // Assert
            GetDataStoreContext.AssertInMessage(id, inmessage =>
            {
                Assert.NotNull(inmessage);
                Assert.Equal(InStatus.Delivered, inmessage.Status.ToEnum <InStatus>());
                Assert.Equal(Operation.Delivered, inmessage.Operation);
            });
        }
        public async Task Reset_InMessage_Operation_ToBeDelivered_When_CurrentRetry_LessThen_MaxRetry(DeliverRetry input)
        {
            // Arrange
            string id = Guid.NewGuid().ToString();

            InMessage im = CreateInMessage(id, InStatus.Received, Operation.Delivering);

            GetDataStoreContext.InsertInMessage(im);

            var r = RetryReliability.CreateForInMessage(
                refToInMessageId: im.Id,
                maxRetryCount: input.MaxRetryCount,
                retryInterval: default(TimeSpan),
                type: RetryType.Notification);

            r.CurrentRetryCount = input.CurrentRetryCount;
            GetDataStoreContext.InsertRetryReliability(r);

            DeliverMessageEnvelope envelope = AnonymousDeliverEnvelope(id);

            var stub = new Mock <IDeliverSender>();

            stub.Setup(s => s.SendAsync(envelope))
            .ReturnsAsync(input.SendResult);

            IStep sut = CreateSendDeliverStepWithSender(stub.Object);

            // Act
            await sut.ExecuteAsync(new MessagingContext(envelope) { ReceivingPMode = CreateDefaultReceivingPMode() });

            // Assert
            GetDataStoreContext.AssertInMessage(id, inMessage =>
            {
                Assert.NotNull(inMessage);
                Assert.Equal(input.ExpectedStatus, inMessage.Status.ToEnum <InStatus>());
                Assert.Equal(input.ExpectedOperation, inMessage.Operation);
            });
        }
示例#17
0
 /// <summary>
 /// Start sending the <see cref="DeliverMessage"/>
 /// </summary>
 /// <param name="envelope"></param>
 public Task <SendResult> SendAsync(DeliverMessageEnvelope envelope)
 {
     throw new SaboteurException("Sabotage 'Deliver' Send");
 }
        /// <summary>
        /// Start uploading the AS4 Message Payloads
        /// </summary>
        /// <param name="messagingContext"></param>
        /// <returns></returns>
        public async Task <StepResult> ExecuteAsync(MessagingContext messagingContext)
        {
            if (messagingContext == null)
            {
                throw new ArgumentNullException(nameof(messagingContext));
            }

            if (messagingContext.DeliverMessage == null)
            {
                throw new InvalidOperationException(
                          $"{nameof(UploadAttachmentsStep)} requires a DeliverMessage to upload the attachments from but no DeliverMessage is present in the MessagingContext");
            }

            DeliverMessageEnvelope deliverEnvelope = messagingContext.DeliverMessage;

            if (!deliverEnvelope.Attachments.Any())
            {
                Logger.Debug("(Deliver) No attachments to upload for DeliverMessage");
                return(StepResult.Success(messagingContext));
            }

            if (messagingContext.ReceivingPMode == null)
            {
                throw new InvalidOperationException(
                          "Unable to send DeliverMessage: no ReceivingPMode is set");
            }

            if (messagingContext.ReceivingPMode.MessageHandling?.DeliverInformation?.PayloadReferenceMethod == null)
            {
                throw new InvalidOperationException(
                          $"Unable to send the DeliverMessage: the ReceivingPMode {messagingContext.ReceivingPMode.Id} "
                          + "does not contain any <PayloadReferenceMethod/> element in the MessageHandling.Deliver element. "
                          + "Please provide a correct <PayloadReferenceMethod/> tag to indicate where the attachments of the DeliverMessage should be sent to.");
            }

            if (messagingContext.ReceivingPMode.MessageHandling.DeliverInformation.PayloadReferenceMethod.Type == null)
            {
                throw new InvalidOperationException(
                          $"Unable to send the DeliverMessage: the ReceivingPMode {messagingContext.ReceivingPMode.Id} "
                          + "does not contain any <Type/> element in the MessageHandling.Deliver.PayloadReferenceMethod element "
                          + "that indicates which uploading strategy that must be used."
                          + "Default uploading strategies are: 'FILE' and 'HTTP'. See 'Deliver Uploading' for more information");
            }

            IAttachmentUploader uploader = GetAttachmentUploader(messagingContext.ReceivingPMode);
            var results = new Collection <UploadResult>();

            foreach (Attachment att in deliverEnvelope.Attachments)
            {
                UploadResult result = await TryUploadAttachmentAsync(att, deliverEnvelope, uploader).ConfigureAwait(false);

                results.Add(result);
            }

            SendResult accResult = results
                                   .Select(r => r.Status)
                                   .Aggregate(SendResultUtils.Reduce);

            await UpdateDeliverMessageAccordinglyToUploadResult(
                messageId : deliverEnvelope.Message.MessageInfo?.MessageId,
                status : accResult);

            if (accResult == SendResult.Success)
            {
                return(StepResult.Success(messagingContext));
            }

            return(StepResult.Failed(messagingContext));
        }
示例#19
0
 /// <summary>
 /// Start sending the <see cref="DeliverMessage"/>
 /// </summary>
 /// <param name="envelope"></param>
 public Task <SendResult> SendAsync(DeliverMessageEnvelope envelope)
 {
     IsDelivered = true;
     return(Task.FromResult(SendResult.Success));
 }