public void TestRecoverAfterFailOnTransactionBeforePrepareSent()
        {
            // Test initialize - Fills in queue with data to send and clears the DB.
            PurgeDatabase();
            PurgeAndFillQueue();

            INetTxConnectionFactory factory = new NetTxConnectionFactory(ReplaceEnvVar(connectionURI));

            using (INetTxConnection connection = factory.CreateNetTxConnection())
            {
                ITransport         transport = (connection as Connection).ITransport;
                TcpFaultyTransport tcpFaulty = transport.Narrow(typeof(TcpFaultyTransport)) as TcpFaultyTransport;
                Assert.IsNotNull(tcpFaulty);
                tcpFaulty.OnewayCommandPreProcessor += this.FailOnPrepareTransportHook;

                connection.ExceptionListener += this.OnException;
                connection.Start();

                ReadFromQueueAndInsertIntoDbWithCommit(connection);

                Thread.Sleep(2000);
            }

            // Messages are visible since no prepare sent
            VerifyBrokerQueueCountNoRecovery();

            // verify sql server has NOT commited the transaction
            VerifyDatabaseTableIsEmpty();

            // check messages are present in the queue
            VerifyBrokerQueueCount();
        }
        public void TestRecoveryAfterCommitFailsAfterSent()
        {
            // Test initialize - Fills in queue with data to send and clears the DB.
            PurgeDatabase();
            PurgeAndFillQueue();

            using (INetTxConnection connection = dtcFactory.CreateNetTxConnection())
            {
                connection.ExceptionListener += this.OnException;
                connection.Start();

                ITransport         transport = (connection as Connection).ITransport;
                TcpFaultyTransport tcpFaulty = transport.Narrow(typeof(TcpFaultyTransport)) as TcpFaultyTransport;
                Assert.IsNotNull(tcpFaulty);
                tcpFaulty.OnewayCommandPostProcessor += this.FailOnCommitTransportHook;

                ReadFromQueueAndInsertIntoDbWithCommit(connection);

                Thread.Sleep(1000);
            }

            // transaction should have been commited
            VerifyNoMessagesInQueueNoRecovery();

            // verify sql server has commited the transaction
            VerifyDatabaseTableIsFull();

            // check messages are not present in the queue
            VerifyNoMessagesInQueue();
        }
Beispiel #3
0
        public void TestRecoverAfterFailOnTransactionDuringPrepareSend()
        {
            // Test initialize - Fills in DB with data to send.
            PrepareDatabase();

            INetTxConnectionFactory factory = new NetTxConnectionFactory(ReplaceEnvVar(connectionURI));

            using (INetTxConnection connection = factory.CreateNetTxConnection())
            {
                connection.ExceptionListener += this.OnException;
                connection.Start();

                ITransport         transport = (connection as Connection).ITransport;
                TcpFaultyTransport tcpFaulty = transport.Narrow(typeof(TcpFaultyTransport)) as TcpFaultyTransport;
                Assert.IsNotNull(tcpFaulty);
                tcpFaulty.OnewayCommandPostProcessor += this.FailOnPrepareTransportHook;

                ReadFromDbAndProduceToQueueWithCommit(connection);

                Thread.Sleep(2000);
            }

            // verify sql server has commited the transaction
            VerifyDatabaseTableIsFull();

            // check messages are present in the queue
            VerifyNoMessagesInQueue();
        }
        public void TestIterativeTransactedConsume()
        {
            // Test initialize - Fills in queue with data to send and clears the DB.
            PurgeDatabase();
            PurgeAndFillQueue(5 * MSG_COUNT);

            using (INetTxConnection connection = dtcFactory.CreateNetTxConnection())
            {
                connection.ExceptionListener += this.OnException;
                connection.Start();

                ReadFromQueueAndInsertIntoDbWithCommit(connection);
                ReadFromQueueAndInsertIntoDbWithCommit(connection);
                ReadFromQueueAndInsertIntoDbWithCommit(connection);
                ReadFromQueueAndInsertIntoDbWithCommit(connection);
                ReadFromQueueAndInsertIntoDbWithCommit(connection);

                Thread.Sleep(2000);
            }

            // verify sql server has commited the transaction
            VerifyDatabaseTableIsFull(5 * MSG_COUNT);

            // check messages are NOT present in the queue
            VerifyNoMessagesInQueueNoRecovery();
        }
        protected static void VerifyBrokerHasMessagesInQueue(string connectionURI)
        {
            INetTxConnectionFactory factory = new NetTxConnectionFactory(ReplaceEnvVar(connectionURI));

            using (INetTxConnection connection = factory.CreateNetTxConnection())
            {
                // check messages are present in the queue
                using (INetTxSession session = connection.CreateNetTxSession())
                {
                    IDestination queue = session.GetQueue(testQueueName);

                    using (IMessageConsumer consumer = session.CreateConsumer(queue))
                    {
                        connection.Start();

                        for (int i = 0; i < MSG_COUNT; ++i)
                        {
                            IMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(2000));
                            Assert.IsNotNull(msg, "message is not in the queue !");
                        }

                        consumer.Close();
                    }
                }
            }
        }
        public void TestRecoverAfterRollbackFailWhenScopeAborted()
        {
            // Test initialize - Fills in queue with data to send and clears the DB.
            PurgeDatabase();
            PurgeAndFillQueue();

            using (INetTxConnection connection = dtcFactory.CreateNetTxConnection())
            {
                connection.ExceptionListener += this.OnException;
                connection.Start();

                ITransport         transport = (connection as Connection).ITransport;
                TcpFaultyTransport tcpFaulty = transport.Narrow(typeof(TcpFaultyTransport)) as TcpFaultyTransport;
                Assert.IsNotNull(tcpFaulty);
                tcpFaulty.OnewayCommandPreProcessor += this.FailOnRollbackTransportHook;

                ReadFromQueueAndInsertIntoDbWithScopeAborted(connection);

                Thread.Sleep(2000);
            }

            // verify sql server has NOT commited the transaction
            VerifyDatabaseTableIsEmpty();

            // check messages are recovered and present in the queue
            NetTxTransactionContext.ResetDtcRecovery();
            VerifyBrokerQueueCount();
        }
