public void Constructor_DefaultsValues()
        {
            var options = new QueuesOptions
            {
                BatchSize          = 32,
                MaxDequeueCount    = 2,
                NewBatchThreshold  = 100,
                VisibilityTimeout  = TimeSpan.FromSeconds(30),
                MaxPollingInterval = TimeSpan.FromSeconds(15)
            };
            QueueProcessorFactoryContext context = new QueueProcessorFactoryContext(_queue, null, options);
            QueueProcessor localProcessor        = new QueueProcessor(context);

            Assert.Equal(options.BatchSize, localProcessor.BatchSize);
            Assert.Equal(options.MaxDequeueCount, localProcessor.MaxDequeueCount);
            Assert.Equal(options.NewBatchThreshold, localProcessor.NewBatchThreshold);
            Assert.Equal(options.VisibilityTimeout, localProcessor.VisibilityTimeout);
            Assert.Equal(options.MaxPollingInterval, localProcessor.MaxPollingInterval);
        }
Exemple #2
0
            public QueueProcessor Create(QueueProcessorFactoryContext context)
            {
                // demonstrates how the Queue.ServiceClient options can be configured
                context.Queue.ServiceClient.DefaultRequestOptions.ServerTimeout = TimeSpan.FromSeconds(30);

                // demonstrates how queue options can be customized
                context.Queue.EncodeMessage = true;

                // demonstrates how batch processing behavior and other knobs
                // can be customized
                context.BatchSize          = 30;
                context.NewBatchThreshold  = 100;
                context.MaxPollingInterval = TimeSpan.FromSeconds(15);

                CustomQueueProcessor processor = new CustomQueueProcessor(context);

                CustomQueueProcessors.Add(processor);
                return(processor);
            }
Exemple #3
0
        public void Constructor_DefaultsValues()
        {
            var config = new JobHostQueuesConfiguration
            {
                BatchSize          = 32,
                MaxDequeueCount    = 2,
                NewBatchThreshold  = 100,
                VisibilityTimeout  = TimeSpan.FromSeconds(30),
                MaxPollingInterval = TimeSpan.FromSeconds(15)
            };
            QueueProcessorFactoryContext context = new QueueProcessorFactoryContext(_queue, _trace, config);
            QueueProcessor localProcessor        = new QueueProcessor(context);

            Assert.Equal(config.BatchSize, localProcessor.BatchSize);
            Assert.Equal(config.MaxDequeueCount, localProcessor.MaxDequeueCount);
            Assert.Equal(config.NewBatchThreshold, localProcessor.NewBatchThreshold);
            Assert.Equal(config.VisibilityTimeout, localProcessor.VisibilityTimeout);
            Assert.Equal(config.MaxPollingInterval, localProcessor.MaxPollingInterval);
        }
        public void Constructor_DefaultsValues()
        {
            CloudQueue     queue         = new CloudQueue(new Uri("https://test.queue.core.windows.net/testqueue"));
            CloudQueue     poisonQueue   = new CloudQueue(new Uri("https://test.queue.core.windows.net/poisonqueue"));
            ILoggerFactory loggerFactory = new LoggerFactory();

            loggerFactory.AddProvider(new TestLoggerProvider());
            JobHostQueuesConfiguration queuesConfig = new JobHostQueuesConfiguration();

            QueueProcessorFactoryContext context = new QueueProcessorFactoryContext(queue, loggerFactory, queuesConfig, poisonQueue);

            Assert.Same(queue, context.Queue);
            Assert.Same(poisonQueue, context.PoisonQueue);
            Assert.NotNull(context.Logger);

            Assert.Equal(queuesConfig.BatchSize, context.BatchSize);
            Assert.Equal(queuesConfig.NewBatchThreshold, context.NewBatchThreshold);
            Assert.Equal(queuesConfig.MaxDequeueCount, context.MaxDequeueCount);
            Assert.Equal(queuesConfig.MaxPollingInterval, context.MaxPollingInterval);
        }
