/// <summary>
        /// Execute the step for a given <paramref name="messagingContext"/>.
        /// </summary>
        /// <param name="messagingContext">Message used during the step execution.</param>
        /// <returns></returns>
        public async Task <StepResult> ExecuteAsync(MessagingContext messagingContext)
        {
            var entityMessage = messagingContext?.ReceivedMessage as ReceivedEntityMessage;

            if (!(entityMessage?.Entity is InMessage receivedInMessage))
            {
                throw new InvalidOperationException(
                          "The MessagingContext must contain a ReceivedMessage that represents an InMessage." + Environment.NewLine +
                          "Other types of ReceivedMessage models are not supported in this Step.");
            }

            // Forward message by creating an OutMessage and set operation to 'ToBeProcessed'.
            Logger.Info($"{messagingContext.LogTag} Create a message that will be forwarded to the next MSH");
            using (Stream originalInMessage =
                       await _messageStore.LoadMessageBodyAsync(receivedInMessage.MessageLocation))
            {
                string outLocation = await _messageStore.SaveAS4MessageStreamAsync(
                    _configuration.OutMessageStoreLocation,
                    originalInMessage);

                originalInMessage.Position = 0;

                AS4Message msg =
                    await SerializerProvider.Default
                    .Get(receivedInMessage.ContentType)
                    .DeserializeAsync(originalInMessage, receivedInMessage.ContentType);

                using (DatastoreContext dbContext = _createDataStoreContext())
                {
                    var repository = new DatastoreRepository(dbContext);

                    // Only create an OutMessage for the primary message-unit.
                    OutMessage outMessage = OutMessageBuilder
                                            .ForMessageUnit(
                        msg.PrimaryMessageUnit,
                        receivedInMessage.ContentType,
                        messagingContext.SendingPMode)
                                            .BuildForForwarding(outLocation, receivedInMessage);

                    Logger.Debug("Insert OutMessage {{Intermediary=true, Operation=ToBeProcesed}}");
                    repository.InsertOutMessage(outMessage);

                    // Set the InMessage to Forwarded.
                    // We do this for all InMessages that are present in this AS4 Message
                    repository.UpdateInMessages(
                        m => msg.MessageIds.Contains(m.EbmsMessageId),
                        r => r.Operation = Operation.Forwarded);

                    await dbContext.SaveChangesAsync();
                }
            }

            return(StepResult.Success(messagingContext));
        }
예제 #2
0
        /// <summary>
        /// Insert an <see cref="InException"/> based on an exception that occurred dring the incoming Submit operation.
        /// </summary>
        /// <param name="exception">The exception which message will be inserted.</param>
        /// <param name="submit">The original message that caused the exception.</param>
        /// <param name="pmode">The PMode that was being used during the Submit operation.</param>
        public async Task <InException> InsertIncomingSubmitExceptionAsync(
            Exception exception,
            SubmitMessage submit,
            ReceivingProcessingMode pmode)
        {
            Stream stream = await AS4XmlSerializer.ToStreamAsync(submit);

            string location = await _bodyStore.SaveAS4MessageStreamAsync(
                _config.InExceptionStoreLocation,
                stream);

            InException entity =
                InException
                .ForMessageBody(messageLocation: location, exception: exception)
                .SetOperationFor(pmode?.ExceptionHandling);

            await entity.SetPModeInformationAsync(pmode);

            _repository.InsertInException(entity);

            return(entity);
        }
예제 #3
0
        /// <summary>
        /// Inserts a received Message in the DataStore.
        /// For each message-unit that exists in the AS4Message,an InMessage record is created.
        /// The AS4 Message Body is persisted as it has been received.
        /// </summary>
        /// <remarks>The received Message is parsed to an AS4 Message instance.</remarks>
        /// <param name="sendingPMode"></param>
        /// <param name="mep"></param>
        /// <param name="messageBodyStore"></param>
        /// <param name="as4Message"></param>
        /// <param name="originalMessage"></param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="InvalidOperationException"></exception>
        /// <returns>A MessagingContext instance that contains the parsed AS4 Message.</returns>
        public async Task <AS4Message> InsertAS4MessageAsync(
            AS4Message as4Message,
            ReceivedMessage originalMessage,
            SendingProcessingMode sendingPMode,
            MessageExchangePattern mep,
            IAS4MessageBodyStore messageBodyStore)
        {
            if (as4Message == null)
            {
                throw new ArgumentNullException(nameof(as4Message));
            }

            if (originalMessage == null)
            {
                throw new InvalidOperationException("The MessagingContext must contain a ReceivedMessage");
            }

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

            // TODO: should we start the transaction here.
            string location =
                await messageBodyStore.SaveAS4MessageStreamAsync(
                    location : _configuration.InMessageStoreLocation,
                    as4MessageStream : originalMessage.UnderlyingStream).ConfigureAwait(false);

            StreamUtilities.MovePositionToStreamStart(originalMessage.UnderlyingStream);

            try
            {
                InsertUserMessages(as4Message, mep, location, sendingPMode);
                InsertSignalMessages(as4Message, mep, location, sendingPMode);

                return(as4Message);
            }
            catch (Exception ex)
            {
                Logger.Error(ex.Message);

                var service = new ExceptionService(_configuration, _repository, messageBodyStore);
                await service.InsertIncomingExceptionAsync(ex, new MemoryStream(Encoding.UTF8.GetBytes(location)));

                throw;
            }
        }