Esempio n. 1
0
        public void When_no_messages_should_return_empty_lists()
        {
            var result = new TransportOperations();

            Assert.AreEqual(0, result.MulticastTransportOperations.Count());
            Assert.AreEqual(0, result.UnicastTransportOperations.Count());
        }
        public async Task<int> Retry(IncomingMessage message, TimeSpan delay, TransportTransaction transportTransaction)
        {
            var outgoingMessage = new OutgoingMessage(message.MessageId, new Dictionary<string, string>(message.Headers), message.Body);

            var currentDelayedRetriesAttempt = message.GetDelayedDeliveriesPerformed() + 1;

            outgoingMessage.SetCurrentDelayedDeliveries(currentDelayedRetriesAttempt);
            outgoingMessage.SetDelayedDeliveryTimestamp(DateTime.UtcNow);

            UnicastAddressTag messageDestination;
            List<DeliveryConstraint> deliveryConstraints = null;
            if (timeoutManagerAddress == null)
            {
                // transport supports native deferred messages, directly send to input queue with delay constraint:
                deliveryConstraints = new List<DeliveryConstraint>(1)
                {
                    new DelayDeliveryWith(delay)
                };
                messageDestination = new UnicastAddressTag(endpointInputQueue);
            }
            else
            {
                // transport doesn't support native deferred messages, reroute to timeout manager:
                outgoingMessage.Headers[TimeoutManagerHeaders.RouteExpiredTimeoutTo] = endpointInputQueue;
                outgoingMessage.Headers[TimeoutManagerHeaders.Expire] = DateTimeExtensions.ToWireFormattedString(DateTime.UtcNow + delay);
                messageDestination = new UnicastAddressTag(timeoutManagerAddress);
            }

            var transportOperations = new TransportOperations(new TransportOperation(outgoingMessage, messageDestination, deliveryConstraints: deliveryConstraints));

            await dispatcher.Dispatch(transportOperations, transportTransaction, new ContextBag()).ConfigureAwait(false);

            return currentDelayedRetriesAttempt;
        }
Esempio n. 3
0
        public Task Dispatch(TransportOperations outgoingMessages, TransportTransaction transaction, ContextBag context)
        {
            var channel = channelProvider.GetPublishChannel();

            try
            {
                var unicastTransportOperations   = outgoingMessages.UnicastTransportOperations;
                var multicastTransportOperations = outgoingMessages.MulticastTransportOperations;

                var tasks = new List <Task>(unicastTransportOperations.Count + multicastTransportOperations.Count);

                foreach (var operation in unicastTransportOperations)
                {
                    context.TryGet(out RabbitMQMessagePriority priority);
                    tasks.Add(SendMessage(operation, channel, priority));
                }

                foreach (var operation in multicastTransportOperations)
                {
                    context.TryGet(out RabbitMQMessagePriority priority);
                    tasks.Add(PublishMessage(operation, channel, priority));
                }

                channelProvider.ReturnPublishChannel(channel);

                return(tasks.Count == 1 ? tasks[0] : Task.WhenAll(tasks));
            }
            catch
            {
                channel.Dispose();
                throw;
            }
        }