Beispiel #7
0
        public void TestConfigureRecoveryPolicyLoggerUsingDefaultLogger(string location, bool autoCreate)
        {
            string testuri = string.Format("activemq:tcp://${{activemqhost}}:61616" +
                                           "?nms.RecoveryPolicy.RecoveryLogger.Location={0}" +
                                           "&nms.RecoveryPolicy.RecoveryLogger.AutoCreateLocation={1}",
                                           location, autoCreate);

            INetTxConnectionFactory factory = new NetTxConnectionFactory(NMSTestSupport.ReplaceEnvVar(testuri));

            using (INetTxConnection connection = factory.CreateNetTxConnection())
            {
                NetTxConnection netTxConnection = connection as NetTxConnection;

                Assert.IsNotNull(netTxConnection);
                NetTxRecoveryPolicy policy = netTxConnection.RecoveryPolicy;

                Assert.AreEqual("file", policy.RecoveryLoggerType);

                RecoveryFileLogger logger = policy.RecoveryLogger as RecoveryFileLogger;

                Assert.IsNotNull(logger);
                Assert.AreEqual(location, logger.Location);
                Assert.AreEqual(autoCreate, logger.AutoCreateLocation);
            }
        }
Beispiel #8
0
        public void TestRecoverAfterRollbackFailWhenScopeAborted()
        {
            // Test initialize - Fills in DB with data to send.
            PrepareDatabase();

            using (INetTxConnection connection = dtcFactory.CreateNetTxConnection())
            {
                connection.ExceptionListener += this.OnException;
                connection.Start();

                ITransport         transport = (connection as Connection).ITransport;
                TcpFaultyTransport tcpFaulty = transport.Narrow(typeof(TcpFaultyTransport)) as TcpFaultyTransport;
                Assert.IsNotNull(tcpFaulty);
                tcpFaulty.OnewayCommandPreProcessor += this.FailOnRollbackTransportHook;

                ReadFromDbAndProduceToQueueWithScopeAborted(connection);

                Thread.Sleep(2000);
            }

            // verify sql server has commited the transaction
            VerifyDatabaseTableIsFull();

            // before recovering, messages should NOT be present in the queue
            VerifyNoMessagesInQueueNoRecovery();

            // check messages are not present in the queue after recover
            VerifyNoMessagesInQueue();
        }
Beispiel #9
0
        public void TestRecoverAfterFailOnTransactionPostCommitSend()
        {
            // Test initialize - Fills in DB with data to send.
            PrepareDatabase();

            using (INetTxConnection connection = dtcFactory.CreateNetTxConnection())
            {
                connection.ExceptionListener += this.OnException;
                connection.Start();

                ITransport         transport = (connection as Connection).ITransport;
                TcpFaultyTransport tcpFaulty = transport.Narrow(typeof(TcpFaultyTransport)) as TcpFaultyTransport;
                Assert.IsNotNull(tcpFaulty);
                tcpFaulty.OnewayCommandPostProcessor += this.FailOnCommitTransportHook;

                ReadFromDbAndProduceToQueueWithCommit(connection);

                Thread.Sleep(1000);
            }

            // transaction should have been commited
            VerifyBrokerQueueCountNoRecovery();

            // verify sql server has commited the transaction
            VerifyDatabaseTableIsEmpty();

            // check messages are present in the queue
            VerifyBrokerQueueCount();
        }
