public void ProcessorOptionsSetOnClient()
        {
            var account = Encoding.Default.GetString(GetRandomBuffer(12));
            var fullyQualifiedNamespace = new UriBuilder($"{account}.servicebus.windows.net/").Host;
            var connString = $"Endpoint=sb://{fullyQualifiedNamespace};SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey={Encoding.Default.GetString(GetRandomBuffer(64))}";
            var client     = new ServiceBusClient(connString);
            var options    = new ServiceBusSessionProcessorOptions
            {
                AutoComplete                 = false,
                MaxConcurrentSessions        = 10,
                PrefetchCount                = 5,
                ReceiveMode                  = ReceiveMode.ReceiveAndDelete,
                MaxAutoLockRenewalDuration   = TimeSpan.FromSeconds(60),
                MaxConcurrentCallsPerSession = 4
            };
            var processor = client.CreateSessionProcessor("queueName", options);

            Assert.AreEqual(options.AutoComplete, processor.AutoComplete);
            Assert.AreEqual(options.MaxConcurrentSessions, processor.MaxConcurrentSessions);
            Assert.AreEqual(options.MaxConcurrentCallsPerSession, processor.MaxConcurrentCallsPerSession);
            Assert.AreEqual(options.PrefetchCount, processor.PrefetchCount);
            Assert.AreEqual(options.ReceiveMode, processor.ReceiveMode);
            Assert.AreEqual(options.MaxAutoLockRenewalDuration, processor.MaxAutoLockRenewalDuration);
            Assert.AreEqual(fullyQualifiedNamespace, processor.FullyQualifiedNamespace);
        }
        public void ProcessorOptionsValidation()
        {
            var options = new ServiceBusSessionProcessorOptions();

            Assert.That(
                () => options.PrefetchCount = -1,
                Throws.InstanceOf <ArgumentOutOfRangeException>());
            Assert.That(
                () => options.MaxConcurrentSessions = 0,
                Throws.InstanceOf <ArgumentOutOfRangeException>());
            Assert.That(
                () => options.MaxConcurrentCallsPerSession = -1,
                Throws.InstanceOf <ArgumentOutOfRangeException>());
            Assert.That(
                () => options.MaxAutoLockRenewalDuration = TimeSpan.FromSeconds(-1),
                Throws.InstanceOf <ArgumentOutOfRangeException>());
            Assert.That(
                () => options.MaxReceiveWaitTime = TimeSpan.FromSeconds(0),
                Throws.InstanceOf <ArgumentOutOfRangeException>());
            Assert.That(
                () => options.MaxReceiveWaitTime = TimeSpan.FromSeconds(-1),
                Throws.InstanceOf <ArgumentOutOfRangeException>());

            // should not throw
            options.PrefetchCount              = 0;
            options.MaxReceiveWaitTime         = TimeSpan.FromSeconds(1);
            options.MaxAutoLockRenewalDuration = TimeSpan.FromSeconds(0);
        }
示例#3
0
        static async Task ReceiveSessionMessageAsync()
        {
            Console.WriteLine("=========================================================");
            Console.WriteLine("Press ENTER key to exit after receiving all the messages.");
            Console.WriteLine("=========================================================");
            var options = new ServiceBusSessionProcessorOptions {
                AutoCompleteMessages         = false,
                MaxConcurrentSessions        = 2,
                MaxConcurrentCallsPerSession = 2
            };

            await using ServiceBusSessionProcessor processor = string.IsNullOrWhiteSpace(SubscriptionName) ?
                                                               srv.CreateSessionProcessor(QueueOrTopicName, options) :
                                                               srv.CreateSessionProcessor(QueueOrTopicName, SubscriptionName, options);
            processor.ProcessMessageAsync += async(arg) => {
                Console.WriteLine($"Received message: {arg.SessionId} SequenceNumber: {arg.Message.SequenceNumber} Body: {Encoding.UTF8.GetString(arg.Message.Body)}");
                if (AbandonarMultiplosDe > 0 && arg.Message.SequenceNumber % AbandonarMultiplosDe == 0)
                {
                    await arg.AbandonMessageAsync(arg.Message);
                }
                else
                {
                    await arg.CompleteMessageAsync(arg.Message);
                }
            };
            processor.ProcessErrorAsync += ExceptionReceivedHandler;
            await processor.StartProcessingAsync();

            Console.Read();
            Console.WriteLine("Exit ...");
            await processor.CloseAsync();
        }