Esempio n. 4
0
        public void Should_split_multicast_and_unicast_messages()
        {
            var unicastOperation   = new TransportOperation(CreateUniqueMessage(), new UnicastAddressTag("destination"), DispatchConsistency.Isolated);
            var multicastOperation = new TransportOperation(CreateUniqueMessage(), new MulticastAddressTag(typeof(object)), DispatchConsistency.Default);
            var operations         = new[]
            {
                unicastOperation,
                multicastOperation
            };

            var result = new TransportOperations(operations);

            Assert.AreEqual(1, result.MulticastTransportOperations.Count());
            var multicastOp = result.MulticastTransportOperations.Single();

            Assert.AreEqual(multicastOperation.Message, multicastOp.Message);
            Assert.AreEqual((multicastOperation.AddressTag as MulticastAddressTag)?.MessageType, multicastOp.MessageType);
            Assert.AreEqual(multicastOperation.DeliveryConstraints, multicastOp.DeliveryConstraints);
            Assert.AreEqual(multicastOperation.RequiredDispatchConsistency, multicastOp.RequiredDispatchConsistency);

            Assert.AreEqual(1, result.UnicastTransportOperations.Count());
            var unicastOp = result.UnicastTransportOperations.Single();

            Assert.AreEqual(unicastOperation.Message, unicastOp.Message);
            Assert.AreEqual((unicastOperation.AddressTag as UnicastAddressTag)?.Destination, unicastOp.Destination);
            Assert.AreEqual(unicastOperation.DeliveryConstraints, unicastOp.DeliveryConstraints);
            Assert.AreEqual(unicastOperation.RequiredDispatchConsistency, unicastOp.RequiredDispatchConsistency);
        }
        public Task Dispatch(TransportOperations outgoingMessages, TransportTransaction transaction, ContextBag context)
        {
            InMemoryTransaction inMemoryTransaction = null;

            if (transaction.TryGet(out inMemoryTransaction))
            {
            }

            foreach (var unicastTransportOperation in outgoingMessages.UnicastTransportOperations)
            {
                if (inMemoryTransaction != null && unicastTransportOperation.RequiredDispatchConsistency != DispatchConsistency.Isolated)
                {
                    var x = unicastTransportOperation;
                    inMemoryTransaction.Enlist(() => DispatchUnicastMessage(x));
                }
                else
                {
                    DispatchUnicastMessage(unicastTransportOperation);
                }
            }

            foreach (var multicastTransportOperation in outgoingMessages.MulticastTransportOperations)
            {
                if (inMemoryTransaction != null && multicastTransportOperation.RequiredDispatchConsistency != DispatchConsistency.Isolated)
                {
                    inMemoryTransaction.Enlist(() => DispatchMulticastMessage(multicastTransportOperation));
                }
                else
                {
                    DispatchMulticastMessage(multicastTransportOperation);
                }
            }

            return(Task.CompletedTask);
        }
        public async Task Dispatch(TransportOperations outgoingMessages, TransportTransaction transaction, ContextBag context)
        {
            try
            {
                var unicastTransportOperations   = outgoingMessages.UnicastTransportOperations;
                var multicastTransportOperations = outgoingMessages.MulticastTransportOperations;

                var tasks = new List <Task>(unicastTransportOperations.Count + multicastTransportOperations.Count);

                foreach (var operation in unicastTransportOperations)
                {
                    tasks.Add(SendMessage(operation));
                }

                foreach (var operation in multicastTransportOperations)
                {
                    tasks.Add(PublishMessage(operation));
                }

                await Task.WhenAll(tasks).ConfigureAwait(false);
            }
            finally
            {
            }
        }
        public Task Dispatch(TransportOperations outgoingMessages, TransportTransaction transaction, CancellationToken cancellationToken = default)
        {
            var channel = channelProvider.GetPublishChannel();

            try
            {
                var unicastTransportOperations   = outgoingMessages.UnicastTransportOperations;
                var multicastTransportOperations = outgoingMessages.MulticastTransportOperations;

                var tasks = new List <Task>(unicastTransportOperations.Count + multicastTransportOperations.Count);

                foreach (var operation in unicastTransportOperations)
                {
                    tasks.Add(SendMessage(operation, channel, cancellationToken));
                }

                foreach (var operation in multicastTransportOperations)
                {
                    tasks.Add(PublishMessage(operation, channel, cancellationToken));
                }

                channelProvider.ReturnPublishChannel(channel);

                return(tasks.Count == 1 ? tasks[0] : Task.WhenAll(tasks));
            }
#pragma warning disable PS0019 // When catching System.Exception, cancellation needs to be properly accounted for - justification:
            // the same action is appropriate when an operation was canceled
            catch
#pragma warning restore PS0019 // When catching System.Exception, cancellation needs to be properly accounted for
            {
                channel.Dispose();
                throw;
            }
        }
Esempio n. 8
0
        public async Task Should_not_dispatch_multicast_operation_if_event_type_is_object()
        {
            var settings = new SettingsHolder();

            var mockSnsClient = new MockSnsClient();

            //given that a subscriber never sets up a topic for object this has to return null
            mockSnsClient.FindTopicAsyncResponse = topic => null;

            var transportConfiguration = new TransportConfiguration(settings);
            var dispatcher             = new MessageDispatcher(transportConfiguration, null, null, mockSnsClient, new QueueCache(null, transportConfiguration), new TopicCache(mockSnsClient, settings.SetupMessageMetadataRegistry(), transportConfiguration));

            var transportOperations = new TransportOperations(
                new TransportOperation(
                    new OutgoingMessage(Guid.NewGuid().ToString(), new Dictionary <string, string>(), Encoding.Default.GetBytes("{}")),
                    new MulticastAddressTag(typeof(object)))
                );

            var transportTransaction = new TransportTransaction();
            var context = new ContextBag();

            await dispatcher.Dispatch(transportOperations, transportTransaction, context);

            Assert.IsEmpty(mockSnsClient.PublishedEvents);
        }
Esempio n. 9
0
        public async Task Should_not_deduplicate_if_compatibility_mode_is_enabled_and_no_subscription_found()
        {
            var settings = new SettingsHolder();

            var mockSnsClient = new MockSnsClient();
            var mockSqsClient = new MockSqsClient();

            var transportConfiguration = new TransportConfiguration(settings);
            var dispatcher             = new MessageDispatcher(transportConfiguration, null, mockSqsClient, mockSnsClient, new QueueCache(mockSqsClient, transportConfiguration), new TopicCache(mockSnsClient, settings.SetupMessageMetadataRegistry(), transportConfiguration));

            var messageId = Guid.NewGuid().ToString();
            var headers   = new Dictionary <string, string>()
            {
                { Headers.EnclosedMessageTypes, typeof(Event).AssemblyQualifiedName }
            };
            var transportOperations = new TransportOperations(
                new TransportOperation(
                    new OutgoingMessage(messageId, headers, Encoding.Default.GetBytes("{}")),
                    new MulticastAddressTag(typeof(Event))),
                new TransportOperation(
                    new OutgoingMessage(messageId, headers, Encoding.Default.GetBytes("{}")),
                    new UnicastAddressTag("abc"))
                );

            var transportTransaction = new TransportTransaction();
            var context = new ContextBag();

            await dispatcher.Dispatch(transportOperations, transportTransaction, context);

            Assert.AreEqual(1, mockSnsClient.PublishedEvents.Count);
            Assert.AreEqual(1, mockSqsClient.BatchRequestsSent.Count);
        }
