Exemple #1
0
        void DoWork(IReceiveMessages messageQueue)
        {
            try
            {
                using (var tx = new TransactionScope())
                {
                    var ctx = new AmbientTransactionContext();
                    var receivedTransportMessage = messageQueue.ReceiveMessage(ctx);

                    if (receivedTransportMessage == null) return;

                    try
                    {
                        SendMessage(receivedTransportMessage);

                        tx.Complete();
                    }
                    catch (Exception e)
                    {
                        log.Error(e, "Could not send message {0} to destination URI {1} - waiting 1 sec before retrying",
                                  receivedTransportMessage.Id, destinationUri);

                        Thread.Sleep(TimeSpan.FromSeconds(1));
                    }
                }
            }
            catch (Exception e)
            {
                log.Error("Unhandled exception during receive operation", e);
            }
        }
 public void CleanupIsPerformedEvenIfTransactionIsNotCommitted()
 {
     int cleanupCalled = 0;
     var tx = new TransactionScope();
     var ctx = new AmbientTransactionContext();
     ctx.Cleanup += () => { cleanupCalled++; };
     
     tx.Dispose();
     cleanupCalled.ShouldBe(1);
 }
        public void CleanupIsPerformedOnDispose()
        {
            bool cleanupCalled = false;
            var tx = new TransactionScope();
            var ctx = new AmbientTransactionContext();
            ctx.Cleanup += () => { cleanupCalled = true; };
            tx.Dispose();

            cleanupCalled.ShouldBe(true);
        }
        public void CleanupIsPerformedOnce()
        {
            int cleanupCalled = 0;
            var tx = new TransactionScope();
            var ctx = new AmbientTransactionContext();
            ctx.Cleanup += () => { cleanupCalled++; };

            tx.Complete();
            cleanupCalled.ShouldBe(0);
            tx.Dispose();
            cleanupCalled.ShouldBe(1);
        }
        public void DoesNotLeakConnectionsForEachMessage()
        {
            // Low timeout + pool size will quickly show the issue.
            var cs = ConnectionString + ";Connect Timeout = 5;Max Pool Size=10";
            var transport = new SqlServerMessageQueue(cs, TableName, InputQueueName);
            transport.EnsureTableIsCreated();
            transport.PurgeInputQueue();

            for (int i = 0; i < 100; i++)
            {
                using (var tx = new TransactionScope())
                {
                    var ctx = new AmbientTransactionContext();
                    transport.Send(InputQueueName, new TransportMessageToSend() { Body = new byte[0], Headers = new Dictionary<string, object>(), Label = "test" }, ctx);
                    tx.Complete();
                }
            }
        }