Exemple #5
0
        public void Constructor_DefaultsValues()
        {
            QueueClient    queue         = new QueueClient(new Uri("https://test.queue.core.windows.net/testqueue"));
            QueueClient    poisonQueue   = new QueueClient(new Uri("https://test.queue.core.windows.net/poisonqueue"));
            ILoggerFactory loggerFactory = new LoggerFactory();

            loggerFactory.AddProvider(new TestLoggerProvider());
            QueuesOptions queuesOptions = new QueuesOptions();

            QueueProcessorFactoryContext context = new QueueProcessorFactoryContext(queue, loggerFactory, queuesOptions, poisonQueue);

            Assert.AreSame(queue, context.Queue);
            Assert.AreSame(poisonQueue, context.PoisonQueue);
            Assert.NotNull(context.Logger);

            Assert.AreEqual(queuesOptions.BatchSize, context.BatchSize);
            Assert.AreEqual(queuesOptions.NewBatchThreshold, context.NewBatchThreshold);
            Assert.AreEqual(queuesOptions.MaxDequeueCount, context.MaxDequeueCount);
            Assert.AreEqual(queuesOptions.MaxPollingInterval, context.MaxPollingInterval);
        }
        public QueueProcessor Create(QueueProcessorFactoryContext context)
        {
            // demonstrates how the Queue.ServiceClient options can be configured
            context.Queue.ServiceClient.DefaultRequestOptions.ServerTimeout = TimeSpan.FromSeconds(30);

            // demonstrates how queue options can be customized
            context.Queue.EncodeMessage = true;

            if (context.Queue.Name == "initialorder")
            {
                // demonstrates how batch processing behavior can be customized
                // per queue (as opposed to the global settings that apply to ALL queues)
                context.BatchSize         = 30;
                context.NewBatchThreshold = 100;

                return(new CustomQueueProcessor(context));
            }

            // return the default processor
            return(new QueueProcessor(context));
        }
        public async Task BeginProcessingMessageAsync_MaxDequeueCountExceeded_MovesMessageToPoisonQueue()
        {
            QueueProcessorFactoryContext context = new QueueProcessorFactoryContext(_queue, null, _queuesOptions, _poisonQueue);
            QueueProcessor localProcessor        = new QueueProcessor(context);

            bool poisonMessageHandlerCalled = false;

            localProcessor.MessageAddedToPoisonQueue += (sender, e) =>
            {
                Assert.Same(sender, localProcessor);
                Assert.Same(_poisonQueue, e.PoisonQueue);
                Assert.NotNull(e.Message);
                poisonMessageHandlerCalled = true;
            };

            string            messageContent = Guid.NewGuid().ToString();
            CloudQueueMessage message        = new CloudQueueMessage(messageContent);
            await _queue.AddMessageAsync(message, CancellationToken.None);

            CloudQueueMessage messageFromCloud = await _queue.GetMessageAsync();

            for (int i = 0; i < context.MaxDequeueCount; i++)
            {
                await _queue.UpdateMessageAsync(messageFromCloud, TimeSpan.FromMilliseconds(0), MessageUpdateFields.Visibility, CancellationToken.None);

                messageFromCloud = await _queue.GetMessageAsync();
            }

            Assert.Equal(6, messageFromCloud.DequeueCount);
            bool continueProcessing = await localProcessor.BeginProcessingMessageAsync(messageFromCloud, CancellationToken.None);

            Assert.False(continueProcessing);

            CloudQueueMessage poisonMessage = await _poisonQueue.GetMessageAsync();

            Assert.NotNull(poisonMessage);
            Assert.Equal(messageContent, poisonMessage.AsString);
            Assert.True(poisonMessageHandlerCalled);
        }
