Пример #1
0
        public async Task Triggers_critical_error_when_receiver_cannot_be_started()
        {
            var cts = new CancellationTokenSource(TimeSpan.FromSeconds(60));
            // 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 brokeredMessageConverter = new BrokeredMessagesToIncomingMessagesConverter(settings, new PassThroughMapper(settings));

            // perform the test
            var notifier = new MessageReceiverNotifier(clientEntityLifeCycleManager, brokeredMessageConverter, BuildMessageReceiverNotifierSettings(settings));

            var completed = new AsyncManualResetEvent(false);
            var error     = new AsyncManualResetEvent(false);

            Exception ex       = null;
            var       received = false;

            notifier.Initialize(new EntityInfoInternal {
                Path = "myqueue", Namespace = new RuntimeNamespaceInfo("namespace", AzureServiceBusConnectionString.Value)
            }, (message, context) =>
            {
                received = true;

                completed.Set();

                return(TaskEx.Completed);
            },
                                null,
                                exception =>
            {
                ex = exception;

                error.Set();
            }, null, 1);

            notifier.Start();

            await Task.WhenAny(completed.WaitAsync(cts.Token).IgnoreCancellation(), error.WaitAsync(cts.Token).IgnoreCancellation());

            // validate
            Assert.IsFalse(received);
            Assert.IsNotNull(ex);
        }
        public async Task Delegates_creation_to_messaging_factory()
        {
            var settings = DefaultConfigurationValues.Apply(SettingsHolderFactory.BuildWithSerializer());

            var factory = new InterceptedMessagingFactory();

            var creator = new MessageReceiverCreator(new InterceptedMessagingFactoryFactory(factory), settings);

            var receiver = await creator.Create("myqueue", AzureServiceBusConnectionString.Value);

            Assert.IsTrue(factory.IsInvoked);
            Assert.IsInstanceOf <IMessageReceiverInternal>(receiver);
        }
Пример #3
0
        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 Applies_user_defined_connectivity_settings()
        {
            var settings = DefaultConfigurationValues.Apply(SettingsHolderFactory.BuildWithSerializer());

            var extensions = new TransportExtensions <AzureServiceBusTransport>(settings);

            extensions.MessageReceivers()
            .PrefetchCount(1000)
            .RetryPolicy(RetryPolicy.NoRetry)
            .ReceiveMode(ReceiveMode.ReceiveAndDelete);

            var factory = new InterceptedMessagingFactory();

            var creator = new MessageReceiverCreator(new InterceptedMessagingFactoryFactory(factory), settings);

            var receiver = await creator.Create("myqueue", AzureServiceBusConnectionString.Value);

            Assert.AreEqual(ReceiveMode.ReceiveAndDelete, receiver.Mode);
            Assert.IsInstanceOf <NoRetry>(receiver.RetryPolicy);
            Assert.AreEqual(1000, receiver.PrefetchCount);
        }
Пример #5
0
        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");
        }
Пример #7
0
        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");
        }
