/// <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)); }
/// <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); }
/// <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; } }