Exemple #6
0
        static void Run(Parameters parameters)
        {
            if (string.IsNullOrWhiteSpace(parameters.ErrorQueueName))
            {
                throw new NiceException("Please specify the name of an error queue");
            }

            using (var tx = new TransactionScope())
            {
                var transactionContext = new AmbientTransactionContext();

                if (!AzureServiceBusErrorQueueExists(parameters))
                {
                    throw new NiceException("The Azure Service Bus queue '{0}' does not exist!", parameters.ErrorQueueName);
                }

                var azureServiceBusMessageQueue = new AzureServiceBusMessageQueue(parameters.ConnectionString, parameters.ErrorQueueName);
                var allTheMessages = GetAllTheMessages(azureServiceBusMessageQueue, transactionContext);

                foreach (var message in allTheMessages)
                {
                    var transportMessageToSend = message.ToForwardableMessage();

                    try
                    {
                        if (!transportMessageToSend.Headers.ContainsKey(Headers.SourceQueue))
                        {
                            throw new NiceException(
                                "Message {0} does not have a source queue header - it will be moved back to the input queue",
                                message.Id);
                        }

                        var sourceQueue = (string)transportMessageToSend.Headers[Headers.SourceQueue];

                        if (parameters.AutoMoveAllMessages.GetValueOrDefault())
                        {
                            azureServiceBusMessageQueue.Send(sourceQueue, transportMessageToSend, transactionContext);

                            Print("Moved {0} to {1}", message.Id, sourceQueue);
                        }
                        else
                        {
                            var answer = PromptChar(new[] { 'y', 'n' }, "Would you like to move {0} to {1}? (y/n)",
                                                    message.Id, sourceQueue);

                            if (answer == 'y')
                            {
                                azureServiceBusMessageQueue.Send(sourceQueue, transportMessageToSend, transactionContext);

                                Print("Moved {0} to {1}", message.Id, sourceQueue);
                            }
                            else
                            {
                                azureServiceBusMessageQueue.Send(azureServiceBusMessageQueue.InputQueueAddress,
                                    transportMessageToSend,
                                    transactionContext);

                                Print("Moved {0} to {1}", message.Id, azureServiceBusMessageQueue.InputQueueAddress);
                            }
                        }
                    }
                    catch (NiceException e)
                    {
                        Print(e.Message);

                        azureServiceBusMessageQueue.Send(azureServiceBusMessageQueue.InputQueueAddress,
                            transportMessageToSend,
                            transactionContext);
                    }
                }

                if (parameters.DryRun.GetValueOrDefault())
                {
                    Print("Aborting queue transaction");
                    return;
                }
                
                if (!parameters.Interactive)
                {
                    tx.Complete();
                    return;
                }

                var commitAnswer = PromptChar(new[] {'y', 'n'}, "Would you like to commit the queue transaction?");

                if (commitAnswer == 'y')
                {
                    Print("Committing queue transaction");

                    tx.Complete();
                    return;
                }

                Print("Queue transaction aborted");
            }
        }
        public void CanSendMessagesDirectlyToExchangeWithRoutingKey(int mode)
        {
            // arrange
            var routeUsingExchanges = mode > 1;
            var exchangeAsAddress = mode > 2;
            var sender = GetQueue("test.sender", removeExiting: true, oneExchangePerType: routeUsingExchanges,
                inputExchange: exchangeAsAddress ? "ex-test.sender" : null);
            var recipient = GetQueue("test.recipient", removeExiting: true);

            using (var cm = new ConnectionManager(ConnectionString, "test.sender"))
            using (var conn = cm.GetConnection())
            using (var model = conn.CreateModel())
            {
                model.QueueBind("test.recipient", "ex-test.recipient", "sample");
            }

            // act
            using (var tx = new TransactionScope())
            {
                var ctx = new AmbientTransactionContext();
                var msg = new TransportMessageToSend { Body = Encoding.GetBytes("this is a message!") };

                sender.Send("*****@*****.**", msg, ctx);
                sender.Send("*****@*****.**", msg, ctx);
                sender.Send("*****@*****.**", msg, ctx);

                tx.Complete();
            }

            // assert
            var receivedTransportMessages = GetAllMessages(recipient);

            receivedTransportMessages.Count.ShouldBe(3);
        }
        public void CanSendMessagesDirectlyToExchange(int mode)
        {
            // arrange
            var routeUsingExchanges = mode > 1;
            var exchangeAsAddress = mode > 2;
            var sender = GetQueue("test.sender", removeExiting: true, oneExchangePerType: routeUsingExchanges,
                inputExchange: exchangeAsAddress ? "ex-test.sender" : null);
            var recipient = GetQueue("test.recipient", removeExiting: true, oneExchangePerType: true, inputExchange: "ex-test.recipient");

            // act
            using (var tx = new TransactionScope())
            {
                var ctx = new AmbientTransactionContext();
                var msg = new TransportMessageToSend { Body = Encoding.GetBytes("this is a message!") };

                sender.Send("@ex-test.recipient", msg, ctx);
                sender.Send("@ex-test.recipient", msg, ctx);
                sender.Send("@ex-test.recipient", msg, ctx);

                tx.Complete();
            }

            // assert
            var receivedTransportMessages = GetAllMessages(recipient);

            receivedTransportMessages.Count.ShouldBe(3);
        }
        public void CanSendMessagesInTransactionToMultipleQueues(bool commitTransactionAndExpectMessagesToBeThere)
        {
            // arrange
            var sender = GetQueue("test.tx.sender");
            var firstRecipient = GetQueue("test.tx.recipient1");
            var secondRecipient = GetQueue("test.tx.recipient2");

            // act
            using (var tx = new TransactionScope())
            {
                var ctx = new AmbientTransactionContext();
                var msg = new TransportMessageToSend { Body = Encoding.GetBytes("this is a message!") };

                sender.Send(firstRecipient.InputQueue, msg, ctx);
                sender.Send(firstRecipient.InputQueue, msg, ctx);
                sender.Send(firstRecipient.InputQueue, msg, ctx);

                sender.Send(secondRecipient.InputQueue, msg, ctx);
                sender.Send(secondRecipient.InputQueue, msg, ctx);
                sender.Send(secondRecipient.InputQueue, msg, ctx);

                if (commitTransactionAndExpectMessagesToBeThere) tx.Complete();
            }

            // assert
            var receivedTransportMessagesFromFirstRecipient = GetAllMessages(firstRecipient);
            var receivedTransportMessagesFromSecondRecipient = GetAllMessages(secondRecipient);

            receivedTransportMessagesFromFirstRecipient.Count.ShouldBe(commitTransactionAndExpectMessagesToBeThere ? 3 : 0);
            receivedTransportMessagesFromSecondRecipient.Count.ShouldBe(commitTransactionAndExpectMessagesToBeThere ? 3 : 0);
        }
        public void CanSendAndReceiveMessages(int count, int consumers)
        {
            const string senderInputQueue = "test.rabbit.sender";
            const string receiverInputQueue = "test.rabbit.receiver";

            var sender = GetQueue(senderInputQueue);
            var receiver = GetQueue(receiverInputQueue);

            var totalMessageCount = count * consumers;

            var stopwatch = Stopwatch.StartNew();

            Console.WriteLine("Sending {0} messages", totalMessageCount);
            Enumerable.Range(0, totalMessageCount).ToList()
                .ForEach(
                    i => sender.Send(receiverInputQueue,
                                new TransportMessageToSend { Body = Encoding.UTF7.GetBytes("w00t! message " + i) },
                                new NoTransaction()));

            var totalSeconds = stopwatch.Elapsed.TotalSeconds;

            Console.WriteLine("Sending {0} messages took {1:0.0} s - that's {2:0} msg/s", totalMessageCount, totalSeconds, totalMessageCount / totalSeconds);

            Thread.Sleep(1.Seconds());

            Console.WriteLine("Receiving {0} messages", totalMessageCount);
            long receivedMessageCount = 0;

            stopwatch = Stopwatch.StartNew();

            var threads = Enumerable.Range(0, consumers)
                .Select(i => new Thread(_ =>
                    {
                        var gotNoMessageCount = 0;
                        do
                        {
                            using (var scope = new TransactionScope())
                            {
                                var ctx = new AmbientTransactionContext();
                                var receivedTransportMessage = receiver.ReceiveMessage(ctx);
                                if (receivedTransportMessage == null)
                                {
                                    gotNoMessageCount++;
                                    continue;
                                }
                                Encoding.UTF7.GetString(receivedTransportMessage.Body).ShouldStartWith("w00t! message ");
                                Interlocked.Increment(ref receivedMessageCount);

                                scope.Complete();
                            }
                        } while (gotNoMessageCount < 3);
                    }))
                .ToList();

            threads.ForEach(t => t.Start());
            threads.ForEach(t => t.Join());

            totalSeconds = stopwatch.Elapsed.TotalSeconds;

            Console.WriteLine("Receiving {0} messages spread across {1} consumers took {2:0.0} s - that's {3:0} msg/s",
                              totalMessageCount, consumers, totalSeconds, totalMessageCount / totalSeconds);

            receivedMessageCount.ShouldBe(totalMessageCount);
        }
            void DoWork()
            {
                while (keepWorking)
                {
                    try
                    {
                        using (var tx = new TransactionScope())
                        {
                            var transactionContext = new AmbientTransactionContext();
                            var message = queue.ReceiveMessage(transactionContext);
                            if (message == null)
                            {
                                Thread.Sleep(200);
                                continue;
                            }

                            var destinationForThisMessage = getNextDestination();

                            log.Debug("Received message {0} will be forwarded to {1}", message.Id, destinationForThisMessage);

                            queue.Send(destinationForThisMessage, message.ToForwardableMessage(), transactionContext);

                            tx.Complete();
                        }
                    }
                    catch (Exception exception)
                    {
                        log.Error("An error occurred while trying to process a message: {0}", exception);
                    }
                }
            }
        public void MultipleSendOperationsToMultipleQueuesAreEnlistedInTheSameTransaction(bool commitTransactionAndExpectMessagesToBeThere)
        {
            // arrange
            const string queueName1 = "test.tx.queue1";
            const string queueName2 = "test.tx.queue2";

            var recipient1 = NewRawMsmqQueue(queueName1);
            var recipient2 = NewRawMsmqQueue(queueName2);

            disposables.Add(recipient1);
            disposables.Add(recipient2);

            var encoding = Encoding.UTF8;

            using (var tx = new TransactionScope())
            {
                var ctx = new AmbientTransactionContext();

                // act
                senderQueue.Send(queueName1, new TransportMessageToSend { Body = encoding.GetBytes("yo dawg 1!") }, ctx);
                senderQueue.Send(queueName1, new TransportMessageToSend { Body = encoding.GetBytes("yo dawg 2!") }, ctx);
                senderQueue.Send(queueName2, new TransportMessageToSend { Body = encoding.GetBytes("yo dawg 3!") }, ctx);
                senderQueue.Send(queueName2, new TransportMessageToSend { Body = encoding.GetBytes("yo dawg 4!") }, ctx);

                if (commitTransactionAndExpectMessagesToBeThere) tx.Complete();
            }

            // assert
            var allMessages = GetAllMessages(recipient1).Concat(GetAllMessages(recipient2)).ToList();

            if (commitTransactionAndExpectMessagesToBeThere)
            {
                allMessages.Count.ShouldBe(4);

                var receivedMessages = allMessages.Select(m => encoding.GetString(m.Body)).ToList();
                receivedMessages.ShouldContain("yo dawg 1!");
                receivedMessages.ShouldContain("yo dawg 2!");
                receivedMessages.ShouldContain("yo dawg 3!");
                receivedMessages.ShouldContain("yo dawg 4!");
            }
            else
            {
                allMessages.Count.ShouldBe(0);
            }
        }
        public void MessageIsSentWhenAmbientTransactionIsCommitted()
        {
            using (var tx = new TransactionScope())
            {
                var ctx = new AmbientTransactionContext();
                senderQueue.Send(destinationQueueName,
                                 serializer.Serialize(new Message
                                     {
                                         Messages = new object[]
                                             {
                                                 "W00t!"
                                             },
                                     }),
                                 ctx);

                tx.Complete();
            }

            var msmqMessage = Receive();

            Assert.IsNotNull(msmqMessage, "No message was received within timeout!");
            var transportMessage = (ReceivedTransportMessage)msmqMessage.Body;
            var message = serializer.Deserialize(transportMessage);
            message.Messages[0].ShouldBe("W00t!");
        }
        public void MessageIsNotSentWhenAmbientTransactionIsNotCommitted()
        {
            using (new TransactionScope())
            {
                var ctx = new AmbientTransactionContext();
                senderQueue.Send(destinationQueueName,
                                 serializer.Serialize(new Message
                                     {
                                         Messages = new object[]
                                             {
                                                 "W00t! should not be delivered!"
                                             }
                                     }),
                                 ctx);

                //< we exit the scope without completing it!
            }

            var transportMessage = Receive();

            if (transportMessage != null)
            {
                Assert.Fail("No messages should have been received! ARGGH: {0}", transportMessage.Body);
            }
        }