Beispiel #10
0
        private void Run()
        {
            var connectionFactory = new NetTxConnectionFactory("failover:(tcp://localhost:61616,tcp://localhost:61616)?randomize=false&timeout=5000")
            {
                AcknowledgementMode = AcknowledgementMode.Transactional,
                PrefetchPolicy      = { QueuePrefetch = 1 }
            };

            using (var connection = connectionFactory.CreateNetTxConnection())
            {
                currentconnection = connection;
                connection.Start();
                using (var session = connection.CreateNetTxSession())
                {
                    this.session = session;
                    var eventDestination   = SessionUtil.GetDestination(session, "queue://Consumer.NMS.VirtualTopic.EventMessage");
                    var commandDestination = SessionUtil.GetDestination(session, "queue://subscribernms");
                    using (var eventConsumer = session.CreateConsumer(eventDestination))
                        using (var commandConsumer = session.CreateConsumer(commandDestination))
                        {
                            eventConsumer.Listener   += OnEventMessage;
                            commandConsumer.Listener += this.OnCommandMessage;

                            Console.WriteLine("Consumer started. Press q to quit");
                            while (Console.ReadKey().KeyChar != 'q')
                            {
                            }
                        }
                }
                connection.Stop();
            }
        }
        public void TestRecoverAfterFailOnTransactionAfterPrepareSent()
        {
            // Test initialize - Fills in queue with data to send and clears the DB.
            PurgeDatabase();
            PurgeAndFillQueue();

            using (INetTxConnection connection = dtcFactory.CreateNetTxConnection())
            {
                ITransport         transport = (connection as Connection).ITransport;
                TcpFaultyTransport tcpFaulty = transport.Narrow(typeof(TcpFaultyTransport)) as TcpFaultyTransport;
                Assert.IsNotNull(tcpFaulty);
                tcpFaulty.OnewayCommandPostProcessor += this.FailOnPrepareTransportHook;

                connection.ExceptionListener += this.OnException;
                connection.Start();

                ReadFromQueueAndInsertIntoDbWithCommit(connection);

                Thread.Sleep(2000);
            }

            // not visible yet because it must be rolled back
            VerifyNoMessagesInQueueNoRecovery();

            // verify sql server has NOT commited the transaction
            VerifyDatabaseTableIsEmpty();

            // check messages are present in the queue
            NetTxTransactionContext.ResetDtcRecovery();
            VerifyBrokerQueueCount();
        }
Beispiel #12
0
        public void TestIterativeTransactedProduceWithDBDelete()
        {
            using (INetTxConnection connection = dtcFactory.CreateNetTxConnection())
            {
                connection.ExceptionListener += this.OnException;
                connection.Start();

                PrepareDatabase();
                ReadFromDbAndProduceToQueueWithCommit(connection);

                PrepareDatabase();
                ReadFromDbAndProduceToQueueWithCommit(connection);

                PrepareDatabase();
                ReadFromDbAndProduceToQueueWithCommit(connection);

                PrepareDatabase();
                ReadFromDbAndProduceToQueueWithCommit(connection);

                PrepareDatabase();
                ReadFromDbAndProduceToQueueWithCommit(connection);
            }

            // verify sql server has commited the transaction
            VerifyDatabaseTableIsEmpty();

            // check messages are present in the queue
            VerifyBrokerQueueCount(MSG_COUNT * 5);
        }
Beispiel #13
0
        public void TestNoRecoverAfterFailOnTransactionWhenLogWriteFails()
        {
            // Test initialize - Fills in DB with data to send.
            PrepareDatabase();

            string newConnectionUri =
                connectionUri + "?nms.RecoveryPolicy.RecoveryLoggerType=harness" +
                "&nms.configuredResourceManagerId=" +
                dtcFactory.ConfiguredResourceManagerId;

            dtcFactory = new NetTxConnectionFactory(ReplaceEnvVar(newConnectionUri));

            using (INetTxConnection connection = dtcFactory.CreateNetTxConnection())
            {
                IRecoveryLogger logger = (connection as NetTxConnection).RecoveryPolicy.RecoveryLogger;
                Assert.IsNotNull(logger);
                RecoveryLoggerHarness harness = logger as RecoveryLoggerHarness;
                Assert.IsNotNull(harness);

                harness.PreLogRecoveryInfoEvent += FailOnPreLogRecoveryHook;

                connection.ExceptionListener += this.OnException;
                connection.Start();

                ReadFromDbAndProduceToQueueWithCommit(connection);

                Thread.Sleep(2000);
            }

            // verify sql server has not commited the transaction
            VerifyDatabaseTableIsFull();

            // check messages are not present in the queue
            VerifyNoMessagesInQueue();
        }