Esempio n. 10
0
            Task MessageReceivedOnChannel(MessageReceivedOnChannelArgs e)
            {
                var body             = e.Body;
                var headers          = e.Headers;
                var id               = e.Id;
                var recoverable      = e.Recoverable;
                var timeToBeReceived = e.TimeToBeReceived;

                var destination = endpointRouter.GetDestinationFor(headers);

                Logger.Info("Sending message to " + destination);

                var outgoingMessage = new OutgoingMessage(id, headers, body);

                outgoingMessage.Headers[Headers.ReplyToAddress] = replyToAddress;

                var deliveryConstraints = new List <DeliveryConstraint>
                {
                    new DiscardIfNotReceivedBefore(timeToBeReceived)
                };

                if (!recoverable)
                {
                    deliveryConstraints.Add(new NonDurableDelivery());
                }

                var transportOperations = new TransportOperations(new TransportOperation(outgoingMessage, new UnicastAddressTag(destination), DispatchConsistency.Default, deliveryConstraints));

                return(dispatchMessages.Dispatch(transportOperations, new TransportTransaction(), new ContextBag()));
            }
        async Task <ErrorHandleResult> MoveToErrorQueue(ErrorContext errorContext, string errorQueue, bool includeStandardHeaders)
        {
            var message = errorContext.Message;

            var outgoingMessage = new OutgoingMessage(message.MessageId, new Dictionary <string, string>(message.Headers), message.Body);

            var headers = outgoingMessage.Headers;

            headers.Remove(Headers.DelayedRetries);
            headers.Remove(Headers.ImmediateRetries);

            ExceptionHeaderHelper.SetExceptionHeaders(headers, errorContext.Exception);

            if (includeStandardHeaders)
            {
                foreach (var faultMetadata in staticFaultMetadata)
                {
                    headers[faultMetadata.Key] = faultMetadata.Value;
                }
            }
            var transportOperations = new TransportOperations(new TransportOperation(outgoingMessage, new UnicastAddressTag(errorQueue)));

            await dispatcher.Dispatch(transportOperations, errorContext.TransportTransaction, new ContextBag()).ConfigureAwait(false);

            return(ErrorHandleResult.Handled);
        }
