/// <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>
        /// Inserts all the message units of the specified <paramref name="as4Message"/> as <see cref="OutMessage"/> records
        /// each containing the appropriate Status and Operation.
        /// User messages will be set to <see cref="Operation.ToBeProcessed"/>
        /// Signal messages that must be async returned will be set to <see cref="Operation.ToBeSent"/>.
        /// </summary>
        /// <param name="as4Message">The message for which the containing message units will be inserted.</param>
        /// <param name="sendingPMode">The processing mode that will be stored with each message unit if present.</param>
        /// <param name="receivingPMode">The processing mode that will be used to determine if the signal messages must be async returned, this pmode will be stored together with the message units.</param>
        public IEnumerable <OutMessage> InsertAS4Message(
            AS4Message as4Message,
            SendingProcessingMode sendingPMode,
            ReceivingProcessingMode receivingPMode)
        {
            if (as4Message == null)
            {
                throw new ArgumentNullException(nameof(as4Message));
            }

            if (!as4Message.MessageUnits.Any())
            {
                Logger.Trace("Incoming AS4Message hasn't got any message units to insert");
                return(Enumerable.Empty <OutMessage>());
            }

            string messageBodyLocation =
                _messageBodyStore.SaveAS4Message(
                    _configuration.OutMessageStoreLocation,
                    as4Message);

            IDictionary <string, MessageExchangePattern> relatedInMessageMeps =
                GetEbsmsMessageIdsOfRelatedSignals(as4Message);

            var results = new Collection <OutMessage>();

            foreach (MessageUnit messageUnit in as4Message.MessageUnits)
            {
                IPMode pmode =
                    SendingOrReceivingPMode(messageUnit, sendingPMode, receivingPMode);

                (OutStatus st, Operation op) =
                    DetermineReplyPattern(messageUnit, relatedInMessageMeps, receivingPMode);

                OutMessage outMessage =
                    OutMessageBuilder
                    .ForMessageUnit(messageUnit, as4Message.ContentType, pmode)
                    .BuildForSending(messageBodyLocation, st, op);

                Logger.Debug($"Insert OutMessage {outMessage.EbmsMessageType} with {{Operation={outMessage.Operation}, Status={outMessage.Status}}}");
                _repository.InsertOutMessage(outMessage);
                results.Add(outMessage);
            }

            return(results.AsEnumerable());
        }
예제 #3
0
 private OutMessage BuildForPrimaryMessageUnit(AS4Message m)
 {
     return(OutMessageBuilder
            .ForMessageUnit(m.PrimaryMessageUnit, m.ContentType, ExpectedPMode())
            .BuildForSending("message-location", OutStatus.NotApplicable, Operation.NotApplicable));
 }