Beispiel #14
0
        protected void VerifyBrokerQueueCount(int expectedCount, string connectionUri)
        {
            using (INetTxConnection connection = dtcFactory.CreateNetTxConnection())
            {
                // check messages are present in the queue
                using (INetTxSession session = connection.CreateNetTxSession())
                {
                    IQueue queue = session.GetQueue(testQueueName);

                    using (IQueueBrowser browser = session.CreateBrowser(queue))
                    {
                        connection.Start();
                        int         count      = 0;
                        IEnumerator enumerator = browser.GetEnumerator();

                        while (enumerator.MoveNext())
                        {
                            IMessage msg = enumerator.Current as IMessage;
                            Assert.IsNotNull(msg, "message is not in the queue !");
                            count++;
                        }

                        // count should match the expected count
                        Assert.AreEqual(expectedCount, count);
                    }
                }
            }
        }
        public void TestRedelivered()
        {
            // enqueue several messages
            PurgeDatabase();
            PurgeAndFillQueue();

            // receive just one
            using (INetTxConnection connection = dtcFactory.CreateNetTxConnection())
            {
                connection.Start();

                using (INetTxSession session = connection.CreateNetTxSession())
                {
                    IQueue queue = session.GetQueue(testQueueName);

                    // read message from queue and insert into db table
                    using (IMessageConsumer consumer = session.CreateConsumer(queue))
                    {
                        using (TransactionScope scoped = new TransactionScope(TransactionScopeOption.RequiresNew))
                            using (SqlConnection sqlConnection = new SqlConnection(createDbConnectionString))
                                using (SqlCommand sqlInsertCommand = new SqlCommand())
                                {
                                    sqlConnection.Open();
                                    sqlInsertCommand.Connection = sqlConnection;

                                    ITextMessage message = consumer.Receive(TimeSpan.FromMilliseconds(10000)) as ITextMessage;
                                    sqlInsertCommand.CommandText =
                                        string.Format("INSERT INTO {0} VALUES ({1})", testTable, Convert.ToInt32(message.Text));
                                    sqlInsertCommand.ExecuteNonQuery();

                                    scoped.Complete();
                                }
                    }

                    session.Close();
                }
            }

            // check that others message have status redelivered = false
            IConnectionFactory checkFactory = new ConnectionFactory(ReplaceEnvVar(connectionUri));

            using (IConnection connection = checkFactory.CreateConnection())
            {
                connection.Start();

                using (ISession session = connection.CreateSession())
                    using (IQueueBrowser browser = session.CreateBrowser(session.GetQueue(testQueueName)))
                    {
                        IEnumerator enumerator = browser.GetEnumerator();

                        while (enumerator.MoveNext())
                        {
                            IMessage msg = enumerator.Current as IMessage;
                            Assert.IsNotNull(msg, "message is not in the queue!");
                            Assert.IsFalse(msg.NMSRedelivered, "message is redelivered!");
                        }
                    }
            }
        }
Beispiel #16
0
        public void TestTransactedProduceAndConsume(
            [Values("tcp://${activemqhost}:61616")]
            string baseConnectionURI)
        {
            INetTxConnectionFactory factory = new NetTxConnectionFactory(NMSTestSupport.ReplaceEnvVar(baseConnectionURI));

            using (INetTxConnection connection = factory.CreateNetTxConnection())
            {
                connection.Start();

                using (INetTxSession session = connection.CreateNetTxSession())
                {
                    IDestination destination = session.CreateTemporaryQueue();
                    using (IMessageProducer producer = session.CreateProducer(destination))
                    {
                        using (TransactionScope scoped = new TransactionScope(TransactionScopeOption.RequiresNew, TransactionScopeAsyncFlowOption.Enabled))
                        {
                            Assert.IsNotNull(Transaction.Current);
                            for (int i = 0; i < MSG_COUNT; ++i)
                            {
                                producer.Send(session.CreateTextMessage("Hello World"));
                            }

                            scoped.Complete();
                        }
                    }

                    using (IMessageConsumer consumer = session.CreateConsumer(destination))
                    {
                        Thread.Sleep(100);

                        using (TransactionScope scoped = new TransactionScope(TransactionScopeOption.RequiresNew, TransactionScopeAsyncFlowOption.Enabled))
                        {
                            for (int i = 0; i < MSG_COUNT; ++i)
                            {
                                IMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(2000));
                                Assert.IsNotNull(msg, "Message was null for index: " + i);
                            }
                            scoped.Complete();
                        }
                    }

                    // No more messages should be in the Q, non rolled back or otherwise.
                    using (IMessageConsumer consumer = session.CreateConsumer(destination))
                    {
                        Thread.Sleep(100);
                        IMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(2000));
                        Assert.IsNull(msg, "Message was not null.");
                    }

                    session.Close();
                }

                connection.Close();
            }
        }
Beispiel #17
0
        public void TestSessionCreateFailsWithInvalidLogLocation()
        {
            using (INetTxConnection connection = factory.CreateNetTxConnection())
            {
                connection.ExceptionListener += this.OnException;
                connection.Start();

                NetTxConnection     con    = connection as NetTxConnection;
                NetTxRecoveryPolicy policy = con.RecoveryPolicy;
                (policy.RecoveryLogger as RecoveryFileLogger).Location = nonExistantPath;
                connection.CreateNetTxSession();
            }
        }