Exemple #8
0
        public SharedBlobQueueListener Create()
        {
            BlobQueueTriggerExecutor triggerExecutor = new BlobQueueTriggerExecutor(_blobWrittenWatcher);

            // The poison queue to use for a given poison blob lives in the same
            // storage account as the triggering blob by default. In multi-storage account scenarios
            // that means that we'll be writing to different poison queues, determined by
            // the triggering blob.
            // However we use a poison queue in the host storage account as a fallback default
            // in case a particular blob lives in a restricted "blob only" storage account (i.e. no queues).
            IStorageQueue defaultPoisonQueue = _hostAccount.CreateQueueClient().GetQueueReference(HostQueueNames.BlobTriggerPoisonQueue);

            // this special queue bypasses the QueueProcessorFactory - we don't want people to
            // override this
            QueueProcessorFactoryContext context        = new QueueProcessorFactoryContext(_hostBlobTriggerQueue.SdkObject, _trace, _queueConfiguration, defaultPoisonQueue.SdkObject);
            SharedBlobQueueProcessor     queueProcessor = new SharedBlobQueueProcessor(context, triggerExecutor);

            IListener listener = new QueueListener(_hostBlobTriggerQueue, defaultPoisonQueue, triggerExecutor,
                                                   _exceptionHandler, _trace, _sharedQueueWatcher, _queueConfiguration, queueProcessor);

            return(new SharedBlobQueueListener(listener, triggerExecutor));
        }
        public async Task CompleteProcessingMessageAsync_MaxDequeueCountExceeded_MovesMessageToPoisonQueue()
        {
            QueueProcessorFactoryContext context = new QueueProcessorFactoryContext(_queue, null, _queuesOptions, _poisonQueue);
            QueueProcessor localProcessor        = new QueueProcessor(context);

            bool poisonMessageHandlerCalled = false;

            localProcessor.MessageAddedToPoisonQueue += (sender, e) =>
            {
                Assert.Same(sender, localProcessor);
                Assert.Same(_poisonQueue, e.PoisonQueue);
                Assert.NotNull(e.Message);
                poisonMessageHandlerCalled = true;
            };

            string            messageContent = Guid.NewGuid().ToString();
            CloudQueueMessage message        = new CloudQueueMessage(messageContent);
            await _queue.AddMessageAsync(message, CancellationToken.None);

            FunctionResult result = new FunctionResult(false);

            for (int i = 0; i < context.MaxDequeueCount; i++)
            {
                message = await _queue.GetMessageAsync();

                await localProcessor.CompleteProcessingMessageAsync(message, result, CancellationToken.None);
            }

            message = await _queue.GetMessageAsync();

            Assert.Null(message);

            CloudQueueMessage poisonMessage = await _poisonQueue.GetMessageAsync();

            Assert.NotNull(poisonMessage);
            Assert.Equal(messageContent, poisonMessage.AsString);
            Assert.True(poisonMessageHandlerCalled);
        }