Esempio n. 12
0
        public async Task Dispatch(TransportOperations outgoingMessages, TransportTransaction transaction, ContextBag context)
        {
            List <Task> concurrentDispatchTasks = null;

            foreach (var dispatchConsistencyGroup in outgoingMessages.UnicastTransportOperations.GroupBy(o => o.RequiredDispatchConsistency))
            {
                switch (dispatchConsistencyGroup.Key)
                {
                case DispatchConsistency.Isolated:
                    concurrentDispatchTasks = concurrentDispatchTasks ?? new List <Task>();
                    concurrentDispatchTasks.Add(DispatchIsolated(dispatchConsistencyGroup));
                    break;

                case DispatchConsistency.Default:
                    concurrentDispatchTasks = concurrentDispatchTasks ?? new List <Task>();
                    concurrentDispatchTasks.Add(DispatchBatched(dispatchConsistencyGroup));
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                try
                {
                    await Task.WhenAll(concurrentDispatchTasks).ConfigureAwait(false);
                }
                catch (Exception e)
                {
                    Logger.Error("Exception from Send.", e);
                    throw;
                }
            }
        }
        public void When_no_messages_should_return_empty_lists()
        {
            var result = new TransportOperations();

            Assert.AreEqual(0, result.MulticastTransportOperations.Count());
            Assert.AreEqual(0, result.UnicastTransportOperations.Count());
        }
Esempio n. 14
0
        async Task OnMessage(MessageContext context, IDispatchMessages dispatcher, Task <bool> barrier, ICollection <string> ownCatalogs)
        {
            //Ensure all endpoinst are created.
            await barrier.ConfigureAwait(false);

            string destination;

            if (!context.Headers.TryGetValue("NServiceBus.SqlServer.Destination", out destination))
            {
                throw new Exception("No destination header present.");
            }
            context.Headers.Remove("NServiceBus.SqlServer.Destination");

            var address = QueueAddress.Parse(destination);

            var outgoingMessage = new OutgoingMessage(context.MessageId, context.Headers, context.Body);
            var operation       = new TransportOperation(outgoingMessage, new UnicastAddressTag(destination));
            var operations      = new TransportOperations(operation);

            if (ownCatalogs.Contains(address.Catalog)) //Forward to the same instance on the receiving connection/transaction
            {
                await dispatcher.Dispatch(operations, context.TransportTransaction, context.Context).ConfigureAwait(false);
            }
            else //Forward to different instance
            {
                IRawEndpointInstance forwarder;
                if (!endpointsByCatalog.TryGetValue(address.Catalog, out forwarder))
                {
                    throw new Exception($"Destination catalog {address.Catalog} is not configured.");
                }
                await forwarder.SendRaw(operations, new TransportTransaction(), new ContextBag()).ConfigureAwait(false);
            }
        }
Esempio n. 15
0
    protected override void Setup(FeatureConfigurationContext context)
    {
        #region DrainTempQueueSatellite

        var settings         = context.Settings;
        var qualifiedAddress = settings.LogicalAddress()
                               .CreateQualifiedAddress("New");
        var tempQueue = settings.GetTransportAddress(qualifiedAddress);
        var mainQueue = settings.LocalAddress();

        context.AddSatelliteReceiver(
            name: "DrainTempQueueSatellite",
            transportAddress: tempQueue,
            runtimeSettings: new PushRuntimeSettings(maxConcurrency: 1),
            recoverabilityPolicy: (config, errorContext) =>
        {
            return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
        },
            onMessage: (builder, messageContext) =>
        {
            var messageDispatcher = builder.Build <IDispatchMessages>();
            var outgoingHeaders   = messageContext.Headers;

            var outgoingMessage   = new OutgoingMessage(messageContext.MessageId, outgoingHeaders, messageContext.Body);
            var outgoingOperation = new TransportOperation(outgoingMessage, new UnicastAddressTag(mainQueue));

            Console.WriteLine($"Moving message from {tempQueue} to {mainQueue}");

            var transportOperations = new TransportOperations(outgoingOperation);
            return(messageDispatcher.Dispatch(transportOperations, messageContext.TransportTransaction, messageContext.Context));
        });

        #endregion
    }
        public Task Dispatch(TransportOperations outgoingMessages, TransportTransaction transaction, ContextBag context)
        {
            var channel = channelProvider.GetPublishChannel();

            try
            {
                var unicastTransportOperations   = outgoingMessages.UnicastTransportOperations;
                var multicastTransportOperations = outgoingMessages.MulticastTransportOperations;

                var tasks = new List <Task>(unicastTransportOperations.Count + multicastTransportOperations.Count);

                foreach (var operation in unicastTransportOperations)
                {
                    tasks.Add(SendMessage(operation, channel));
                }

                foreach (var operation in multicastTransportOperations)
                {
                    tasks.Add(PublishMessage(operation, channel));
                }

                return(tasks.Count == 1 ? tasks[0] : Task.WhenAll(tasks));
            }
            finally
            {
                channelProvider.ReturnPublishChannel(channel);
            }
        }
 public Task Dispatch(TransportOperations outgoingMessages, TransportTransaction transaction, ContextBag context)
 {
     TransportOperations = outgoingMessages;
     ContextBag          = context;
     Transaction         = transaction;
     return(Task.FromResult(0));
 }
        public async Task <int> Retry(IncomingMessage message, TimeSpan delay, TransportTransaction transportTransaction)
        {
            var outgoingMessage = new OutgoingMessage(message.MessageId, new Dictionary <string, string>(message.Headers), message.Body);

            var currentDelayedRetriesAttempt = message.GetDelayedDeliveriesPerformed() + 1;

            outgoingMessage.SetCurrentDelayedDeliveries(currentDelayedRetriesAttempt);
            outgoingMessage.SetDelayedDeliveryTimestamp(DateTime.UtcNow);

            UnicastAddressTag         messageDestination;
            List <DeliveryConstraint> deliveryConstraints = null;

            if (timeoutManagerAddress == null)
            {
                // transport supports native deferred messages, directly send to input queue with delay constraint:
                deliveryConstraints = new List <DeliveryConstraint>(1)
                {
                    new DelayDeliveryWith(delay)
                };
                messageDestination = new UnicastAddressTag(endpointInputQueue);
            }
            else
            {
                // transport doesn't support native deferred messages, reroute to timeout manager:
                outgoingMessage.Headers[TimeoutManagerHeaders.RouteExpiredTimeoutTo] = endpointInputQueue;
                outgoingMessage.Headers[TimeoutManagerHeaders.Expire] = DateTimeExtensions.ToWireFormattedString(DateTime.UtcNow + delay);
                messageDestination = new UnicastAddressTag(timeoutManagerAddress);
            }

            var transportOperations = new TransportOperations(new TransportOperation(outgoingMessage, messageDestination, deliveryConstraints: deliveryConstraints));

            await dispatcher.Dispatch(transportOperations, transportTransaction, new ContextBag()).ConfigureAwait(false);

            return(currentDelayedRetriesAttempt);
        }
Esempio n. 19
0
        public Task Dispatch(TransportOperations outgoingMessages, TransportTransaction transaction, ContextBag context)
        {
            foreach (var operation in outgoingMessages.UnicastTransportOperations)
            {
                var    serializedHeaders = HeaderSerializer.Serialize(operation.Message.Headers);
                var    transportSettings = _settings.getTransportSettings();
                var    queueIndex        = operation.Destination.IndexOf("@", StringComparison.Ordinal);
                string to;
                string subject;
                if (queueIndex > 0)
                {
                    to      = operation.Destination.Substring(queueIndex + 1);
                    subject = $"NSB-MSG-{operation.Destination.Substring(0, queueIndex)}-{operation.Message.MessageId}";
                }
                else
                {
                    to      = transportSettings.ImapUser;
                    subject = $"NSB-MSG-{operation.Destination}-{operation.Message.MessageId}";
                }

                SmtpUtils.SendMail(
                    transportSettings.SmtpServer,
                    transportSettings.SmtpServerPort,
                    transportSettings.SmtpUser,
                    transportSettings.SmtpPassword,
                    transportSettings.ImapUser,
                    to,
                    subject,
                    serializedHeaders,
                    operation.Message.Body);
            }

            return(Task.CompletedTask);
        }
Esempio n. 20
0
        public async Task Should_dispatch_multicast_operations()
        {
            var settings = new SettingsHolder();

            var mockSnsClient = new MockSnsClient();

            var transportConfiguration = new TransportConfiguration(settings);

            var dispatcher = new MessageDispatcher(transportConfiguration, null, null, mockSnsClient, new QueueCache(null, transportConfiguration), new TopicCache(mockSnsClient, settings.SetupMessageMetadataRegistry(), transportConfiguration));

            var transportOperations = new TransportOperations(
                new TransportOperation(
                    new OutgoingMessage(Guid.NewGuid().ToString(), new Dictionary <string, string>(), Encoding.Default.GetBytes("{}")),
                    new MulticastAddressTag(typeof(Event))),
                new TransportOperation(
                    new OutgoingMessage(Guid.NewGuid().ToString(), new Dictionary <string, string>(), Encoding.Default.GetBytes("{}")),
                    new MulticastAddressTag(typeof(AnotherEvent)))
                );

            var transportTransaction = new TransportTransaction();
            var context = new ContextBag();

            await dispatcher.Dispatch(transportOperations, transportTransaction, context);

            Assert.AreEqual(2, mockSnsClient.PublishedEvents.Count);
            Assert.AreEqual("arn:aws:sns:us-west-2:123456789012:NServiceBus-Transport-SQS-Tests-MessageDispatcherTests-Event", mockSnsClient.PublishedEvents.ElementAt(0).TopicArn);
            Assert.AreEqual("arn:aws:sns:us-west-2:123456789012:NServiceBus-Transport-SQS-Tests-MessageDispatcherTests-AnotherEvent", mockSnsClient.PublishedEvents.ElementAt(1).TopicArn);
        }
Esempio n. 21
0
        public async Task Does_not_send_extra_properties_in_payload_by_default()
        {
            var settings = new SettingsHolder();

            var mockSqsClient = new MockSqsClient();

            var dispatcher = new MessageDispatcher(new TransportConfiguration(settings), null, mockSqsClient, new QueueUrlCache(mockSqsClient));

            var transportOperations = new TransportOperations(
                new TransportOperation(
                    new OutgoingMessage("1234", new Dictionary <string, string>
            {
                { TransportHeaders.TimeToBeReceived, expectedTtbr.ToString() },
                { Headers.ReplyToAddress, expectedReplyToAddress }
            }, Encoding.Default.GetBytes("{}")),
                    new UnicastAddressTag("address")));

            var transportTransaction = new TransportTransaction();
            var context = new ContextBag();

            await dispatcher.Dispatch(transportOperations, transportTransaction, context);

            Assert.IsNotEmpty(mockSqsClient.RequestsSent, "No requests sent");
            var request = mockSqsClient.RequestsSent.First();

            IDictionary <string, JToken> bodyJson = JObject.Parse(request.MessageBody);

            Assert.IsFalse(bodyJson.ContainsKey("TimeToBeReceived"), "TimeToBeReceived serialized");
            Assert.IsFalse(bodyJson.ContainsKey("ReplyToAddress"), "ReplyToAddress serialized");
        }
        public void throws_when_message_is_large_and_no_s3_bucket_configured()
        {
            var settings          = new SettingsHolder();
            var transportSettings = new TransportExtensions <SqsTransport>(settings);

            transportSettings
            .Region("ap-southeast-2");

            var sut = new SqsMessageDispatcher
            {
                ConnectionConfiguration = new SqsConnectionConfiguration(settings)
            };

            var stringBuilder = new StringBuilder();

            while (stringBuilder.Length < 256 * 1024)
            {
                stringBuilder.Append("This is a large string. ");
            }

            var largeOutgoingMessageToSend = new OutgoingMessage("1234",
                                                                 new Dictionary <string, string>(),
                                                                 Encoding.Default.GetBytes(stringBuilder.ToString()));

            var transportOperations = new TransportOperations(
                new TransportOperation(
                    largeOutgoingMessageToSend,
                    new UnicastAddressTag("address")));

            var transportTransaction = new TransportTransaction();
            var context = new ContextBag();

            Assert.ThrowsAsync <InvalidOperationException>(async() => await sut.Dispatch(transportOperations, transportTransaction, context));
        }
        public async Task Should_batch_non_isolated_operations()
        {
            var settings = new SettingsHolder();

            var mockSqsClient = new MockSqsClient();

            var dispatcher = new MessageDispatcher(new TransportConfiguration(settings), null, mockSqsClient, new QueueUrlCache(mockSqsClient));

            var transportOperations = new TransportOperations(
                new TransportOperation(
                    new OutgoingMessage(Guid.NewGuid().ToString(), new Dictionary <string, string>(), Encoding.Default.GetBytes("{}")),
                    new UnicastAddressTag("address1"),
                    DispatchConsistency.Default),
                new TransportOperation(
                    new OutgoingMessage(Guid.NewGuid().ToString(), new Dictionary <string, string>(), Encoding.Default.GetBytes("{}")),
                    new UnicastAddressTag("address2"),
                    DispatchConsistency.Default));

            var transportTransaction = new TransportTransaction();
            var context = new ContextBag();

            await dispatcher.Dispatch(transportOperations, transportTransaction, context);

            Assert.IsEmpty(mockSqsClient.RequestsSent);
            Assert.AreEqual(2, mockSqsClient.BatchRequestsSent.Count);
            Assert.AreEqual("address1", mockSqsClient.BatchRequestsSent.ElementAt(0).QueueUrl);
            Assert.AreEqual("address2", mockSqsClient.BatchRequestsSent.ElementAt(1).QueueUrl);
        }
        public void Should_raise_queue_does_not_exists_for_delayed_delivery_for_isolated_dispatch()
        {
            var settings            = new SettingsHolder();
            var transportExtensions = new TransportExtensions <SqsTransport>(settings);

            transportExtensions.UnrestrictedDurationDelayedDelivery();

            var mockSqsClient = new MockSqsClient();

            mockSqsClient.RequestResponse = req => throw new QueueDoesNotExistException("Queue does not exist");

            var dispatcher = new MessageDispatcher(new TransportConfiguration(settings), null, mockSqsClient, new QueueUrlCache(mockSqsClient));

            var transportOperations = new TransportOperations(
                new TransportOperation(
                    new OutgoingMessage(Guid.NewGuid().ToString(), new Dictionary <string, string>(), Encoding.Default.GetBytes("{}")),
                    new UnicastAddressTag("address1"),
                    DispatchConsistency.Isolated,
                    new List <DeliveryConstraint>
            {
                new DelayDeliveryWith(TimeSpan.FromMinutes(30))
            }));

            var transportTransaction = new TransportTransaction();
            var context = new ContextBag();

            var exception = Assert.ThrowsAsync <QueueDoesNotExistException>(async() => await dispatcher.Dispatch(transportOperations, transportTransaction, context));

            StringAssert.StartsWith("Destination 'address1' doesn't support delayed messages longer than", exception.Message);
        }
        public async Task Includes_message_id_in_message_attributes(List <DeliveryConstraint> constraints)
        {
            var settings            = new SettingsHolder();
            var transportExtensions = new TransportExtensions <SqsTransport>(settings);

            transportExtensions.UnrestrictedDurationDelayedDelivery();

            var mockSqsClient = new MockSqsClient();

            var dispatcher = new MessageDispatcher(new TransportConfiguration(settings), null, mockSqsClient, new QueueUrlCache(mockSqsClient));

            var expectedId = "1234";

            var transportOperations = new TransportOperations(
                new TransportOperation(
                    new OutgoingMessage(expectedId, new Dictionary <string, string>(), Encoding.Default.GetBytes("{}")),
                    new UnicastAddressTag("address"),
                    DispatchConsistency.Isolated,
                    constraints));

            var transportTransaction = new TransportTransaction();
            var context = new ContextBag();

            await dispatcher.Dispatch(transportOperations, transportTransaction, context);

            var sentMessage = mockSqsClient.RequestsSent.First();

            Assert.AreEqual(expectedId, sentMessage.MessageAttributes[Headers.MessageId].StringValue);
        }
        public void Should_split_multicast_and_unicast_messages()
        {
            var unicastOperation = new TransportOperation(CreateUniqueMessage(), new UnicastAddressTag("destination"), DispatchConsistency.Isolated);
            var multicastOperation = new TransportOperation(CreateUniqueMessage(), new MulticastAddressTag(typeof(object)), DispatchConsistency.Default);
            var operations = new[]
            {
                unicastOperation,
                multicastOperation
            };

            var result = new TransportOperations(operations);

            Assert.AreEqual(1, result.MulticastTransportOperations.Count());
            var multicastOp = result.MulticastTransportOperations.Single();
            Assert.AreEqual(multicastOperation.Message, multicastOp.Message);
            Assert.AreEqual((multicastOperation.AddressTag as MulticastAddressTag)?.MessageType, multicastOp.MessageType);
            Assert.AreEqual(multicastOperation.DeliveryConstraints, multicastOp.DeliveryConstraints);
            Assert.AreEqual(multicastOperation.RequiredDispatchConsistency, multicastOp.RequiredDispatchConsistency);

            Assert.AreEqual(1, result.UnicastTransportOperations.Count());
            var unicastOp = result.UnicastTransportOperations.Single();
            Assert.AreEqual(unicastOperation.Message, unicastOp.Message);
            Assert.AreEqual((unicastOperation.AddressTag as UnicastAddressTag)?.Destination, unicastOp.Destination);
            Assert.AreEqual(unicastOperation.DeliveryConstraints, unicastOp.DeliveryConstraints);
            Assert.AreEqual(unicastOperation.RequiredDispatchConsistency, unicastOp.RequiredDispatchConsistency);
        }
    public Task Dispatch(TransportOperations outgoingMessages, TransportTransaction transaction, ContextBag context)
    {
        foreach (var operation in outgoingMessages.UnicastTransportOperations)
        {
            var basePath        = BaseDirectoryBuilder.BuildBasePath(operation.Destination);
            var nativeMessageId = Guid.NewGuid().ToString();
            var bodyPath        = Path.Combine(basePath, ".bodies", $"{nativeMessageId}.xml");

            var dir = Path.GetDirectoryName(bodyPath);
            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }
            File.WriteAllBytes(bodyPath, operation.Message.Body);

            var messageContents = new List <string>
            {
                bodyPath,
                HeaderSerializer.Serialize(operation.Message.Headers)
            };

            var messagePath = Path.Combine(basePath, $"{nativeMessageId}.txt");

            // write to temp file first so an atomic move can be done
            // this avoids the file being locked when the receiver tries to process it
            var tempFile = Path.GetTempFileName();
            File.WriteAllLines(tempFile, messageContents);
            File.Move(tempFile, messagePath);
        }

        return(TaskEx.CompletedTask);
    }
        public IList <Batch> ToBatches(TransportOperations operations)
        {
            var indexedBatches = new Dictionary <string, Batch>();

            AddMulticastOperationBatches(operations, indexedBatches);
            AddUnicastOperationBatches(operations, indexedBatches);
            return(indexedBatches.Values.ToList());
        }