Beispiel #18
0
        public void MessageShouldEnlistToTheCorrectTransaction()
        {
            const int messageCount = 100;
            const int receiveCount = 100;

            // enqueue several messages
            PurgeDatabase();
            PurgeAndFillQueue(messageCount);

            var enlistment = new TestSinglePhaseCommit();
            var rand       = new Random();

            using (INetTxConnection connection = dtcFactory.CreateNetTxConnection())
            {
                connection.Start();

                // receive half of total messages
                using (INetTxSession session = connection.CreateNetTxSession())
                {
                    IQueue queue = session.GetQueue(testQueueName);
                    using (IMessageConsumer consumer = session.CreateConsumer(queue))
                    {
                        for (int i = 0; i < receiveCount; i++)
                        {
                            try
                            {
                                using (TransactionScope scoped = new TransactionScope(TransactionScopeOption.RequiresNew, TransactionScopeAsyncFlowOption.Enabled))
                                {
                                    ITextMessage message = consumer.Receive(TimeSpan.FromMilliseconds(10000)) as ITextMessage;

                                    Transaction.Current.EnlistDurable(Guid.NewGuid(), enlistment, EnlistmentOptions.None);
                                    if (rand.Next(2) == 0)
                                    {
                                        Tracer.InfoFormat("Throwing random Exception for Message {0}", message.NMSMessageId);
                                        throw new Exception();
                                    }

                                    scoped.Complete();
                                }
                            }
                            catch
                            {
                            }

                            Assert.False(enlistment.singlePhaseCommit, "No single phase commit should happen.");
                        }
                    }
                }
            }
        }
        public void TestConsumeWithDBInsertLogLocation()
        {
            const string logLocation      = @".\RecoveryDir";
            string       newConnectionUri =
                connectionUri + "?nms.RecoveryPolicy.RecoveryLogger.Location=" + logLocation +
                "&nms.configuredResourceManagerId=" +
                dtcFactory.ConfiguredResourceManagerId;

            // Test initialize - Fills in queue with data to send and clears the DB.
            PurgeDatabase();
            PurgeAndFillQueue();

            if (Directory.Exists(logLocation))
            {
                Directory.Delete(logLocation, true);
            }

            Directory.CreateDirectory(logLocation);

            dtcFactory = new NetTxConnectionFactory(ReplaceEnvVar(newConnectionUri));

            using (INetTxConnection connection = dtcFactory.CreateNetTxConnection())
            {
                connection.ExceptionListener += this.OnException;
                connection.Start();

                ITransport         transport = (connection as Connection).ITransport;
                TcpFaultyTransport tcpFaulty = transport.Narrow(typeof(TcpFaultyTransport)) as TcpFaultyTransport;
                Assert.IsNotNull(tcpFaulty);
                tcpFaulty.OnewayCommandPreProcessor += this.FailOnCommitTransportHook;

                ReadFromQueueAndInsertIntoDbWithCommit(connection);

                Thread.Sleep(2000);
            }

            Assert.AreEqual(1, Directory.GetFiles(logLocation).Length);

            // verify sql server has commited the transaction
            VerifyDatabaseTableIsFull();

            // check messages are NOT present in the queue
            NetTxTransactionContext.ResetDtcRecovery();
            VerifyBrokerQueueCount(0, newConnectionUri);

            Assert.AreEqual(0, Directory.GetFiles(logLocation).Length);
        }
Beispiel #20
0
        protected static void ReadFromDbAndProduceToQueueWithCommit(INetTxConnection connection)
        {
            IList entries = ExtractDataSet();

            using (INetTxSession session = connection.CreateNetTxSession(true))
            {
                IQueue queue = session.GetQueue(testQueueName);

                // enqueue several messages read from DB
                try
                {
                    using (IMessageProducer producer = session.CreateProducer(queue))
                    {
                        producer.DeliveryMode = MsgDeliveryMode.Persistent;

                        using (TransactionScope scoped = new TransactionScope(TransactionScopeOption.RequiresNew))
                            using (SqlConnection sqlConnection = new SqlConnection(createDbConnectionString))
                            {
                                sqlConnection.Open();

                                Assert.IsNotNull(Transaction.Current);

                                Tracer.DebugFormat("Sending {0} messages to Broker in this TX", entries.Count);
                                foreach (string textBody in entries)
                                {
                                    producer.Send(session.CreateTextMessage(textBody));
                                }

                                using (SqlCommand sqlDeleteCommand = new SqlCommand(
                                           string.Format("DELETE FROM {0}", testTable), sqlConnection))
                                {
                                    int count = sqlDeleteCommand.ExecuteNonQuery();
                                    Assert.AreEqual(entries.Count, count, "wrong number of rows deleted");
                                }

                                scoped.Complete();
                            }
                    }
                }
                catch (Exception e) // exception thrown in TransactionContext.Commit(Enlistment enlistment)
                {
                    Tracer.Debug("TX;Error from TransactionScope: " + e.Message);
                    Tracer.Debug(e.ToString());
                }
            }
        }
        public void TestTransactedAsyncConsumption()
        {
            PurgeDatabase();
            PurgeAndFillQueue(MSG_COUNT * BATCH_COUNT);

            INetTxConnectionFactory factory = new NetTxConnectionFactory(ReplaceEnvVar(connectionURI));

            using (INetTxConnection connection = factory.CreateNetTxConnection())
                using (NetTxSession session = connection.CreateNetTxSession() as NetTxSession)
                {
                    IQueue           queue    = session.GetQueue(testQueueName);
                    IMessageConsumer consumer = session.CreateConsumer(queue);
                    consumer.Listener += AsyncTxAwareOnMessage;

                    // Be carefull, message are dispatched once this is done, so you could receive
                    // a Message outside a TX.  We use the awaitBatchProcessingStart event here to
                    // gate te OnMessage callback, once that method returns the Message is ack'd and
                    // no longer has a chance to participate in a TX.
                    connection.Start();

                    for (int i = 0; i < BATCH_COUNT; ++i)
                    {
                        using (TransactionScope scoped = new TransactionScope(TransactionScopeOption.RequiresNew))
                        {
                            session.Enlist(Transaction.Current);

                            batchTxControl = Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete);
                            awaitBatchProcessingStart.Set();
                            scoped.Complete();
                        }

                        // Reenlisting to fast seems to annoy the DTC.  Also since DTC operations are
                        // async we need to allow a little time for lag so that the last TX actually
                        // completes before we start a new one.
                        Thread.Sleep(250);
                    }
                }

            // verify sql server has commited the transaction
            VerifyDatabaseTableIsFull(MSG_COUNT * BATCH_COUNT);

            // check messages are NOT present in the queue
            VerifyNoMessagesInQueue();
        }