Пример #8
0
        public async Task AutoRenewTimout_will_extend_lock_for_processing_to_finish()
        {
            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);

            // set lock duration on a queue to 20 seconds and emulate message processing that takes longer than that, but less than AutoRenewTimeout
            settings.Set(WellKnownConfigurationKeys.Topology.Resources.Queues.LockDuration, TimeSpan.FromSeconds(20));

            // 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 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("autorenewtimeout", 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("autorenewtimeout", null, "namespace");

            var messageToSend = new BrokeredMessage(Encoding.UTF8.GetBytes("Whatever"))
            {
                MessageId = Guid.NewGuid().ToString()
            };
            await sender.Send(messageToSend);

            // sending messages to the queue is done

            var notifier = new MessageReceiverNotifier(clientEntityLifeCycleManager, brokeredMessageConverter, settings);

            notifier.Initialize(new EntityInfo {
                Path = "autorenewtimeout", Namespace = new RuntimeNamespaceInfo("namespace", AzureServiceBusConnectionString.Value)
            },
                                async(message, context) =>
            {
                if (message.MessageId == messageToSend.MessageId)
                {
                    Interlocked.Increment(ref receivedMessages);
                    if (receivedMessages > 1)
                    {
                        Assert.Fail("Callback should only receive one message once, but it did more than that.");
                    }
                    await Task.Delay(TimeSpan.FromSeconds(30));
                    completed.Set();
                }
            }, null, null, 10);


            var sw = new Stopwatch();

            sw.Start();
            notifier.Start();
            await completed.WaitAsync(cts.Token).IgnoreCancellation();

            await Task.Delay(TimeSpan.FromSeconds(10));

            sw.Stop();

            await notifier.Stop();

            Assert.AreEqual(1, receivedMessages, $"Expected to receive message once, but got {receivedMessages}.");
            Console.WriteLine($"Callback processing took {sw.ElapsedMilliseconds} milliseconds");

            //cleanup
            await namespaceManager.DeleteQueue("autorenewtimeout");
        }
        public async Task Should_have_rolled_back_message_to_error_queue()
        {
            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);

            // set lock duration on a queue to 5 seconds and emulate message processing that takes longer than that, but less than AutoRenewTimeout
            settings.Get <TopologySettings>().QueueSettings.LockDuration = TimeSpan.FromSeconds(2);
            settings.Set(WellKnownConfigurationKeys.Connectivity.MessageReceivers.AutoRenewTimeout, TimeSpan.FromSeconds(5));

            // default values set by DefaultConfigurationValues.Apply - shouldn't hardcode those here, so OK to use settings
            var messageReceiverNotifierSettings = new MessageReceiverNotifierSettings(
                ReceiveMode.PeekLock,
                TransportTransactionMode.SendsAtomicWithReceive,
                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(settings.Get <TopologySettings>().QueueSettings, settings);

            var brokeredMessageConverter = new BrokeredMessagesToIncomingMessagesConverter(settings, new PassThroughMapper(settings));

            // create the queue
            var namespaceManager = namespaceLifecycleManager.Get("namespace");
            await creator.Create("completionfailure", namespaceManager);

            var completed = new AsyncManualResetEvent(false);

            // sending messages to the queue
            var senderFactory = new MessageSenderCreator(messagingFactoryLifeCycleManager, settings);
            var sender        = await senderFactory.Create("completionfailure", null, "namespace");

            var messageToSend = new BrokeredMessage(Encoding.UTF8.GetBytes("Whatever"))
            {
                MessageId = Guid.NewGuid().ToString()
            };
            await sender.Send(messageToSend);

            // sending messages to the queue is done

            var rolledBack = new RollbackDetection();

            var notifier = new MessageReceiverNotifier(messageReceiverCreator, brokeredMessageConverter, messageReceiverNotifierSettings);

            notifier.Initialize(new EntityInfoInternal {
                Path = "completionfailure", Namespace = new RuntimeNamespaceInfo("namespace", AzureServiceBusConnectionString.Value)
            },
                                (message, context) =>
            {
                if (message.MessageId == messageToSend.MessageId)
                {
                    Transaction.Current.EnlistVolatile(new EmulateCompletionFailure(), EnlistmentOptions.EnlistDuringPrepareRequired);
                    throw new Exception("Force processing failure");
                }
                return(TaskEx.Completed);
            }, null, null, context =>
            {
                if (context.Message.MessageId == messageToSend.MessageId)
                {
                    Transaction.Current.EnlistVolatile(rolledBack, EnlistmentOptions.None);
                    completed.Set();
                }
                return(Task.FromResult(ErrorHandleResult.Handled));
            }, 1);


            var sw = new Stopwatch();

            sw.Start();
            notifier.Start();
            await completed.WaitAsync(cts.Token).IgnoreCancellation();

            sw.Stop();

            await notifier.Stop();

            Assert.IsTrue(rolledBack.RolledBack, "Should have rolled back the error message.");
            Console.WriteLine($"Callback processing took {sw.ElapsedMilliseconds} milliseconds");

            //cleanup
            await namespaceManager.DeleteQueue("completionfailure");
        }