Esempio n. 29
0
 public Task Dispatch(TransportOperations outgoingMessages, TransportTransaction transaction, ContextBag context)
 {
     foreach (var operation in outgoingMessages.UnicastTransportOperations)
     {
         Callback(operation);
     }
     return(Task.FromResult(0));
 }
            public Task Dispatch(TransportOperations outgoingMessages, TransportTransaction transaction, ContextBag context)
            {
                var operation = outgoingMessages.UnicastTransportOperations.Single();

                Message     = operation.Message;
                Destination = operation.Destination;
                return(Task.FromResult(0));
            }
        // We need to check if we can support cancellation in here as well?
        public async Task Dispatch(TransportOperations operations, TransportTransaction transportTransaction, CancellationToken cancellationToken = default)
        {
            var sortedOperations = operations.UnicastTransportOperations
                                   .Concat(await ConvertToUnicastOperations(operations, cancellationToken).ConfigureAwait(false))
                                   .SortAndDeduplicate(addressTranslator);

            await DispatchDefault(sortedOperations, transportTransaction, cancellationToken).ConfigureAwait(false);
            await DispatchIsolated(sortedOperations, transportTransaction, cancellationToken).ConfigureAwait(false);
        }
        public void It_deduplicates_based_on_message_id_and_address(TransportOperations transportOperations, int expectedDispatchedMessageCount)
        {
            var queueAddressTranslator = new QueueAddressTranslator("nservicebus", "dbo", null, null);

            var sortResult = transportOperations.UnicastTransportOperations.SortAndDeduplicate(queueAddressTranslator);

            Assert.AreEqual(expectedDispatchedMessageCount, sortResult.DefaultDispatch.Count());
            Assert.IsNull(sortResult.IsolatedDispatch);
        }
