public async Task Should_be_able_to_update_an_existing_queue_with_new_property_values() { var namespaceManager = new NamespaceManagerAdapter(NamespaceManager.CreateFromConnectionString(AzureServiceBusConnectionString.Value)); await namespaceManager.DeleteQueue("existingqueue").ConfigureAwait(false); await namespaceManager.CreateQueue(new QueueDescription("existingqueue")); var settings = new DefaultConfigurationValues().Apply(new SettingsHolder()); var extensions = new TransportExtensions <AzureServiceBusTransport>(settings); extensions.Queues().DescriptionFactory((queuePath, readOnlySettings) => new QueueDescription(queuePath) { AutoDeleteOnIdle = TimeSpan.FromMinutes(100), EnableExpress = true }); var creator = new AzureServiceBusQueueCreator(settings); await creator.Create("existingqueue", namespaceManager); var queueDescription = await namespaceManager.GetQueue("existingqueue"); Assert.AreEqual(TimeSpan.FromMinutes(100), queueDescription.AutoDeleteOnIdle); //cleanup await namespaceManager.DeleteQueue("existingqueue"); }
public async Task Should_be_able_to_update_an_existing_queue_with_new_property_values() { var namespaceManager = new NamespaceManagerAdapterInternal(NamespaceManager.CreateFromConnectionString(AzureServiceBusConnectionString.Value)); await namespaceManager.DeleteQueue("existingqueue").ConfigureAwait(false); await namespaceManager.CreateQueue(new QueueDescription("existingqueue")); var settings = DefaultConfigurationValues.Apply(SettingsHolderFactory.BuildWithSerializer()); var extensions = new TransportExtensions <AzureServiceBusTransport>(settings); extensions.Queues().DescriptionCustomizer(qd => { qd.AutoDeleteOnIdle = TimeSpan.FromMinutes(100); qd.EnableExpress = true; }); var creator = new AzureServiceBusQueueCreator(settings.Get <TopologySettings>().QueueSettings, settings); await creator.Create("existingqueue", namespaceManager); var queueDescription = await namespaceManager.GetQueue("existingqueue"); Assert.AreEqual(TimeSpan.FromMinutes(100), queueDescription.AutoDeleteOnIdle); //cleanup await namespaceManager.DeleteQueue("existingqueue"); }
public async Task Should_not_update_properties_of_an_existing_system_queue() { var queuePath = "errorQ"; var namespaceManager = new NamespaceManagerAdapterInternal(NamespaceManager.CreateFromConnectionString(AzureServiceBusConnectionString.Value)); await namespaceManager.DeleteQueue(queuePath).ConfigureAwait(false); if (!await namespaceManager.QueueExists(queuePath).ConfigureAwait(false)) { await namespaceManager.CreateQueue(new QueueDescription(queuePath)).ConfigureAwait(false); } var settings = DefaultConfigurationValues.Apply(SettingsHolderFactory.BuildWithSerializer()); settings.Set(WellKnownConfigurationKeys.Core.RecoverabilityNumberOfImmediateRetries, 2); var queueBindings = new QueueBindings(); queueBindings.BindSending(queuePath); settings.Set <QueueBindings>(queueBindings); var extensions = new TransportExtensions <AzureServiceBusTransport>(settings); extensions.Queues().LockDuration(TimeSpan.FromMinutes(4)); var creator = new AzureServiceBusQueueCreator(settings.Get <TopologySettings>().QueueSettings, settings); await creator.Create(queuePath, namespaceManager); var real = await namespaceManager.GetQueue(queuePath); Assert.That(real.LockDuration, Is.EqualTo(TimeSpan.FromSeconds(60))); //cleanup await namespaceManager.DeleteQueue(queuePath); }
public async Task Properly_sets_ForwardDeadLetteredMessagesTo_on_the_created_entity() { var namespaceManager = new NamespaceManagerAdapter(NamespaceManager.CreateFromConnectionString(AzureServiceBusConnectionString.Value)); // forwarding queue needs to exist before you can use it as a forwarding target // needs to be created with different settings as it cannot forward to itself obviously var originalsettings = new DefaultConfigurationValues().Apply(new SettingsHolder()); var originalcreator = new AzureServiceBusQueueCreator(originalsettings); await originalcreator.Create("myotherqueue", namespaceManager); // actual test var settings = new DefaultConfigurationValues().Apply(new SettingsHolder()); var extensions = new TransportExtensions <AzureServiceBusTransport>(settings); extensions.Queues().ForwardDeadLetteredMessagesTo("myotherqueue"); var creator = new AzureServiceBusQueueCreator(settings); await creator.Create("myqueue", namespaceManager); var real = await namespaceManager.GetQueue("myqueue"); Assert.IsTrue(real.ForwardDeadLetteredMessagesTo.EndsWith("myotherqueue")); //cleanup await namespaceManager.DeleteQueue("myqueue"); await namespaceManager.DeleteQueue("myotherqueue"); }
public async Task Should_throw_exception_for_a_message_that_exceeds_maximum_size() { // default settings var settings = DefaultConfigurationValues.Apply(SettingsHolderFactory.BuildWithSerializer()); settings.Set(new TopologySettings()); var namespacesDefinition = settings.Get <NamespaceConfigurations>(WellKnownConfigurationKeys.Topology.Addressing.Namespaces); namespacesDefinition.Add("namespace", AzureServiceBusConnectionString.Value, NamespacePurpose.Partitioning); // setup the infrastructure var namespaceManagerCreator = new NamespaceManagerCreator(settings); var namespaceLifecycleManager = new NamespaceManagerLifeCycleManagerInternal(namespaceManagerCreator); var messagingFactoryCreator = new MessagingFactoryCreator(namespaceLifecycleManager, settings); var messagingFactoryLifeCycleManager = new MessagingFactoryLifeCycleManager(messagingFactoryCreator, settings); var messageSenderCreator = new MessageSenderCreator(messagingFactoryLifeCycleManager, settings); var clientLifecycleManager = new MessageSenderLifeCycleManager(messageSenderCreator, settings); var router = new OutgoingBatchRouter(new BatchedOperationsToBrokeredMessagesConverter(settings), clientLifecycleManager, settings, new ThrowOnOversizedBrokeredMessages()); // create the queue var creator = new AzureServiceBusQueueCreator(settings.Get <TopologySettings>().QueueSettings, settings); var namespaceManager = namespaceLifecycleManager.Get("namespace"); await creator.Create("myqueue", namespaceManager); // setup the batch var @namespace = new RuntimeNamespaceInfo("namespace", AzureServiceBusConnectionString.Value); var bytes = Enumerable.Range(0, settings.Get <int>(WellKnownConfigurationKeys.Connectivity.MessageSenders.MaximumMessageSizeInKilobytes) * 1024).Select(x => (byte)(x % 256)).ToArray(); var batch = new BatchInternal { Destinations = new TopologySectionInternal { Entities = new List <EntityInfoInternal> { new EntityInfoInternal { Namespace = @namespace, Path = "MyQueue", Type = EntityType.Queue } }, Namespaces = new List <RuntimeNamespaceInfo> { @namespace } }, RequiredDispatchConsistency = DispatchConsistency.Default, Operations = new List <BatchedOperationInternal> { new BatchedOperationInternal { Message = new OutgoingMessage("Id-1", new Dictionary <string, string>(), bytes), DeliveryConstraints = new List <DeliveryConstraint>() } } }; // perform the test Assert.That(async() => await router.RouteBatch(batch, null, DispatchConsistency.Default), Throws.Exception.TypeOf <MessageTooLargeException>()); }
public async Task Should_not_update_properties_of_an_existing_system_queue() { var queuePath = "errorQ"; var namespaceManager = new NamespaceManagerAdapter(NamespaceManager.CreateFromConnectionString(AzureServiceBusConnectionString.Value)); await namespaceManager.DeleteQueue(queuePath).ConfigureAwait(false); if (!await namespaceManager.QueueExists(queuePath).ConfigureAwait(false)) { await namespaceManager.CreateQueue(new QueueDescription(queuePath)).ConfigureAwait(false); } var settings = new DefaultConfigurationValues().Apply(new SettingsHolder()); settings.Set(WellKnownConfigurationKeys.Core.RecoverabilityNumberOfImmediateRetries, 2); var queueBindings = new QueueBindings(); queueBindings.BindSending(queuePath); settings.Set <QueueBindings>(queueBindings); var extensions = new TransportExtensions <AzureServiceBusTransport>(settings); extensions.Queues().MaxDeliveryCount(2); var creator = new AzureServiceBusQueueCreator(settings); await creator.Create(queuePath, namespaceManager); var real = await namespaceManager.GetQueue(queuePath); Assert.That(real.MaxDeliveryCount, Is.EqualTo(10)); //cleanup await namespaceManager.DeleteQueue(queuePath); }
public async Task Properly_sets_ForwardDeadLetteredMessagesTo_on_the_created_entity_that_qualifies_condition() { var namespaceManager = new NamespaceManagerAdapter(NamespaceManager.CreateFromConnectionString(AzureServiceBusConnectionString.Value)); var settings = new DefaultConfigurationValues().Apply(new SettingsHolder()); var extensions = new TransportExtensions <AzureServiceBusTransport>(settings); extensions.Queues().ForwardDeadLetteredMessagesTo(name => name == "myqueue", "myotherqueue"); var creator = new AzureServiceBusQueueCreator(settings); await creator.Create("myotherqueue", namespaceManager); await creator.Create("myqueue", namespaceManager); var real = await namespaceManager.GetQueue("myqueue"); var forwardReal = await namespaceManager.GetQueue("myotherqueue"); Assert.IsTrue(real.ForwardDeadLetteredMessagesTo.EndsWith("myotherqueue")); Assert.IsTrue(string.IsNullOrEmpty(forwardReal.ForwardDeadLetteredMessagesTo)); //cleanup await namespaceManager.DeleteQueue("myqueue"); await namespaceManager.DeleteQueue("myotherqueue"); }
public async Task Should_throw_if_at_least_one_batch_fails() { // cleanup await TestUtility.Delete("myqueue", "myqueue2"); // default settings var settings = DefaultConfigurationValues.Apply(SettingsHolderFactory.BuildWithSerializer()); settings.Set(new TopologySettings()); var namespacesDefinition = settings.Get <NamespaceConfigurations>(WellKnownConfigurationKeys.Topology.Addressing.Namespaces); namespacesDefinition.Add("namespace", AzureServiceBusConnectionString.Value, NamespacePurpose.Partitioning); // setup the infrastructure var namespaceManagerCreator = new NamespaceManagerCreator(settings); var namespaceLifecycleManager = new NamespaceManagerLifeCycleManagerInternal(namespaceManagerCreator); var messagingFactoryCreator = new MessagingFactoryCreator(namespaceLifecycleManager, settings); var messagingFactoryLifeCycleManager = new MessagingFactoryLifeCycleManager(messagingFactoryCreator, settings); var messageSenderCreator = new MessageSenderCreator(messagingFactoryLifeCycleManager, settings); var clientLifecycleManager = new MessageSenderLifeCycleManager(messageSenderCreator, settings); var router = new OutgoingBatchRouter(new BatchedOperationsToBrokeredMessagesConverter(settings), clientLifecycleManager, settings, new ThrowOnOversizedBrokeredMessages()); // create the queue var creator = new AzureServiceBusQueueCreator(settings.Get <TopologySettings>().QueueSettings, settings); var namespaceManager = namespaceLifecycleManager.Get("namespace"); await creator.Create("myqueue", namespaceManager); // perform the test var dispatcher = new Dispatcher(router, new FakeBatcher()); // validate Assert.ThrowsAsync <MessagingEntityNotFoundException>(async() => await dispatcher.Dispatch(new TransportOperations(), new TransportTransaction(), new ContextBag())); }
public async Task Can_send_a_brokered_message() { // default settings var settings = DefaultConfigurationValues.Apply(SettingsHolderFactory.BuildWithSerializer()); settings.Set <TopologySettings>(new TopologySettings()); var namespacesDefinition = settings.Get <NamespaceConfigurations>(WellKnownConfigurationKeys.Topology.Addressing.Namespaces); namespacesDefinition.Add("namespace", AzureServiceBusConnectionString.Value, NamespacePurpose.Partitioning); // setup the infrastructure var namespaceManagerCreator = new NamespaceManagerCreator(settings); var namespaceLifecycleManager = new NamespaceManagerLifeCycleManagerInternal(namespaceManagerCreator); var messagingFactoryCreator = new MessagingFactoryCreator(namespaceLifecycleManager, settings); var messagingFactoryLifeCycleManager = new MessagingFactoryLifeCycleManager(messagingFactoryCreator, settings); var messageSenderCreator = new MessageSenderCreator(messagingFactoryLifeCycleManager, settings); var creator = new AzureServiceBusQueueCreator(settings.Get <TopologySettings>().QueueSettings, settings); // create the queue var namespaceManager = namespaceLifecycleManager.Get("namespace"); await creator.Create("myqueue", namespaceManager); // perform the test var sender = await messageSenderCreator.Create("myqueue", null, "namespace"); await sender.Send(new BrokeredMessage()); //validate var queue = await namespaceManager.GetQueue("myqueue"); Assert.IsTrue(queue.MessageCount > 0); //cleanup await namespaceManager.DeleteQueue("myqueue"); }
public async Task Should_be_able_to_update_an_existing_queue_with_new_property_values_without_failing_on_readonly_properties() { var namespaceManager = new NamespaceManagerAdapter(NamespaceManager.CreateFromConnectionString(AzureServiceBusConnectionString.Value)); await namespaceManager.DeleteQueue("existingqueue").ConfigureAwait(false); await namespaceManager.CreateQueue(new QueueDescription("existingqueue") { LockDuration = TimeSpan.FromSeconds(50), MaxSizeInMegabytes = SizeInMegabytes.Size2048, RequiresDuplicateDetection = true, EnablePartitioning = true, RequiresSession = true }); var queueDescription = await namespaceManager.GetQueue("existingqueue"); // partitioned topics will have a size that is 16x the requested max Assert.AreEqual(2048 * 16, queueDescription.MaxSizeInMegabytes); Assert.AreEqual(TimeSpan.FromSeconds(50), queueDescription.LockDuration); Assert.IsTrue(queueDescription.EnablePartitioning); Assert.IsTrue(queueDescription.RequiresDuplicateDetection); var settings = new DefaultConfigurationValues().Apply(new SettingsHolder()); var extensions = new TransportExtensions <AzureServiceBusTransport>(settings); extensions.Queues().DescriptionFactory((queuePath, readOnlySettings) => new QueueDescription(queuePath) { LockDuration = TimeSpan.FromSeconds(70), MaxSizeInMegabytes = SizeInMegabytes.Size3072, RequiresDuplicateDetection = false, EnablePartitioning = false, RequiresSession = false, }); var creator = new AzureServiceBusQueueCreator(settings); await creator.Create("existingqueue", namespaceManager); queueDescription = await namespaceManager.GetQueue("existingqueue"); Assert.AreEqual(3072 * 16, queueDescription.MaxSizeInMegabytes); Assert.AreEqual(TimeSpan.FromSeconds(70), queueDescription.LockDuration); Assert.IsTrue(queueDescription.EnablePartitioning); Assert.IsTrue(queueDescription.RequiresDuplicateDetection); //cleanup await namespaceManager.DeleteQueue("existingqueue"); }
public async Task Should_set_MaxDeliveryCount_to_maximum() { var namespaceManager = new NamespaceManagerAdapterInternal(NamespaceManager.CreateFromConnectionString(AzureServiceBusConnectionString.Value)); var settings = DefaultConfigurationValues.Apply(SettingsHolderFactory.BuildWithSerializer()); var creator = new AzureServiceBusQueueCreator(settings.Get <TopologySettings>().QueueSettings, settings); await creator.Create("myqueue", namespaceManager); var real = await namespaceManager.GetQueue("myqueue"); Assert.That(real.MaxDeliveryCount, Is.EqualTo(AzureServiceBusQueueCreator.DefaultMaxDeliveryCountForNoImmediateRetries)); //cleanup await namespaceManager.DeleteQueue("myqueue"); }
public async Task Should_dispatch_multiple_batches() { // cleanup await TestUtility.Delete("myqueue", "myqueue2"); // default settings var settings = DefaultConfigurationValues.Apply(SettingsHolderFactory.BuildWithSerializer()); settings.Set(new TopologySettings()); settings.Set("NServiceBus.Routing.EndpointName", "myqueue"); var namespacesDefinition = settings.Get <NamespaceConfigurations>(WellKnownConfigurationKeys.Topology.Addressing.Namespaces); namespacesDefinition.Add("namespace", AzureServiceBusConnectionString.Value, NamespacePurpose.Partitioning); // setup the infrastructure var namespaceManagerCreator = new NamespaceManagerCreator(settings); var namespaceLifecycleManager = new NamespaceManagerLifeCycleManagerInternal(namespaceManagerCreator); var messagingFactoryCreator = new MessagingFactoryCreator(namespaceLifecycleManager, settings); var messagingFactoryLifeCycleManager = new MessagingFactoryLifeCycleManager(messagingFactoryCreator, settings); var messageSenderCreator = new MessageSenderCreator(messagingFactoryLifeCycleManager, settings); var clientLifecycleManager = new MessageSenderLifeCycleManager(messageSenderCreator, settings); var router = new OutgoingBatchRouter(new BatchedOperationsToBrokeredMessagesConverter(settings), clientLifecycleManager, settings, new ThrowOnOversizedBrokeredMessages()); // create the queue var creator = new AzureServiceBusQueueCreator(settings.Get <TopologySettings>().QueueSettings, settings); var namespaceManager = namespaceLifecycleManager.Get("namespace"); await creator.Create("myqueue", namespaceManager); await creator.Create("myqueue2", namespaceManager); // perform the test var dispatcher = new Dispatcher(router, new FakeBatcher()); await dispatcher.Dispatch(new TransportOperations(), new TransportTransaction(), new ContextBag()); //validate var queue = await namespaceManager.GetQueue("myqueue"); Assert.IsTrue(queue.MessageCount == 2, $"'myqueue' was expected to have 2 message, but it didn't ({queue.MessageCount} found)"); queue = await namespaceManager.GetQueue("myqueue2"); Assert.IsTrue(queue.MessageCount == 2, $"'myqueue2' was expected to have 2 message, but it didn't ({queue.MessageCount} found)"); }
public async Task Properly_sets_DefaultMessageTimeToLive_on_the_created_entity() { var namespaceManager = new NamespaceManagerAdapter(NamespaceManager.CreateFromConnectionString(AzureServiceBusConnectionString.Value)); var settings = new DefaultConfigurationValues().Apply(new SettingsHolder()); var extensions = new TransportExtensions <AzureServiceBusTransport>(settings); extensions.Queues().DefaultMessageTimeToLive(TimeSpan.FromDays(1)); var creator = new AzureServiceBusQueueCreator(settings); await creator.Create("myqueue", namespaceManager); var real = await namespaceManager.GetQueue("myqueue"); Assert.AreEqual(TimeSpan.FromDays(1), real.DefaultMessageTimeToLive); //cleanup await namespaceManager.DeleteQueue("myqueue"); }
public async Task Should_set_forwarding_to_an_explicitly_provided_forwardto() { var namespaceManager = new NamespaceManagerAdapterInternal(NamespaceManager.CreateFromConnectionString(AzureServiceBusConnectionString.Value), AzureServiceBusConnectionString.Value); var queueCreator = new AzureServiceBusQueueCreator(new TopologyQueueSettings(), DefaultConfigurationValues.Apply(SettingsHolderFactory.BuildWithSerializer())); var queueToForwardTo = await queueCreator.Create("forwardto", namespaceManager); var creator = new AzureServiceBusSubscriptionCreator(new TopologySubscriptionSettings()); const string subscriptionName = "sub15"; await creator.Create(topicPath, subscriptionName, metadata, sqlFilter, namespaceManager, queueToForwardTo.Path); var foundDescription = await namespaceManager.GetSubscription(topicPath, subscriptionName); Assert.That(foundDescription.ForwardTo.EndsWith(queueToForwardTo.Path)); await namespaceManager.DeleteSubscription(new SubscriptionDescription(topicPath, subscriptionName)); await namespaceManager.DeleteQueue(queueToForwardTo.Path); }
public async Task Uses_queue_description_when_provided_by_user() { var settings = new DefaultConfigurationValues().Apply(new SettingsHolder()); var extensions = new TransportExtensions <AzureServiceBusTransport>(settings); var namespaceManager = new NamespaceManagerAdapter(NamespaceManager.CreateFromConnectionString(AzureServiceBusConnectionString.Value)); var descriptionToUse = new QueueDescription("myqueue"); extensions.Queues().DescriptionFactory((name, s) => descriptionToUse); var creator = new AzureServiceBusQueueCreator(settings); var description = await creator.Create("myqueue", namespaceManager); Assert.IsTrue(await namespaceManager.QueueExists("myqueue")); Assert.AreEqual(descriptionToUse, description); //cleanup await namespaceManager.DeleteQueue("myqueue"); }
public async Task Properly_sets_SupportOrdering_on_the_created_entity() { var namespaceManager = new NamespaceManagerAdapter(NamespaceManager.CreateFromConnectionString(AzureServiceBusConnectionString.Value)); var settings = new DefaultConfigurationValues().Apply(new SettingsHolder()); var extensions = new TransportExtensions <AzureServiceBusTransport>(settings); extensions.Queues().SupportOrdering(true); var creator = new AzureServiceBusQueueCreator(settings); await creator.Create("myqueue", namespaceManager); var real = await namespaceManager.GetQueue("myqueue"); Assert.IsTrue(real.SupportOrdering); //cleanup await namespaceManager.DeleteQueue("myqueue"); }
public async Task Properly_sets_EnableExpress_on_the_created_entity_that_qualifies_condition() { var namespaceManager = new NamespaceManagerAdapter(NamespaceManager.CreateFromConnectionString(AzureServiceBusConnectionString.Value)); var settings = new DefaultConfigurationValues().Apply(new SettingsHolder()); var extensions = new TransportExtensions <AzureServiceBusTransport>(settings); extensions.Queues().EnableExpress(name => name == "myqueue", true); var creator = new AzureServiceBusQueueCreator(settings); await creator.Create("myqueue", namespaceManager); var real = await namespaceManager.GetQueue("myqueue"); Assert.IsTrue(real.EnableExpress, "Queue should be marked as express, but it wasn't."); //cleanup await namespaceManager.DeleteQueue("myqueue"); }
public async Task Can_start_stop_and_restart_notifier() { // default settings var settings = DefaultConfigurationValues.Apply(SettingsHolderFactory.BuildWithSerializer()); settings.Set <TopologySettings>(new TopologySettings()); var namespacesDefinition = settings.Get <NamespaceConfigurations>(WellKnownConfigurationKeys.Topology.Addressing.Namespaces); namespacesDefinition.Add("namespace", AzureServiceBusConnectionString.Value, NamespacePurpose.Partitioning); // setup the infrastructure var namespaceManagerCreator = new NamespaceManagerCreator(settings); var namespaceLifecycleManager = new NamespaceManagerLifeCycleManagerInternal(namespaceManagerCreator); var messagingFactoryCreator = new MessagingFactoryCreator(namespaceLifecycleManager, settings); var messagingFactoryLifeCycleManager = new MessagingFactoryLifeCycleManager(messagingFactoryCreator, settings); var messageReceiverCreator = new MessageReceiverCreator(messagingFactoryLifeCycleManager, settings); var clientEntityLifeCycleManager = new MessageReceiverLifeCycleManager(messageReceiverCreator, settings); var creator = new AzureServiceBusQueueCreator(settings.Get <TopologySettings>().QueueSettings, settings); var brokeredMessageConverter = new BrokeredMessagesToIncomingMessagesConverter(settings, new PassThroughMapper(settings)); // create the queue var namespaceManager = namespaceLifecycleManager.Get("namespace"); await creator.Create("myqueue", namespaceManager); // perform the test var notifier = new MessageReceiverNotifier(clientEntityLifeCycleManager, brokeredMessageConverter, BuildMessageReceiverNotifierSettings(settings)); notifier.Initialize(new EntityInfoInternal { Path = "myqueue", Namespace = new RuntimeNamespaceInfo("namespace", AzureServiceBusConnectionString.Value) }, (message, context) => TaskEx.Completed, null, null, null, 10); notifier.Start(); await notifier.Stop(); notifier.Start(); await notifier.Stop(); //cleanup await namespaceManager.DeleteQueue("myqueue"); }
public async Task Properly_sets_LockDuration_on_the_created_entity() { var namespaceManager = new NamespaceManagerAdapterInternal(NamespaceManager.CreateFromConnectionString(AzureServiceBusConnectionString.Value)); var settings = DefaultConfigurationValues.Apply(SettingsHolderFactory.BuildWithSerializer()); var extensions = new TransportExtensions <AzureServiceBusTransport>(settings); extensions.Queues().LockDuration(TimeSpan.FromMinutes(5)); var creator = new AzureServiceBusQueueCreator(settings.Get <TopologySettings>().QueueSettings, settings); await creator.Create("myqueue", namespaceManager); var real = await namespaceManager.GetQueue("myqueue"); Assert.AreEqual(TimeSpan.FromMinutes(5), real.LockDuration); //cleanup await namespaceManager.DeleteQueue("myqueue"); }
public async Task Uses_queue_description_when_provided_by_user() { var settings = DefaultConfigurationValues.Apply(SettingsHolderFactory.BuildWithSerializer()); var extensions = new TransportExtensions <AzureServiceBusTransport>(settings); var namespaceManager = new NamespaceManagerAdapterInternal(NamespaceManager.CreateFromConnectionString(AzureServiceBusConnectionString.Value)); var userQueueDescriptionFactoryWasInvoked = false; extensions.Queues().DescriptionCustomizer(qd => userQueueDescriptionFactoryWasInvoked = true); var creator = new AzureServiceBusQueueCreator(settings.Get <TopologySettings>().QueueSettings, settings); await creator.Create("myqueue", namespaceManager); Assert.IsTrue(await namespaceManager.QueueExists("myqueue")); Assert.IsTrue(userQueueDescriptionFactoryWasInvoked); //cleanup await namespaceManager.DeleteQueue("myqueue"); }
public async Task Properly_sets_EnableBatchedOperations_on_the_created_entity() { var namespaceManager = new NamespaceManagerAdapterInternal(NamespaceManager.CreateFromConnectionString(AzureServiceBusConnectionString.Value), AzureServiceBusConnectionString.Value); var settings = DefaultConfigurationValues.Apply(SettingsHolderFactory.BuildWithSerializer()); var extensions = new TransportExtensions <AzureServiceBusTransport>(settings); extensions.Queues().EnableBatchedOperations(false); var creator = new AzureServiceBusQueueCreator(settings.Get <TopologySettings>().QueueSettings, settings); await creator.Create("myqueue", namespaceManager); var real = await namespaceManager.GetQueue("myqueue"); Assert.IsFalse(real.EnableBatchedOperations); //cleanup await namespaceManager.DeleteQueue("myqueue"); }
public async Task Should_properly_set_ForwardTo_on_the_created_entity_with_hierarchy() { var namespaceManager = new NamespaceManagerAdapterInternal(NamespaceManager.CreateFromConnectionString(AzureServiceBusConnectionString.Value), AzureServiceBusConnectionString.Value); var queueCreator = new AzureServiceBusQueueCreator(new TopologyQueueSettings(), DefaultConfigurationValues.Apply(SettingsHolderFactory.BuildWithSerializer())); var queueToForwardTo = await queueCreator.Create("forwardto", namespaceManager); var creator = new AzureServiceBusSubscriptionCreator(new TopologySubscriptionSettings()); const string subscriptionName = "sub17"; await creator.Create(hierarchyTopicPath, subscriptionName, metadata, sqlFilter, namespaceManager, queueToForwardTo.Path); // create again without forward to await creator.Create(hierarchyTopicPath, subscriptionName, metadata, sqlFilter, namespaceManager); var foundDescription = await namespaceManager.GetSubscription(hierarchyTopicPath, subscriptionName); Assert.IsNull(foundDescription.ForwardTo); await namespaceManager.DeleteSubscription(new SubscriptionDescription(hierarchyTopicPath, subscriptionName)); await namespaceManager.DeleteQueue(queueToForwardTo.Path); }
public async Task Properly_sets_EnablePartitioning_on_the_created_entity() { var namespaceManager = new NamespaceManagerAdapter(NamespaceManager.CreateFromConnectionString(AzureServiceBusConnectionString.Value)); //make sure any previously created queues with this name are removed as the EnablePartitioning cannot be updated await namespaceManager.DeleteQueue("myqueue"); var settings = new DefaultConfigurationValues().Apply(new SettingsHolder()); var extensions = new TransportExtensions <AzureServiceBusTransport>(settings); extensions.Queues().EnablePartitioning(true); var creator = new AzureServiceBusQueueCreator(settings); await creator.Create("myqueue", namespaceManager); var real = await namespaceManager.GetQueue("myqueue"); Assert.IsTrue(real.EnablePartitioning); //cleanup await namespaceManager.DeleteQueue("myqueue"); }
public async Task Can_receive_an_incoming_message() { var cts = new CancellationTokenSource(TimeSpan.FromSeconds(60)); // default settings var settings = new DefaultConfigurationValues().Apply(new SettingsHolder()); var namespacesDefinition = settings.Get <NamespaceConfigurations>(WellKnownConfigurationKeys.Topology.Addressing.Namespaces); namespacesDefinition.Add("namespace", AzureServiceBusConnectionString.Value, NamespacePurpose.Partitioning); // setup the infrastructure var namespaceManagerCreator = new NamespaceManagerCreator(settings); var namespaceManagerLifeCycleManager = new NamespaceManagerLifeCycleManager(namespaceManagerCreator); var messagingFactoryCreator = new MessagingFactoryCreator(namespaceManagerLifeCycleManager, settings); var messagingFactoryLifeCycleManager = new MessagingFactoryLifeCycleManager(messagingFactoryCreator, settings); var messageReceiverCreator = new MessageReceiverCreator(messagingFactoryLifeCycleManager, settings); var messageSenderCreator = new MessageSenderCreator(messagingFactoryLifeCycleManager, settings); var clientEntityLifeCycleManager = new MessageReceiverLifeCycleManager(messageReceiverCreator, settings); var creator = new AzureServiceBusQueueCreator(settings); var brokeredMessageConverter = new DefaultBrokeredMessagesToIncomingMessagesConverter(settings, new PassThroughMapper(settings)); // create the queue var namespaceManager = namespaceManagerLifeCycleManager.Get("namespace"); await creator.Create("myqueue", namespaceManager); // put a message on the queue var sender = await messageSenderCreator.Create("myqueue", null, "namespace"); await sender.Send(new BrokeredMessage()); // perform the test var notifier = new MessageReceiverNotifier(clientEntityLifeCycleManager, brokeredMessageConverter, settings); var completed = new AsyncManualResetEvent(false); var error = new AsyncManualResetEvent(false); Exception ex = null; var received = false; notifier.Initialize(new EntityInfo { Path = "myqueue", Namespace = new RuntimeNamespaceInfo("namespace", AzureServiceBusConnectionString.Value) }, (message, context) => { received = true; completed.Set(); return(TaskEx.Completed); }, exception => { ex = exception; error.Set(); return(TaskEx.Completed); }, null, 1); notifier.Start(); await Task.WhenAny(completed.WaitAsync(cts.Token).IgnoreCancellation(), error.WaitAsync(cts.Token).IgnoreCancellation()); // validate Assert.IsTrue(received); Assert.IsNull(ex); //cleanup await notifier.Stop(); await namespaceManager.DeleteQueue("myqueue"); }
public async Task Can_receive_a_brokered_message() { var cts = new CancellationTokenSource(TimeSpan.FromSeconds(60)); // default settings var settings = DefaultConfigurationValues.Apply(SettingsHolderFactory.BuildWithSerializer()); settings.Set(new TopologySettings()); var namespacesDefinition = settings.Get <NamespaceConfigurations>(WellKnownConfigurationKeys.Topology.Addressing.Namespaces); namespacesDefinition.Add("namespace", AzureServiceBusConnectionString.Value, NamespacePurpose.Partitioning); // setup the infrastructure var namespaceManagerCreator = new NamespaceManagerCreator(settings); var namespaceLifecycleManager = new NamespaceManagerLifeCycleManagerInternal(namespaceManagerCreator); var messagingFactoryCreator = new MessagingFactoryCreator(namespaceLifecycleManager, settings); var messagingFactoryLifeCycleManager = new MessagingFactoryLifeCycleManager(messagingFactoryCreator, settings); var messageReceiverCreator = new MessageReceiverCreator(messagingFactoryLifeCycleManager, settings); var messageSenderCreator = new MessageSenderCreator(messagingFactoryLifeCycleManager, settings); var creator = new AzureServiceBusQueueCreator(settings.Get <TopologySettings>().QueueSettings, settings); // create the queue var namespaceManager = namespaceLifecycleManager.Get("namespace"); await creator.Create("myqueue", namespaceManager); // put a message on the queue var sender = await messageSenderCreator.Create("myqueue", null, "namespace"); await sender.Send(new BrokeredMessage()); // perform the test var receiver = await messageReceiverCreator.Create("myqueue", "namespace"); var completed = new AsyncManualResetEvent(false); var error = new AsyncManualResetEvent(false); Exception ex = null; var received = false; var options = new OnMessageOptions(); options.ExceptionReceived += (o, args) => { ex = args.Exception; error.Set(); }; receiver.OnMessage(message => { received = true; completed.Set(); return(TaskEx.Completed); }, options); await Task.WhenAny(completed.WaitAsync(cts.Token).IgnoreCancellation(), error.WaitAsync(cts.Token).IgnoreCancellation()); // validate Assert.IsTrue(received); Assert.IsNull(ex); //cleanup await receiver.CloseAsync(); await namespaceManager.DeleteQueue("myqueue"); }
public async Task Can_receive_messages_with_prefetch_fast() { var cts = new CancellationTokenSource(TimeSpan.FromSeconds(60)); // default settings var settings = DefaultConfigurationValues.Apply(SettingsHolderFactory.BuildWithSerializer()); var namespacesDefinition = settings.Get <NamespaceConfigurations>(WellKnownConfigurationKeys.Topology.Addressing.Namespaces); namespacesDefinition.Add("namespace", AzureServiceBusConnectionString.Value, NamespacePurpose.Partitioning); settings.Set(WellKnownConfigurationKeys.Connectivity.MessageReceivers.PrefetchCount, 500); settings.Set(WellKnownConfigurationKeys.Connectivity.MessageReceivers.ReceiveMode, ReceiveMode.PeekLock); settings.Set(WellKnownConfigurationKeys.Connectivity.SendViaReceiveQueue, true); // default values set by DefaultConfigurationValues.Apply - shouldn't hardcode those here, so OK to use settings var messageReceiverNotifierSettings = new MessageReceiverNotifierSettings( ReceiveMode.PeekLock, settings.HasExplicitValue <TransportTransactionMode>() ? settings.Get <TransportTransactionMode>() : settings.SupportedTransactionMode(), settings.Get <TimeSpan>(WellKnownConfigurationKeys.Connectivity.MessageReceivers.AutoRenewTimeout), settings.Get <int>(WellKnownConfigurationKeys.Connectivity.NumberOfClientsPerEntity)); // setup the infrastructure var namespaceManagerCreator = new NamespaceManagerCreator(settings); var namespaceLifeCycleManager = new NamespaceManagerLifeCycleManagerInternal(namespaceManagerCreator); var messagingFactoryCreator = new MessagingFactoryCreator(namespaceLifeCycleManager, settings); var messagingFactoryLifeCycleManager = new MessagingFactoryLifeCycleManager(messagingFactoryCreator, settings); var messageReceiverCreator = new MessageReceiverCreator(messagingFactoryLifeCycleManager, settings); var creator = new AzureServiceBusQueueCreator(new TopologyQueueSettings(), settings); var brokeredMessageConverter = new BrokeredMessagesToIncomingMessagesConverter(settings, new PassThroughMapper(settings)); // create the queue var namespaceManager = namespaceLifeCycleManager.Get("namespace"); var queue = await creator.Create("myqueue", namespaceManager); var receivedMessages = 0; var completed = new AsyncManualResetEvent(false); // sending messages to the queue var senderFactory = new MessageSenderCreator(messagingFactoryLifeCycleManager, settings); var sender = await senderFactory.Create("myqueue", null, "namespace"); var counter = 0; var tasks = new List <Task>(); for (var j = 0; j < 10; j++) { var batch = new List <BrokeredMessage>(); for (var i = 0; i < 100; i++) { batch.Add(new BrokeredMessage(Encoding.UTF8.GetBytes("Whatever" + counter))); counter++; } tasks.Add(sender.RetryOnThrottleAsync(s => s.SendBatch(batch), s => s.SendBatch(batch.Select(x => x.Clone())), TimeSpan.FromSeconds(10), 5)); } await Task.WhenAll(tasks); var faulted = tasks.Count(task => task.IsFaulted); var expected = 1000 - faulted; // sending messages to the queue is done var notifier = new MessageReceiverNotifier(messageReceiverCreator, brokeredMessageConverter, messageReceiverNotifierSettings); notifier.Initialize(new EntityInfoInternal { Path = "myqueue", Namespace = new RuntimeNamespaceInfo("namespace", AzureServiceBusConnectionString.Value) }, (message, context) => { var numberOfMessages = Interlocked.Increment(ref receivedMessages); if (numberOfMessages == expected) { completed.Set(); } return(TaskEx.Completed); }, null, null, null, 32); var sw = new Stopwatch(); sw.Start(); notifier.Start(); await completed.WaitAsync(cts.Token).IgnoreCancellation(); sw.Stop(); await notifier.Stop(); Assert.IsTrue(receivedMessages == expected); Console.WriteLine($"Receiving {receivedMessages} messages took {sw.ElapsedMilliseconds} milliseconds"); Console.WriteLine("Total of {0} msgs / second", (double)receivedMessages / sw.ElapsedMilliseconds * 1000); // make sure messages are auto-completed Assert.That(queue.MessageCount, Is.EqualTo(0), "Messages where not completed!"); //cleanup await namespaceManager.DeleteQueue("myqueue"); }
public async Task Should_route_via_active_namespace_first() { // default settings var settings = DefaultConfigurationValues.Apply(SettingsHolderFactory.BuildWithSerializer()); settings.Set <TopologySettings>(new TopologySettings()); var namespacesDefinition = settings.Get <NamespaceConfigurations>(WellKnownConfigurationKeys.Topology.Addressing.Namespaces); namespacesDefinition.Add("primary", AzureServiceBusConnectionString.Value, NamespacePurpose.Partitioning); namespacesDefinition.Add("fallback", AzureServiceBusConnectionString.Fallback, NamespacePurpose.Partitioning); // setup the infrastructure var namespaceManagerCreator = new NamespaceManagerCreator(settings); var namespaceLifecycleManager = new NamespaceManagerLifeCycleManagerInternal(namespaceManagerCreator); var messagingFactoryCreator = new MessagingFactoryCreator(namespaceLifecycleManager, settings); var messagingFactoryLifeCycleManager = new MessagingFactoryLifeCycleManager(messagingFactoryCreator, settings); var messageSenderCreator = new MessageSenderCreator(messagingFactoryLifeCycleManager, settings); var clientLifecycleManager = new MessageSenderLifeCycleManager(messageSenderCreator, settings); var router = new OutgoingBatchRouter(new BatchedOperationsToBrokeredMessagesConverter(settings), clientLifecycleManager, settings, new ThrowOnOversizedBrokeredMessages()); // create the fallback queue (but not the queue in the primary to emulate that it is down) var creator = new AzureServiceBusQueueCreator(settings.Get <TopologySettings>().QueueSettings, settings); var primaryNamespaceManager = namespaceLifecycleManager.Get("primary"); var fallbackNamespaceManager = namespaceLifecycleManager.Get("fallback"); await creator.Create("myqueue", primaryNamespaceManager); await creator.Create("myqueue", fallbackNamespaceManager); // setup the batch var @namespace = new RuntimeNamespaceInfo("primary", AzureServiceBusConnectionString.Value); var fallback = new RuntimeNamespaceInfo("fallback", AzureServiceBusConnectionString.Fallback, mode: NamespaceMode.Passive); var bytes = Encoding.UTF8.GetBytes("Whatever"); var batch = new BatchInternal { Destinations = new TopologySectionInternal { Entities = new List <EntityInfoInternal> { new EntityInfoInternal { Namespace = @namespace, Path = "MyQueue", Type = EntityType.Queue }, new EntityInfoInternal { Namespace = fallback, Path = "MyQueue", Type = EntityType.Queue } }, Namespaces = new List <RuntimeNamespaceInfo> { @namespace, fallback } }, RequiredDispatchConsistency = DispatchConsistency.Default, Operations = new List <BatchedOperationInternal> { new BatchedOperationInternal { Message = new OutgoingMessage("SomeId", new Dictionary <string, string>(), bytes), DeliveryConstraints = new List <DeliveryConstraint>() }, } }; // perform the test await router.RouteBatch(batch, null, DispatchConsistency.Default); //validate var queueOnPrimaryNamespace = await primaryNamespaceManager.GetQueue("myqueue"); Assert.IsTrue(queueOnPrimaryNamespace.MessageCount > 0, "expected to have messages in the primary queue, but there were no messages"); var queueOnSecondaryNamespace = await fallbackNamespaceManager.GetQueue("myqueue"); Assert.IsTrue(queueOnSecondaryNamespace.MessageCount == 0, "expected NOT to have messages in the secondary queue, but there were no messages"); //cleanup await primaryNamespaceManager.DeleteQueue("myqueue"); await fallbackNamespaceManager.DeleteQueue("myqueue"); }
public async Task Should_invoke_non_throwing_oversized_brokered_message_handler_for_a_message_that_exceeds_maximum_size_only_once_even_if_fallback_namespace_is_set() { // default settings var settings = DefaultConfigurationValues.Apply(SettingsHolderFactory.BuildWithSerializer()); settings.Set <TopologySettings>(new TopologySettings()); var namespacesDefinition = settings.Get <NamespaceConfigurations>(WellKnownConfigurationKeys.Topology.Addressing.Namespaces); namespacesDefinition.Add("primary", AzureServiceBusConnectionString.Value, NamespacePurpose.Partitioning); namespacesDefinition.Add("fallback", AzureServiceBusConnectionString.Fallback, NamespacePurpose.Partitioning); var oversizedHandler = new MyOversizedBrokeredMessageHandler(); // setup the infrastructure var namespaceManagerCreator = new NamespaceManagerCreator(settings); var namespaceLifecycleManager = new NamespaceManagerLifeCycleManagerInternal(namespaceManagerCreator); var messagingFactoryCreator = new MessagingFactoryCreator(namespaceLifecycleManager, settings); var messagingFactoryLifeCycleManager = new MessagingFactoryLifeCycleManager(messagingFactoryCreator, settings); var messageSenderCreator = new MessageSenderCreator(messagingFactoryLifeCycleManager, settings); var clientLifecycleManager = new MessageSenderLifeCycleManager(messageSenderCreator, settings); var router = new OutgoingBatchRouter(new BatchedOperationsToBrokeredMessagesConverter(settings), clientLifecycleManager, settings, oversizedHandler); // create the queue & fallback queue var creator = new AzureServiceBusQueueCreator(settings.Get <TopologySettings>().QueueSettings, settings); var namespaceManager = namespaceLifecycleManager.Get("primary"); await creator.Create("myqueue", namespaceManager); var fallbackNamespaceManager = namespaceLifecycleManager.Get("fallback"); await creator.Create("myqueue", fallbackNamespaceManager); // setup the batch var @namespace = new RuntimeNamespaceInfo("primary", AzureServiceBusConnectionString.Value); var @fallback = new RuntimeNamespaceInfo("fallback", AzureServiceBusConnectionString.Value, mode: NamespaceMode.Passive); var bytes = Enumerable.Range(0, settings.Get <int>(WellKnownConfigurationKeys.Connectivity.MessageSenders.MaximumMessageSizeInKilobytes) * 1024).Select(x => (byte)(x % 256)).ToArray(); var batch = new BatchInternal { Destinations = new TopologySectionInternal { Entities = new List <EntityInfoInternal> { new EntityInfoInternal { Namespace = @namespace, Path = "myqueue", Type = EntityType.Queue } }, Namespaces = new List <RuntimeNamespaceInfo> { @namespace, @fallback } }, RequiredDispatchConsistency = DispatchConsistency.Default, Operations = new List <BatchedOperationInternal> { new BatchedOperationInternal { Message = new OutgoingMessage("Id-1", new Dictionary <string, string>(), bytes), DeliveryConstraints = new List <DeliveryConstraint>() } } }; // perform the test await router.RouteBatch(batch, null, DispatchConsistency.Default); // validate Assert.True(oversizedHandler.InvocationCount == 1); //cleanup await fallbackNamespaceManager.DeleteQueue("myqueue"); await namespaceManager.DeleteQueue("myqueue"); }
public async Task Can_route_an_outgoing_batch_of_messages() { // default settings var settings = DefaultConfigurationValues.Apply(SettingsHolderFactory.BuildWithSerializer()); settings.Set <TopologySettings>(new TopologySettings()); var namespacesDefinition = settings.Get <NamespaceConfigurations>(WellKnownConfigurationKeys.Topology.Addressing.Namespaces); namespacesDefinition.Add("namespace", AzureServiceBusConnectionString.Value, NamespacePurpose.Partitioning); // setup the infrastructure var namespaceManagerCreator = new NamespaceManagerCreator(settings); var namespaceLifecycleManager = new NamespaceManagerLifeCycleManagerInternal(namespaceManagerCreator); var messagingFactoryCreator = new MessagingFactoryCreator(namespaceLifecycleManager, settings); var messagingFactoryLifeCycleManager = new MessagingFactoryLifeCycleManager(messagingFactoryCreator, settings); var messageSenderCreator = new MessageSenderCreator(messagingFactoryLifeCycleManager, settings); var clientLifecycleManager = new MessageSenderLifeCycleManager(messageSenderCreator, settings); var router = new OutgoingBatchRouter(new BatchedOperationsToBrokeredMessagesConverter(settings), clientLifecycleManager, settings, new ThrowOnOversizedBrokeredMessages()); // create the queue var creator = new AzureServiceBusQueueCreator(settings.Get <TopologySettings>().QueueSettings, settings); var namespaceManager = namespaceLifecycleManager.Get("namespace"); await creator.Create("myqueue", namespaceManager); // setup the batch var @namespace = new RuntimeNamespaceInfo("namespace", AzureServiceBusConnectionString.Value); var bytes = Encoding.UTF8.GetBytes("Whatever"); var batch = new BatchInternal { Destinations = new TopologySectionInternal { Entities = new List <EntityInfoInternal> { new EntityInfoInternal { Namespace = @namespace, Path = "MyQueue", Type = EntityType.Queue } }, Namespaces = new List <RuntimeNamespaceInfo> { @namespace } }, RequiredDispatchConsistency = DispatchConsistency.Default, Operations = new List <BatchedOperationInternal> { new BatchedOperationInternal { Message = new OutgoingMessage("Id-1", new Dictionary <string, string>(), bytes), DeliveryConstraints = new List <DeliveryConstraint>() }, new BatchedOperationInternal { Message = new OutgoingMessage("Id-2", new Dictionary <string, string>(), bytes), DeliveryConstraints = new List <DeliveryConstraint>() } } }; // perform the test await router.RouteBatch(batch, null, DispatchConsistency.Default); //validate var queue = await namespaceManager.GetQueue("myqueue"); Assert.IsTrue(queue.MessageCount == 2); //cleanup await namespaceManager.DeleteQueue("myqueue"); }
public async Task Can_send_batches_of_brokered_messages_fast() { // default settings var settings = DefaultConfigurationValues.Apply(SettingsHolderFactory.BuildWithSerializer()); settings.Set(new TopologySettings()); var namespacesDefinition = settings.Get <NamespaceConfigurations>(WellKnownConfigurationKeys.Topology.Addressing.Namespaces); namespacesDefinition.Add("namespace", AzureServiceBusConnectionString.Value, NamespacePurpose.Partitioning); var extensions = new TransportExtensions <AzureServiceBusTransport>(settings); extensions.NumberOfClientsPerEntity(5); extensions.MessagingFactories() .NumberOfMessagingFactoriesPerNamespace(5) .BatchFlushInterval(TimeSpan.FromMilliseconds(0)); // turns of native batching // setup the infrastructure var namespaceManagerCreator = new NamespaceManagerCreator(settings); var namespaceLifecycleManager = new NamespaceManagerLifeCycleManagerInternal(namespaceManagerCreator); var messagingFactoryCreator = new MessagingFactoryCreator(namespaceLifecycleManager, settings); var messagingFactoryLifeCycleManager = new MessagingFactoryLifeCycleManager(messagingFactoryCreator, settings); var messageSenderCreator = new MessageSenderCreator(messagingFactoryLifeCycleManager, settings); var entityLifecycleManager = new MessageSenderLifeCycleManager(messageSenderCreator, settings); var creator = new AzureServiceBusQueueCreator(settings.Get <TopologySettings>().QueueSettings, settings); // create the queue var namespaceManager = namespaceLifecycleManager.Get("namespace"); await creator.Create("myqueue", namespaceManager); // perform the test var sw = new Stopwatch(); sw.Start(); var counter = 0; var tasks = new List <Task>(); for (var j = 0; j < 10; j++) { var batch = new List <BrokeredMessage>(); for (var i = 0; i < 1000; i++) { batch.Add(new BrokeredMessage()); counter++; } var sender = await entityLifecycleManager.Get("myqueue", null, "namespace"); tasks.Add(sender.RetryOnThrottleAsync(s => s.SendBatch(batch), s => s.SendBatch(batch.Select(x => x.Clone())), TimeSpan.FromSeconds(10), 5)); } await Task.WhenAll(tasks); //validate sw.Stop(); Console.WriteLine("Sending {1} messages took {0} milliseconds", sw.ElapsedMilliseconds, counter); var faulted = tasks.Count(task => task.IsFaulted); Console.WriteLine("Total of {0} msgs / second", (double)(10000 - faulted) / sw.ElapsedMilliseconds * 1000); Assert.IsTrue(sw.ElapsedMilliseconds < TimeSpan.FromMinutes(1).TotalMilliseconds); //cleanup await namespaceManager.DeleteQueue("myqueue"); }