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