Esempio n. 33
0
        public async Task It_deduplicates_based_on_message_id_and_address(TransportOperations transportOperations, int expectedDispatchedMessageCount)
        {
            var queueDispatcher = new FakeTableBasedQueueDispatcher();

            var dispatcher = new MessageDispatcher(queueDispatcher, new QueueAddressTranslator("nservicebus", "dbo", null, null));

            await dispatcher.Dispatch(transportOperations, new TransportTransaction(), new ContextBag());

            Assert.AreEqual(expectedDispatchedMessageCount, queueDispatcher.DispatchedMessageIds.Count);
        }
        public Task Dispatch(TransportOperations outgoingMessages, TransportTransaction transaction, ContextBag context)
        {
            Guard.AgainstNull(nameof(outgoingMessages), outgoingMessages);

            if (outgoingMessages.MulticastTransportOperations.Any())
            {
                throw new Exception("The MSMQ transport only supports unicast transport operations.");
            }

            foreach (var unicastTransportOperation in outgoingMessages.UnicastTransportOperations)
            {
                ExecuteTransportOperation(transaction, unicastTransportOperation);
            }

            return TaskEx.CompletedTask;
        }
Esempio n. 35
0
        async Task RawSending(IDispatchMessages dispatcher)
        {
            #region DispatcherRawSending

            Dictionary<string, string> headers = new Dictionary<string, string>();
            OutgoingMessage outgoingMessage = new OutgoingMessage("MessageId", headers, new byte[]
            {
            });
            NonDurableDelivery[] constraints =
            {
                new NonDurableDelivery()
            };
            UnicastAddressTag address = new UnicastAddressTag("Destination");
            TransportOperation transportOperation = new TransportOperation(outgoingMessage, address, DispatchConsistency.Default, constraints);
            TransportOperations operations = new TransportOperations(transportOperation);
            await dispatcher.Dispatch(operations, new ContextBag());

            #endregion
        }