Beispiel #22
0
        public void TestTransactedDBReadAndProduce()
        {
            // Test initialize - Fills in DB with data to send.
            PrepareDatabase();

            using (INetTxConnection connection = factory.CreateNetTxConnection())
            {
                connection.ExceptionListener += this.OnException;
                connection.Start();

                ReadFromDbAndProduceToQueueWithCommit(connection);

                Thread.Sleep(2000);
            }

            // verify sql server has commited the transaction
            VerifyDatabaseTableIsEmpty();

            // check messages are present in the queue
            VerifyBrokerQueueCount();
        }
Beispiel #23
0
        public void TestRecoverAfterTransactionScopeAborted()
        {
            // Test initialize - Fills in DB with data to send.
            PrepareDatabase();

            using (INetTxConnection connection = dtcFactory.CreateNetTxConnection())
            {
                connection.ExceptionListener += this.OnException;
                connection.Start();

                ReadFromDbAndProduceToQueueWithScopeAborted(connection);

                Thread.Sleep(2000);
            }

            // verify sql server has NOT commited the transaction
            VerifyDatabaseTableIsFull();

            // check messages are NOT present in the queue
            VerifyNoMessagesInQueue();
        }
Beispiel #24
0
        public void TestConfigureRecoveryPolicyLoggerType(
            [Values("tcp://${activemqhost}:61616?nms.RecoveryPolicy.RecoveryLoggerType=file")]
            string baseConnectionURI)
        {
            INetTxConnectionFactory factory = new NetTxConnectionFactory(NMSTestSupport.ReplaceEnvVar(baseConnectionURI));

            using (INetTxConnection connection = factory.CreateNetTxConnection())
            {
                NetTxConnection netTxConnection = connection as NetTxConnection;

                Assert.IsNotNull(netTxConnection);
                NetTxRecoveryPolicy policy = netTxConnection.RecoveryPolicy;

                Assert.AreEqual("file", policy.RecoveryLoggerType);

                RecoveryFileLogger logger = policy.RecoveryLogger as RecoveryFileLogger;

                Assert.IsNotNull(logger);
                Assert.AreEqual(Directory.GetCurrentDirectory(), logger.Location);
            }
        }
Beispiel #25
0
        public void TestNoRecoverAfterFailOnTransactionWhenLogDeleted()
        {
            // Test initialize - Fills in DB with data to send.
            PrepareDatabase();

            INetTxConnectionFactory factory      = new NetTxConnectionFactory(ReplaceEnvVar(connectionURI));
            NetTxConnectionFactory  netTxFactory = factory as NetTxConnectionFactory;
            RecoveryFileLogger      logger       = netTxFactory.RecoveryPolicy.RecoveryLogger as RecoveryFileLogger;
            string logDirectory = logger.Location;

            using (INetTxConnection connection = factory.CreateNetTxConnection())
            {
                connection.ExceptionListener += this.OnException;
                connection.Start();

                ITransport         transport = (connection as Connection).ITransport;
                TcpFaultyTransport tcpFaulty = transport.Narrow(typeof(TcpFaultyTransport)) as TcpFaultyTransport;
                Assert.IsNotNull(tcpFaulty);
                tcpFaulty.OnewayCommandPreProcessor += this.FailOnCommitTransportHook;

                ReadFromDbAndProduceToQueueWithCommit(connection);

                Thread.Sleep(2000);
            }

            // transaction should not have been commited
            VerifyNoMessagesInQueueNoRecovery();

            // delete all recovery files
            foreach (string file in Directory.GetFiles(logDirectory, "*.bin"))
            {
                File.Delete(file);
            }

            // verify sql server has commited the transaction
            VerifyDatabaseTableIsEmpty();

            // check messages are NOT present in the queue bacause recovery file has been deleted
            VerifyNoMessagesInQueue();
        }
Beispiel #26
0
        protected static void ReadFromQueueAndInsertIntoDbWithCommit(INetTxConnection connection)
        {
            using (INetTxSession session = connection.CreateNetTxSession(true))
            {
                IQueue queue = session.GetQueue(testQueueName);

                // read message from queue and insert into db table
                try
                {
                    using (IMessageConsumer consumer = session.CreateConsumer(queue))
                    {
                        using (TransactionScope scoped = new TransactionScope(TransactionScopeOption.RequiresNew))
                            using (SqlConnection sqlConnection = new SqlConnection(createDbConnectionString))
                                using (SqlCommand sqlInsertCommand = new SqlCommand())
                                {
                                    sqlConnection.Open();
                                    sqlInsertCommand.Connection = sqlConnection;

                                    Assert.IsNotNull(Transaction.Current);

                                    for (int i = 0; i < MSG_COUNT; i++)
                                    {
                                        ITextMessage message = consumer.Receive() as ITextMessage;
                                        Assert.IsNotNull(message, "missing message");
                                        sqlInsertCommand.CommandText =
                                            string.Format("INSERT INTO {0} VALUES ({1})", testTable, Convert.ToInt32(message.Text));
                                        sqlInsertCommand.ExecuteNonQuery();
                                    }

                                    scoped.Complete();
                                }
                    }
                }
                catch (Exception e)
                {
                    Tracer.Debug("TX;Error from TransactionScope: " + e.Message);
                    Tracer.Debug(e.ToString());
                }
            }
        }