示例#4
0
 public static PluginSessionProcessor CreatePluginSessionProcessor(
     this ServiceBusClient client,
     string queueName,
     IEnumerable <Func <ServiceBusReceivedMessage, Task> > plugins,
     ServiceBusSessionProcessorOptions options = default)
 {
     return(new PluginSessionProcessor(queueName, client, plugins, options ?? new ServiceBusSessionProcessorOptions()));
 }
        private async Task RunSessionServiceProcessorAsync()
        {
            var  cred         = new DefaultAzureCredential();
            var  client       = new ServiceBusClient(NamespaceName, cred);
            long messageCount = 0;
            var  sw           = Stopwatch.StartNew();
            var  bagStart     = sw.ElapsedMilliseconds;

            Console.WriteLine($"Receiving from entity '{EntityName}' in namespace '{NamespaceName}'");

            var timer = new Timer(state =>
            {
                var snapshot    = Interlocked.Exchange(ref messageCount, 0);
                var bagDuration = sw.ElapsedMilliseconds - bagStart;
                bagStart        = sw.ElapsedMilliseconds;

                Console.ResetColor();
                Console.WriteLine($"\nReceived {snapshot / (bagDuration / 1000.0)} msg/sec,  {snapshot} in {bagDuration} ms");
            }, null, 10000, 10000);

            var options = new ServiceBusSessionProcessorOptions()
            {
                AutoCompleteMessages         = true,
                MaxConcurrentSessions        = 1,
                MaxConcurrentCallsPerSession = this.ConcurrentCalls,
                ReceiveMode   = this.ReceiveDelete ? ServiceBusReceiveMode.ReceiveAndDelete : ServiceBusReceiveMode.PeekLock,
                PrefetchCount = this.PrefetchCount,
                MaxAutoLockRenewalDuration = TimeSpan.FromMinutes(2),
                SessionIdleTimeout         = TimeSpan.FromSeconds(1)
            };

            var processor = client.CreateSessionProcessor(EntityName, options);

            processor.ProcessMessageAsync += async args =>
            {
                if (!string.IsNullOrEmpty(args.Message.SessionId) ||
                    !string.IsNullOrEmpty(args.Message.Subject))
                {
                    int color = Math.Abs(string.IsNullOrEmpty(args.Message.SessionId) ? args.Message.Subject.GetHashCode() : args.Message.SessionId.GetHashCode());
                    Console.BackgroundColor = ConsoleColor.Black;
                    Console.ForegroundColor = (ConsoleColor)((color % 14) + 1);
                }
                Console.Write($"[]");
                Interlocked.Increment(ref messageCount);
            };
            processor.ProcessErrorAsync += async args =>
            {
            };
            await processor.StartProcessingAsync();

            Console.ReadKey();

            timer.Dispose();
            await processor.StopProcessingAsync();
        }