Exemple #10
0
        public async Task BeginProcessingMessageAsync_MaxDequeueCountExceeded_MovesMessageToPoisonQueue()
        {
            QueueProcessorFactoryContext context = new QueueProcessorFactoryContext(_queue, null, _queuesOptions, _poisonQueue);
            QueueProcessor localProcessor        = new QueueProcessor(context);

            bool poisonMessageHandlerCalled = false;

            localProcessor.MessageAddedToPoisonQueue += (sender, e) =>
            {
                Assert.AreSame(sender, localProcessor);
                Assert.AreSame(_poisonQueue, e.PoisonQueue);
                Assert.NotNull(e.Message);
                poisonMessageHandlerCalled = true;
            };

            string messageContent = Guid.NewGuid().ToString();
            await _queue.SendMessageAsync(messageContent);

            QueueMessage messageFromCloud = (await _queue.ReceiveMessagesAsync(1)).Value.FirstOrDefault();

            for (int i = 0; i < context.MaxDequeueCount; i++)
            {
                await _queue.UpdateMessageAsync(messageFromCloud.MessageId, messageFromCloud.PopReceipt, visibilityTimeout : TimeSpan.FromMilliseconds(0));

                messageFromCloud = (await _queue.ReceiveMessagesAsync(1)).Value.FirstOrDefault();
            }

            Assert.AreEqual(6, messageFromCloud.DequeueCount);
            bool continueProcessing = await localProcessor.BeginProcessingMessageAsync(messageFromCloud, CancellationToken.None);

            Assert.False(continueProcessing);

            QueueMessage poisonMessage = (await _poisonQueue.ReceiveMessagesAsync(1)).Value.FirstOrDefault();

            Assert.NotNull(poisonMessage);
            Assert.AreEqual(messageContent, poisonMessage.MessageText);
            Assert.True(poisonMessageHandlerCalled);
        }
        public async Task CompleteProcessingMessageAsync_Failure_AppliesVisibilityTimeout()
        {
            var queuesOptions = new QueuesOptions
            {
                // configure a non-zero visibility timeout
                VisibilityTimeout = TimeSpan.FromMinutes(5)
            };
            QueueProcessorFactoryContext context = new QueueProcessorFactoryContext(_queue, null, queuesOptions, _poisonQueue);
            QueueProcessor localProcessor        = new QueueProcessor(context);

            string            messageContent = Guid.NewGuid().ToString();
            CloudQueueMessage message        = new CloudQueueMessage(messageContent);
            await _queue.AddMessageAsync(message, CancellationToken.None);

            var functionResult = new FunctionResult(false);

            message = await _queue.GetMessageAsync();

            await localProcessor.CompleteProcessingMessageAsync(message, functionResult, CancellationToken.None);

            var delta = message.NextVisibleTime - DateTime.UtcNow;

            Assert.True(delta.Value.TotalMinutes > 4);
        }
        internal static QueueProcessor CreateQueueProcessor(CloudQueue queue, CloudQueue poisonQueue, TraceWriter trace, IQueueConfiguration queueConfig, EventHandler poisonQueueMessageAddedHandler)
        {
            QueueProcessorFactoryContext context = new QueueProcessorFactoryContext(queue, trace, queueConfig, poisonQueue);

            QueueProcessor queueProcessor = null;
            if (HostQueueNames.IsHostQueue(queue.Name) && 
                string.Compare(queue.Uri.Host, "localhost", StringComparison.OrdinalIgnoreCase) != 0)
            {
                // We only delegate to the processor factory for application queues,
                // not our built in control queues
                // We bypass this check for local testing though
                queueProcessor = new QueueProcessor(context);
            }
            else
            {
                queueProcessor = queueConfig.QueueProcessorFactory.Create(context);
            }

            if (poisonQueueMessageAddedHandler != null)
            {
                queueProcessor.MessageAddedToPoisonQueue += poisonQueueMessageAddedHandler;
            }

            return queueProcessor;
        }
 public QueueProcessor Create(QueueProcessorFactoryContext context)
 {
     return(new CustomQueueProcessor(context, Configuration));
 }