Esempio n. 36
0
    public Task Dispatch(TransportOperations outgoingMessages, ContextBag context)
    {
        foreach (UnicastTransportOperation transportOperation in outgoingMessages.UnicastTransportOperations)
        {
            string basePath = BaseDirectoryBuilder.BuildBasePath(transportOperation.Destination);
            string nativeMessageId = Guid.NewGuid().ToString();
            string bodyPath = Path.Combine(basePath, ".bodies", nativeMessageId) + ".xml";

            var dir = Path.GetDirectoryName(bodyPath);
            if (!Directory.Exists(dir))
                Directory.CreateDirectory(dir);
            File.WriteAllBytes(bodyPath, transportOperation.Message.Body);

            List<string> messageContents = new List<string>
            {
                bodyPath,
                HeaderSerializer.Serialize(transportOperation.Message.Headers)
            };

            DirectoryBasedTransaction transaction;

            string messagePath = Path.Combine(basePath, nativeMessageId) + ".txt";

            if (transportOperation.RequiredDispatchConsistency != DispatchConsistency.Isolated &&
                context.TryGet(out transaction))
            {
                transaction.Enlist(messagePath, messageContents);
            }
            else
            {
                string tempFile = Path.GetTempFileName();

                //write to temp file first so we can do a atomic move 
                //this avoids the file being locked when the receiver tries to process it
                File.WriteAllLines(tempFile, messageContents);
                File.Move(tempFile, messagePath);
            }
        }

        return TaskEx.CompletedTask;
    }
        public Task MoveToErrorQueue(string errorQueueAddress, IncomingMessage message, Exception exception, TransportTransaction transportTransaction)
        {
            message.RevertToOriginalBodyIfNeeded();

            var outgoingMessage = new OutgoingMessage(message.MessageId, new Dictionary<string, string>(message.Headers), message.Body);

            var headers = outgoingMessage.Headers;
            headers.Remove(Headers.DelayedRetries);
            headers.Remove(Headers.ImmediateRetries);

            ExceptionHeaderHelper.SetExceptionHeaders(headers, exception);

            foreach (var faultMetadata in staticFaultMetadata)
            {
                headers[faultMetadata.Key] = faultMetadata.Value;
            }

            headerCustomizations(headers);

            var transportOperations = new TransportOperations(new TransportOperation(outgoingMessage, new UnicastAddressTag(errorQueueAddress)));

            return dispatcher.Dispatch(transportOperations, transportTransaction, new ContextBag());
        }