示例#6
0
        private static async Task SendRequestMessageWithResponse()
        {
            const string requestQueue  = "sbq-request-queue";
            const string responseQueue = "sbq-response-queue";

            var managementClient = new ServiceBusAdministrationClient(Config.Namespace, Config.Credential);

            if (!await managementClient.QueueExistsAsync(requestQueue))
            {
                await managementClient.CreateQueueAsync(requestQueue);
            }

            if (!await managementClient.QueueExistsAsync(responseQueue))
            {
                var createQueueOptions = new CreateQueueOptions(responseQueue)
                {
                    RequiresSession = true
                };

                await managementClient.CreateQueueAsync(createQueueOptions);
            }

            var responseSessionId = Guid.NewGuid().ToString();

            await using var requestClient = new ServiceBusClient(Config.Namespace, Config.Credential);

            var sender = requestClient.CreateSender(requestQueue);

            var message = new ServiceBusMessage(Encoding.UTF8.GetBytes("This is a simple test message"))
            {
                ReplyToSessionId = responseSessionId
            };

            Console.WriteLine("Press any key to send a message. Press Enter to exit.");

            await using var responseClient = new ServiceBusClient(Config.Namespace, Config.Credential);

            var serviceBusSessionProcessorOptions = new ServiceBusSessionProcessorOptions();

            serviceBusSessionProcessorOptions.SessionIds.Add(responseSessionId);

            var sessionProcessor = responseClient.CreateSessionProcessor(responseQueue, serviceBusSessionProcessorOptions);

            sessionProcessor.ProcessMessageAsync += MessageHandler;
            sessionProcessor.ProcessErrorAsync   += ErrorHandler;
示例#7
0
        public void ToSessionProcessorOptions_DynamicConcurrencyEnabled_ReturnsExpectedValue()
        {
            ServiceBusOptions sbOptions = new ServiceBusOptions
            {
                AutoCompleteMessages       = false,
                PrefetchCount              = 123,
                MaxAutoLockRenewalDuration = TimeSpan.FromSeconds(123),
                SessionIdleTimeout         = TimeSpan.FromSeconds(123),
                MaxConcurrentSessions      = 123
            };

            ServiceBusSessionProcessorOptions processorOptions = sbOptions.ToSessionProcessorOptions(true, true);

            Assert.AreEqual(true, processorOptions.AutoCompleteMessages);
            Assert.AreEqual(sbOptions.PrefetchCount, processorOptions.PrefetchCount);
            Assert.AreEqual(sbOptions.MaxAutoLockRenewalDuration, processorOptions.MaxAutoLockRenewalDuration);
            Assert.AreEqual(sbOptions.SessionIdleTimeout, processorOptions.SessionIdleTimeout);
            Assert.AreEqual(1, processorOptions.MaxConcurrentSessions);
        }
示例#8
0
        public static async Task RunSessionProcessor(string connectionString, string queueName, TimeSpan timeSpan)
        {
            // since ServiceBusClient implements IAsyncDisposable we create it with "await using"
            await using var client = new ServiceBusClient(connectionString);

            // get the options to use for configuring the processor
            var options = new ServiceBusSessionProcessorOptions
            {
                // By default after the message handler returns, the processor will complete the message
                // If I want more fine-grained control over settlement, I can set this to false.
                AutoCompleteMessages = false,

                // I can also allow for processing multiple sessions
                MaxConcurrentSessions = 5,

                // By default, there will be a single concurrent call per session. I can
                // increase that here to enable parallel processing within each session.
                MaxConcurrentCallsPerSession = 2
            };

            // create a processor that we can use to process the messages
            ServiceBusSessionProcessor processor = client.CreateSessionProcessor(queueName, options);

            processor.ProcessMessageAsync += MessageHandler;
            processor.ProcessErrorAsync   += ErrorHandler;

            await processor.StartProcessingAsync();

            // since the message handler will run in a background thread, in order to prevent
            // this sample from terminating immediately
            DateTime endProcessing = DateTime.Now.Add(timeSpan);

            while (DateTime.Now < endProcessing)
            {
                await Task.Delay(100);
            }

            // stop processing once the task completion source was completed.
            await processor.StopProcessingAsync();
        }
        protected virtual ServiceBusSessionProcessor GetAzureServiceBusSessionProcessor()
        {
            //Configure additional options...
            var sessionProcessorOptions = new ServiceBusSessionProcessorOptions()
            {
                AutoCompleteMessages = false,
                ReceiveMode          = ServiceBusReceiveMode.PeekLock
            };

            if (this.Options.PrefetchCount > 0)
            {
                sessionProcessorOptions.PrefetchCount = this.Options.PrefetchCount;
            }

            if (this.Options.MaxConcurrentReceiversOrSessions > 0)
            {
                sessionProcessorOptions.MaxConcurrentSessions = this.Options.MaxConcurrentReceiversOrSessions;
            }

            //Good Detail Summary of this property is at: https://stackoverflow.com/a/60381046/7293142
            if (this.Options.MaxAutoRenewDuration.HasValue)
            {
                sessionProcessorOptions.MaxAutoLockRenewalDuration = this.Options.MaxAutoRenewDuration.Value;
            }

            if (this.Options.SessionConnectionIdleTimeout.HasValue)
            {
                sessionProcessorOptions.SessionIdleTimeout = this.Options.SessionConnectionIdleTimeout.Value;
            }

            var sessionProcessingClient = this.AzureServiceBusClient.CreateSessionProcessor(
                this.ServiceBusTopic,
                this.ServiceBusSubscription,
                sessionProcessorOptions
                );

            return(sessionProcessingClient);
        }
示例#10
0
            protected internal override SessionMessageProcessor CreateSessionMessageProcessor(
                ServiceBusClient client,
                string entityPath,
                ServiceBusSessionProcessorOptions options)
            {
                ServiceBusSessionProcessor processor;

                // override the options computed from ServiceBusOptions
                options.SessionIdleTimeout    = TimeSpan.FromSeconds(90);
                options.MaxConcurrentSessions = 1;
                if (entityPath == _firstQueueScope.QueueName)
                {
                    processor = client.CreateSessionProcessor(entityPath, options);
                }
                else
                {
                    string[] arr = entityPath.Split('/');
                    processor = client.CreateSessionProcessor(arr[0], arr[2], options);
                }

                processor.ProcessErrorAsync += args => Task.CompletedTask;
                return(new CustomSessionMessageProcessor(processor, _logger));
            }
示例#11
0
        public async Task ProcessSessionMessages()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: true))
            {
                string connectionString = TestEnvironment.ServiceBusConnectionString;
                string queueName        = scope.QueueName;
                await using var client = GetClient();

                #region Snippet:ServiceBusProcessSessionMessages
                //@@ string connectionString = "<connection_string>";
                //@@ string queueName = "<queue_name>";
                // since ServiceBusClient implements IAsyncDisposable we create it with "await using"
                //@@ await using var client = new ServiceBusClient(connectionString);

                // create the sender
                ServiceBusSender sender = client.CreateSender(queueName);

                // create a message batch that we can send
                ServiceBusMessageBatch messageBatch = await sender.CreateMessageBatchAsync();

                messageBatch.TryAddMessage(
                    new ServiceBusMessage(Encoding.UTF8.GetBytes("First"))
                {
                    SessionId = "Session1"
                });
                messageBatch.TryAddMessage(
                    new ServiceBusMessage(Encoding.UTF8.GetBytes("Second"))
                {
                    SessionId = "Session2"
                });

                // send the message batch
                await sender.SendMessagesAsync(messageBatch);

                // get the options to use for configuring the processor
                var options = new ServiceBusSessionProcessorOptions
                {
                    // By default after the message handler returns, the processor will complete the message
                    // If I want more fine-grained control over settlement, I can set this to false.
                    AutoCompleteMessages = false,

                    // I can also allow for processing multiple sessions
                    MaxConcurrentSessions = 5,

                    // By default, there will be a single concurrent call per session. I can
                    // increase that here to enable parallel processing within each session.
                    MaxConcurrentCallsPerSession = 2
                };

                // create a session processor that we can use to process the messages
                ServiceBusSessionProcessor processor = client.CreateSessionProcessor(queueName, options);

                // since the message handler will run in a background thread, in order to prevent
                // this sample from terminating immediately, we can use a task completion source that
                // we complete from within the message handler.
                TaskCompletionSource <bool> tcs = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously);
                int processedMessageCount       = 0;
                processor.ProcessMessageAsync += MessageHandler;
                processor.ProcessErrorAsync   += ErrorHandler;

                async Task MessageHandler(ProcessSessionMessageEventArgs args)
                {
                    var body = args.Message.Body.ToString();

                    // we can evaluate application logic and use that to determine how to settle the message.
                    await args.CompleteMessageAsync(args.Message);

                    // we can also set arbitrary session state using this receiver
                    // the state is specific to the session, and not any particular message
                    await args.SetSessionStateAsync(new BinaryData("some state"));

                    // Once we've received the last message, complete the
                    // task completion source.
                    if (Interlocked.Increment(ref processedMessageCount) == 2)
                    {
                        tcs.SetResult(true);
                    }
                }

                Task ErrorHandler(ProcessErrorEventArgs args)
                {
                    // the error source tells me at what point in the processing an error occurred
                    Console.WriteLine(args.ErrorSource);
                    // the fully qualified namespace is available
                    Console.WriteLine(args.FullyQualifiedNamespace);
                    // as well as the entity path
                    Console.WriteLine(args.EntityPath);
                    Console.WriteLine(args.Exception.ToString());
                    return(Task.CompletedTask);
                }

                await processor.StartProcessingAsync();

                // await our task completion source task so that the message handler will be invoked at least once.
                await tcs.Task;

                // stop processing once the task completion source was completed.
                await processor.StopProcessingAsync();

                #endregion
            }
        }