Exemple #14
0
 public SharedBlobQueueProcessor(QueueProcessorFactoryContext context, BlobQueueTriggerExecutor executor) : base(context)
 {
     _executor = executor;
 }
 public CustomQueueProcessor(QueueProcessorFactoryContext context, IConfiguration configuration)
     : base(context)
 {
     Configuration = configuration;
 }
 public CustomQueueProcessor(QueueProcessorFactoryContext context) : base(context)
 {
     Context = context;
 }
        public void CreateQueueProcessor_CreatesProcessorCorrectly()
        {
            CloudQueue poisonQueue = null;
            bool       poisonMessageHandlerInvoked = false;
            EventHandler <PoisonMessageEventArgs> poisonMessageEventHandler = (sender, e) => { poisonMessageHandlerInvoked = true; };
            Mock <IQueueProcessorFactory>         mockQueueProcessorFactory = new Mock <IQueueProcessorFactory>(MockBehavior.Strict);
            QueuesOptions queueConfig = new QueuesOptions
            {
                MaxDequeueCount = 7
            };
            QueueProcessor expectedQueueProcessor  = null;
            bool           processorFactoryInvoked = false;

            // create for a host queue - don't expect custom factory to be invoked
            CloudQueue     queue          = new CloudQueue(new Uri(string.Format("https://test.queue.core.windows.net/{0}", HostQueueNames.GetHostQueueName("12345"))));
            QueueProcessor queueProcessor = QueueListener.CreateQueueProcessor(queue, poisonQueue, _loggerFactory, mockQueueProcessorFactory.Object, queueConfig, poisonMessageEventHandler);

            Assert.False(processorFactoryInvoked);
            Assert.NotSame(expectedQueueProcessor, queueProcessor);
            queueProcessor.OnMessageAddedToPoisonQueue(new PoisonMessageEventArgs(null, poisonQueue));
            Assert.True(poisonMessageHandlerInvoked);

            QueueProcessorFactoryContext processorFactoryContext = null;

            mockQueueProcessorFactory.Setup(p => p.Create(It.IsAny <QueueProcessorFactoryContext>()))
            .Callback <QueueProcessorFactoryContext>((mockProcessorContext) =>
            {
                processorFactoryInvoked = true;

                Assert.Same(queue, mockProcessorContext.Queue);
                Assert.Same(poisonQueue, mockProcessorContext.PoisonQueue);
                Assert.Equal(queueConfig.MaxDequeueCount, mockProcessorContext.MaxDequeueCount);
                Assert.NotNull(mockProcessorContext.Logger);

                processorFactoryContext = mockProcessorContext;
            })
            .Returns(() =>
            {
                expectedQueueProcessor = new QueueProcessor(processorFactoryContext);
                return(expectedQueueProcessor);
            });

            // when storage host is "localhost" we invoke the processor factory even for
            // host queues (this enables local test mocking)
            processorFactoryInvoked = false;
            queue          = new CloudQueue(new Uri(string.Format("https://localhost/{0}", HostQueueNames.GetHostQueueName("12345"))));
            queueProcessor = QueueListener.CreateQueueProcessor(queue, poisonQueue, _loggerFactory, mockQueueProcessorFactory.Object, queueConfig, poisonMessageEventHandler);
            Assert.True(processorFactoryInvoked);
            Assert.Same(expectedQueueProcessor, queueProcessor);

            // create for application queue - expect processor factory to be invoked
            poisonMessageHandlerInvoked = false;
            processorFactoryInvoked     = false;
            queue          = new CloudQueue(new Uri("https://test.queue.core.windows.net/testqueue"));
            queueProcessor = QueueListener.CreateQueueProcessor(queue, poisonQueue, _loggerFactory, mockQueueProcessorFactory.Object, queueConfig, poisonMessageEventHandler);
            Assert.True(processorFactoryInvoked);
            Assert.Same(expectedQueueProcessor, queueProcessor);
            queueProcessor.OnMessageAddedToPoisonQueue(new PoisonMessageEventArgs(null, poisonQueue));
            Assert.True(poisonMessageHandlerInvoked);

            // if poison message watcher not specified, event not subscribed to
            poisonMessageHandlerInvoked = false;
            processorFactoryInvoked     = false;
            queueProcessor = QueueListener.CreateQueueProcessor(queue, poisonQueue, _loggerFactory, mockQueueProcessorFactory.Object, queueConfig, null);
            Assert.True(processorFactoryInvoked);
            Assert.Same(expectedQueueProcessor, queueProcessor);
            queueProcessor.OnMessageAddedToPoisonQueue(new PoisonMessageEventArgs(null, poisonQueue));
            Assert.False(poisonMessageHandlerInvoked);
        }
Exemple #18
0
 public override QueueProcessor Create(QueueProcessorFactoryContext context)
 {
     return(new FakeQueueProcessor(context, _storageAccount));
 }
Exemple #19
0
 public CustomQueueProcessor(QueueProcessorFactoryContext context)
     : base(context)
 {
     MaxDequeueCount = 12;
 }
 public QueueProcessor Create(QueueProcessorFactoryContext context)
 {
     context = new QueueProcessorFactoryContext(_queue, _loggerFactory, _options, _poisonQueue);
     return(new SharedBlobQueueProcessor(context, _triggerExecutor));
 }
 public TestQueueProcessor(QueueProcessorFactoryContext context)
     : base(context)
 {
 }
 public QueueProcessor Create(QueueProcessorFactoryContext context)
 {
     return(new TestQueueProcessor(context));
 }