예제 #1
0
        public async Task Deliver_Message_Only_When_Referenced_Payloads_Are_Delivered()
        {
            AS4Message as4Message = await CreateAS4MessageFrom(deliveragent_message);

            string deliverLocation = DeliverPayloadLocationOf(as4Message.Attachments.First());

            CleanDirectoryAt(Path.GetDirectoryName(deliverLocation));

            // Act
            IPMode pmode = CreateReceivedPMode(
                deliverMessageLocation: DeliveryRoot,
                deliverPayloadLocation: @"%# \ (+_O) / -> Not a valid path");

            InMessage inMessage = CreateInMessageRepresentingUserMessage(as4Message.GetPrimaryMessageId(), as4Message, pmode);

            await InsertInMessageAsync(inMessage);

            // Assert
            var       spy    = DatabaseSpy.Create(_as4Msh.GetConfiguration());
            InMessage actual = await PollUntilPresent(
                () => spy.GetInMessageFor(im => im.Id == inMessage.Id && im.Status == InStatus.Exception.ToString()),
                TimeSpan.FromSeconds(10));

            Assert.Empty(Directory.EnumerateFiles(DeliveryRoot));
            Assert.Equal(InStatus.Exception, actual.Status.ToEnum <InStatus>());
            Assert.Equal(Operation.DeadLettered, actual.Operation);
        }
예제 #2
0
        public Property Updates_Bundled_MessageUnits_For_Forwarding()
        {
            return(Prop.ForAll(
                       CreateUserReceiptArb(),
                       messageUnits =>
            {
                // Before
                Assert.All(
                    messageUnits,
                    u => GetDataStoreContext.InsertInMessage(new InMessage(u.MessageId)));

                // Arrange
                AS4Message received = AS4Message.Create(messageUnits);

                // Act
                ExerciseUpdateReceivedMessage(
                    received,
                    CreateNotifyAllSendingPMode(),
                    CreateForwardingReceivingPMode())
                .GetAwaiter()
                .GetResult();

                // Assert
                IEnumerable <InMessage> updates =
                    GetDataStoreContext.GetInMessages(
                        m => received.MessageIds.Contains(m.EbmsMessageId));

                Assert.All(updates, u => Assert.True(u.Intermediary));

                InMessage primaryUpdate = updates.First(u => u.EbmsMessageId == received.GetPrimaryMessageId());
                Assert.Equal(Operation.ToBeForwarded, primaryUpdate.Operation);
            }));
        }
예제 #3
0
        private static async Task <MessagingContext> PrepareAS4MessageForDeliveryAsync(AS4Message msg, ReceivingProcessingMode pmode)
        {
            var transformer = new DeliverMessageTransformer();

            var entity = new InMessage(msg.GetPrimaryMessageId());

            entity.SetPModeInformation(pmode);

            return(await transformer.TransformAsync(new ReceivedEntityMessage(entity, msg.ToStream(), msg.ContentType)));
        }
예제 #4
0
        private static async Task <string> GetEbmsMessageId(MessagingContext context)
        {
            string ebmsMessageId = context.EbmsMessageId;

            if (String.IsNullOrWhiteSpace(ebmsMessageId) && context.ReceivedMessage != null)
            {
                AS4Message as4Message = await TryDeserialize(context.ReceivedMessage);

                ebmsMessageId = as4Message?.GetPrimaryMessageId();
            }

            return(ebmsMessageId);
        }
예제 #5
0
        private void InsertRelatedSignedUserMessage(IPMode nrrPMode, AS4Message signedUserMessage)
        {
            string location = Registry.Instance.MessageBodyStore
                              .SaveAS4Message(_as4Msh.GetConfiguration().OutMessageStoreLocation, signedUserMessage);

            var outMessage = new OutMessage(signedUserMessage.GetPrimaryMessageId())
            {
                ContentType     = signedUserMessage.ContentType,
                MessageLocation = location,
            };

            outMessage.SetPModeInformation(nrrPMode);

            _databaseSpy.InsertOutMessage(outMessage);
        }
            private static InMessage CreateInMessage(AS4Message message)
            {
                var result = new InMessage(message.GetPrimaryMessageId())
                {
                    EbmsRefToMessageId = message.PrimaryMessageUnit.RefToMessageId,
                    ContentType        = message.ContentType,
                    Intermediary       = true
                };

                result.EbmsMessageType = MessageType.UserMessage;
                result.Operation       = Operation.ToBeForwarded;

                result.AssignAS4Properties(message.PrimaryMessageUnit);

                return(result);
            }