示例#12
0
        public async Task ProcessSessionMessages()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: true))
            {
                #region Snippet:ServiceBusProcessSessionMessages
#if SNIPPET
                string connectionString = "<connection_string>";
                string queueName        = "<queue_name>";
                // since ServiceBusClient implements IAsyncDisposable we create it with "await using"
                await using var client = new ServiceBusClient(connectionString);
#else
                string connectionString = TestEnvironment.ServiceBusConnectionString;
                string queueName        = scope.QueueName;
                await using var client = CreateClient();
#endif

                // create the sender
                ServiceBusSender sender = client.CreateSender(queueName);

                // create a message batch that we can send
                ServiceBusMessageBatch messageBatch = await sender.CreateMessageBatchAsync();

                messageBatch.TryAddMessage(
                    new ServiceBusMessage("First")
                {
                    SessionId = "Session1"
                });
                messageBatch.TryAddMessage(
                    new ServiceBusMessage("Second")
                {
                    SessionId = "Session2"
                });

                // send the message batch
                await sender.SendMessagesAsync(messageBatch);

                #region Snippet:ServiceBusConfigureSessionProcessor
                // create the options to use for configuring the processor
                var options = new ServiceBusSessionProcessorOptions
                {
                    // By default after the message handler returns, the processor will complete the message
                    // If I want more fine-grained control over settlement, I can set this to false.
                    AutoCompleteMessages = false,

                    // I can also allow for processing multiple sessions
                    MaxConcurrentSessions = 5,

                    // By default or when AutoCompleteMessages is set to true, the processor will complete the message after executing the message handler
                    // Set AutoCompleteMessages to false to [settle messages](https://docs.microsoft.com/en-us/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock) on your own.
                    // In both cases, if the message handler throws an exception without settling the message, the processor will abandon the message.
                    MaxConcurrentCallsPerSession = 2,

                    // Processing can be optionally limited to a subset of session Ids.
                    SessionIds = { "my-session", "your-session" },
                };

                // create a session processor that we can use to process the messages
                await using ServiceBusSessionProcessor processor = client.CreateSessionProcessor(queueName, options);

                // configure the message and error handler to use
                processor.ProcessMessageAsync += MessageHandler;
                processor.ProcessErrorAsync   += ErrorHandler;

                async Task MessageHandler(ProcessSessionMessageEventArgs args)
                {
                    var body = args.Message.Body.ToString();

                    // we can evaluate application logic and use that to determine how to settle the message.
                    await args.CompleteMessageAsync(args.Message);

                    // we can also set arbitrary session state using this receiver
                    // the state is specific to the session, and not any particular message
                    await args.SetSessionStateAsync(new BinaryData("some state"));
                }

                Task ErrorHandler(ProcessErrorEventArgs args)
                {
                    // the error source tells me at what point in the processing an error occurred
                    Console.WriteLine(args.ErrorSource);
                    // the fully qualified namespace is available
                    Console.WriteLine(args.FullyQualifiedNamespace);
                    // as well as the entity path
                    Console.WriteLine(args.EntityPath);
                    Console.WriteLine(args.Exception.ToString());
                    return(Task.CompletedTask);
                }

                // start processing
                await processor.StartProcessingAsync();

                // since the processing happens in the background, we add a Conole.ReadKey to allow the processing to continue until a key is pressed.
                Console.ReadKey();
                #endregion
                #endregion
            }
        }
示例#13
0
 internal PluginSessionProcessor(string topicName, string subscriptionName, ServiceBusClient client, IEnumerable <Func <ServiceBusReceivedMessage, Task> > plugins, ServiceBusSessionProcessorOptions options) :
     base(client, topicName, subscriptionName, options)
 {
     _plugins = plugins;
 }