Esempio n. 38
0
        public async Task RawSending()
        {
            IDispatchMessages dispatcher = null;

            #region DispatcherRawSending

            var headers = new Dictionary<string, string>();
            var outgoingMessage = new OutgoingMessage("MessageId", headers, new byte[]
            {
            });
            var constraints = new[]
            {
                new NonDurableDelivery()
            };
            UnicastAddressTag address = new UnicastAddressTag("Destination");
            TransportOperation transportOperation = new TransportOperation(outgoingMessage, address, DispatchConsistency.Default, constraints);
            UnicastTransportOperation unicastTransportOperation = new UnicastTransportOperation(outgoingMessage, "destination");
            IEnumerable<MulticastTransportOperation> multicastOperations = Enumerable.Empty<MulticastTransportOperation>();
            UnicastTransportOperation[] unicastOperations = {unicastTransportOperation};
            TransportOperations operations = new TransportOperations(multicastOperations, unicastOperations);
            await dispatcher.Dispatch(operations, new ContextBag());

            #endregion
        }
            public Task Dispatch(TransportOperations outgoingMessages, TransportTransaction transaction, ContextBag context)
            {
                if (numberOfTimes.HasValue && FailedNumberOfTimes < numberOfTimes.Value)
                {
                    FailedNumberOfTimes++;
                    throw new QueueNotFoundException();
                }

                DispatchedTransportOperations.Add(outgoingMessages);
                return TaskEx.CompletedTask;
            }
 public Task Dispatch(TransportOperations outgoingMessages, TransportTransaction transaction, ContextBag context)
 {
     TransportOperations = outgoingMessages;
     ContextBag = context;
     Transaction = transaction;
     return Task.FromResult(0);
 }
 public DispatchedMessage(TransportOperations operations, TransportTransaction transaction, ContextBag context)
 {
     Operations = operations;
     Context = context;
     Transaction = transaction;
 }
 public Task Dispatch(TransportOperations outgoingMessages, TransportTransaction transaction, ContextBag context)
 {
     DispatchedMessages.Add(new DispatchedMessage(outgoingMessages, transaction, context));
     return TaskEx.CompletedTask;
 }
 public Task Dispatch(TransportOperations outgoingMessages, TransportTransaction transportTransaction, ContextBag context)
 {
     OutgoingTransportOperations = outgoingMessages;
     TransportTransactionUsed = transportTransaction;
     return TaskEx.CompletedTask;
 }
 public Task Dispatch(TransportOperations outgoingMessages, TransportTransaction transportTransaction, ContextBag context)
 {
     MessagesSent += outgoingMessages.MulticastTransportOperations.Count + outgoingMessages.UnicastTransportOperations.Count;
     return TaskEx.CompletedTask;
 }
 public Task Dispatch(TransportOperations outgoingMessages, TransportTransaction transportTransaction, ContextBag context)
 {
     throw new Exception("simulated exception");
 }