예제 #7
0
        private void PutMessageToSend(AS4Message as4Message, SendingProcessingMode pmode, bool actAsIntermediaryMsh)
        {
            var outMessage = new OutMessage(as4Message.GetPrimaryMessageId())
            {
                ContentType     = as4Message.ContentType,
                MessageLocation =
                    Registry.Instance
                    .MessageBodyStore.SaveAS4Message(
                        Config.Instance.OutMessageStoreLocation,
                        as4Message),
                Intermediary    = actAsIntermediaryMsh,
                EbmsMessageType = MessageType.UserMessage,
                MEP             = MessageExchangePattern.Push,
                Operation       = Operation.ToBeSent,
            };

            outMessage.SetPModeInformation(pmode);

            _databaseSpy.InsertOutMessage(outMessage);
        }
예제 #8
0
        private static AS4Message SignedNRReceipt(X509Certificate2 cert, AS4Message signedUserMessage, Func <int, int> selection)
        {
            IEnumerable <Reference> hashes =
                signedUserMessage
                .SecurityHeader
                .GetReferences()
                .Select(r =>
            {
                r.DigestValue = r.DigestValue.Select(v => (byte)selection(v)).ToArray();
                return(Reference.CreateFromReferenceElement(r));
            });

            AS4Message receipt = AS4Message.Create(
                new Receipt(
                    messageId: $"receipt-{Guid.NewGuid()}",
                    refToMessageId: signedUserMessage.GetPrimaryMessageId(),
                    nonRepudiation: new NonRepudiationInformation(hashes)));

            return(AS4MessageUtils.SignWithCertificate(receipt, cert));
        }
예제 #9
0
        private static void LogReceivedAS4Response(AS4Message request, AS4Message response)
        {
            if (request?.PrimaryMessageUnit != null && response.PrimaryMessageUnit != null)
            {
                Logger.Info($"Sending AS4Message {request.GetPrimaryMessageId()} results in: {request.PrimaryMessageUnit.GetType().Name} -> {response.PrimaryMessageUnit.GetType().Name} ");
            }

            foreach (MessageUnit mu in response.MessageUnits)
            {
                switch (mu)
                {
                case Error err:
                    Logger.Error($"Error message {err.FormatErrorLines()} response received for message with with ebMS Id {mu.RefToMessageId}");
                    break;

                case Receipt r:
                    Logger.Debug($"{(r.NonRepudiationInformation != null ? "Non-Repudiation " : String.Empty)}Receipt message response received for message with ebMS Id {mu.RefToMessageId}");
                    break;
                }
            }
        }
예제 #10
0
 private static string DeliverMessageLocationOf(AS4Message as4Message)
 {
     return(Path.Combine(Environment.CurrentDirectory, @"messages\in", as4Message.GetPrimaryMessageId() + ".xml"));
 }
        /// <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.UnderlyingStream == null)
            {
                throw new InvalidMessageException(
                          "The incoming stream is not an ebMS Message. " +
                          "Only ebMS messages conform with the AS4 Profile are supported.");
            }

            if (!ContentTypeSupporter.IsContentTypeSupported(message.ContentType))
            {
                throw new InvalidMessageException(
                          $"ContentType is not supported {message.ContentType}{Environment.NewLine}" +
                          $"Supported ContentTypes are {Constants.ContentTypes.Soap} and {Constants.ContentTypes.Mime}");
            }

            ReceivedMessage rm = await EnsureIncomingStreamIsSeekable(message);

            AS4Message as4Message = await DeserializeToAS4Message(rm);

            //Debug.Assert(m.UnderlyingStream.Position == 0, "The Deserializer failed to reposition the stream to its start-position");

            if (as4Message.IsSignalMessage && ReceivingPMode != null)
            {
                Logger.Error(
                    "Static Receive configuration doesn't allow receiving signal messages. " +
                    $"Please remove the static configured Receiving PMode: {ReceivingPMode} to also receive signal messages");

                throw new InvalidMessageException(
                          "Static Receive configuration doesn't allow receiving signal messages. ");
            }

            if (as4Message.PrimaryMessageUnit != null)
            {
                Logger.Info($"(Receive) Receiving AS4Message -> {as4Message.PrimaryMessageUnit.GetType().Name} {as4Message.PrimaryMessageUnit.MessageId}");
            }

            var context = new MessagingContext(as4Message, rm, MessagingContextMode.Receive);

            if (ReceivingPMode != null)
            {
                ReceivingProcessingMode pmode =
                    _config.GetReceivingPModes()
                    ?.FirstOrDefault(p => p.Id == ReceivingPMode);

                if (pmode != null)
                {
                    context.ReceivingPMode = pmode;
                }
                else
                {
                    Logger.Error(
                        $"ReceivingPMode with Id: {ReceivingPMode} was configured as default PMode, but this PMode cannot be found in the configured receiving PModes."
                        + $"{Environment.NewLine} Configured Receiving PModes are placed on the folder: '.\\config\\receive-pmodes\\'.");

                    var errorResult = new ErrorResult(
                        "Static configured ReceivingPMode cannot be found",
                        ErrorAlias.ProcessingModeMismatch);

                    var as4Error = new Error(
                        IdentifierFactory.Instance.Create(),
                        as4Message.GetPrimaryMessageId() ?? IdentifierFactory.Instance.Create(),
                        ErrorLine.FromErrorResult(errorResult));

                    return(new MessagingContext(
                               AS4Message.Create(as4Error),
                               MessagingContextMode.Receive)
                    {
                        ErrorResult = errorResult
                    });
                }
            }

            return(context);
        }