Beispiel #27
0
        public void TestTransacteDequeueAndDbWrite()
        {
            // Test initialize - Fills in DB with data to send.
            PurgeDatabase();
            PurgeAndFillQueue();

            using (INetTxConnection connection = factory.CreateNetTxConnection())
            {
                connection.ExceptionListener += this.OnException;
                connection.Start();

                ReadFromQueueAndInsertIntoDbWithCommit(connection);

                Thread.Sleep(2000);
            }

            // verify sql server has commited the transaction and stored all messages
            VerifyDatabaseTableIsFull();

            // check no messages are present in the queue after commit.
            VerifyNoMessagesInQueueNoRecovery();
        }
Beispiel #28
0
        public void TestRecoverAfterTransactionScopeAborted()
        {
            // Test initialize - Fills in queue with data to send and clears the DB.
            PurgeDatabase();
            PurgeAndFillQueue();

            using (INetTxConnection connection = factory.CreateNetTxConnection())
            {
                connection.ExceptionListener += this.OnException;
                connection.Start();

                ReadFromQueueAndInsertIntoDbWithScopeAborted(connection);

                Thread.Sleep(2000);
            }

            // verify sql server has NOT commited the transaction
            VerifyDatabaseTableIsEmpty();

            // check messages are present in the queue
            VerifyBrokerQueueCount();
        }
Beispiel #29
0
        private static void RunProducer(INetTxConnection connection)
        {
            Console.WriteLine("Press 'e' to publish an IEvent, EventMessage, and AnotherEventMessage alternately.");
            Console.WriteLine("Press 's' to start a saga on MyPublisher.");
            Console.WriteLine("Press 'c' to send a command to Subscriber1");
            Console.WriteLine("Press 'n' to send a command to SubscriberNMS");
            Console.WriteLine("Press 'q' to exit");

            while (true)
            {
                var key = Console.ReadKey();
                using (var session = connection.CreateNetTxSession())
                {
                    switch (key.KeyChar)
                    {
                    case 'q':
                        return;

                    case 'e':
                        PublishEvent(session);
                        break;

                    case 's':
                        StartSaga(session, "queue://Mypublisher");
                        break;

                    case 'n':
                        SendCommand(session, "queue://subscribernms", new MyRequestNMS());
                        break;

                    case 'c':
                        SendCommand(session, "queue://Subscriber1", new MyRequest1());
                        break;
                    }
                }
            }
        }
Beispiel #30
0
        public void TestTransactedProduceConsumeWithSessionClose(
            [Values("tcp://${activemqhost}:61616")]
            string baseConnectionURI)
        {
            INetTxConnectionFactory factory = new NetTxConnectionFactory(NMSTestSupport.ReplaceEnvVar(baseConnectionURI));

            using (INetTxConnection connection = factory.CreateNetTxConnection())
            {
                connection.Start();

                IDestination destination = null;

                using (INetTxSession session = connection.CreateNetTxSession())
                {
                    session.TransactionStartedListener    += TransactionStarted;
                    session.TransactionCommittedListener  += TransactionCommitted;
                    session.TransactionRolledBackListener += TransactionRolledBack;

                    destination = session.CreateTemporaryQueue();
                    using (IMessageProducer producer = session.CreateProducer(destination))
                    {
                        using (TransactionScope scoped = new TransactionScope(TransactionScopeOption.RequiresNew, TransactionScopeAsyncFlowOption.Enabled))
                        {
                            Assert.IsFalse(this.transactionStarted);

                            Assert.IsNotNull(Transaction.Current);
                            for (int i = 0; i < MSG_COUNT; ++i)
                            {
                                producer.Send(session.CreateTextMessage("Hello World"));
                            }

                            Assert.IsTrue(this.transactionStarted, "A TX should have been started by producing");

                            scoped.Complete();
                        }

                        Assert.IsFalse(this.transactionStarted, "TX Should have Committed and cleared Started");
                        Assert.IsTrue(this.transactionCommitted, "TX Should have Committed");
                        Assert.IsFalse(this.transactionRolledBack, "TX Should not have Rolledback");

                        session.Close();
                    }
                }

                using (INetTxSession session = connection.CreateNetTxSession())
                {
                    session.TransactionStartedListener    += TransactionStarted;
                    session.TransactionCommittedListener  += TransactionCommitted;
                    session.TransactionRolledBackListener += TransactionRolledBack;

                    using (IMessageConsumer consumer = session.CreateConsumer(destination))
                    {
                        using (TransactionScope scoped = new TransactionScope(TransactionScopeOption.RequiresNew, TransactionScopeAsyncFlowOption.Enabled))
                        {
                            Assert.IsFalse(this.transactionStarted);

                            for (int i = 0; i < MSG_COUNT; ++i)
                            {
                                IMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(2000));
                                Assert.IsNotNull(msg, "Message was null for index: " + i);
                            }

                            Assert.IsTrue(this.transactionStarted, "A TX should have been started by consuming");

                            scoped.Complete();
                        }

                        Assert.IsFalse(this.transactionStarted, "TX Should have Committed and cleared Started");
                        Assert.IsTrue(this.transactionCommitted, "TX Should have Committed");
                        Assert.IsFalse(this.transactionRolledBack, "TX Should not have Rolledback");

                        session.Close();
                    }
                }

                using (INetTxSession session = connection.CreateNetTxSession())
                {
                    using (IMessageConsumer consumer = session.CreateConsumer(destination))
                    {
                        for (int i = 0; i < MSG_COUNT; ++i)
                        {
                            IMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(50));
                            Assert.IsNull(msg, "Message was not null for index: " + i);
                        }
                    }

                    session.Close();
                }

                connection.Close();
            }
        }
