コード例 #1
0
            public static HSMessageWrapper FromCloudQueueMessage(CloudQueueMessage msg, CloudQueue originQ)
            {
                if (msg == null)
                {
                    return(null);
                }

                HSMessageWrapper result = new HSMessageWrapper(msg.AsBytes);

                FieldInfo[] fields_of_class =
                    msg.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);

                foreach (FieldInfo fi in fields_of_class)
                {
                    fi.SetValue(result, fi.GetValue(msg));
                }


                result._origin = originQ;

                return(result);
            }
コード例 #2
0
        public void Poison_message_is_rejected()
        {
            // Arrange
            var onMessageInvokeCount    = 0;
            var onQueueEmptyInvokeCount = 0;
            var onErrorInvokeCount      = 0;

            var isRejected   = false;
            var retries      = 3;
            var lockObject   = new Object();
            var cloudMessage = new CloudQueueMessage("Message");

            var queueName          = "myqueue";
            var mockQueue          = GetMockQueue(queueName);
            var mockQueueClient    = GetMockQueueClient(mockQueue);
            var mockBlobContainer  = GetMockBlobContainer();
            var mockBlobClient     = GetMockBlobClient(mockBlobContainer);
            var mockStorageAccount = GetMockStorageAccount(mockBlobClient, mockQueueClient);

            mockQueue.Setup(q => q.GetMessagesAsync(It.IsAny <int>(), It.IsAny <TimeSpan?>(), It.IsAny <QueueRequestOptions>(), It.IsAny <OperationContext>(), It.IsAny <CancellationToken>())).ReturnsAsync((int messageCount, TimeSpan? visibilityTimeout, QueueRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) =>
            {
                if (cloudMessage != null)
                {
                    lock (lockObject)
                    {
                        if (cloudMessage != null)
                        {
                            // DequeueCount is a private property. Therefore we must use reflection to change its value
                            var dequeueCountProperty = cloudMessage.GetType().GetProperty("DequeueCount");
                            dequeueCountProperty.SetValue(cloudMessage, retries + 1);                               // intentionally set 'DequeueCount' to a value exceeding maxRetries to simulate a poison message

                            return(new[] { cloudMessage });
                        }
                    }
                }
                return(Enumerable.Empty <CloudQueueMessage>());
            });
            mockQueue.Setup(q => q.DeleteMessageAsync(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <QueueRequestOptions>(), It.IsAny <OperationContext>(), It.IsAny <CancellationToken>())).Returns((string messageId, string popReceipt, QueueRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) =>
            {
                lock (lockObject)
                {
                    cloudMessage = null;
                }
                return(Task.FromResult(true));
            });

            var messagePump = new AsyncMessagePump("myqueue", mockStorageAccount.Object, 1, TimeSpan.FromMinutes(1), retries);

            messagePump.OnMessage = (message, cancellationToken) =>
            {
                Interlocked.Increment(ref onMessageInvokeCount);
                throw new Exception("An error occured when attempting to process the message");
            };
            messagePump.OnQueueEmpty = cancellationToken =>
            {
                Interlocked.Increment(ref onQueueEmptyInvokeCount);
                messagePump.Stop();
            };
            messagePump.OnError = (message, exception, isPoison) =>
            {
                Interlocked.Increment(ref onErrorInvokeCount);
                if (isPoison)
                {
                    lock (lockObject)
                    {
                        isRejected   = true;
                        cloudMessage = null;
                    }
                }
            };

            // Act
            messagePump.Start();

            // Assert
            onMessageInvokeCount.ShouldBe(1);
            onQueueEmptyInvokeCount.ShouldBeGreaterThan(0);
            onErrorInvokeCount.ShouldBe(1);
            isRejected.ShouldBeTrue();
            mockQueue.Verify(q => q.GetMessagesAsync(It.IsAny <int>(), It.IsAny <TimeSpan?>(), It.IsAny <QueueRequestOptions>(), It.IsAny <OperationContext>(), It.IsAny <CancellationToken>()), Times.AtLeast(2));
            mockQueue.Verify(q => q.DeleteMessageAsync(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <QueueRequestOptions>(), It.IsAny <OperationContext>(), It.IsAny <CancellationToken>()), Times.Exactly(1));
        }
コード例 #3
0
        public void Poison_message_is_rejected()
        {
            // Arrange
            var onMessageInvokeCount    = 0;
            var onQueueEmptyInvokeCount = 0;
            var onErrorInvokeCount      = 0;

            var isRejected   = false;
            var retries      = 3;
            var lockObject   = new Object();
            var cloudMessage = new CloudQueueMessage("Message");

            var mockStorageUri = new Uri("http://bogus/myaccount");
            var mockQueue      = new Mock <CloudQueue>(MockBehavior.Strict, mockStorageUri);

            mockQueue.Setup(q => q.GetMessageAsync(It.IsAny <TimeSpan?>(), It.IsAny <QueueRequestOptions>(), It.IsAny <OperationContext>(), It.IsAny <CancellationToken>())).Returns((TimeSpan? visibilityTimeout, QueueRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) =>
            {
                if (cloudMessage == null)
                {
                    return(null);
                }

                lock (lockObject)
                {
                    if (cloudMessage != null)
                    {
                        // DequeueCount is a private property. Therefore we must use reflection to change its value
                        var t = cloudMessage.GetType();
                        t.InvokeMember("DequeueCount", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.SetProperty | BindingFlags.Instance, null, cloudMessage, new object[] { cloudMessage.DequeueCount + 1 });
                    }
                    return(Task.FromResult(cloudMessage));
                }
            });
            mockQueue.Setup(q => q.DeleteMessageAsync(It.IsAny <CloudQueueMessage>())).Returns((CloudQueueMessage message) =>
            {
                lock (lockObject)
                {
                    cloudMessage = null;
                }
                return(Task.FromResult(true));
            });

            var messagePump = new AsyncMessagePump(mockQueue.Object, 1, 1, TimeSpan.FromMinutes(1), retries);

            messagePump.OnMessage = (message, cancellationToken) =>
            {
                Interlocked.Increment(ref onMessageInvokeCount);
                throw new Exception("An error occured when attempting to process the message");
            };
            messagePump.OnQueueEmpty = cancellationToken =>
            {
                Interlocked.Increment(ref onQueueEmptyInvokeCount);

                // Run the 'OnStop' on a different thread so we don't block it
                Task.Run(() =>
                {
                    messagePump.Stop();
                }).ConfigureAwait(false);
            };
            messagePump.OnError = (message, exception, isPoison) =>
            {
                Interlocked.Increment(ref onErrorInvokeCount);
                if (isPoison)
                {
                    lock (lockObject)
                    {
                        isRejected   = true;
                        cloudMessage = null;
                    }
                }
            };

            // Act
            messagePump.Start();

            // Assert
            Assert.AreEqual(retries + 1, onMessageInvokeCount);
            Assert.IsTrue(onQueueEmptyInvokeCount > 0);
            Assert.AreEqual(retries + 1, onErrorInvokeCount);
            Assert.IsTrue(isRejected);
            mockQueue.Verify(q => q.GetMessageAsync(It.IsAny <TimeSpan?>(), It.IsAny <QueueRequestOptions>(), It.IsAny <OperationContext>(), It.IsAny <CancellationToken>()), Times.AtLeast(retries));
        }