예제 #12
0
        /// <summary>
        /// Updates an <see cref="AS4Message"/> for delivery and notification.
        /// </summary>
        /// <param name="as4Message">The message.</param>
        /// <param name="receivingPMode"></param>
        /// <param name="messageBodyStore">The as4 message body persister.</param>
        /// <param name="sendingPMode"></param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <returns></returns>
        public void UpdateAS4MessageForMessageHandling(
            AS4Message as4Message,
            SendingProcessingMode sendingPMode,
            ReceivingProcessingMode receivingPMode,
            IAS4MessageBodyStore messageBodyStore)
        {
            if (as4Message == null)
            {
                throw new ArgumentNullException(nameof(as4Message));
            }

            if (messageBodyStore == null)
            {
                throw new ArgumentNullException(nameof(messageBodyStore));
            }

            if (as4Message.HasUserMessage)
            {
                string savedLocation =
                    messageBodyStore.SaveAS4Message(_configuration.InMessageStoreLocation, as4Message);

                IEnumerable <string> userMessageIds = as4Message.UserMessages.Select(u => u.MessageId);

                _repository.UpdateInMessages(
                    m => userMessageIds.Any(id => id == m.EbmsMessageId),
                    m => m.MessageLocation = savedLocation);
            }

            if (receivingPMode?.MessageHandling?.MessageHandlingType == MessageHandlingChoiceType.Forward)
            {
                Logger.Debug($"Received AS4Message must be forwarded since the ReceivingPMode {receivingPMode?.Id} MessageHandling has a <Forward/> element");

                string pmodeString = AS4XmlSerializer.ToString(receivingPMode);
                string pmodeId     = receivingPMode.Id;

                // Only set the Operation of the InMessage that represents the
                // Primary Message-Unit to 'ToBeForwarded' since we want to prevent
                // that the same message is forwarded more than once (x number of messaging units
                // present in the AS4 Message).

                _repository.UpdateInMessages(
                    m => as4Message.MessageIds.Contains(m.EbmsMessageId),
                    m =>
                {
                    m.Intermediary = true;
                    m.SetPModeInformation(pmodeId, pmodeString);
                    Logger.Debug($"Update InMessage {m.EbmsMessageType} with {{Intermediary={m.Intermediary}, PMode={pmodeId}}}");
                });

                _repository.UpdateInMessage(
                    as4Message.GetPrimaryMessageId(),
                    m =>
                {
                    m.Operation = Operation.ToBeForwarded;
                    Logger.Debug($"Update InMessage {m.EbmsMessageType} with Operation={m.Operation}");
                });
            }
            else if (receivingPMode?.MessageHandling?.MessageHandlingType == MessageHandlingChoiceType.Deliver)
            {
                UpdateUserMessagesForDelivery(as4Message.UserMessages, receivingPMode);
                UpdateSignalMessagesForNotification(as4Message.SignalMessages, sendingPMode);
            }
            else
            {
                UpdateSignalMessagesForNotification(as4Message.SignalMessages, sendingPMode);
            }
        }