Beispiel #31
0
        private void Run()
        {
            var connectionFactory = new NetTxConnectionFactory("failover:(tcp://localhost:61616,tcp://localhost:61616)?randomize=false&timeout=5000")
                {
                    AcknowledgementMode = AcknowledgementMode.Transactional,
                    PrefetchPolicy = { QueuePrefetch = 1 }
                };

            using (var connection = connectionFactory.CreateNetTxConnection())
            {
                currentconnection = connection;
                connection.Start();
                using (var session = connection.CreateNetTxSession())
                {
                    this.session = session;
                    var eventDestination = SessionUtil.GetDestination(session, "queue://Consumer.NMS.VirtualTopic.EventMessage");
                    var commandDestination = SessionUtil.GetDestination(session, "queue://subscribernms");
                    using (var eventConsumer = session.CreateConsumer(eventDestination))
                    using (var commandConsumer = session.CreateConsumer(commandDestination))
                    {
                        eventConsumer.Listener += OnEventMessage;
                        commandConsumer.Listener += this.OnCommandMessage;

                        Console.WriteLine("Consumer started. Press q to quit");
                        while (Console.ReadKey().KeyChar != 'q')
                        {
                        }
                    }
                }
                connection.Stop();
            }
        }
        protected static void ReadFromDbAndProduceToQueueWithScopeAborted(INetTxConnection connection)
        {
            IList entries = ExtractDataSet();

            using (INetTxSession session = connection.CreateNetTxSession())
            {
                IQueue queue = session.GetQueue(testQueueName);

                // enqueue several messages read from DB
                try
                {
                    using (IMessageProducer producer = session.CreateProducer(queue))
                    {
                        producer.DeliveryMode = MsgDeliveryMode.Persistent;

                        using (TransactionScope scoped = new TransactionScope(TransactionScopeOption.RequiresNew))
                        using (SqlConnection sqlConnection = new SqlConnection(sqlConnectionString))
                        {
                            sqlConnection.Open();

                            Assert.IsNotNull(Transaction.Current);

                            Tracer.DebugFormat("Sending {0} messages to Broker in this TX", entries.Count);
                            foreach (string textBody in entries)
                            {
                                producer.Send(session.CreateTextMessage(textBody));
                            }

                            using (SqlCommand sqlDeleteCommand = new SqlCommand(
                                string.Format("DELETE FROM {0}", testTable), sqlConnection))
                            {
                                int count = sqlDeleteCommand.ExecuteNonQuery();
                                Assert.AreEqual(entries.Count, count, "wrong number of rows deleted");
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Tracer.Debug("TX;Error from TransactionScope: " + e.Message);
                    Tracer.Debug(e.ToString());
                }
            }
        }
        protected static void ReadFromQueueAndInsertIntoDbWithScopeAborted(INetTxConnection connection)
        {
            using (INetTxSession session = connection.CreateNetTxSession())
            {
                IQueue queue = session.GetQueue(testQueueName);

                // read message from queue and insert into db table
                try
                {
                    using (IMessageConsumer consumer = session.CreateConsumer(queue))
                    {
                        using (TransactionScope scoped = new TransactionScope(TransactionScopeOption.RequiresNew))
                        using (SqlConnection sqlConnection = new SqlConnection(sqlConnectionString))
                        using (SqlCommand sqlInsertCommand = new SqlCommand())
                        {
                            sqlConnection.Open();
                            sqlInsertCommand.Connection = sqlConnection;
                            Assert.IsNotNull(Transaction.Current);

                            for (int i = 0; i < MSG_COUNT; i++)
                            {
                                ITextMessage message = consumer.Receive() as ITextMessage;
                                Assert.IsNotNull(message, "missing message");

                                sqlInsertCommand.CommandText =
                                    string.Format("INSERT INTO {0} VALUES ({1})", testTable, Convert.ToInt32(message.Text));
                                sqlInsertCommand.ExecuteNonQuery();
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Tracer.Debug("TX;Error from TransactionScope: " + e.Message);
                    Tracer.Debug(e.ToString());
                }
            }
        }