You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ta...@apache.org on 2017/03/08 23:12:03 UTC

[01/50] [abbrv] activemq-nms-openwire git commit: https://issues.apache.org/jira/browse/AMQNET-489

Repository: activemq-nms-openwire
Updated Branches:
  refs/heads/1.2.x [created] 7599d7fdb
  refs/heads/1.3.x [created] 633899cef
  refs/heads/1.4.x [created] 408861aee
  refs/heads/1.5.x [created] 6c88b806b
  refs/heads/1.6.x [created] 94ad40978
  refs/heads/1.7.x [created] dab33daf2
  refs/heads/master [created] a3bfe8bed


https://issues.apache.org/jira/browse/AMQNET-489

Merge in fixes from AMQ-5146 to honor the redelivery policy on messages dispatched from the Broker.


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/22fbad24
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/22fbad24
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/22fbad24

Branch: refs/heads/1.6.x
Commit: 22fbad2421cdf043f2c09936cd6ac49ae197630f
Parents: a0f256c
Author: Timothy A. Bish <ta...@apache.org>
Authored: Thu Aug 21 21:20:25 2014 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Thu Aug 21 21:20:25 2014 +0000

----------------------------------------------------------------------
 src/main/csharp/MessageConsumer.cs             |  60 +++++++-
 src/main/csharp/Threads/CompositeTaskRunner.cs |   1 -
 src/test/csharp/AMQRedeliveryPolicyTest.cs     | 158 ++++++++++++++++++++
 3 files changed, 213 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/22fbad24/src/main/csharp/MessageConsumer.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/MessageConsumer.cs b/src/main/csharp/MessageConsumer.cs
index 3c02041..3d77291 100755
--- a/src/main/csharp/MessageConsumer.cs
+++ b/src/main/csharp/MessageConsumer.cs
@@ -39,6 +39,8 @@ namespace Apache.NMS.ActiveMQ
 	/// </summary>
 	public class MessageConsumer : IMessageConsumer, IDispatcher
 	{
+        private const int NO_MAXIMUM_REDELIVERIES = -1;
+
         private readonly MessageTransformation messageTransformation;
         private readonly MessageDispatchChannel unconsumedMessages;
         private readonly LinkedList<MessageDispatch> dispatchedMessages = new LinkedList<MessageDispatch>();
@@ -789,7 +791,15 @@ namespace Apache.NMS.ActiveMQ
 						{
 							if(listener != null && this.unconsumedMessages.Running)
 							{
-								dispatchMessage = true;
+                                if (RedeliveryExceeded(dispatch)) 
+                                {
+                                    PosionAck(dispatch, "dispatch to " + ConsumerId + " exceeds redelivery policy limit:" + redeliveryPolicy.MaximumRedeliveries);
+                                    return;
+                                } 
+                                else
+                                {
+								    dispatchMessage = true;
+                                }
 							}
 							else
 							{
@@ -1014,6 +1024,11 @@ namespace Apache.NMS.ActiveMQ
 						}
 					}
 				}
+                else if (RedeliveryExceeded(dispatch))
+                {
+                    Tracer.DebugFormat("[{0}] received with excessive redelivered: {1}", ConsumerId, dispatch);
+                    PosionAck(dispatch, "dispatch to " + ConsumerId + " exceeds redelivery policy limit:" + redeliveryPolicy.MaximumRedeliveries);
+                }
 				else
 				{
 					return dispatch;
@@ -1231,7 +1246,7 @@ namespace Apache.NMS.ActiveMQ
 			}
 
 	        // evaluate both expired and normal msgs as otherwise consumer may get stalled
-			if((0.5 * this.info.PrefetchSize) <= (this.deliveredCounter + this.ackCounter - this.additionalWindowSize))
+			if ((0.5 * this.info.PrefetchSize) <= (this.deliveredCounter + this.ackCounter - this.additionalWindowSize))
 			{
 				this.session.SendAck(pendingAck);
 				this.pendingAck = null;
@@ -1250,6 +1265,18 @@ namespace Apache.NMS.ActiveMQ
 	        this.session.Connection.SyncRequest(ack);
 	    }
 
+        private void PosionAck(MessageDispatch dispatch, string cause)
+        {
+            BrokerError poisonCause = new BrokerError();
+            poisonCause.ExceptionClass = "javax.jms.JMSException";
+            poisonCause.Message = cause;
+
+            MessageAck posionAck = new MessageAck(dispatch, (byte) AckType.PoisonAck, 1);
+            posionAck.FirstMessageId = dispatch.Message.MessageId;
+            posionAck.PoisonCause = poisonCause;
+            this.session.Connection.SyncRequest(posionAck);
+        }
+
 	    private void RegisterSync()
 		{
 			// Don't acknowledge now, but we may need to let the broker know the
@@ -1387,14 +1414,19 @@ namespace Apache.NMS.ActiveMQ
                                                this.info.ConsumerId, this.dispatchedMessages.Count, this.redeliveryPolicy.MaximumRedeliveries);
                         }
 
+                        BrokerError poisonCause = new BrokerError();
+                        poisonCause.ExceptionClass = "javax.jms.JMSException";
+                        poisonCause.Message = "Exceeded RedeliveryPolicy limit: " + RedeliveryPolicy.MaximumRedeliveries;
+
 						if (lastMd.RollbackCause != null)
 						{
 							BrokerError cause = new BrokerError();
-							cause.ExceptionClass = "javax.jms.JMSException";
-							cause.Message = lastMd.RollbackCause.Message;
-							ack.PoisonCause = cause;
+                            poisonCause.ExceptionClass = "javax.jms.JMSException";
+                            poisonCause.Message = lastMd.RollbackCause.Message;
+                            poisonCause.Cause = cause;
 						}
                     	ack.FirstMessageId = firstMsgId;
+                        ack.PoisonCause = poisonCause;
 
 						this.session.SendAck(ack);
 
@@ -1743,6 +1775,24 @@ namespace Apache.NMS.ActiveMQ
 			}
 		}
 
+        private bool RedeliveryExceeded(MessageDispatch dispatch) 
+        {
+            try 
+            {
+                ActiveMQMessage amqMessage = dispatch.Message as ActiveMQMessage;
+
+                return session.IsTransacted && redeliveryPolicy != null &&
+                       redeliveryPolicy.MaximumRedeliveries != NO_MAXIMUM_REDELIVERIES &&
+                       dispatch.RedeliveryCounter > redeliveryPolicy.MaximumRedeliveries &&
+                       // redeliveryCounter > x expected after resend via brokerRedeliveryPlugin
+                       !amqMessage.Properties.Contains("redeliveryDelay");
+            }
+            catch (Exception ignored) 
+            {
+                return false;
+            }
+        }
+
 		#endregion
 
 		#region Nested ISyncronization Types

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/22fbad24/src/main/csharp/Threads/CompositeTaskRunner.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Threads/CompositeTaskRunner.cs b/src/main/csharp/Threads/CompositeTaskRunner.cs
index 96305c6..b19bdd4 100755
--- a/src/main/csharp/Threads/CompositeTaskRunner.cs
+++ b/src/main/csharp/Threads/CompositeTaskRunner.cs
@@ -17,7 +17,6 @@
 
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using System.Threading;
 
 namespace Apache.NMS.ActiveMQ.Threads

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/22fbad24/src/test/csharp/AMQRedeliveryPolicyTest.cs
----------------------------------------------------------------------
diff --git a/src/test/csharp/AMQRedeliveryPolicyTest.cs b/src/test/csharp/AMQRedeliveryPolicyTest.cs
index 2cab249..2ebdf0d 100644
--- a/src/test/csharp/AMQRedeliveryPolicyTest.cs
+++ b/src/test/csharp/AMQRedeliveryPolicyTest.cs
@@ -19,6 +19,7 @@ using System;
 using System.Threading;
 using Apache.NMS.Test;
 using Apache.NMS.ActiveMQ.Commands;
+using Apache.NMS.Util;
 using NUnit.Framework;
 
 namespace Apache.NMS.ActiveMQ.Test
@@ -27,6 +28,7 @@ namespace Apache.NMS.ActiveMQ.Test
     public class AMQRedeliveryPolicyTest : NMSTestSupport
     {
         private const string DESTINATION_NAME = "TEST.RedeliveryPolicyTestDest";
+        private const string DLQ_DELIVERY_FAILURE_CAUSE_PROPERTY = "dlqDeliveryFailureCause";
 
         [Test]
         public void TestExponentialRedeliveryPolicyDelaysDeliveryOnRollback()
@@ -443,5 +445,161 @@ namespace Apache.NMS.ActiveMQ.Test
                 session.Rollback();
             }
         }
+
+        [Test]
+        public void TestRepeatedRedeliveryReceiveNoCommit() 
+        {
+            using(Connection connection = (Connection) CreateConnection())
+            {
+                connection.Start();
+
+                ISession dlqSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
+                IDestination destination = dlqSession.GetQueue("TestRepeatedRedeliveryReceiveNoCommit");
+                IDestination dlq = dlqSession.GetQueue("ActiveMQ.DLQ");
+                connection.DeleteDestination(destination);
+                connection.DeleteDestination(dlq);
+                IMessageProducer producer = dlqSession.CreateProducer(destination);
+                producer.Send(dlqSession.CreateTextMessage("1st"));
+                IMessageConsumer dlqConsumer = dlqSession.CreateConsumer(dlq);
+
+                const int maxRedeliveries = 4;
+                for (int i = 0; i <= maxRedeliveries + 1; i++) 
+                {
+                    using(Connection loopConnection = (Connection) CreateConnection())
+                    {
+                        // Receive a message with the JMS API
+                        IRedeliveryPolicy policy = loopConnection.RedeliveryPolicy;
+                        policy.InitialRedeliveryDelay = 0;
+                        policy.UseExponentialBackOff = false;
+                        policy.MaximumRedeliveries = maxRedeliveries;
+
+                        loopConnection.Start();
+                        ISession session = loopConnection.CreateSession(AcknowledgementMode.Transactional);
+                        IMessageConsumer consumer = session.CreateConsumer(destination);
+
+                        ActiveMQTextMessage m = consumer.Receive(TimeSpan.FromMilliseconds(4000)) as ActiveMQTextMessage;
+                        if (m != null) 
+                        {
+                            Tracer.DebugFormat("Received Message: {0} delivery count = {1}", m.Text, m.RedeliveryCounter);
+                        }
+
+                        if (i <= maxRedeliveries)
+                        {
+                            Assert.IsNotNull(m);
+                            Assert.AreEqual("1st", m.Text);
+                            Assert.AreEqual(i, m.RedeliveryCounter);
+                        } 
+                        else
+                        {
+                            Assert.IsNull(m, "null on exceeding redelivery count");
+                        }
+                    }
+                }
+
+                // We should be able to get the message off the DLQ now.
+                ITextMessage msg = dlqConsumer.Receive(TimeSpan.FromMilliseconds(2000)) as ITextMessage;
+                Assert.IsNotNull(msg, "Got message from DLQ");
+                Assert.AreEqual("1st", msg.Text);
+                String cause = msg.Properties.GetString(DLQ_DELIVERY_FAILURE_CAUSE_PROPERTY);
+                if (cause != null) 
+                {
+                    Tracer.DebugFormat("Rollback Cause = {0}", cause);
+                    Assert.IsTrue(cause.Contains("RedeliveryPolicy"), "cause exception has no policy ref");
+                }
+                else
+                {
+                    Tracer.Debug("DLQ'd message has no cause tag.");
+                }
+            }
+        }
+
+        [Test]
+        public void TestRepeatedRedeliveryOnMessageNoCommit() 
+        {
+            using(Connection connection = (Connection) CreateConnection())
+            {
+                connection.Start();
+                ISession dlqSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
+                IDestination destination = dlqSession.GetQueue("TestRepeatedRedeliveryOnMessageNoCommit");
+                IDestination dlq = dlqSession.GetQueue("ActiveMQ.DLQ");
+                connection.DeleteDestination(destination);
+                connection.DeleteDestination(dlq);
+                IMessageProducer producer = dlqSession.CreateProducer(destination);
+                IMessageConsumer dlqConsumer = dlqSession.CreateConsumer(dlq);
+
+                producer.Send(dlqSession.CreateTextMessage("1st"));
+
+                const int maxRedeliveries = 4;
+                Atomic<int> receivedCount = new Atomic<int>(0);
+
+                for (int i = 0; i <= maxRedeliveries + 1; i++) 
+                {
+                    using(Connection loopConnection = (Connection) CreateConnection())
+                    {
+                        IRedeliveryPolicy policy = loopConnection.RedeliveryPolicy;
+                        policy.InitialRedeliveryDelay = 0;
+                        policy.UseExponentialBackOff = false;
+                        policy.MaximumRedeliveries = maxRedeliveries;
+
+                        loopConnection.Start();
+                        ISession session = loopConnection.CreateSession(AcknowledgementMode.Transactional);
+                        IMessageConsumer consumer = session.CreateConsumer(destination);
+                        OnMessageNoCommitCallback callback = new OnMessageNoCommitCallback(receivedCount);
+                        consumer.Listener += new MessageListener(callback.consumer_Listener);
+
+                        if (i <= maxRedeliveries) 
+                        {
+                            Assert.IsTrue(callback.Await(), "listener should have dispatched a message");
+                        } 
+                        else 
+                        {
+                            // final redlivery gets poisoned before dispatch
+                            Assert.IsFalse(callback.Await(), "listener should not have dispatched after max redliveries");
+                        }
+                    }
+                }
+
+                // We should be able to get the message off the DLQ now.
+                ITextMessage msg = dlqConsumer.Receive(TimeSpan.FromMilliseconds(2000)) as ITextMessage;
+                Assert.IsNotNull(msg, "Got message from DLQ");
+                Assert.AreEqual("1st", msg.Text);
+                String cause = msg.Properties.GetString(DLQ_DELIVERY_FAILURE_CAUSE_PROPERTY);
+                if (cause != null) 
+                {
+                    Tracer.DebugFormat("Rollback Cause = {0}", cause);
+                    Assert.IsTrue(cause.Contains("RedeliveryPolicy"), "cause exception has no policy ref");
+                }
+                else
+                {
+                    Tracer.Debug("DLQ'd message has no cause tag.");
+                }
+            }
+        }
+
+        class OnMessageNoCommitCallback
+        {
+            private Atomic<int> receivedCount;
+            private CountDownLatch done = new CountDownLatch(1);
+
+            public OnMessageNoCommitCallback(Atomic<int> receivedCount)
+            {
+                this.receivedCount = receivedCount;
+            }
+
+            public bool Await() 
+            {
+                return done.await(TimeSpan.FromMilliseconds(5000));
+            }
+
+            public void consumer_Listener(IMessage message)
+            {
+                ActiveMQTextMessage m = message as ActiveMQTextMessage;
+                Tracer.DebugFormat("Received Message: {0} delivery count = {1}", m.Text, m.RedeliveryCounter);
+                Assert.AreEqual("1st", m.Text);
+                Assert.AreEqual(receivedCount.Value, m.RedeliveryCounter);
+                receivedCount.GetAndSet(receivedCount.Value + 1);
+                done.countDown();
+            }
+        }
     }
 }


[33/50] [abbrv] activemq-nms-openwire git commit: Merge fixes for

Posted by ta...@apache.org.
Merge fixes for 

AMQNET-505
AMQNET-506
AMQNET-507
AMQNET-508


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/58728fe9
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/58728fe9
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/58728fe9

Branch: refs/heads/1.7.x
Commit: 58728fe9ba62f114490047a62f61b6dcb174ba71
Parents: 8f10900
Author: Timothy A. Bish <ta...@apache.org>
Authored: Thu Aug 13 18:01:06 2015 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Thu Aug 13 18:01:06 2015 +0000

----------------------------------------------------------------------
 src/main/csharp/MessageConsumer.cs          | 35 ++++++++++-
 src/test/csharp/IndividualAckTest.cs        | 57 ++++++++++++++++++
 src/test/csharp/QueueBrowserTests.cs        | 76 +++++++++++++++++++++++-
 src/test/csharp/ZeroPrefetchConsumerTest.cs | 48 +++++++++++++++
 4 files changed, 213 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/58728fe9/src/main/csharp/MessageConsumer.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/MessageConsumer.cs b/src/main/csharp/MessageConsumer.cs
index a500b4f..6f04946 100755
--- a/src/main/csharp/MessageConsumer.cs
+++ b/src/main/csharp/MessageConsumer.cs
@@ -507,7 +507,7 @@ namespace Apache.NMS.ActiveMQ
                     this.session.Scheduler.Cancel(this.optimizedAckTask);
                 }
 
-                if (this.session.IsClientAcknowledge)
+                if (this.session.IsClientAcknowledge || this.session.IsIndividualAcknowledge)
                 {
                     if (!this.info.Browser)
                     {
@@ -1035,7 +1035,7 @@ namespace Apache.NMS.ActiveMQ
                 {
                     return null;
                 }
-                else if(!IgnoreExpiration && dispatch.Message.IsExpired())
+                else if(ConsumeExpiredMessage(dispatch))
                 {
                     Tracer.DebugFormat("Consumer[{0}] received expired message: {1}",
                                        ConsumerId, dispatch.Message.MessageId);
@@ -1058,6 +1058,8 @@ namespace Apache.NMS.ActiveMQ
                             timeout = deadline - dispatchTime;
                         }
                     }
+
+                    SendPullRequest((long) timeout.TotalMilliseconds);
                 }
                 else if (RedeliveryExceeded(dispatch))
                 {
@@ -1065,6 +1067,25 @@ namespace Apache.NMS.ActiveMQ
                                        ConsumerId, dispatch);
                     PosionAck(dispatch, "dispatch to " + ConsumerId + " exceeds redelivery " +
                                         "policy limit:" + redeliveryPolicy.MaximumRedeliveries);
+
+                    // Refresh the dispatch time
+                    dispatchTime = DateTime.Now;
+
+                    if(timeout > TimeSpan.Zero && !this.unconsumedMessages.Closed)
+                    {
+                        if(dispatchTime > deadline)
+                        {
+                            // Out of time.
+                            timeout = TimeSpan.Zero;
+                        }
+                        else
+                        {
+                            // Adjust the timeout to the remaining time.
+                            timeout = deadline - dispatchTime;
+                        }
+                    }
+
+                    SendPullRequest((long) timeout.TotalMilliseconds);
                 }
                 else
                 {
@@ -1073,6 +1094,16 @@ namespace Apache.NMS.ActiveMQ
             }
         }
 
+        private bool ConsumeExpiredMessage(MessageDispatch dispatch) 
+        {
+            if (dispatch.Message.IsExpired()) 
+            {
+                return !info.Browser && !IgnoreExpiration;
+            }
+
+            return false;
+        }
+
         public virtual void BeforeMessageIsConsumed(MessageDispatch dispatch)
         {
             dispatch.DeliverySequenceId = session.NextDeliveryId;

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/58728fe9/src/test/csharp/IndividualAckTest.cs
----------------------------------------------------------------------
diff --git a/src/test/csharp/IndividualAckTest.cs b/src/test/csharp/IndividualAckTest.cs
index fe95593..a1c68fb 100644
--- a/src/test/csharp/IndividualAckTest.cs
+++ b/src/test/csharp/IndividualAckTest.cs
@@ -260,5 +260,62 @@ namespace Apache.NMS.ActiveMQ.Test
             Assert.IsNull(msg);
             session.Close();
         }
+
+        [Test]
+        public void TestIndividualAcksWithClosedConsumerAndAuditSync()
+        {
+            const int MSG_COUNT = 20;
+            const string QUEUE_NAME = "TEST.TestIndividualAcksWithClosedConsumerAndAuditSync";
+
+            ProduceSomeMessages(MSG_COUNT, QUEUE_NAME);
+
+            string uri = "failover:(tcp://${activemqhost}:61616)";
+            IConnectionFactory factory = new ConnectionFactory(NMSTestSupport.ReplaceEnvVar(uri));
+
+            using (IConnection connection = factory.CreateConnection() as Connection)
+            using (ISession session = connection.CreateSession(AcknowledgementMode.IndividualAcknowledge))
+            using (IQueue queue = session.GetQueue(QUEUE_NAME))
+            {
+                connection.Start();
+
+                // Consume all messages with no ACK
+                using (IMessageConsumer consumer = session.CreateConsumer(queue))
+                {
+                    for (int i = 0; i < MSG_COUNT; ++i)
+                    {
+                        IMessage message = consumer.Receive(TimeSpan.FromMilliseconds(3000));
+                        Assert.NotNull(message);
+                        Tracer.DebugFormat("Received message: {0}", message.NMSMessageId);
+                    }
+                }
+
+                // Consumer the same batch again.
+                using (IMessageConsumer consumer = session.CreateConsumer(queue))
+                {
+                    for (int i = 0; i < MSG_COUNT; ++i)
+                    {
+                        IMessage message = consumer.Receive(TimeSpan.FromMilliseconds(3000));
+                        Assert.NotNull(message);
+                        Tracer.DebugFormat("Received message: {0}", message.NMSMessageId);
+                    }
+                }
+
+                session.DeleteDestination(queue);
+            }
+        }
+
+        private void ProduceSomeMessages(int count, string queueName)
+        {
+            using (IConnection connection = CreateConnection())
+            using (ISession session = connection.CreateSession(AcknowledgementMode.IndividualAcknowledge))
+            using (IQueue queue = session.GetQueue(queueName))
+            using (IMessageProducer producer = session.CreateProducer(queue))
+            {
+                for (int i = 0; i < count; ++i)
+                {
+                    producer.Send(session.CreateMessage());
+                }
+            }
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/58728fe9/src/test/csharp/QueueBrowserTests.cs
----------------------------------------------------------------------
diff --git a/src/test/csharp/QueueBrowserTests.cs b/src/test/csharp/QueueBrowserTests.cs
index 3faaa12..c737090 100644
--- a/src/test/csharp/QueueBrowserTests.cs
+++ b/src/test/csharp/QueueBrowserTests.cs
@@ -205,6 +205,80 @@ namespace Apache.NMS.ActiveMQ.Test
                 IQueueBrowser browser = session.CreateBrowser(queue);
 				browser.Close();
             }
-        }		
+        }
+
+        [Test]
+        public void TestBrowsingExpiration()
+        {
+            const int MESSAGES_TO_SEND = 50;
+            const string QUEUE_NAME = "TEST.TestBrowsingExpiration";
+
+            // Browse the queue.
+            using (Connection connection = CreateConnection() as Connection)
+            using (ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+            using (IQueue queue = session.GetQueue(QUEUE_NAME))
+            {
+                session.DeleteDestination(queue);
+
+                SendTestMessages(MESSAGES_TO_SEND, QUEUE_NAME);
+
+                connection.Start();
+                int browsed = Browse(QUEUE_NAME, connection);
+
+                // The number of messages browsed should be equal to the number of
+                // messages sent.
+                Assert.AreEqual(MESSAGES_TO_SEND, browsed);
+
+                // Broker expired message period is 30 seconds by default
+                for (int i = 0; i < 12; ++i)
+                {
+                    Thread.Sleep(5000);
+                    browsed = Browse(QUEUE_NAME, connection);
+                }
+
+                session.DeleteDestination(session.GetQueue(QUEUE_NAME));
+
+                Assert.AreEqual(0, browsed);
+            }
+        }
+
+        private int Browse(String queueName, Connection connection)
+        {
+            int browsed = 0;
+
+            using (ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+            using (IQueue queue = session.GetQueue(queueName))
+            using (IQueueBrowser browser = session.CreateBrowser(queue))
+            {
+                IEnumerator enumeration = browser.GetEnumerator();
+                while (enumeration.MoveNext())
+                {
+                    ITextMessage message = enumeration.Current as ITextMessage;
+                    Tracer.DebugFormat("Browsed message: {0}", message.NMSMessageId);
+                    browsed++;
+                }
+            }
+
+            return browsed;
+        }
+
+        protected void SendTestMessages(int count, String queueName)
+        {
+            // Send the messages to the Queue.
+            using (Connection connection = CreateConnection() as Connection)
+            using (ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+            using (IQueue queue = session.GetQueue(queueName))
+            using (IMessageProducer producer = session.CreateProducer(queue))
+            {
+                for (int i = 1; i <= count; i++) 
+                {
+                    String msgStr = "Message: " + i;
+                    producer.Send(session.CreateTextMessage(msgStr), 
+                                  MsgDeliveryMode.NonPersistent, 
+                                  MsgPriority.Normal, 
+                                  TimeSpan.FromMilliseconds(1500));
+                }
+            }
+        }
 	}
 }

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/58728fe9/src/test/csharp/ZeroPrefetchConsumerTest.cs
----------------------------------------------------------------------
diff --git a/src/test/csharp/ZeroPrefetchConsumerTest.cs b/src/test/csharp/ZeroPrefetchConsumerTest.cs
index b536d71..482557e 100644
--- a/src/test/csharp/ZeroPrefetchConsumerTest.cs
+++ b/src/test/csharp/ZeroPrefetchConsumerTest.cs
@@ -154,6 +154,54 @@ namespace Apache.NMS.ActiveMQ.Test
             Assert.IsNull(answer, "Should have not received a message!");
         }
 
+        [Test]
+        public void TestConsumerReceivePrefetchZeroRedeliveryZero()
+        {
+            const string QUEUE_NAME = "TEST.TestConsumerReceivePrefetchZeroRedeliveryZero";
+
+            using (Connection connection = CreateConnection() as Connection)
+            using (ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+            using (IQueue queue = session.GetQueue(QUEUE_NAME))
+            {              
+                session.DeleteDestination(queue);
+
+                using (IMessageProducer producer = session.CreateProducer(queue))
+                {
+                    ITextMessage textMessage = session.CreateTextMessage("test Message");
+                    producer.Send(textMessage);
+                }
+            }
+
+            // consume and rollback - increase redelivery counter on message
+            using (Connection connection = CreateConnection() as Connection)
+            using (ISession session = connection.CreateSession(AcknowledgementMode.Transactional))
+            using (IQueue queue = session.GetQueue(QUEUE_NAME))
+            using (IMessageConsumer consumer = session.CreateConsumer(queue))
+            {              
+                connection.Start();
+                IMessage message = consumer.Receive(TimeSpan.FromMilliseconds(3000));
+                Assert.IsNotNull(message);
+                session.Rollback();
+            }
+
+            // try consume with timeout - expect it to timeout and return NULL message
+            using (Connection connection = CreateConnection() as Connection)
+            {
+                connection.PrefetchPolicy.All = 0;
+                connection.RedeliveryPolicy.MaximumRedeliveries = 0;
+                connection.Start();
+
+                ISession session = connection.CreateSession(AcknowledgementMode.Transactional);
+                IQueue queue = session.GetQueue(QUEUE_NAME);
+
+                using (IMessageConsumer consumer = session.CreateConsumer(queue))
+                {
+                    IMessage message = consumer.Receive(TimeSpan.FromMilliseconds(3000));
+                    Assert.IsNull(message);
+                }
+            }
+        }
+
         [SetUp]
         public override void SetUp()
         {


[44/50] [abbrv] activemq-nms-openwire git commit: Apply fix for problems with LRUCache not properly cleaning up after itself. Fixes [AMQNET-AMQNET-521]. (See https://issues.apache.org/jira/browse/AMQNET-AMQNET-521)

Posted by ta...@apache.org.
Apply fix for problems with LRUCache not properly cleaning up after itself.  
Fixes [AMQNET-AMQNET-521]. (See https://issues.apache.org/jira/browse/AMQNET-AMQNET-521)



Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/399c1db2
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/399c1db2
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/399c1db2

Branch: refs/heads/1.7.x
Commit: 399c1db2c7f89b4f539219925cc42f12ad10bc9c
Parents: d091a99
Author: Timothy A. Bish <ta...@apache.org>
Authored: Tue Mar 15 14:55:05 2016 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Tue Mar 15 14:55:05 2016 +0000

----------------------------------------------------------------------
 src/main/csharp/Util/LRUCache.cs | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/399c1db2/src/main/csharp/Util/LRUCache.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Util/LRUCache.cs b/src/main/csharp/Util/LRUCache.cs
index ec3d7b9..0fcdb90 100644
--- a/src/main/csharp/Util/LRUCache.cs
+++ b/src/main/csharp/Util/LRUCache.cs
@@ -47,6 +47,7 @@ namespace Apache.NMS.ActiveMQ.Util
 		public void Clear()
 		{
 			dictionary.Clear();
+            entries.Clear();
 		}
 
         public int Count
@@ -65,12 +66,12 @@ namespace Apache.NMS.ActiveMQ.Util
 			get { return dictionary[key]; }
 			set 
 			{ 
-				TValue currentValue = default (TValue);
+				TValue currentValue;
 				// Moved used item to end of list since it been used again.
 				if (dictionary.TryGetValue(key, out currentValue))
 				{
 					KeyValuePair<TKey, TValue> entry = 
-						new KeyValuePair<TKey, TValue>(key, value);
+                        new KeyValuePair<TKey, TValue>(key, currentValue);
 					entries.Remove(entry);
 				}
 


[22/50] [abbrv] activemq-nms-openwire git commit: Merged revision(s) 1689927 from activemq/activemq-dotnet/Apache.NMS.ActiveMQ/branches/1.7.x: Apply patch to improve ID parsing to avoid mis-parsing hostnames with hyphens. Thanks, Andrea Montemaggio! Fixe

Posted by ta...@apache.org.
Merged revision(s) 1689927 from activemq/activemq-dotnet/Apache.NMS.ActiveMQ/branches/1.7.x:
Apply patch to improve ID parsing to avoid mis-parsing hostnames with hyphens. Thanks, Andrea Montemaggio!
Fixes [AMQNET-398]. (See https://issues.apache.org/jira/browse/AMQNET-398)


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/aba1ae0f
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/aba1ae0f
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/aba1ae0f

Branch: refs/heads/master
Commit: aba1ae0fb960e5c889c5a2e6378ac7255f95367d
Parents: ecc841b
Author: Jim Gomes <jg...@apache.org>
Authored: Wed Jul 8 18:16:34 2015 +0000
Committer: Jim Gomes <jg...@apache.org>
Committed: Wed Jul 8 18:16:34 2015 +0000

----------------------------------------------------------------------
 src/main/csharp/NetTxConnection.cs | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/aba1ae0f/src/main/csharp/NetTxConnection.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/NetTxConnection.cs b/src/main/csharp/NetTxConnection.cs
index 8f1976c..8005e2c 100644
--- a/src/main/csharp/NetTxConnection.cs
+++ b/src/main/csharp/NetTxConnection.cs
@@ -16,6 +16,7 @@
  */
 
 using System;
+using System.Text.RegularExpressions;
 using System.Transactions;
 using Apache.NMS.ActiveMQ.Transport;
 using Apache.NMS.ActiveMQ.Util;
@@ -95,18 +96,20 @@ namespace Apache.NMS.ActiveMQ
 
         private static Guid GuidFromId(string id)
         {
-            // Remove the ID: prefix, that's non-unique to be sure
-            string resId = id.TrimStart("ID:".ToCharArray());
-
-            // Remaing parts should be host-port-timestamp-instance:sequence
-            string[] parts = resId.Split(":-".ToCharArray());
-
+            MatchCollection matches = Regex.Matches(id, @"(\d+)-(\d+)-(\d+):(\d+)$");
+            if(0 == matches.Count)
+            {
+                throw new FormatException(string.Format("Unable to extract a GUID from string '{0}'", id));
+            }
+ 
+            GroupCollection groups = matches[0].Groups;
+ 
             // We don't use the hostname here, just the remaining bits.
-            int a = Int32.Parse(parts[parts.Length-4]);
-            short b = Int16.Parse(parts[parts.Length-2]);
-            short c = Int16.Parse(parts[parts.Length-1]);
-            byte[] d = System.BitConverter.GetBytes(Int64.Parse(parts[parts.Length-3]));
-
+            int a = Int32.Parse(groups[1].Value);
+            short b = Int16.Parse(groups[3].Value);
+            short c = Int16.Parse(groups[4].Value);
+            byte[] d = BitConverter.GetBytes(Int64.Parse(groups[2].Value));
+ 
             return new Guid(a, b, c, d);
         }
     }


[31/50] [abbrv] activemq-nms-openwire git commit: https://issues.apache.org/jira/browse/AMQNET-508 https://issues.apache.org/jira/browse/AMQNET-507

Posted by ta...@apache.org.
https://issues.apache.org/jira/browse/AMQNET-508
https://issues.apache.org/jira/browse/AMQNET-507

Ensure that a pull command is sent on expire, also ensure that the tinout is not updated if set to -1 to indicate broker side timeout.  


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/009fa01f
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/009fa01f
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/009fa01f

Branch: refs/heads/master
Commit: 009fa01fc6a469f64a82c64317168845090e5aef
Parents: 3e9f720
Author: Timothy A. Bish <ta...@apache.org>
Authored: Wed Aug 12 23:09:24 2015 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Wed Aug 12 23:09:24 2015 +0000

----------------------------------------------------------------------
 src/main/csharp/MessageConsumer.cs | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/009fa01f/src/main/csharp/MessageConsumer.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/MessageConsumer.cs b/src/main/csharp/MessageConsumer.cs
index 48018f3..6f04946 100755
--- a/src/main/csharp/MessageConsumer.cs
+++ b/src/main/csharp/MessageConsumer.cs
@@ -1058,6 +1058,8 @@ namespace Apache.NMS.ActiveMQ
                             timeout = deadline - dispatchTime;
                         }
                     }
+
+                    SendPullRequest((long) timeout.TotalMilliseconds);
                 }
                 else if (RedeliveryExceeded(dispatch))
                 {
@@ -1069,15 +1071,18 @@ namespace Apache.NMS.ActiveMQ
                     // Refresh the dispatch time
                     dispatchTime = DateTime.Now;
 
-                    if(dispatchTime > deadline)
-                    {
-                        // Out of time.
-                        timeout = TimeSpan.Zero;
-                    }
-                    else
+                    if(timeout > TimeSpan.Zero && !this.unconsumedMessages.Closed)
                     {
-                        // Adjust the timeout to the remaining time.
-                        timeout = deadline - dispatchTime;
+                        if(dispatchTime > deadline)
+                        {
+                            // Out of time.
+                            timeout = TimeSpan.Zero;
+                        }
+                        else
+                        {
+                            // Adjust the timeout to the remaining time.
+                            timeout = deadline - dispatchTime;
+                        }
                     }
 
                     SendPullRequest((long) timeout.TotalMilliseconds);


[40/50] [abbrv] activemq-nms-openwire git commit: https://issues.apache.org/jira/browse/AMQNET-513

Posted by ta...@apache.org.
https://issues.apache.org/jira/browse/AMQNET-513

Preserve the rollback cause when poisoning a message.


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/62b0c95d
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/62b0c95d
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/62b0c95d

Branch: refs/heads/1.7.x
Commit: 62b0c95ddb81b20faf7bcf8b3a275c4bdad4ffaa
Parents: 0d92ec5
Author: Timothy A. Bish <ta...@apache.org>
Authored: Thu Nov 19 23:19:50 2015 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Thu Nov 19 23:19:50 2015 +0000

----------------------------------------------------------------------
 src/main/csharp/MessageConsumer.cs              |   8 +-
 .../csharp/MessageListenerRedeliveryTest.cs     | 244 ++++++++++++++++++-
 2 files changed, 245 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/62b0c95d/src/main/csharp/MessageConsumer.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/MessageConsumer.cs b/src/main/csharp/MessageConsumer.cs
index 6f04946..74d07a1 100755
--- a/src/main/csharp/MessageConsumer.cs
+++ b/src/main/csharp/MessageConsumer.cs
@@ -883,10 +883,10 @@ namespace Apache.NMS.ActiveMQ
                     }
                     catch(Exception e)
                     {
+                        dispatch.RollbackCause = e;
                         if(IsAutoAcknowledgeBatch || IsAutoAcknowledgeEach || IsIndividualAcknowledge)
                         {
                             // Schedule redelivery and possible dlq processing
-                            dispatch.RollbackCause = e;
                             Rollback();
                         }
                         else
@@ -1094,9 +1094,9 @@ namespace Apache.NMS.ActiveMQ
             }
         }
 
-        private bool ConsumeExpiredMessage(MessageDispatch dispatch) 
+        private bool ConsumeExpiredMessage(MessageDispatch dispatch)
         {
-            if (dispatch.Message.IsExpired()) 
+            if (dispatch.Message.IsExpired())
             {
                 return !info.Browser && !IgnoreExpiration;
             }
@@ -1480,7 +1480,9 @@ namespace Apache.NMS.ActiveMQ
                             cause.ExceptionClass = "javax.jms.JMSException";
                             cause.Message = lastMd.RollbackCause.Message;
                             poisonCause.Cause = cause;
+                            poisonCause.Message = poisonCause.Message + " cause: " + lastMd.RollbackCause.Message;
                         }
+
                         ack.FirstMessageId = firstMsgId;
                         ack.PoisonCause = poisonCause;
 

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/62b0c95d/src/test/csharp/MessageListenerRedeliveryTest.cs
----------------------------------------------------------------------
diff --git a/src/test/csharp/MessageListenerRedeliveryTest.cs b/src/test/csharp/MessageListenerRedeliveryTest.cs
index 0b22b7a..17d4293 100644
--- a/src/test/csharp/MessageListenerRedeliveryTest.cs
+++ b/src/test/csharp/MessageListenerRedeliveryTest.cs
@@ -15,7 +15,11 @@
  * limitations under the License.
  */
 
+using System;
 using System.Threading;
+using System.Collections;
+using Apache.NMS;
+using Apache.NMS.Util;
 using Apache.NMS.Test;
 using Apache.NMS.Policies;
 using NUnit.Framework;
@@ -26,15 +30,29 @@ namespace Apache.NMS.ActiveMQ.Test
     public class MessageListenerRedeliveryTest : NMSTestSupport
     {
         private Connection connection;
-        private int counter;
+        private volatile int counter;
         private ISession session;
+        private ArrayList received;
+        private ArrayList dlqMessages;
+        private int maxDeliveries;
+
+        private CountDownLatch gotOneMessage;
+        private CountDownLatch gotTwoMessages;
+        private CountDownLatch gotOneDlqMessage;
+        private CountDownLatch gotMaxRedeliveries;
 
         [SetUp]
         public override void SetUp()
         {
             this.connection = (Connection) CreateConnection();
             this.connection.RedeliveryPolicy = GetRedeliveryPolicy();
-
+            this.gotOneMessage = new CountDownLatch(1);
+            this.gotTwoMessages = new CountDownLatch(2);
+            this.gotOneDlqMessage = new CountDownLatch(1);
+            this.maxDeliveries = GetRedeliveryPolicy().MaximumRedeliveries;
+            this.gotMaxRedeliveries = new CountDownLatch(maxDeliveries);
+            this.received = new ArrayList();
+            this.dlqMessages = new ArrayList();
             this.counter = 0;
         }
 
@@ -76,6 +94,39 @@ namespace Apache.NMS.ActiveMQ.Test
             }
         }
 
+        private void OnTracedReceiveMessage(IMessage message) 
+        {
+            try 
+            {
+                received.Add(((ITextMessage) message).Text);
+            } 
+            catch (Exception e) 
+            {
+                Assert.Fail("Error: " + e.Message);
+            }
+
+            if (++counter < maxDeliveries) 
+            {
+                throw new Exception("force a redelivery");
+            }
+
+            // new blood
+            counter = 0;
+            gotTwoMessages.countDown();
+        }
+
+        private void OnDlqMessage(IMessage message) 
+        {
+            dlqMessages.Add(message);
+            gotOneDlqMessage.countDown();
+        }
+
+        private void OnRedeliveredMessage(IMessage message) 
+        {
+            gotMaxRedeliveries.countDown();
+            throw new Exception("Test Forcing a Rollback");
+        }
+
         [Test]
         public void TestQueueRollbackConsumerListener() 
         {
@@ -91,7 +142,7 @@ namespace Apache.NMS.ActiveMQ.Test
             IMessageConsumer consumer = session.CreateConsumer(queue);
 
             consumer.Listener += new MessageListener(OnMessageListener);
-    
+
             Thread.Sleep(500);
 
             // first try.. should get 2 since there is no delay on the
@@ -125,6 +176,191 @@ namespace Apache.NMS.ActiveMQ.Test
     
             session.Close();
         }
-       
+
+        [Test]
+        public void TestQueueRollbackSessionListener()
+        {
+            connection.Start();
+
+            this.session = connection.CreateSession(AcknowledgementMode.Transactional);
+            IQueue queue = session.CreateTemporaryQueue();
+            IMessageProducer producer = CreateProducer(session, queue);
+            IMessage message = CreateTextMessage(session);
+            producer.Send(message);
+            session.Commit();
+
+            IMessageConsumer consumer = session.CreateConsumer(queue);
+            consumer.Listener += new MessageListener(OnMessageListener);
+
+            Thread.Sleep(1000);
+
+            // first try
+            Assert.AreEqual(2, counter);
+
+            Thread.Sleep(1500);
+
+            // second try (redelivery after 1 sec)
+            Assert.AreEqual(3, counter);
+
+            Thread.Sleep(3000);
+
+            // third try (redelivery after 2 seconds) - it should give up after that
+            Assert.AreEqual(4, counter);
+
+            // create new message
+            producer.Send(CreateTextMessage(session));
+            session.Commit();
+          
+            Thread.Sleep(1000);
+
+            // it should be committed, so no redelivery
+            Assert.AreEqual(5, counter);
+
+            Thread.Sleep(2000);
+
+            // no redelivery, counter should still be 4
+            Assert.AreEqual(5, counter);
+
+            session.Close();
+        }
+
+        [Test]
+        public void TestQueueSessionListenerExceptionRetry()
+        {
+            connection.Start();
+
+            ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
+            IQueue queue = session.CreateTemporaryQueue();
+            IMessageProducer producer = CreateProducer(session, queue);
+            IMessage message = CreateTextMessage(session, "1");
+            producer.Send(message);
+            message = CreateTextMessage(session, "2");
+            producer.Send(message);
+
+            IMessageConsumer consumer = session.CreateConsumer(queue);
+            consumer.Listener += new MessageListener(OnTracedReceiveMessage);
+
+            Assert.IsTrue(gotTwoMessages.await(TimeSpan.FromSeconds(20)), "got message before retry expiry");
+
+            for (int i = 0; i < maxDeliveries; i++)
+            {
+                Assert.AreEqual("1", received[i], "got first redelivered: " + i);
+            }
+            for (int i = maxDeliveries; i < maxDeliveries * 2; i++)
+            {
+                Assert.AreEqual("2", received[i], "got first redelivered: " + i);
+            }
+
+            session.Close();
+        }
+
+        [Test]
+        public void TestQueueSessionListenerExceptionDlq()
+        {
+            connection.Start();
+
+            session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
+            IQueue queue = session.CreateTemporaryQueue();
+            IMessageProducer producer = CreateProducer(session, queue);
+            IMessage message = CreateTextMessage(session);
+            producer.Send(message);
+
+            IDestination dlqDestination = session.GetQueue("ActiveMQ.DLQ");
+            connection.DeleteDestination(dlqDestination);
+            IMessageConsumer dlqConsumer = session.CreateConsumer(dlqDestination);
+            dlqConsumer.Listener += new MessageListener(OnDlqMessage);           
+
+            IMessageConsumer consumer = session.CreateConsumer(queue);
+            consumer.Listener += new MessageListener(OnRedeliveredMessage);
+
+            Assert.IsTrue(gotMaxRedeliveries.await(TimeSpan.FromSeconds(20)), "got message before retry expiry");
+
+            // check DLQ
+            Assert.IsTrue(gotOneDlqMessage.await(TimeSpan.FromSeconds(20)), "got dlq message");
+
+            // check DLQ message cause is captured
+            message = dlqMessages[0] as IMessage;
+            Assert.IsNotNull(message, "dlq message captured");
+            String cause = message.Properties.GetString("dlqDeliveryFailureCause");
+
+            Assert.IsTrue(cause.Contains("JMSException"), "cause 'cause' exception is remembered");
+            Assert.IsTrue(cause.Contains("Test"), "is correct exception");
+            Assert.IsTrue(cause.Contains("RedeliveryPolicy"), "cause policy is remembered");
+
+            session.Close();
+        }
+
+        private void OnMessageThenRollback(IMessage message)
+        {
+            gotOneMessage.countDown();
+            try
+            {
+                session.Rollback();
+            } 
+            catch (Exception) 
+            {
+            }
+
+            throw new Exception("Test force a redelivery");
+        }
+
+        [Test]
+        public void TestTransactedQueueSessionListenerExceptionDlq()
+        {
+            connection.Start();
+
+            session = connection.CreateSession(AcknowledgementMode.Transactional);
+            IQueue queue = session.CreateTemporaryQueue();
+            IMessageProducer producer = CreateProducer(session, queue);
+            IMessage message = CreateTextMessage(session);
+            producer.Send(message);
+            session.Commit();
+
+            IDestination dlqDestination = session.GetQueue("ActiveMQ.DLQ");
+            connection.DeleteDestination(dlqDestination);
+            IMessageConsumer dlqConsumer = session.CreateConsumer(dlqDestination);
+            dlqConsumer.Listener += new MessageListener(OnDlqMessage);           
+
+            IMessageConsumer consumer = session.CreateConsumer(queue);
+            consumer.Listener += new MessageListener(OnMessageThenRollback);
+
+            Assert.IsTrue(gotOneMessage.await(TimeSpan.FromSeconds(20)), "got message before retry expiry");
+
+            // check DLQ
+            Assert.IsTrue(gotOneDlqMessage.await(TimeSpan.FromSeconds(20)), "got dlq message");
+
+            // check DLQ message cause is captured
+            message = dlqMessages[0] as IMessage;
+            Assert.IsNotNull(message, "dlq message captured");
+            String cause = message.Properties.GetString("dlqDeliveryFailureCause");
+
+            Assert.IsTrue(cause.Contains("JMSException"), "cause 'cause' exception is remembered");
+            Assert.IsTrue(cause.Contains("Test force"), "is correct exception");
+            Assert.IsTrue(cause.Contains("RedeliveryPolicy"), "cause policy is remembered");
+
+            session.Close();
+        }
+
+        private ITextMessage CreateTextMessage(ISession session, String text)
+        {
+            return session.CreateTextMessage(text);
+        }
+
+        private ITextMessage CreateTextMessage(ISession session)
+        {
+            return session.CreateTextMessage("Hello");
+        }
+
+        private IMessageProducer CreateProducer(ISession session, IDestination queue)
+        {
+            IMessageProducer producer = session.CreateProducer(queue);
+            producer.DeliveryMode = GetDeliveryMode();
+            return producer;
+        }
+
+        protected MsgDeliveryMode GetDeliveryMode() 
+        {
+            return MsgDeliveryMode.Persistent;
+        }
     }
 }


[08/50] [abbrv] activemq-nms-openwire git commit: https://issues.apache.org/jira/browse/AMQNET-495

Posted by ta...@apache.org.
https://issues.apache.org/jira/browse/AMQNET-495

Read compacted long values as unsigned.


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/c0258fa0
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/c0258fa0
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/c0258fa0

Branch: refs/heads/1.6.x
Commit: c0258fa07c2f715b92aceea492c660576a282d5b
Parents: ea082f1
Author: Timothy A. Bish <ta...@apache.org>
Authored: Tue Dec 16 21:10:09 2014 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Tue Dec 16 21:10:09 2014 +0000

----------------------------------------------------------------------
 .../csharp/OpenWire/BaseDataStreamMarshaller.cs |  57 ++---------
 .../OpenWire/BaseDataStreamMarshallerTest.cs    | 100 +++++++++++++++++++
 2 files changed, 110 insertions(+), 47 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/c0258fa0/src/main/csharp/OpenWire/BaseDataStreamMarshaller.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/OpenWire/BaseDataStreamMarshaller.cs b/src/main/csharp/OpenWire/BaseDataStreamMarshaller.cs
index 6493331..8dbc084 100755
--- a/src/main/csharp/OpenWire/BaseDataStreamMarshaller.cs
+++ b/src/main/csharp/OpenWire/BaseDataStreamMarshaller.cs
@@ -28,7 +28,6 @@ namespace Apache.NMS.ActiveMQ.OpenWire
     /// </summary>
     public abstract class BaseDataStreamMarshaller
     {
-        
         private static readonly String[] HEX_TABLE = new String[]{
             "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a", "0b", "0c", "0d", "0e", "0f",
             "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1a", "1b", "1c", "1d", "1e", "1f",
@@ -55,6 +54,7 @@ namespace Apache.NMS.ActiveMQ.OpenWire
         {
             return 0;
         }
+
         public virtual void TightMarshal2(
             OpenWireFormat wireFormat,
             Object o,
@@ -70,8 +70,7 @@ namespace Apache.NMS.ActiveMQ.OpenWire
             BooleanStream bs)
         {
         }
-        
-        
+
         protected virtual DataStructure TightUnmarshalNestedObject(
             OpenWireFormat wireFormat,
             BinaryReader dataIn,
@@ -262,6 +261,7 @@ namespace Apache.NMS.ActiveMQ.OpenWire
                 }
             }
         }
+
         public virtual long TightUnmarshalLong(OpenWireFormat wireFormat, BinaryReader dataIn, BooleanStream bs)
         {
             if (bs.ReadBoolean())
@@ -272,14 +272,14 @@ namespace Apache.NMS.ActiveMQ.OpenWire
                 }
                 else
                 {
-                    return dataIn.ReadInt32();
+                    return dataIn.ReadUInt32();
                 }
             }
             else
             {
                 if (bs.ReadBoolean())
                 {
-                    return dataIn.ReadInt16();
+                    return dataIn.ReadUInt16();
                 }
                 else
                 {
@@ -287,6 +287,7 @@ namespace Apache.NMS.ActiveMQ.OpenWire
                 }
             }
         }
+
         protected virtual int TightMarshalObjectArray1(
             OpenWireFormat wireFormat,
             DataStructure[] objects,
@@ -326,7 +327,6 @@ namespace Apache.NMS.ActiveMQ.OpenWire
             }
         }
         
-        
         protected virtual BrokerError TightUnmarshalBrokerError(
             OpenWireFormat wireFormat,
             BinaryReader dataIn,
@@ -422,7 +422,6 @@ namespace Apache.NMS.ActiveMQ.OpenWire
             }
         }
 
-        
         public virtual void LooseMarshal(
             OpenWireFormat wireFormat,
             Object o,
@@ -437,7 +436,6 @@ namespace Apache.NMS.ActiveMQ.OpenWire
         {
         }
         
-        
         protected virtual DataStructure LooseUnmarshalNestedObject(
             OpenWireFormat wireFormat,
             BinaryReader dataIn)
@@ -457,48 +455,17 @@ namespace Apache.NMS.ActiveMQ.OpenWire
             OpenWireFormat wireFormat,
             BinaryReader dataIn)
         {
-            /*
-             if (wireFormat.isCacheEnabled()) {
-             if (bs.ReadBoolean()) {
-             short index = dataIndataIn.ReadInt16()Int16();
-             DataStructure value = wireFormat.UnmarshalNestedObject(dataIn, bs);
-             wireFormat.setInUnmarshallCache(index, value);
-             return value;
-             } else {
-             short index = dataIn.ReadInt16();
-             return wireFormat.getFromUnmarshallCache(index);
-             }
-             } else {
-             return wireFormat.UnmarshalNestedObject(dataIn, bs);
-             }
-             */
             return wireFormat.LooseUnmarshalNestedObject(dataIn);
         }
-        
-        
+
         protected virtual void LooseMarshalCachedObject(
             OpenWireFormat wireFormat,
             DataStructure o,
             BinaryWriter dataOut)
         {
-            /*
-             if (wireFormat.isCacheEnabled()) {
-             Short index = wireFormat.getMarshallCacheIndex(o);
-             if (bs.ReadBoolean()) {
-             dataOut.Write(index.shortValue(), dataOut);
-             wireFormat.Marshal2NestedObject(o, dataOut, bs);
-             } else {
-             dataOut.Write(index.shortValue(), dataOut);
-             }
-             } else {
-             wireFormat.Marshal2NestedObject(o, dataOut, bs);
-             }
-             */
             wireFormat.LooseMarshalNestedObject(o, dataOut);
         }
-        
-        
-        
+
         protected virtual String LooseUnmarshalString(BinaryReader dataIn)
         {
             if (dataIn.ReadBoolean())
@@ -510,8 +477,7 @@ namespace Apache.NMS.ActiveMQ.OpenWire
                 return null;
             }
         }
-        
-        
+
         public static void LooseMarshalString(String value, BinaryWriter dataOut)
         {
             dataOut.Write(value != null);
@@ -655,8 +621,6 @@ namespace Apache.NMS.ActiveMQ.OpenWire
             return new String(text);
         }
         
-        
-                
         /// <summary>
         /// Converts the object to a String
         /// </summary>
@@ -664,6 +628,7 @@ namespace Apache.NMS.ActiveMQ.OpenWire
         {
             return ToString(id.ProducerId) + ":" + id.ProducerSequenceId;
         }
+
         /// <summary>
         /// Converts the object to a String
         /// </summary>
@@ -672,7 +637,6 @@ namespace Apache.NMS.ActiveMQ.OpenWire
             return id.ConnectionId + ":" + id.SessionId + ":" + id.Value;
         }
         
-        
         /// <summary>
         /// Converts the given transaction ID into a String
         /// </summary>
@@ -703,7 +667,6 @@ namespace Apache.NMS.ActiveMQ.OpenWire
             }
             return buffer.ToString();
         }
-        
     }
 }
 

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/c0258fa0/src/test/csharp/OpenWire/BaseDataStreamMarshallerTest.cs
----------------------------------------------------------------------
diff --git a/src/test/csharp/OpenWire/BaseDataStreamMarshallerTest.cs b/src/test/csharp/OpenWire/BaseDataStreamMarshallerTest.cs
new file mode 100644
index 0000000..dfd3cab
--- /dev/null
+++ b/src/test/csharp/OpenWire/BaseDataStreamMarshallerTest.cs
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.IO;
+using Apache.NMS.ActiveMQ.OpenWire;
+using Apache.NMS.ActiveMQ.Commands;
+using Apache.NMS.Util;
+using NUnit.Framework;
+
+namespace Apache.NMS.ActiveMQ.Test
+{
+    [TestFixture]
+    public class BaseDataStreamMarshalerTest
+    {
+        OpenWireFormat wireFormat;
+        TestDataStreamMarshaller testMarshaller;
+
+        [SetUp]
+        public void SetUp()
+        {
+            wireFormat = new OpenWireFormat();
+            testMarshaller = new TestDataStreamMarshaller();
+        }
+
+        [Test]
+        public void TestCompactedLongToIntegerTightUnmarshal()
+        {
+            long inputValue = 2147483667;
+
+            BooleanStream stream = new BooleanStream();
+            stream.WriteBoolean(true);
+            stream.WriteBoolean(false);
+
+            stream.Clear();
+
+            MemoryStream buffer = new MemoryStream();
+            BinaryWriter ds = new EndianBinaryWriter(buffer);
+
+            ds.Write((int) inputValue);
+
+            MemoryStream ins = new MemoryStream(buffer.ToArray());
+            BinaryReader dis = new EndianBinaryReader(ins);
+
+            long outputValue = testMarshaller.TightUnmarshalLong(wireFormat, dis, stream);
+            Assert.AreEqual(inputValue, outputValue);
+        }
+
+        [Test]
+        public void TestCompactedLongToShortTightUnmarshal()
+        {
+            long inputValue = 33000;
+
+            BooleanStream stream = new BooleanStream();
+            stream.WriteBoolean(false);
+            stream.WriteBoolean(true);
+
+            stream.Clear();
+
+            MemoryStream buffer = new MemoryStream();
+            BinaryWriter ds = new EndianBinaryWriter(buffer);
+
+            ds.Write((short) inputValue);
+
+            MemoryStream ins = new MemoryStream(buffer.ToArray());
+            BinaryReader dis = new EndianBinaryReader(ins);
+
+            long outputValue = testMarshaller.TightUnmarshalLong(wireFormat, dis, stream);
+            Assert.AreEqual(inputValue, outputValue);
+        }
+
+        private class TestDataStreamMarshaller : BaseDataStreamMarshaller
+        {
+            public override DataStructure CreateObject()
+            {
+                return null;
+            }
+
+            public override byte GetDataStructureType()
+            {
+                return 0;
+            }
+        }
+    }
+}
+


[35/50] [abbrv] activemq-nms-openwire git commit: NO-JIRA Fix failing test but ensuring that priority processing is enabled.

Posted by ta...@apache.org.
NO-JIRA Fix failing test but ensuring that priority processing is enabled.


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/ec37f323
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/ec37f323
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/ec37f323

Branch: refs/heads/master
Commit: ec37f323aa4575ff623b6218aac5bb60bca4a09c
Parents: 262ebde
Author: Timothy A. Bish <ta...@apache.org>
Authored: Tue Sep 29 22:27:46 2015 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Tue Sep 29 22:27:46 2015 +0000

----------------------------------------------------------------------
 src/test/csharp/QueueConsumerPriorityTest.cs | 4 ++++
 1 file changed, 4 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/ec37f323/src/test/csharp/QueueConsumerPriorityTest.cs
----------------------------------------------------------------------
diff --git a/src/test/csharp/QueueConsumerPriorityTest.cs b/src/test/csharp/QueueConsumerPriorityTest.cs
index 266fd91..2d6b947 100644
--- a/src/test/csharp/QueueConsumerPriorityTest.cs
+++ b/src/test/csharp/QueueConsumerPriorityTest.cs
@@ -101,6 +101,10 @@ namespace Apache.NMS.ActiveMQ.Test
         {
             IConnection conn = createConnection(true);
 
+            Connection connection = conn as Connection;
+            Assert.IsNotNull(connection);
+            connection.MessagePrioritySupported = true;
+
             ISession receiverSession = conn.CreateSession();
             ISession senderSession = conn.CreateSession();
 


[10/50] [abbrv] activemq-nms-openwire git commit: https://issues.apache.org/jira/browse/AMQNET-497

Posted by ta...@apache.org.
https://issues.apache.org/jira/browse/AMQNET-497


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/417e279e
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/417e279e
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/417e279e

Branch: refs/heads/1.6.x
Commit: 417e279e0490622c1922a788c19e5b1b39e1c258
Parents: f2606eb
Author: Timothy A. Bish <ta...@apache.org>
Authored: Fri Jan 9 15:01:26 2015 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Fri Jan 9 15:01:26 2015 +0000

----------------------------------------------------------------------
 src/main/csharp/MessageConsumer.cs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/417e279e/src/main/csharp/MessageConsumer.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/MessageConsumer.cs b/src/main/csharp/MessageConsumer.cs
index 9b03735..9e68fb3 100755
--- a/src/main/csharp/MessageConsumer.cs
+++ b/src/main/csharp/MessageConsumer.cs
@@ -57,7 +57,7 @@ namespace Apache.NMS.ActiveMQ
 
         private int redeliveryTimeout = 500;
         protected bool disposed = false;
-        private long lastDeliveredSequenceId = 0;
+        private long lastDeliveredSequenceId = -1;
         private int ackCounter = 0;
         private int deliveredCounter = 0;
         private int additionalWindowSize = 0;


[05/50] [abbrv] activemq-nms-openwire git commit: https://issues.apache.org/jira/browse/AMQNET-471

Posted by ta...@apache.org.
https://issues.apache.org/jira/browse/AMQNET-471

Resolve issues around transaction rollback during normal operation or during a failure detected with the FailoverTransport handling reconnection.  Issues involving false positives of duplicate redelivery and messages not being properly re-added to the unconsumed channel after rollback were fixed.  Also added logic to attempt to detect delivery of rolled back messages to another consumer on the same connection which requires the TX be rolled back as invalid.  


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/c6595f25
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/c6595f25
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/c6595f25

Branch: refs/heads/1.6.x
Commit: c6595f25b7bd0daf3a5ffc6ac617d946b687926e
Parents: 22fbad2
Author: Timothy A. Bish <ta...@apache.org>
Authored: Thu Aug 28 15:54:34 2014 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Thu Aug 28 15:54:34 2014 +0000

----------------------------------------------------------------------
 src/main/csharp/Commands/MessageDispatch.cs     |   14 +
 src/main/csharp/Connection.cs                   | 3083 +++++++--------
 src/main/csharp/MessageConsumer.cs              | 3556 +++++++++---------
 src/main/csharp/Session.cs                      |  141 +-
 src/main/csharp/TransactionContext.cs           |   78 +-
 .../csharp/Util/FifoMessageDispatchChannel.cs   |   46 +-
 src/main/csharp/Util/MessageDispatchChannel.cs  |    6 +-
 .../SimplePriorityMessageDispatchChannel.cs     |   44 +-
 .../failover/FailoverTransactionTest.cs         |   80 +-
 9 files changed, 3623 insertions(+), 3425 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/c6595f25/src/main/csharp/Commands/MessageDispatch.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Commands/MessageDispatch.cs b/src/main/csharp/Commands/MessageDispatch.cs
index e292b28..c3a2846 100644
--- a/src/main/csharp/Commands/MessageDispatch.cs
+++ b/src/main/csharp/Commands/MessageDispatch.cs
@@ -35,6 +35,8 @@ namespace Apache.NMS.ActiveMQ.Commands
         public const byte ID_MESSAGEDISPATCH = 21;
 
         private Exception rollbackCause = null;
+        private long deliverySequenceId;
+        private object consumer;
 
         ConsumerId consumerId;
         ActiveMQDestination destination;
@@ -75,6 +77,18 @@ namespace Apache.NMS.ActiveMQ.Commands
             set { this.rollbackCause = value; }
         }
 
+        public long DeliverySequenceId
+        {
+            get { return this.deliverySequenceId; }
+            set { this.deliverySequenceId = value; }
+        }
+
+        public object Consumer
+        {
+            get { return this.consumer; }
+            set { this.consumer = value; }
+        }
+
         public ConsumerId ConsumerId
         {
             get { return consumerId; }


[42/50] [abbrv] activemq-nms-openwire git commit: Ensure that the message body is always marshaled. Fixes case of a single message -> receive -> send -> receive which would lose its body on the re-send.

Posted by ta...@apache.org.
Ensure that the message body is always marshaled.  Fixes case of a single message -> receive -> send -> receive which would lose its body on the re-send.  

AMQNET-514
Fixes [AMQNET-AMQNET-514]. (See https://issues.apache.org/jira/browse/AMQNET-AMQNET-514)



Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/d091a999
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/d091a999
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/d091a999

Branch: refs/heads/1.7.x
Commit: d091a999ee25c0143d5c9b48394a18444d8fc639
Parents: 62b0c95
Author: Timothy A. Bish <ta...@apache.org>
Authored: Tue Jan 5 17:21:24 2016 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Tue Jan 5 17:21:24 2016 +0000

----------------------------------------------------------------------
 src/main/csharp/Commands/ActiveMQMapMessage.cs  |  6 +--
 .../csharp/Commands/ActiveMQMapMessageTest.cs   | 53 ++++++++++++++++++--
 2 files changed, 49 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/d091a999/src/main/csharp/Commands/ActiveMQMapMessage.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Commands/ActiveMQMapMessage.cs b/src/main/csharp/Commands/ActiveMQMapMessage.cs
index 7bdebdf..2b9a057 100644
--- a/src/main/csharp/Commands/ActiveMQMapMessage.cs
+++ b/src/main/csharp/Commands/ActiveMQMapMessage.cs
@@ -91,11 +91,7 @@ namespace Apache.NMS.ActiveMQ.Commands
 
 		public override void BeforeMarshall(OpenWireFormat wireFormat)
 		{
-			if(body == null)
-			{
-				Content = null;
-			}
-			else
+            if (this.Content == null && this.body != null && this.body.Count > 0)
 			{
 				MemoryStream buffer = new MemoryStream();
 				Stream target = buffer;

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/d091a999/src/test/csharp/Commands/ActiveMQMapMessageTest.cs
----------------------------------------------------------------------
diff --git a/src/test/csharp/Commands/ActiveMQMapMessageTest.cs b/src/test/csharp/Commands/ActiveMQMapMessageTest.cs
index 016822f..ecde5a6 100644
--- a/src/test/csharp/Commands/ActiveMQMapMessageTest.cs
+++ b/src/test/csharp/Commands/ActiveMQMapMessageTest.cs
@@ -19,15 +19,17 @@ using System;
 using System.Collections;
 using System.Globalization;
 using System.Text;
+using Apache.NMS;
+using Apache.NMS.Test;
+using Apache.NMS.Util;
 using Apache.NMS.ActiveMQ.Commands;
 using NUnit.Framework;
 
 namespace Apache.NMS.ActiveMQ.Test.Commands
 {    
     [TestFixture]
-    public class ActiveMQMapMessageTest
+    public class ActiveMQMapMessageTest : NMSTestSupport
     {
-
         private string name = "testName";
         
         [Test]
@@ -305,7 +307,6 @@ namespace Apache.NMS.ActiveMQ.Test.Commands
             catch(MessageFormatException)
             {
             }
-    
         }
     
         [Test]
@@ -457,7 +458,8 @@ namespace Apache.NMS.ActiveMQ.Test.Commands
             {
             }
             
-            try {
+            try 
+            {
                 msg.Body.SetFloat("float", 1.5f);
                 Assert.Fail("should throw exception");
             } 
@@ -543,6 +545,47 @@ namespace Apache.NMS.ActiveMQ.Test.Commands
             msg.Body.GetShort("short");
             msg.Body.GetString("string");
         }
-        
+
+        [Test]
+        public void TestMessageQueueDequeQueueDequeue()
+        {
+            using (IConnection connection = CreateConnection())
+            using (ISession session = connection.CreateSession())
+            {
+                IDestination destination = session.GetQueue("TestMessageQueueDequeQueueDequeue");
+
+                (connection as Connection).DeleteDestination(destination);
+
+                using (IMessageConsumer consumer = session.CreateConsumer(destination))
+                using (IMessageProducer producer = session.CreateProducer(destination))
+                {
+                    connection.Start();
+
+                    producer.DeliveryMode = MsgDeliveryMode.Persistent;
+
+                    IMapMessage request = session.CreateMapMessage();
+                    request.Body.SetString("Unit-Test-Key", "Unit-Test-Value");
+                    Assert.IsNotNull(request, "request is null");
+                    Assert.IsTrue(request.Body.Contains("Unit-Test-Key"), "Unit-Test-Key does not exist");
+                    producer.Send(request);
+
+                    // Relay from Queue back again.
+                    IMessage received = consumer.Receive(TimeSpan.FromSeconds(2));
+                    Assert.IsNotNull(received);
+                    IMapMessage mapMessage = received as IMapMessage;
+                    Assert.IsNotNull(mapMessage);
+                    producer.Send(mapMessage);
+
+                    // Read it again and validate.
+                    received = consumer.Receive(TimeSpan.FromSeconds(2));
+                    Assert.IsNotNull(received);
+                    mapMessage = received as IMapMessage;
+                    Assert.IsNotNull(mapMessage, "currentMessage is null");
+
+                    // This entry in the map message should not be removed
+                    Assert.IsTrue(mapMessage.Body.Contains("Unit-Test-Key"), "Unit-Test-Key does not exist");
+                }
+            }
+        }
     }
 }


[15/50] [abbrv] activemq-nms-openwire git commit: https://issues.apache.org/jira/browse/AMQNET-498

Posted by ta...@apache.org.
https://issues.apache.org/jira/browse/AMQNET-498

Reduce log level to debug as it is not an error condition.


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/94ad4097
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/94ad4097
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/94ad4097

Branch: refs/heads/1.6.x
Commit: 94ad40978325fdf43b50b85d985bb9730d9c6296
Parents: 1e6374d
Author: Timothy A. Bish <ta...@apache.org>
Authored: Tue Feb 24 14:41:56 2015 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Tue Feb 24 14:41:56 2015 +0000

----------------------------------------------------------------------
 src/main/csharp/Connection.cs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/94ad4097/src/main/csharp/Connection.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Connection.cs b/src/main/csharp/Connection.cs
index 242a3cb..1d82d6f 100755
--- a/src/main/csharp/Connection.cs
+++ b/src/main/csharp/Connection.cs
@@ -1167,7 +1167,7 @@ namespace Apache.NMS.ActiveMQ
                 }
             }
 
-            Tracer.ErrorFormat("Connection[{0}]: No such consumer active: {1}", this.ConnectionId, dispatch.ConsumerId);
+            Tracer.DebugFormat("Connection[{0}]: No such consumer active: {1}", this.ConnectionId, dispatch.ConsumerId);
         }
 
         protected void OnKeepAliveCommand(ITransport commandTransport, KeepAliveInfo info)


[24/50] [abbrv] activemq-nms-openwire git commit: Merged revision(s) 1689948 from activemq/activemq-dotnet/Apache.NMS.ActiveMQ/branches/1.7.x: Set the socket exception error code to RTSSL_HANDSHAKE_FAILURE. Fixes [AMQNET-502]. (See https://issues.apache.

Posted by ta...@apache.org.
Merged revision(s) 1689948 from activemq/activemq-dotnet/Apache.NMS.ActiveMQ/branches/1.7.x:
Set the socket exception error code to RTSSL_HANDSHAKE_FAILURE.
Fixes [AMQNET-502]. (See https://issues.apache.org/jira/browse/AMQNET-502)


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/3c31b7e2
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/3c31b7e2
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/3c31b7e2

Branch: refs/heads/master
Commit: 3c31b7e202808dc982fc68fdd69ed228d99e7dd0
Parents: aba1ae0
Author: Jim Gomes <jg...@apache.org>
Authored: Wed Jul 8 19:45:40 2015 +0000
Committer: Jim Gomes <jg...@apache.org>
Committed: Wed Jul 8 19:45:40 2015 +0000

----------------------------------------------------------------------
 src/main/csharp/Transport/Tcp/TcpTransportFactory.cs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/3c31b7e2/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs b/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs
index 786e4e2..2907a65 100644
--- a/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs
+++ b/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs
@@ -372,7 +372,8 @@ namespace Apache.NMS.ActiveMQ.Transport.Tcp
 
                 if(null == socket)
                 {
-                    throw new SocketException();
+                    const int RTSSL_HANDSHAKE_FAILURE = -2;
+                    throw new SocketException(RTSSL_HANDSHAKE_FAILURE);
                 }
             }
             catch(Exception ex)


[37/50] [abbrv] activemq-nms-openwire git commit: https://issues.apache.org/jira/browse/AMQNET-489

Posted by ta...@apache.org.
https://issues.apache.org/jira/browse/AMQNET-489

Ensure that the lastDeliveredSequenceId gets sent when the ConnectionInfo is sent.


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/0d92ec56
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/0d92ec56
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/0d92ec56

Branch: refs/heads/1.7.x
Commit: 0d92ec561181501241a5ea7b902432f9c1231a07
Parents: 80368b0
Author: Timothy A. Bish <ta...@apache.org>
Authored: Wed Sep 30 18:53:27 2015 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Wed Sep 30 18:53:27 2015 +0000

----------------------------------------------------------------------
 src/main/csharp/Connection.cs | 8 ++++++--
 src/main/csharp/Session.cs    | 5 +++++
 2 files changed, 11 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/0d92ec56/src/main/csharp/Connection.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Connection.cs b/src/main/csharp/Connection.cs
index a4a5247..74be66f 100755
--- a/src/main/csharp/Connection.cs
+++ b/src/main/csharp/Connection.cs
@@ -713,11 +713,13 @@ namespace Apache.NMS.ActiveMQ
                         }
                     }
 
+                    long lastDeliveredSequenceId = -1;
                     lock(sessions.SyncRoot)
                     {
                         foreach(Session session in sessions)
                         {
                             session.Shutdown();
+                            lastDeliveredSequenceId = Math.Max(lastDeliveredSequenceId, session.LastDeliveredSequenceId);
                         }
                     }
                     sessions.Clear();
@@ -740,7 +742,7 @@ namespace Apache.NMS.ActiveMQ
                     // inform the broker of a remove, and if the transport is failed, why bother.
                     if(connected.Value && !transportFailed.Value)
                     {
-                        DisposeOf(ConnectionId);
+                        DisposeOf(ConnectionId, lastDeliveredSequenceId);
                         ShutdownInfo shutdowninfo = new ShutdownInfo();
                         transport.Oneway(shutdowninfo);
                     }
@@ -908,12 +910,14 @@ namespace Apache.NMS.ActiveMQ
             }
         }
 
-        private void DisposeOf(DataStructure objectId)
+        private void DisposeOf(DataStructure objectId, long lastDeliveredSequenceId)
         {
             try
             {
                 RemoveInfo command = new RemoveInfo();
                 command.ObjectId = objectId;
+                command.LastDeliveredSequenceId = lastDeliveredSequenceId;
+
                 if(asyncClose)
                 {
                     Tracer.DebugFormat("Connection[{0}]: Asynchronously disposing of Connection.", this.ConnectionId);

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/0d92ec56/src/main/csharp/Session.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Session.cs b/src/main/csharp/Session.cs
index 8fd6db3..ef91700 100755
--- a/src/main/csharp/Session.cs
+++ b/src/main/csharp/Session.cs
@@ -305,6 +305,11 @@ namespace Apache.NMS.ActiveMQ
             }
         }
 
+        internal long LastDeliveredSequenceId
+        {
+            get { return this.lastDeliveredSequenceId; }
+        }
+
         #endregion
 
         #region ISession Members


[39/50] [abbrv] activemq-nms-openwire git commit: https://issues.apache.org/jira/browse/AMQNET-513

Posted by ta...@apache.org.
https://issues.apache.org/jira/browse/AMQNET-513

Preserve the rollback cause when poisoning a message.


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/78d40fd9
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/78d40fd9
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/78d40fd9

Branch: refs/heads/master
Commit: 78d40fd907781b688e42c5855a27030acb78c767
Parents: 34770b6
Author: Timothy A. Bish <ta...@apache.org>
Authored: Thu Nov 19 23:18:39 2015 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Thu Nov 19 23:18:39 2015 +0000

----------------------------------------------------------------------
 src/main/csharp/MessageConsumer.cs              |   8 +-
 .../csharp/MessageListenerRedeliveryTest.cs     | 244 ++++++++++++++++++-
 2 files changed, 245 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/78d40fd9/src/main/csharp/MessageConsumer.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/MessageConsumer.cs b/src/main/csharp/MessageConsumer.cs
index 6f04946..74d07a1 100755
--- a/src/main/csharp/MessageConsumer.cs
+++ b/src/main/csharp/MessageConsumer.cs
@@ -883,10 +883,10 @@ namespace Apache.NMS.ActiveMQ
                     }
                     catch(Exception e)
                     {
+                        dispatch.RollbackCause = e;
                         if(IsAutoAcknowledgeBatch || IsAutoAcknowledgeEach || IsIndividualAcknowledge)
                         {
                             // Schedule redelivery and possible dlq processing
-                            dispatch.RollbackCause = e;
                             Rollback();
                         }
                         else
@@ -1094,9 +1094,9 @@ namespace Apache.NMS.ActiveMQ
             }
         }
 
-        private bool ConsumeExpiredMessage(MessageDispatch dispatch) 
+        private bool ConsumeExpiredMessage(MessageDispatch dispatch)
         {
-            if (dispatch.Message.IsExpired()) 
+            if (dispatch.Message.IsExpired())
             {
                 return !info.Browser && !IgnoreExpiration;
             }
@@ -1480,7 +1480,9 @@ namespace Apache.NMS.ActiveMQ
                             cause.ExceptionClass = "javax.jms.JMSException";
                             cause.Message = lastMd.RollbackCause.Message;
                             poisonCause.Cause = cause;
+                            poisonCause.Message = poisonCause.Message + " cause: " + lastMd.RollbackCause.Message;
                         }
+
                         ack.FirstMessageId = firstMsgId;
                         ack.PoisonCause = poisonCause;
 

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/78d40fd9/src/test/csharp/MessageListenerRedeliveryTest.cs
----------------------------------------------------------------------
diff --git a/src/test/csharp/MessageListenerRedeliveryTest.cs b/src/test/csharp/MessageListenerRedeliveryTest.cs
index 0b22b7a..17d4293 100644
--- a/src/test/csharp/MessageListenerRedeliveryTest.cs
+++ b/src/test/csharp/MessageListenerRedeliveryTest.cs
@@ -15,7 +15,11 @@
  * limitations under the License.
  */
 
+using System;
 using System.Threading;
+using System.Collections;
+using Apache.NMS;
+using Apache.NMS.Util;
 using Apache.NMS.Test;
 using Apache.NMS.Policies;
 using NUnit.Framework;
@@ -26,15 +30,29 @@ namespace Apache.NMS.ActiveMQ.Test
     public class MessageListenerRedeliveryTest : NMSTestSupport
     {
         private Connection connection;
-        private int counter;
+        private volatile int counter;
         private ISession session;
+        private ArrayList received;
+        private ArrayList dlqMessages;
+        private int maxDeliveries;
+
+        private CountDownLatch gotOneMessage;
+        private CountDownLatch gotTwoMessages;
+        private CountDownLatch gotOneDlqMessage;
+        private CountDownLatch gotMaxRedeliveries;
 
         [SetUp]
         public override void SetUp()
         {
             this.connection = (Connection) CreateConnection();
             this.connection.RedeliveryPolicy = GetRedeliveryPolicy();
-
+            this.gotOneMessage = new CountDownLatch(1);
+            this.gotTwoMessages = new CountDownLatch(2);
+            this.gotOneDlqMessage = new CountDownLatch(1);
+            this.maxDeliveries = GetRedeliveryPolicy().MaximumRedeliveries;
+            this.gotMaxRedeliveries = new CountDownLatch(maxDeliveries);
+            this.received = new ArrayList();
+            this.dlqMessages = new ArrayList();
             this.counter = 0;
         }
 
@@ -76,6 +94,39 @@ namespace Apache.NMS.ActiveMQ.Test
             }
         }
 
+        private void OnTracedReceiveMessage(IMessage message) 
+        {
+            try 
+            {
+                received.Add(((ITextMessage) message).Text);
+            } 
+            catch (Exception e) 
+            {
+                Assert.Fail("Error: " + e.Message);
+            }
+
+            if (++counter < maxDeliveries) 
+            {
+                throw new Exception("force a redelivery");
+            }
+
+            // new blood
+            counter = 0;
+            gotTwoMessages.countDown();
+        }
+
+        private void OnDlqMessage(IMessage message) 
+        {
+            dlqMessages.Add(message);
+            gotOneDlqMessage.countDown();
+        }
+
+        private void OnRedeliveredMessage(IMessage message) 
+        {
+            gotMaxRedeliveries.countDown();
+            throw new Exception("Test Forcing a Rollback");
+        }
+
         [Test]
         public void TestQueueRollbackConsumerListener() 
         {
@@ -91,7 +142,7 @@ namespace Apache.NMS.ActiveMQ.Test
             IMessageConsumer consumer = session.CreateConsumer(queue);
 
             consumer.Listener += new MessageListener(OnMessageListener);
-    
+
             Thread.Sleep(500);
 
             // first try.. should get 2 since there is no delay on the
@@ -125,6 +176,191 @@ namespace Apache.NMS.ActiveMQ.Test
     
             session.Close();
         }
-       
+
+        [Test]
+        public void TestQueueRollbackSessionListener()
+        {
+            connection.Start();
+
+            this.session = connection.CreateSession(AcknowledgementMode.Transactional);
+            IQueue queue = session.CreateTemporaryQueue();
+            IMessageProducer producer = CreateProducer(session, queue);
+            IMessage message = CreateTextMessage(session);
+            producer.Send(message);
+            session.Commit();
+
+            IMessageConsumer consumer = session.CreateConsumer(queue);
+            consumer.Listener += new MessageListener(OnMessageListener);
+
+            Thread.Sleep(1000);
+
+            // first try
+            Assert.AreEqual(2, counter);
+
+            Thread.Sleep(1500);
+
+            // second try (redelivery after 1 sec)
+            Assert.AreEqual(3, counter);
+
+            Thread.Sleep(3000);
+
+            // third try (redelivery after 2 seconds) - it should give up after that
+            Assert.AreEqual(4, counter);
+
+            // create new message
+            producer.Send(CreateTextMessage(session));
+            session.Commit();
+          
+            Thread.Sleep(1000);
+
+            // it should be committed, so no redelivery
+            Assert.AreEqual(5, counter);
+
+            Thread.Sleep(2000);
+
+            // no redelivery, counter should still be 4
+            Assert.AreEqual(5, counter);
+
+            session.Close();
+        }
+
+        [Test]
+        public void TestQueueSessionListenerExceptionRetry()
+        {
+            connection.Start();
+
+            ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
+            IQueue queue = session.CreateTemporaryQueue();
+            IMessageProducer producer = CreateProducer(session, queue);
+            IMessage message = CreateTextMessage(session, "1");
+            producer.Send(message);
+            message = CreateTextMessage(session, "2");
+            producer.Send(message);
+
+            IMessageConsumer consumer = session.CreateConsumer(queue);
+            consumer.Listener += new MessageListener(OnTracedReceiveMessage);
+
+            Assert.IsTrue(gotTwoMessages.await(TimeSpan.FromSeconds(20)), "got message before retry expiry");
+
+            for (int i = 0; i < maxDeliveries; i++)
+            {
+                Assert.AreEqual("1", received[i], "got first redelivered: " + i);
+            }
+            for (int i = maxDeliveries; i < maxDeliveries * 2; i++)
+            {
+                Assert.AreEqual("2", received[i], "got first redelivered: " + i);
+            }
+
+            session.Close();
+        }
+
+        [Test]
+        public void TestQueueSessionListenerExceptionDlq()
+        {
+            connection.Start();
+
+            session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
+            IQueue queue = session.CreateTemporaryQueue();
+            IMessageProducer producer = CreateProducer(session, queue);
+            IMessage message = CreateTextMessage(session);
+            producer.Send(message);
+
+            IDestination dlqDestination = session.GetQueue("ActiveMQ.DLQ");
+            connection.DeleteDestination(dlqDestination);
+            IMessageConsumer dlqConsumer = session.CreateConsumer(dlqDestination);
+            dlqConsumer.Listener += new MessageListener(OnDlqMessage);           
+
+            IMessageConsumer consumer = session.CreateConsumer(queue);
+            consumer.Listener += new MessageListener(OnRedeliveredMessage);
+
+            Assert.IsTrue(gotMaxRedeliveries.await(TimeSpan.FromSeconds(20)), "got message before retry expiry");
+
+            // check DLQ
+            Assert.IsTrue(gotOneDlqMessage.await(TimeSpan.FromSeconds(20)), "got dlq message");
+
+            // check DLQ message cause is captured
+            message = dlqMessages[0] as IMessage;
+            Assert.IsNotNull(message, "dlq message captured");
+            String cause = message.Properties.GetString("dlqDeliveryFailureCause");
+
+            Assert.IsTrue(cause.Contains("JMSException"), "cause 'cause' exception is remembered");
+            Assert.IsTrue(cause.Contains("Test"), "is correct exception");
+            Assert.IsTrue(cause.Contains("RedeliveryPolicy"), "cause policy is remembered");
+
+            session.Close();
+        }
+
+        private void OnMessageThenRollback(IMessage message)
+        {
+            gotOneMessage.countDown();
+            try
+            {
+                session.Rollback();
+            } 
+            catch (Exception) 
+            {
+            }
+
+            throw new Exception("Test force a redelivery");
+        }
+
+        [Test]
+        public void TestTransactedQueueSessionListenerExceptionDlq()
+        {
+            connection.Start();
+
+            session = connection.CreateSession(AcknowledgementMode.Transactional);
+            IQueue queue = session.CreateTemporaryQueue();
+            IMessageProducer producer = CreateProducer(session, queue);
+            IMessage message = CreateTextMessage(session);
+            producer.Send(message);
+            session.Commit();
+
+            IDestination dlqDestination = session.GetQueue("ActiveMQ.DLQ");
+            connection.DeleteDestination(dlqDestination);
+            IMessageConsumer dlqConsumer = session.CreateConsumer(dlqDestination);
+            dlqConsumer.Listener += new MessageListener(OnDlqMessage);           
+
+            IMessageConsumer consumer = session.CreateConsumer(queue);
+            consumer.Listener += new MessageListener(OnMessageThenRollback);
+
+            Assert.IsTrue(gotOneMessage.await(TimeSpan.FromSeconds(20)), "got message before retry expiry");
+
+            // check DLQ
+            Assert.IsTrue(gotOneDlqMessage.await(TimeSpan.FromSeconds(20)), "got dlq message");
+
+            // check DLQ message cause is captured
+            message = dlqMessages[0] as IMessage;
+            Assert.IsNotNull(message, "dlq message captured");
+            String cause = message.Properties.GetString("dlqDeliveryFailureCause");
+
+            Assert.IsTrue(cause.Contains("JMSException"), "cause 'cause' exception is remembered");
+            Assert.IsTrue(cause.Contains("Test force"), "is correct exception");
+            Assert.IsTrue(cause.Contains("RedeliveryPolicy"), "cause policy is remembered");
+
+            session.Close();
+        }
+
+        private ITextMessage CreateTextMessage(ISession session, String text)
+        {
+            return session.CreateTextMessage(text);
+        }
+
+        private ITextMessage CreateTextMessage(ISession session)
+        {
+            return session.CreateTextMessage("Hello");
+        }
+
+        private IMessageProducer CreateProducer(ISession session, IDestination queue)
+        {
+            IMessageProducer producer = session.CreateProducer(queue);
+            producer.DeliveryMode = GetDeliveryMode();
+            return producer;
+        }
+
+        protected MsgDeliveryMode GetDeliveryMode() 
+        {
+            return MsgDeliveryMode.Persistent;
+        }
     }
 }


[11/50] [abbrv] activemq-nms-openwire git commit: Branch for a 1.7.x release tree.

Posted by ta...@apache.org.
Branch for a 1.7.x release tree.


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/1d3049bd
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/1d3049bd
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/1d3049bd

Branch: refs/heads/1.7.x
Commit: 1d3049bdc602439b72f742594ea9f185ca74e7de
Parents: b9d7a80
Author: Timothy A. Bish <ta...@apache.org>
Authored: Fri Jan 9 15:29:11 2015 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Fri Jan 9 15:29:11 2015 +0000

----------------------------------------------------------------------

----------------------------------------------------------------------



[21/50] [abbrv] activemq-nms-openwire git commit: Apply patch to improve ID parsing to avoid mis-parsing hostnames with hyphens. Thanks, Andrea Montemaggio! Fixes [AMQNET-398]. (See https://issues.apache.org/jira/browse/AMQNET-398)

Posted by ta...@apache.org.
Apply patch to improve ID parsing to avoid mis-parsing hostnames with hyphens. Thanks, Andrea Montemaggio!
Fixes [AMQNET-398]. (See https://issues.apache.org/jira/browse/AMQNET-398)



Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/66662a53
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/66662a53
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/66662a53

Branch: refs/heads/1.7.x
Commit: 66662a53648e86dc9b07ba63f66c2dcdae69a5db
Parents: 8e6479f
Author: Jim Gomes <jg...@apache.org>
Authored: Wed Jul 8 18:14:57 2015 +0000
Committer: Jim Gomes <jg...@apache.org>
Committed: Wed Jul 8 18:14:57 2015 +0000

----------------------------------------------------------------------
 src/main/csharp/NetTxConnection.cs | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/66662a53/src/main/csharp/NetTxConnection.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/NetTxConnection.cs b/src/main/csharp/NetTxConnection.cs
index 8f1976c..8005e2c 100644
--- a/src/main/csharp/NetTxConnection.cs
+++ b/src/main/csharp/NetTxConnection.cs
@@ -16,6 +16,7 @@
  */
 
 using System;
+using System.Text.RegularExpressions;
 using System.Transactions;
 using Apache.NMS.ActiveMQ.Transport;
 using Apache.NMS.ActiveMQ.Util;
@@ -95,18 +96,20 @@ namespace Apache.NMS.ActiveMQ
 
         private static Guid GuidFromId(string id)
         {
-            // Remove the ID: prefix, that's non-unique to be sure
-            string resId = id.TrimStart("ID:".ToCharArray());
-
-            // Remaing parts should be host-port-timestamp-instance:sequence
-            string[] parts = resId.Split(":-".ToCharArray());
-
+            MatchCollection matches = Regex.Matches(id, @"(\d+)-(\d+)-(\d+):(\d+)$");
+            if(0 == matches.Count)
+            {
+                throw new FormatException(string.Format("Unable to extract a GUID from string '{0}'", id));
+            }
+ 
+            GroupCollection groups = matches[0].Groups;
+ 
             // We don't use the hostname here, just the remaining bits.
-            int a = Int32.Parse(parts[parts.Length-4]);
-            short b = Int16.Parse(parts[parts.Length-2]);
-            short c = Int16.Parse(parts[parts.Length-1]);
-            byte[] d = System.BitConverter.GetBytes(Int64.Parse(parts[parts.Length-3]));
-
+            int a = Int32.Parse(groups[1].Value);
+            short b = Int16.Parse(groups[3].Value);
+            short c = Int16.Parse(groups[4].Value);
+            byte[] d = BitConverter.GetBytes(Int64.Parse(groups[2].Value));
+ 
             return new Guid(a, b, c, d);
         }
     }


[16/50] [abbrv] activemq-nms-openwire git commit: https://issues.apache.org/jira/browse/AMQNET-498

Posted by ta...@apache.org.
https://issues.apache.org/jira/browse/AMQNET-498

Reduce log level to debug as it is not an error condition.


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/b20dde96
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/b20dde96
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/b20dde96

Branch: refs/heads/master
Commit: b20dde9603a2d609b08bf85e3e87a222c4c1a503
Parents: f4332dd
Author: Timothy A. Bish <ta...@apache.org>
Authored: Tue Feb 24 14:44:24 2015 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Tue Feb 24 14:44:24 2015 +0000

----------------------------------------------------------------------
 src/main/csharp/Connection.cs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/b20dde96/src/main/csharp/Connection.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Connection.cs b/src/main/csharp/Connection.cs
index a4a5247..33fb3e8 100755
--- a/src/main/csharp/Connection.cs
+++ b/src/main/csharp/Connection.cs
@@ -1167,7 +1167,7 @@ namespace Apache.NMS.ActiveMQ
                 }
             }
 
-            Tracer.ErrorFormat("Connection[{0}]: No such consumer active: {1}", this.ConnectionId, dispatch.ConsumerId);
+            Tracer.DebugFormat("Connection[{0}]: No such consumer active: {1}", this.ConnectionId, dispatch.ConsumerId);
         }
 
         protected void OnKeepAliveCommand(ITransport commandTransport, KeepAliveInfo info)


[25/50] [abbrv] activemq-nms-openwire git commit: AMQNET-504 test svngit2jira

Posted by ta...@apache.org.
AMQNET-504 test svngit2jira


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/f1882322
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/f1882322
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/f1882322

Branch: refs/heads/master
Commit: f1882322c2b34600814863039f6b88f5cf8ed24a
Parents: 3c31b7e
Author: Timothy A. Bish <ta...@apache.org>
Authored: Tue Jul 14 15:47:29 2015 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Tue Jul 14 15:47:29 2015 +0000

----------------------------------------------------------------------
 test.txt | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/f1882322/test.txt
----------------------------------------------------------------------
diff --git a/test.txt b/test.txt
new file mode 100644
index 0000000..e69de29


[30/50] [abbrv] activemq-nms-openwire git commit: Ensure that a new pull command is sent when a message exceeds the redelivery max and is poisoned. Fixes [AMQNET-507]. (See https://issues.apache.org/jira/browse/AMQNET-507)

Posted by ta...@apache.org.
Ensure that a new pull command is sent when a message exceeds the redelivery max and is poisoned. 
Fixes [AMQNET-507]. (See https://issues.apache.org/jira/browse/AMQNET-507)



Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/3e9f720b
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/3e9f720b
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/3e9f720b

Branch: refs/heads/master
Commit: 3e9f720b53c90deba3356d98dce842af83f8b925
Parents: edb4f05
Author: Timothy A. Bish <ta...@apache.org>
Authored: Wed Aug 12 22:59:21 2015 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Wed Aug 12 22:59:21 2015 +0000

----------------------------------------------------------------------
 src/main/csharp/MessageConsumer.cs          | 16 ++++++++
 src/test/csharp/ZeroPrefetchConsumerTest.cs | 48 ++++++++++++++++++++++++
 2 files changed, 64 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/3e9f720b/src/main/csharp/MessageConsumer.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/MessageConsumer.cs b/src/main/csharp/MessageConsumer.cs
index 41df167..48018f3 100755
--- a/src/main/csharp/MessageConsumer.cs
+++ b/src/main/csharp/MessageConsumer.cs
@@ -1065,6 +1065,22 @@ namespace Apache.NMS.ActiveMQ
                                        ConsumerId, dispatch);
                     PosionAck(dispatch, "dispatch to " + ConsumerId + " exceeds redelivery " +
                                         "policy limit:" + redeliveryPolicy.MaximumRedeliveries);
+
+                    // Refresh the dispatch time
+                    dispatchTime = DateTime.Now;
+
+                    if(dispatchTime > deadline)
+                    {
+                        // Out of time.
+                        timeout = TimeSpan.Zero;
+                    }
+                    else
+                    {
+                        // Adjust the timeout to the remaining time.
+                        timeout = deadline - dispatchTime;
+                    }
+
+                    SendPullRequest((long) timeout.TotalMilliseconds);
                 }
                 else
                 {

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/3e9f720b/src/test/csharp/ZeroPrefetchConsumerTest.cs
----------------------------------------------------------------------
diff --git a/src/test/csharp/ZeroPrefetchConsumerTest.cs b/src/test/csharp/ZeroPrefetchConsumerTest.cs
index b536d71..482557e 100644
--- a/src/test/csharp/ZeroPrefetchConsumerTest.cs
+++ b/src/test/csharp/ZeroPrefetchConsumerTest.cs
@@ -154,6 +154,54 @@ namespace Apache.NMS.ActiveMQ.Test
             Assert.IsNull(answer, "Should have not received a message!");
         }
 
+        [Test]
+        public void TestConsumerReceivePrefetchZeroRedeliveryZero()
+        {
+            const string QUEUE_NAME = "TEST.TestConsumerReceivePrefetchZeroRedeliveryZero";
+
+            using (Connection connection = CreateConnection() as Connection)
+            using (ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+            using (IQueue queue = session.GetQueue(QUEUE_NAME))
+            {              
+                session.DeleteDestination(queue);
+
+                using (IMessageProducer producer = session.CreateProducer(queue))
+                {
+                    ITextMessage textMessage = session.CreateTextMessage("test Message");
+                    producer.Send(textMessage);
+                }
+            }
+
+            // consume and rollback - increase redelivery counter on message
+            using (Connection connection = CreateConnection() as Connection)
+            using (ISession session = connection.CreateSession(AcknowledgementMode.Transactional))
+            using (IQueue queue = session.GetQueue(QUEUE_NAME))
+            using (IMessageConsumer consumer = session.CreateConsumer(queue))
+            {              
+                connection.Start();
+                IMessage message = consumer.Receive(TimeSpan.FromMilliseconds(3000));
+                Assert.IsNotNull(message);
+                session.Rollback();
+            }
+
+            // try consume with timeout - expect it to timeout and return NULL message
+            using (Connection connection = CreateConnection() as Connection)
+            {
+                connection.PrefetchPolicy.All = 0;
+                connection.RedeliveryPolicy.MaximumRedeliveries = 0;
+                connection.Start();
+
+                ISession session = connection.CreateSession(AcknowledgementMode.Transactional);
+                IQueue queue = session.GetQueue(QUEUE_NAME);
+
+                using (IMessageConsumer consumer = session.CreateConsumer(queue))
+                {
+                    IMessage message = consumer.Receive(TimeSpan.FromMilliseconds(3000));
+                    Assert.IsNull(message);
+                }
+            }
+        }
+
         [SetUp]
         public override void SetUp()
         {


[43/50] [abbrv] activemq-nms-openwire git commit: Apply fix for problems with LRUCache not properly cleaning up after itself. Fixes [AMQNET-AMQNET-521]. (See https://issues.apache.org/jira/browse/AMQNET-AMQNET-521)

Posted by ta...@apache.org.
Apply fix for problems with LRUCache not properly cleaning up after itself.  
Fixes [AMQNET-AMQNET-521]. (See https://issues.apache.org/jira/browse/AMQNET-AMQNET-521)



Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/37c86bdc
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/37c86bdc
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/37c86bdc

Branch: refs/heads/master
Commit: 37c86bdc07289cd995a3c4d4ab12992bfafc9da0
Parents: 44f4319
Author: Timothy A. Bish <ta...@apache.org>
Authored: Tue Mar 15 14:53:28 2016 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Tue Mar 15 14:53:28 2016 +0000

----------------------------------------------------------------------
 src/main/csharp/Util/LRUCache.cs | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/37c86bdc/src/main/csharp/Util/LRUCache.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Util/LRUCache.cs b/src/main/csharp/Util/LRUCache.cs
index ec3d7b9..0fcdb90 100644
--- a/src/main/csharp/Util/LRUCache.cs
+++ b/src/main/csharp/Util/LRUCache.cs
@@ -47,6 +47,7 @@ namespace Apache.NMS.ActiveMQ.Util
 		public void Clear()
 		{
 			dictionary.Clear();
+            entries.Clear();
 		}
 
         public int Count
@@ -65,12 +66,12 @@ namespace Apache.NMS.ActiveMQ.Util
 			get { return dictionary[key]; }
 			set 
 			{ 
-				TValue currentValue = default (TValue);
+				TValue currentValue;
 				// Moved used item to end of list since it been used again.
 				if (dictionary.TryGetValue(key, out currentValue))
 				{
 					KeyValuePair<TKey, TValue> entry = 
-						new KeyValuePair<TKey, TValue>(key, value);
+                        new KeyValuePair<TKey, TValue>(key, currentValue);
 					entries.Remove(entry);
 				}
 


[41/50] [abbrv] activemq-nms-openwire git commit: Ensure that the message body is always marshaled. Fixes case of a single message -> receive -> send -> receive which would lose its body on the re-send.

Posted by ta...@apache.org.
Ensure that the message body is always marshaled.  Fixes case of a single message -> receive -> send -> receive which would lose its body on the re-send.  

AMQNET-514
Fixes [AMQNET-AMQNET-514]. (See https://issues.apache.org/jira/browse/AMQNET-AMQNET-514)



Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/44f43190
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/44f43190
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/44f43190

Branch: refs/heads/master
Commit: 44f43190fb3714c908f5d759501ba50958f172f9
Parents: 78d40fd
Author: Timothy A. Bish <ta...@apache.org>
Authored: Tue Jan 5 17:17:31 2016 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Tue Jan 5 17:17:31 2016 +0000

----------------------------------------------------------------------
 src/main/csharp/Commands/ActiveMQMapMessage.cs  |  6 +--
 .../csharp/Commands/ActiveMQMapMessageTest.cs   | 53 ++++++++++++++++++--
 2 files changed, 49 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/44f43190/src/main/csharp/Commands/ActiveMQMapMessage.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Commands/ActiveMQMapMessage.cs b/src/main/csharp/Commands/ActiveMQMapMessage.cs
index 7bdebdf..2b9a057 100644
--- a/src/main/csharp/Commands/ActiveMQMapMessage.cs
+++ b/src/main/csharp/Commands/ActiveMQMapMessage.cs
@@ -91,11 +91,7 @@ namespace Apache.NMS.ActiveMQ.Commands
 
 		public override void BeforeMarshall(OpenWireFormat wireFormat)
 		{
-			if(body == null)
-			{
-				Content = null;
-			}
-			else
+            if (this.Content == null && this.body != null && this.body.Count > 0)
 			{
 				MemoryStream buffer = new MemoryStream();
 				Stream target = buffer;

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/44f43190/src/test/csharp/Commands/ActiveMQMapMessageTest.cs
----------------------------------------------------------------------
diff --git a/src/test/csharp/Commands/ActiveMQMapMessageTest.cs b/src/test/csharp/Commands/ActiveMQMapMessageTest.cs
index 016822f..ecde5a6 100644
--- a/src/test/csharp/Commands/ActiveMQMapMessageTest.cs
+++ b/src/test/csharp/Commands/ActiveMQMapMessageTest.cs
@@ -19,15 +19,17 @@ using System;
 using System.Collections;
 using System.Globalization;
 using System.Text;
+using Apache.NMS;
+using Apache.NMS.Test;
+using Apache.NMS.Util;
 using Apache.NMS.ActiveMQ.Commands;
 using NUnit.Framework;
 
 namespace Apache.NMS.ActiveMQ.Test.Commands
 {    
     [TestFixture]
-    public class ActiveMQMapMessageTest
+    public class ActiveMQMapMessageTest : NMSTestSupport
     {
-
         private string name = "testName";
         
         [Test]
@@ -305,7 +307,6 @@ namespace Apache.NMS.ActiveMQ.Test.Commands
             catch(MessageFormatException)
             {
             }
-    
         }
     
         [Test]
@@ -457,7 +458,8 @@ namespace Apache.NMS.ActiveMQ.Test.Commands
             {
             }
             
-            try {
+            try 
+            {
                 msg.Body.SetFloat("float", 1.5f);
                 Assert.Fail("should throw exception");
             } 
@@ -543,6 +545,47 @@ namespace Apache.NMS.ActiveMQ.Test.Commands
             msg.Body.GetShort("short");
             msg.Body.GetString("string");
         }
-        
+
+        [Test]
+        public void TestMessageQueueDequeQueueDequeue()
+        {
+            using (IConnection connection = CreateConnection())
+            using (ISession session = connection.CreateSession())
+            {
+                IDestination destination = session.GetQueue("TestMessageQueueDequeQueueDequeue");
+
+                (connection as Connection).DeleteDestination(destination);
+
+                using (IMessageConsumer consumer = session.CreateConsumer(destination))
+                using (IMessageProducer producer = session.CreateProducer(destination))
+                {
+                    connection.Start();
+
+                    producer.DeliveryMode = MsgDeliveryMode.Persistent;
+
+                    IMapMessage request = session.CreateMapMessage();
+                    request.Body.SetString("Unit-Test-Key", "Unit-Test-Value");
+                    Assert.IsNotNull(request, "request is null");
+                    Assert.IsTrue(request.Body.Contains("Unit-Test-Key"), "Unit-Test-Key does not exist");
+                    producer.Send(request);
+
+                    // Relay from Queue back again.
+                    IMessage received = consumer.Receive(TimeSpan.FromSeconds(2));
+                    Assert.IsNotNull(received);
+                    IMapMessage mapMessage = received as IMapMessage;
+                    Assert.IsNotNull(mapMessage);
+                    producer.Send(mapMessage);
+
+                    // Read it again and validate.
+                    received = consumer.Receive(TimeSpan.FromSeconds(2));
+                    Assert.IsNotNull(received);
+                    mapMessage = received as IMapMessage;
+                    Assert.IsNotNull(mapMessage, "currentMessage is null");
+
+                    // This entry in the map message should not be removed
+                    Assert.IsTrue(mapMessage.Body.Contains("Unit-Test-Key"), "Unit-Test-Key does not exist");
+                }
+            }
+        }
     }
 }


[07/50] [abbrv] activemq-nms-openwire git commit: Bump version to 1.6.5-SNAPSHOT

Posted by ta...@apache.org.
Bump version to 1.6.5-SNAPSHOT


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/ea082f14
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/ea082f14
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/ea082f14

Branch: refs/heads/1.6.x
Commit: ea082f14d778e4b101b8585864f794575ce66741
Parents: 2ac8c73
Author: Timothy A. Bish <ta...@apache.org>
Authored: Tue Sep 2 14:18:58 2014 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Tue Sep 2 14:18:58 2014 +0000

----------------------------------------------------------------------
 nant.build  | 2 +-
 package.ps1 | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/ea082f14/nant.build
----------------------------------------------------------------------
diff --git a/nant.build b/nant.build
index 8f205dd..4e794f1 100644
--- a/nant.build
+++ b/nant.build
@@ -22,7 +22,7 @@
     <property name="basedir" value="${project::get-base-directory()}" />
     <property name="project.name" value="Apache.NMS.ActiveMQ" />
     <property name="project.group" value="org.apache.activemq" />
-    <property name="project.version" value="1.6.4" unless="${property::exists('project.version')}" />
+    <property name="project.version" value="1.6.5" unless="${property::exists('project.version')}" />
     <property name="project.release.type" value="SNAPSHOT" unless="${property::exists('project.release.type')}" />
     <property name="project.short_description" value="Apache NMS for ActiveMQ Class Library" />
     <property name="project.description" value="Apache NMS for ActiveMQ Class Library (.Net Messaging Library Implementation): An implementation of the NMS API for ActiveMQ" />

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/ea082f14/package.ps1
----------------------------------------------------------------------
diff --git a/package.ps1 b/package.ps1
index de57b3b..ad51e9f 100644
--- a/package.ps1
+++ b/package.ps1
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 $pkgname = "Apache.NMS.ActiveMQ"
-$pkgver = "1.6.4-SNAPSHOT"
+$pkgver = "1.6.5-SNAPSHOT"
 $configurations = "release", "debug"
 $frameworks = "mono-2.0", "net-2.0", "net-3.5", "net-4.0"
 


[38/50] [abbrv] activemq-nms-openwire git commit: https://issues.apache.org/jira/browse/AMQNET-489

Posted by ta...@apache.org.
https://issues.apache.org/jira/browse/AMQNET-489

Ensure that the lastDeliveredSequenceId gets sent when the ConnectionInfo is sent.


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/34770b60
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/34770b60
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/34770b60

Branch: refs/heads/master
Commit: 34770b6010c7c4a1d250ec204d1b37652048bef0
Parents: ec37f32
Author: Timothy A. Bish <ta...@apache.org>
Authored: Wed Sep 30 18:55:48 2015 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Wed Sep 30 18:55:48 2015 +0000

----------------------------------------------------------------------
 src/main/csharp/Connection.cs | 8 ++++++--
 src/main/csharp/Session.cs    | 5 +++++
 2 files changed, 11 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/34770b60/src/main/csharp/Connection.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Connection.cs b/src/main/csharp/Connection.cs
index 33fb3e8..10832b3 100755
--- a/src/main/csharp/Connection.cs
+++ b/src/main/csharp/Connection.cs
@@ -713,11 +713,13 @@ namespace Apache.NMS.ActiveMQ
                         }
                     }
 
+                    long lastDeliveredSequenceId = -1;
                     lock(sessions.SyncRoot)
                     {
                         foreach(Session session in sessions)
                         {
                             session.Shutdown();
+                            lastDeliveredSequenceId = Math.Max(lastDeliveredSequenceId, session.LastDeliveredSequenceId);
                         }
                     }
                     sessions.Clear();
@@ -740,7 +742,7 @@ namespace Apache.NMS.ActiveMQ
                     // inform the broker of a remove, and if the transport is failed, why bother.
                     if(connected.Value && !transportFailed.Value)
                     {
-                        DisposeOf(ConnectionId);
+                        DisposeOf(ConnectionId, lastDeliveredSequenceId);
                         ShutdownInfo shutdowninfo = new ShutdownInfo();
                         transport.Oneway(shutdowninfo);
                     }
@@ -908,12 +910,14 @@ namespace Apache.NMS.ActiveMQ
             }
         }
 
-        private void DisposeOf(DataStructure objectId)
+        private void DisposeOf(DataStructure objectId, long lastDeliveredSequenceId)
         {
             try
             {
                 RemoveInfo command = new RemoveInfo();
                 command.ObjectId = objectId;
+                command.LastDeliveredSequenceId = lastDeliveredSequenceId;
+
                 if(asyncClose)
                 {
                     Tracer.DebugFormat("Connection[{0}]: Asynchronously disposing of Connection.", this.ConnectionId);

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/34770b60/src/main/csharp/Session.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Session.cs b/src/main/csharp/Session.cs
index 8fd6db3..ef91700 100755
--- a/src/main/csharp/Session.cs
+++ b/src/main/csharp/Session.cs
@@ -305,6 +305,11 @@ namespace Apache.NMS.ActiveMQ
             }
         }
 
+        internal long LastDeliveredSequenceId
+        {
+            get { return this.lastDeliveredSequenceId; }
+        }
+
         #endregion
 
         #region ISession Members


[06/50] [abbrv] activemq-nms-openwire git commit: https://issues.apache.org/jira/browse/AMQNET-474

Posted by ta...@apache.org.
https://issues.apache.org/jira/browse/AMQNET-474

Fire only async error notifications if an error occurs during the transaction operations.


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/2ac8c73b
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/2ac8c73b
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/2ac8c73b

Branch: refs/heads/1.6.x
Commit: 2ac8c73b867d6cdffbf530a39cee17abbdc036b2
Parents: c6595f2
Author: Timothy A. Bish <ta...@apache.org>
Authored: Fri Aug 29 15:29:00 2014 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Fri Aug 29 15:29:00 2014 +0000

----------------------------------------------------------------------
 src/main/csharp/NetTxTransactionContext.cs | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/2ac8c73b/src/main/csharp/NetTxTransactionContext.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/NetTxTransactionContext.cs b/src/main/csharp/NetTxTransactionContext.cs
index 690e95d..c7f5657 100644
--- a/src/main/csharp/NetTxTransactionContext.cs
+++ b/src/main/csharp/NetTxTransactionContext.cs
@@ -252,7 +252,7 @@ namespace Apache.NMS.ActiveMQ
                     preparingEnlistment.ForceRollback();
                     try
                     {
-                        this.connection.OnException(ex);
+                        this.connection.OnAsyncException(ex);
                     }
                     catch (Exception error)
                     {
@@ -301,8 +301,8 @@ namespace Apache.NMS.ActiveMQ
                     Tracer.DebugFormat("Transaction[{0}] Commit failed with error: {1}",
                                        this.transactionId, ex.Message);
                     try
-                    {
-                        this.connection.OnException(ex);
+                    {
+                        this.connection.OnAsyncException(ex);
                     }
                     catch (Exception error)
                     {
@@ -362,8 +362,8 @@ namespace Apache.NMS.ActiveMQ
                     AfterRollback();
                     enlistment.Done();
                     try
-                    {
-                        this.connection.OnException(ex);
+                    {
+                        this.connection.OnAsyncException(ex);
                     }
                     catch (Exception error)
                     {
@@ -422,8 +422,8 @@ namespace Apache.NMS.ActiveMQ
                                        this.transactionId, ex.Message);
                     AfterRollback();
                     try
-                    {
-                        this.connection.OnException(ex);
+                    {
+                        this.connection.OnAsyncException(ex);
                     }
                     catch (Exception error)
                     {


[19/50] [abbrv] activemq-nms-openwire git commit: Applied patch from Enrique Garcia to copy the 509 certificates to internal list. Thanks, Enrique! Fixes [AMQNET-500]. (See https://issues.apache.org/jira/browse/AMQNET-500)

Posted by ta...@apache.org.
Applied patch from Enrique Garcia to copy the 509 certificates to internal list. Thanks, Enrique!
Fixes [AMQNET-500]. (See https://issues.apache.org/jira/browse/AMQNET-500)



Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/8e6479f2
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/8e6479f2
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/8e6479f2

Branch: refs/heads/1.7.x
Commit: 8e6479f27e5b40e104ceabb4dd7e7c4eed6c5b15
Parents: d13fe5c
Author: Jim Gomes <jg...@apache.org>
Authored: Wed Jul 8 17:39:44 2015 +0000
Committer: Jim Gomes <jg...@apache.org>
Committed: Wed Jul 8 17:39:44 2015 +0000

----------------------------------------------------------------------
 src/main/csharp/Transport/Tcp/SslTransport.cs | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/8e6479f2/src/main/csharp/Transport/Tcp/SslTransport.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Transport/Tcp/SslTransport.cs b/src/main/csharp/Transport/Tcp/SslTransport.cs
index caa3ec7..17f2e06 100644
--- a/src/main/csharp/Transport/Tcp/SslTransport.cs
+++ b/src/main/csharp/Transport/Tcp/SslTransport.cs
@@ -314,7 +314,9 @@ namespace Apache.NMS.ActiveMQ.Transport.Tcp
 
                 X509Store store = new X509Store(name, location);
                 store.Open(OpenFlags.ReadOnly);
-                collection = store.Certificates;
+                X509Certificate2[] certificates = new X509Certificate2[store.Certificates.Count];
+                store.Certificates.CopyTo(certificates, 0);
+                collection.AddRange(certificates);
                 store.Close();
             }
 


[04/50] [abbrv] activemq-nms-openwire git commit: https://issues.apache.org/jira/browse/AMQNET-471

Posted by ta...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/c6595f25/src/main/csharp/Connection.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Connection.cs b/src/main/csharp/Connection.cs
index 8956abe..242a3cb 100755
--- a/src/main/csharp/Connection.cs
+++ b/src/main/csharp/Connection.cs
@@ -31,961 +31,978 @@ using Apache.NMS.Util;
 
 namespace Apache.NMS.ActiveMQ
 {
-	/// <summary>
-	/// Represents a connection with a message broker
-	/// </summary>
-	public class Connection : IConnection
-	{
-		private static readonly IdGenerator CONNECTION_ID_GENERATOR = new IdGenerator();
-		private static readonly TimeSpan InfiniteTimeSpan = TimeSpan.FromMilliseconds(Timeout.Infinite);
-
-		// Uri configurable options.
-		private AcknowledgementMode acknowledgementMode = AcknowledgementMode.AutoAcknowledge;
-		private bool asyncSend = false;
-		private bool alwaysSyncSend = false;
-		private bool asyncClose = true;
-		private bool useCompression = false;
-		private bool copyMessageOnSend = true;
-		private bool sendAcksAsync = false;
-		private bool dispatchAsync = true;
-		private int producerWindowSize = 0;
-		private bool messagePrioritySupported = true;
-		private bool watchTopicAdviosires = true;
-		private bool optimizeAcknowledge;
-    	private long optimizeAcknowledgeTimeOut = 300;
-    	private long optimizedAckScheduledAckInterval = 0;
-	    private bool useRetroactiveConsumer;
-	    private bool exclusiveConsumer;
-	    private long consumerFailoverRedeliveryWaitPeriod = 0;
-	    private bool checkForDuplicates = true;
-	    private bool transactedIndividualAck = false;
-		private bool nonBlockingRedelivery = false;
-
-		private bool userSpecifiedClientID;
-		private readonly Uri brokerUri;
-		private ITransport transport;
-		private readonly ConnectionInfo info;
-		private TimeSpan requestTimeout = NMSConstants.defaultRequestTimeout; // from connection factory
-		private BrokerInfo brokerInfo; // from broker
-		private readonly CountDownLatch brokerInfoReceived = new CountDownLatch(1);
-		private WireFormatInfo brokerWireFormatInfo; // from broker
-		private readonly IList sessions = ArrayList.Synchronized(new ArrayList());
-		private readonly IDictionary producers = Hashtable.Synchronized(new Hashtable());
-		private readonly IDictionary dispatchers = Hashtable.Synchronized(new Hashtable());
-		private readonly IDictionary tempDests = Hashtable.Synchronized(new Hashtable());
-		private readonly object connectedLock = new object();
-		private readonly Atomic<bool> connected = new Atomic<bool>(false);
-		private readonly Atomic<bool> closed = new Atomic<bool>(false);
-		private readonly Atomic<bool> closing = new Atomic<bool>(false);
-		private readonly Atomic<bool> transportFailed = new Atomic<bool>(false);
-		private Exception firstFailureError = null;
-		private int sessionCounter = 0;
-		private int temporaryDestinationCounter = 0;
-		private int localTransactionCounter;
-		private readonly Atomic<bool> started = new Atomic<bool>(false);
-		private ConnectionMetaData metaData = null;
-		private bool disposed = false;
-		private IRedeliveryPolicy redeliveryPolicy;
-		private PrefetchPolicy prefetchPolicy = new PrefetchPolicy();
-		private ICompressionPolicy compressionPolicy = new CompressionPolicy();
-		private readonly IdGenerator clientIdGenerator;
-		private int consumerIdCounter = 0;
-		private long transportInterruptionProcessingComplete;
-		private readonly MessageTransformation messageTransformation;
-		private readonly ThreadPoolExecutor executor = new ThreadPoolExecutor();
-		private AdvisoryConsumer advisoryConsumer = null;
-		private Scheduler scheduler = null;
-		private readonly ConnectionAudit connectionAudit = new ConnectionAudit();
-
-		public Connection(Uri connectionUri, ITransport transport, IdGenerator clientIdGenerator)
-		{
-			this.brokerUri = connectionUri;
-			this.clientIdGenerator = clientIdGenerator;
-
-			SetTransport(transport);
-
-			ConnectionId id = new ConnectionId();
-			id.Value = CONNECTION_ID_GENERATOR.GenerateId();
-
-			this.info = new ConnectionInfo();
-			this.info.ConnectionId = id;
-			this.info.FaultTolerant = transport.IsFaultTolerant;
-
-			this.messageTransformation = new ActiveMQMessageTransformation(this);
-			this.connectionAudit.CheckForDuplicates = transport.IsFaultTolerant;
-		}
-
-		~Connection()
-		{
-			Dispose(false);
-		}
-
-		/// <summary>
-		/// A delegate that can receive transport level exceptions.
-		/// </summary>
-		public event ExceptionListener ExceptionListener;
-
-		/// <summary>
-		/// An asynchronous listener that is notified when a Fault tolerant connection
-		/// has been interrupted.
-		/// </summary>
-		public event ConnectionInterruptedListener ConnectionInterruptedListener;
-
-		/// <summary>
-		/// An asynchronous listener that is notified when a Fault tolerant connection
-		/// has been resumed.
-		/// </summary>
-		public event ConnectionResumedListener ConnectionResumedListener;
-
-		private ConsumerTransformerDelegate consumerTransformer;
-		public ConsumerTransformerDelegate ConsumerTransformer
-		{
-			get { return this.consumerTransformer; }
-			set { this.consumerTransformer = value; }
-		}
-
-		private ProducerTransformerDelegate producerTransformer;
-		public ProducerTransformerDelegate ProducerTransformer
-		{
-			get { return this.producerTransformer; }
-			set { this.producerTransformer = value; }
-		}
-
-		#region Properties
-
-		public String UserName
-		{
-			get { return this.info.UserName; }
-			set { this.info.UserName = value; }
-		}
-
-		public String Password
-		{
-			get { return this.info.Password; }
-			set { this.info.Password = value; }
-		}
-
-		/// <summary>
-		/// This property indicates what version of the Protocol we are using to
-		/// communicate with the Broker, if not set we return the lowest version
-		/// number to indicate we support only the basic command set.
-		/// </summary>
-		public int ProtocolVersion
-		{
-			get
-			{
-				if(brokerWireFormatInfo != null)
-				{
-					return brokerWireFormatInfo.Version;
-				}
-
-				return 1;
-			}
-		}
-
-		/// <summary>
-		/// This property indicates whether or not async send is enabled.
-		/// </summary>
-		public bool AsyncSend
-		{
-			get { return asyncSend; }
-			set { asyncSend = value; }
-		}
-
-		/// <summary>
-		/// This property indicates whether or not async close is enabled.
-		/// When the connection is closed, it will either send a synchronous
-		/// DisposeOf command to the broker and wait for confirmation (if true),
-		/// or it will send the DisposeOf command asynchronously.
-		/// </summary>
-		public bool AsyncClose
-		{
-			get { return asyncClose; }
-			set { asyncClose = value; }
-		}
-
-		/// <summary>
-		/// This property indicates whether or not async sends are used for
-		/// message acknowledgement messages.  Sending Acks async can improve
-		/// performance but may decrease reliability.
-		/// </summary>
-		public bool SendAcksAsync
-		{
-			get { return sendAcksAsync; }
-			set { sendAcksAsync = value; }
-		}
-
-		/// <summary>
-		/// This property sets the acknowledgment mode for the connection.
-		/// The URI parameter connection.ackmode can be set to a string value
-		/// that maps to the enumeration value.
-		/// </summary>
-		public string AckMode
-		{
-			set { this.acknowledgementMode = NMSConvert.ToAcknowledgementMode(value); }
-		}
-
-		/// <summary>
-		/// This property is the maximum number of bytes in memory that a producer will transmit
-		/// to a broker before waiting for acknowledgement messages from the broker that it has
-		/// accepted the previously sent messages. In other words, this how you configure the
-		/// producer flow control window that is used for async sends where the client is responsible
-		/// for managing memory usage. The default value of 0 means no flow control at the client
-		/// </summary>
-		public int ProducerWindowSize
-		{
-			get { return producerWindowSize; }
-			set { producerWindowSize = value; }
-		}
-
-		/// <summary>
-		/// This property forces all messages that are sent to be sent synchronously overriding
-		/// any usage of the AsyncSend flag. This can reduce performance in some cases since the
-		/// only messages we normally send synchronously are Persistent messages not sent in a
-		/// transaction. This options guarantees that no send will return until the broker has
-		/// acknowledge receipt of the message
-		/// </summary>
-		public bool AlwaysSyncSend
-		{
-			get { return alwaysSyncSend; }
-			set { alwaysSyncSend = value; }
-		}
-
-		/// <summary>
-		/// This property indicates whether Message's should be copied before being sent via
-		/// one of the Connection's send methods.  Copying the Message object allows the user
-		/// to resuse the Object over for another send.  If the message isn't copied performance
-		/// can improve but the user must not reuse the Object as it may not have been sent
-		/// before they reset its payload.
-		/// </summary>
-		public bool CopyMessageOnSend
-		{
-			get { return copyMessageOnSend; }
-			set { copyMessageOnSend = value; }
-		}
-
-		/// <summary>
-		/// Enable or Disable the use of Compression on Message bodies.  When enabled all
-		/// messages have their body compressed using the Deflate compression algorithm.
-		/// The recipient of the message must support the use of message compression as well
-		/// otherwise the receiving client will receive a message whose body appears in the
-		/// compressed form.
-		/// </summary>
-		public bool UseCompression
-		{
-			get { return this.useCompression; }
-			set { this.useCompression = value; }
-		}
-
-		/// <summary>
-		/// Indicate whether or not the resources of this Connection should support the
-		/// Message Priority value of incoming messages and dispatch them accordingly.
-		/// When disabled Message are always dispatched to Consumers in FIFO order.
-		/// </summary>
-		public bool MessagePrioritySupported
-		{
-			get { return this.messagePrioritySupported; }
-			set { this.messagePrioritySupported = value; }
-		}
-
-    	public bool OptimizeAcknowledge 
-		{
-			get { return this.optimizeAcknowledge; }
-			set { this.optimizeAcknowledge = value; }
-		}
-
-    	public long OptimizeAcknowledgeTimeOut
-		{
-			get { return this.optimizeAcknowledgeTimeOut; }
-			set { this.optimizeAcknowledgeTimeOut = value; }
-		}
-
-		public long OptimizedAckScheduledAckInterval
-		{
-			get { return this.optimizedAckScheduledAckInterval; }
-			set { this.optimizedAckScheduledAckInterval = value; }
-		}
-
-		public bool UseRetroactiveConsumer
-		{
-			get { return this.useRetroactiveConsumer; }
-			set { this.useRetroactiveConsumer = value; }
-		}
-
-		public bool ExclusiveConsumer
-		{
-			get { return this.exclusiveConsumer; }
-			set { this.exclusiveConsumer = value; }
-		}
-
-		public long ConsumerFailoverRedeliveryWaitPeriod
-		{
-			get { return this.consumerFailoverRedeliveryWaitPeriod; }
-			set { this.consumerFailoverRedeliveryWaitPeriod = value; }
-		}
-
-		public bool CheckForDuplicates
-		{
-			get { return this.checkForDuplicates; }
-			set { this.checkForDuplicates = value; }
-		}
-
-		public bool TransactedIndividualAck
-		{
-			get { return this.transactedIndividualAck; }
-			set { this.transactedIndividualAck = value; }
-		}
-
-		public bool NonBlockingRedelivery
-		{
-			get { return this.nonBlockingRedelivery; }
-			set { this.nonBlockingRedelivery = value; }
-		}
-
-		public int AuditDepth
-		{
-			get { return this.connectionAudit.AuditDepth; }
-			set { this.connectionAudit.AuditDepth = value; }
-		}
-
-		public int AuditMaximumProducerNumber
-		{
-			get { return this.connectionAudit.AuditMaximumProducerNumber; }
-			set { this.connectionAudit.AuditMaximumProducerNumber = value; }
-		}
-
-		public IConnectionMetaData MetaData
-		{
-			get { return this.metaData ?? (this.metaData = new ConnectionMetaData()); }
-		}
-
-		public Uri BrokerUri
-		{
-			get { return brokerUri; }
-		}
-
-		public ITransport ITransport
-		{
-			get { return transport; }
-			set { this.transport = value; }
-		}
-
-		public bool TransportFailed
-		{
-			get { return this.transportFailed.Value; }
-		}
-
-		public Exception FirstFailureError
-		{
-			get { return this.firstFailureError; }
-		}
-
-		public TimeSpan RequestTimeout
-		{
-			get { return this.requestTimeout; }
-			set { this.requestTimeout = value; }
-		}
-
-		public AcknowledgementMode AcknowledgementMode
-		{
-			get { return acknowledgementMode; }
-			set { this.acknowledgementMode = value; }
-		}
-
-		/// <summary>
-		/// synchronously or asynchronously by the broker.
-		/// </summary>
-		public bool DispatchAsync
-		{
-			get { return this.dispatchAsync; }
-			set { this.dispatchAsync = value; }
-		}
-
-		public bool WatchTopicAdvisories
-		{
-			get { return this.watchTopicAdviosires; }
-			set { this.watchTopicAdviosires = value; }
-		}
-
-		public string ClientId
-		{
-			get { return info.ClientId; }
-			set
-			{
-				if(this.connected.Value)
-				{
-					throw new NMSException("You cannot change the ClientId once the Connection is connected");
-				}
-
-				this.info.ClientId = value;
-				this.userSpecifiedClientID = true;
-				CheckConnected();
-			}
-		}
-
-		/// <summary>
-		/// The Default Client Id used if the ClientId property is not set explicity.
-		/// </summary>
-		public string DefaultClientId
-		{
-			set
-			{
-				this.info.ClientId = value;
-				this.userSpecifiedClientID = true;
-			}
-		}
-
-		public ConnectionId ConnectionId
-		{
-			get { return info.ConnectionId; }
-		}
-
-		public BrokerInfo BrokerInfo
-		{
-			get { return brokerInfo; }
-		}
-
-		public WireFormatInfo BrokerWireFormat
-		{
-			get { return brokerWireFormatInfo; }
-		}
-
-		public String ResourceManagerId
-		{
-			get
-			{
-				this.brokerInfoReceived.await();
-				return brokerInfo.BrokerId.Value;
-			}
-		}
-
-		/// <summary>
-		/// Get/or set the redelivery policy for this connection.
-		/// </summary>
-		public IRedeliveryPolicy RedeliveryPolicy
-		{
-			get { return this.redeliveryPolicy; }
-			set { this.redeliveryPolicy = value; }
-		}
-
-		public PrefetchPolicy PrefetchPolicy
-		{
-			get { return this.prefetchPolicy; }
-			set { this.prefetchPolicy = value; }
-		}
-
-		public ICompressionPolicy CompressionPolicy
-		{
-			get { return this.compressionPolicy; }
-			set { this.compressionPolicy = value; }
-		}
-
-		internal MessageTransformation MessageTransformation
-		{
-			get { return this.messageTransformation; }
-		}
-
-	    internal Scheduler Scheduler
-		{
-			get
-			{
-		        Scheduler result = this.scheduler;
-		        if (result == null) 
-				{
-		            lock (this) 
-					{
-		                result = scheduler;
-		                if (result == null) 
-						{
-		                    CheckClosed();
-		                    try 
-							{
-		                        result = scheduler = new Scheduler(
-									"ActiveMQConnection["+this.info.ConnectionId.Value+"] Scheduler");
-		                        scheduler.Start();
-		                    }
-							catch(Exception e)
-							{
-		                        throw NMSExceptionSupport.Create(e);
-		                    }
-		                }
-		            }
-		        }
-		        return result;
-			}
-	    }
-
-		#endregion
-
-		private void SetTransport(ITransport newTransport)
-		{
-			this.transport = newTransport;
-			this.transport.Command = new CommandHandler(OnCommand);
-			this.transport.Exception = new ExceptionHandler(OnTransportException);
-			this.transport.Interrupted = new InterruptedHandler(OnTransportInterrupted);
-			this.transport.Resumed = new ResumedHandler(OnTransportResumed);
-		}
-
-		/// <summary>
-		/// Starts asynchronous message delivery of incoming messages for this connection.
-		/// Synchronous delivery is unaffected.
-		/// </summary>
-		public void Start()
-		{
-			CheckConnected();
-			if(started.CompareAndSet(false, true))
-			{
-				lock(sessions.SyncRoot)
-				{
-					foreach(Session session in sessions)
-					{
-						session.Start();
-					}
-				}
-			}
-		}
-
-		/// <summary>
-		/// This property determines if the asynchronous message delivery of incoming
-		/// messages has been started for this connection.
-		/// </summary>
-		public bool IsStarted
-		{
-			get { return started.Value; }
-		}
-
-		/// <summary>
-		/// Temporarily stop asynchronous delivery of inbound messages for this connection.
-		/// The sending of outbound messages is unaffected.
-		/// </summary>
-		public void Stop()
-		{
-			if(started.CompareAndSet(true, false))
-			{
-				lock(sessions.SyncRoot)
-				{
-					foreach(Session session in sessions)
-					{
-						session.Stop();
-					}
-				}
-			}
-		}
-
-		/// <summary>
-		/// Creates a new session to work on this connection
-		/// </summary>
-		public ISession CreateSession()
-		{
-			return CreateActiveMQSession(acknowledgementMode);
-		}
-
-		/// <summary>
-		/// Creates a new session to work on this connection
-		/// </summary>
-		public ISession CreateSession(AcknowledgementMode sessionAcknowledgementMode)
-		{
-			return CreateActiveMQSession(sessionAcknowledgementMode);
-		}
-
-		protected virtual Session CreateActiveMQSession(AcknowledgementMode ackMode)
-		{
-			CheckConnected();
-			return new Session(this, NextSessionId, ackMode);
-		}
-
-		internal void AddSession(Session session)
-		{
-			if(!this.closing.Value)
-			{
-				sessions.Add(session);
-			}
-		}
-
-		internal void RemoveSession(Session session)
-		{
-			if(!this.closing.Value)
-			{
-				sessions.Remove(session);
-				RemoveDispatcher(session);
-			}
-		}
-
-		internal void AddDispatcher(ConsumerId id, IDispatcher dispatcher)
-		{
-			if(!this.closing.Value)
-			{
-				this.dispatchers.Add(id, dispatcher);
-			}
-		}
-
-		internal void RemoveDispatcher(ConsumerId id)
-		{
-			if(!this.closing.Value)
-			{
-				this.dispatchers.Remove(id);
-			}
-		}
-
-		internal void AddProducer(ProducerId id, MessageProducer producer)
-		{
-			if(!this.closing.Value)
-			{
-				this.producers.Add(id, producer);
-			}
-		}
-
-		internal void RemoveProducer(ProducerId id)
-		{
-			if(!this.closing.Value)
-			{
-				this.producers.Remove(id);
-			}
-		}
-
-	    internal void RemoveDispatcher(IDispatcher dispatcher) 
-		{
-	        this.connectionAudit.RemoveDispatcher(dispatcher);
-	    }
-
-	    internal bool IsDuplicate(IDispatcher dispatcher, Message message) 
-		{
-	        return this.checkForDuplicates && this.connectionAudit.IsDuplicate(dispatcher, message);
-	    }
-
-	    internal void RollbackDuplicate(IDispatcher dispatcher, Message message)
-		{
-	        this.connectionAudit.RollbackDuplicate(dispatcher, message);
-	    }
-
-		public void Close()
-		{
-			if(!this.closed.Value && !transportFailed.Value)
-			{
-				this.Stop();
-			}
-
-			lock(connectedLock)
-			{
-				if(this.closed.Value)
-				{
-					return;
-				}
-
-				try
-				{
-					Tracer.InfoFormat("Connection[{0}]: Closing Connection Now.", this.ConnectionId);
-					this.closing.Value = true;
-
-					if(this.advisoryConsumer != null)
-					{
-						this.advisoryConsumer.Dispose();
-						this.advisoryConsumer = null;
-					}
+    /// <summary>
+    /// Represents a connection with a message broker
+    /// </summary>
+    public class Connection : IConnection
+    {
+        private static readonly IdGenerator CONNECTION_ID_GENERATOR = new IdGenerator();
+        private static readonly TimeSpan InfiniteTimeSpan = TimeSpan.FromMilliseconds(Timeout.Infinite);
+
+        // Uri configurable options.
+        private AcknowledgementMode acknowledgementMode = AcknowledgementMode.AutoAcknowledge;
+        private bool asyncSend = false;
+        private bool alwaysSyncSend = false;
+        private bool asyncClose = true;
+        private bool useCompression = false;
+        private bool copyMessageOnSend = true;
+        private bool sendAcksAsync = false;
+        private bool dispatchAsync = true;
+        private int producerWindowSize = 0;
+        private bool messagePrioritySupported = true;
+        private bool watchTopicAdviosires = true;
+        private bool optimizeAcknowledge;
+        private long optimizeAcknowledgeTimeOut = 300;
+        private long optimizedAckScheduledAckInterval = 0;
+        private bool useRetroactiveConsumer;
+        private bool exclusiveConsumer;
+        private long consumerFailoverRedeliveryWaitPeriod = 0;
+        private bool checkForDuplicates = true;
+        private bool transactedIndividualAck = false;
+        private bool nonBlockingRedelivery = false;
+
+        private bool userSpecifiedClientID;
+        private readonly Uri brokerUri;
+        private ITransport transport;
+        private readonly ConnectionInfo info;
+        private TimeSpan requestTimeout = NMSConstants.defaultRequestTimeout; // from connection factory
+        private BrokerInfo brokerInfo; // from broker
+        private readonly CountDownLatch brokerInfoReceived = new CountDownLatch(1);
+        private WireFormatInfo brokerWireFormatInfo; // from broker
+        private readonly IList sessions = ArrayList.Synchronized(new ArrayList());
+        private readonly IDictionary producers = Hashtable.Synchronized(new Hashtable());
+        private readonly IDictionary dispatchers = Hashtable.Synchronized(new Hashtable());
+        private readonly IDictionary tempDests = Hashtable.Synchronized(new Hashtable());
+        private readonly object connectedLock = new object();
+        private readonly Atomic<bool> connected = new Atomic<bool>(false);
+        private readonly Atomic<bool> closed = new Atomic<bool>(false);
+        private readonly Atomic<bool> closing = new Atomic<bool>(false);
+        private readonly Atomic<bool> transportFailed = new Atomic<bool>(false);
+        private Exception firstFailureError = null;
+        private int sessionCounter = 0;
+        private int temporaryDestinationCounter = 0;
+        private int localTransactionCounter;
+        private readonly Atomic<bool> started = new Atomic<bool>(false);
+        private ConnectionMetaData metaData = null;
+        private bool disposed = false;
+        private IRedeliveryPolicy redeliveryPolicy;
+        private PrefetchPolicy prefetchPolicy = new PrefetchPolicy();
+        private ICompressionPolicy compressionPolicy = new CompressionPolicy();
+        private readonly IdGenerator clientIdGenerator;
+        private int consumerIdCounter = 0;
+        private long transportInterruptionProcessingComplete;
+        private readonly MessageTransformation messageTransformation;
+        private readonly ThreadPoolExecutor executor = new ThreadPoolExecutor();
+        private AdvisoryConsumer advisoryConsumer = null;
+        private Scheduler scheduler = null;
+        private readonly ConnectionAudit connectionAudit = new ConnectionAudit();
+
+        public Connection(Uri connectionUri, ITransport transport, IdGenerator clientIdGenerator)
+        {
+            this.brokerUri = connectionUri;
+            this.clientIdGenerator = clientIdGenerator;
+
+            SetTransport(transport);
+
+            ConnectionId id = new ConnectionId();
+            id.Value = CONNECTION_ID_GENERATOR.GenerateId();
+
+            this.info = new ConnectionInfo();
+            this.info.ConnectionId = id;
+            this.info.FaultTolerant = transport.IsFaultTolerant;
+
+            this.messageTransformation = new ActiveMQMessageTransformation(this);
+            this.connectionAudit.CheckForDuplicates = transport.IsFaultTolerant;
+        }
+
+        ~Connection()
+        {
+            Dispose(false);
+        }
+
+        /// <summary>
+        /// A delegate that can receive transport level exceptions.
+        /// </summary>
+        public event ExceptionListener ExceptionListener;
+
+        /// <summary>
+        /// An asynchronous listener that is notified when a Fault tolerant connection
+        /// has been interrupted.
+        /// </summary>
+        public event ConnectionInterruptedListener ConnectionInterruptedListener;
+
+        /// <summary>
+        /// An asynchronous listener that is notified when a Fault tolerant connection
+        /// has been resumed.
+        /// </summary>
+        public event ConnectionResumedListener ConnectionResumedListener;
+
+        private ConsumerTransformerDelegate consumerTransformer;
+        public ConsumerTransformerDelegate ConsumerTransformer
+        {
+            get { return this.consumerTransformer; }
+            set { this.consumerTransformer = value; }
+        }
+
+        private ProducerTransformerDelegate producerTransformer;
+        public ProducerTransformerDelegate ProducerTransformer
+        {
+            get { return this.producerTransformer; }
+            set { this.producerTransformer = value; }
+        }
+
+        #region Properties
+
+        public String UserName
+        {
+            get { return this.info.UserName; }
+            set { this.info.UserName = value; }
+        }
+
+        public String Password
+        {
+            get { return this.info.Password; }
+            set { this.info.Password = value; }
+        }
+
+        /// <summary>
+        /// This property indicates what version of the Protocol we are using to
+        /// communicate with the Broker, if not set we return the lowest version
+        /// number to indicate we support only the basic command set.
+        /// </summary>
+        public int ProtocolVersion
+        {
+            get
+            {
+                if(brokerWireFormatInfo != null)
+                {
+                    return brokerWireFormatInfo.Version;
+                }
+
+                return 1;
+            }
+        }
+
+        /// <summary>
+        /// This property indicates whether or not async send is enabled.
+        /// </summary>
+        public bool AsyncSend
+        {
+            get { return asyncSend; }
+            set { asyncSend = value; }
+        }
+
+        /// <summary>
+        /// This property indicates whether or not async close is enabled.
+        /// When the connection is closed, it will either send a synchronous
+        /// DisposeOf command to the broker and wait for confirmation (if true),
+        /// or it will send the DisposeOf command asynchronously.
+        /// </summary>
+        public bool AsyncClose
+        {
+            get { return asyncClose; }
+            set { asyncClose = value; }
+        }
+
+        /// <summary>
+        /// This property indicates whether or not async sends are used for
+        /// message acknowledgement messages.  Sending Acks async can improve
+        /// performance but may decrease reliability.
+        /// </summary>
+        public bool SendAcksAsync
+        {
+            get { return sendAcksAsync; }
+            set { sendAcksAsync = value; }
+        }
+
+        /// <summary>
+        /// This property sets the acknowledgment mode for the connection.
+        /// The URI parameter connection.ackmode can be set to a string value
+        /// that maps to the enumeration value.
+        /// </summary>
+        public string AckMode
+        {
+            set { this.acknowledgementMode = NMSConvert.ToAcknowledgementMode(value); }
+        }
+
+        /// <summary>
+        /// This property is the maximum number of bytes in memory that a producer will transmit
+        /// to a broker before waiting for acknowledgement messages from the broker that it has
+        /// accepted the previously sent messages. In other words, this how you configure the
+        /// producer flow control window that is used for async sends where the client is responsible
+        /// for managing memory usage. The default value of 0 means no flow control at the client
+        /// </summary>
+        public int ProducerWindowSize
+        {
+            get { return producerWindowSize; }
+            set { producerWindowSize = value; }
+        }
+
+        /// <summary>
+        /// This property forces all messages that are sent to be sent synchronously overriding
+        /// any usage of the AsyncSend flag. This can reduce performance in some cases since the
+        /// only messages we normally send synchronously are Persistent messages not sent in a
+        /// transaction. This options guarantees that no send will return until the broker has
+        /// acknowledge receipt of the message
+        /// </summary>
+        public bool AlwaysSyncSend
+        {
+            get { return alwaysSyncSend; }
+            set { alwaysSyncSend = value; }
+        }
+
+        /// <summary>
+        /// This property indicates whether Message's should be copied before being sent via
+        /// one of the Connection's send methods.  Copying the Message object allows the user
+        /// to resuse the Object over for another send.  If the message isn't copied performance
+        /// can improve but the user must not reuse the Object as it may not have been sent
+        /// before they reset its payload.
+        /// </summary>
+        public bool CopyMessageOnSend
+        {
+            get { return copyMessageOnSend; }
+            set { copyMessageOnSend = value; }
+        }
+
+        /// <summary>
+        /// Enable or Disable the use of Compression on Message bodies.  When enabled all
+        /// messages have their body compressed using the Deflate compression algorithm.
+        /// The recipient of the message must support the use of message compression as well
+        /// otherwise the receiving client will receive a message whose body appears in the
+        /// compressed form.
+        /// </summary>
+        public bool UseCompression
+        {
+            get { return this.useCompression; }
+            set { this.useCompression = value; }
+        }
+
+        /// <summary>
+        /// Indicate whether or not the resources of this Connection should support the
+        /// Message Priority value of incoming messages and dispatch them accordingly.
+        /// When disabled Message are always dispatched to Consumers in FIFO order.
+        /// </summary>
+        public bool MessagePrioritySupported
+        {
+            get { return this.messagePrioritySupported; }
+            set { this.messagePrioritySupported = value; }
+        }
+
+        public bool OptimizeAcknowledge
+        {
+            get { return this.optimizeAcknowledge; }
+            set { this.optimizeAcknowledge = value; }
+        }
+
+        public long OptimizeAcknowledgeTimeOut
+        {
+            get { return this.optimizeAcknowledgeTimeOut; }
+            set { this.optimizeAcknowledgeTimeOut = value; }
+        }
+
+        public long OptimizedAckScheduledAckInterval
+        {
+            get { return this.optimizedAckScheduledAckInterval; }
+            set { this.optimizedAckScheduledAckInterval = value; }
+        }
+
+        public bool UseRetroactiveConsumer
+        {
+            get { return this.useRetroactiveConsumer; }
+            set { this.useRetroactiveConsumer = value; }
+        }
+
+        public bool ExclusiveConsumer
+        {
+            get { return this.exclusiveConsumer; }
+            set { this.exclusiveConsumer = value; }
+        }
+
+        public long ConsumerFailoverRedeliveryWaitPeriod
+        {
+            get { return this.consumerFailoverRedeliveryWaitPeriod; }
+            set { this.consumerFailoverRedeliveryWaitPeriod = value; }
+        }
+
+        public bool CheckForDuplicates
+        {
+            get { return this.checkForDuplicates; }
+            set { this.checkForDuplicates = value; }
+        }
+
+        public bool TransactedIndividualAck
+        {
+            get { return this.transactedIndividualAck; }
+            set { this.transactedIndividualAck = value; }
+        }
+
+        public bool NonBlockingRedelivery
+        {
+            get { return this.nonBlockingRedelivery; }
+            set { this.nonBlockingRedelivery = value; }
+        }
+
+        public int AuditDepth
+        {
+            get { return this.connectionAudit.AuditDepth; }
+            set { this.connectionAudit.AuditDepth = value; }
+        }
+
+        public int AuditMaximumProducerNumber
+        {
+            get { return this.connectionAudit.AuditMaximumProducerNumber; }
+            set { this.connectionAudit.AuditMaximumProducerNumber = value; }
+        }
+
+        public IConnectionMetaData MetaData
+        {
+            get { return this.metaData ?? (this.metaData = new ConnectionMetaData()); }
+        }
+
+        public Uri BrokerUri
+        {
+            get { return brokerUri; }
+        }
+
+        public ITransport ITransport
+        {
+            get { return transport; }
+            set { this.transport = value; }
+        }
+
+        public bool TransportFailed
+        {
+            get { return this.transportFailed.Value; }
+        }
+
+        public Exception FirstFailureError
+        {
+            get { return this.firstFailureError; }
+        }
+
+        public TimeSpan RequestTimeout
+        {
+            get { return this.requestTimeout; }
+            set { this.requestTimeout = value; }
+        }
+
+        public AcknowledgementMode AcknowledgementMode
+        {
+            get { return acknowledgementMode; }
+            set { this.acknowledgementMode = value; }
+        }
+
+        /// <summary>
+        /// synchronously or asynchronously by the broker.
+        /// </summary>
+        public bool DispatchAsync
+        {
+            get { return this.dispatchAsync; }
+            set { this.dispatchAsync = value; }
+        }
+
+        public bool WatchTopicAdvisories
+        {
+            get { return this.watchTopicAdviosires; }
+            set { this.watchTopicAdviosires = value; }
+        }
+
+        public string ClientId
+        {
+            get { return info.ClientId; }
+            set
+            {
+                if(this.connected.Value)
+                {
+                    throw new NMSException("You cannot change the ClientId once the Connection is connected");
+                }
+
+                this.info.ClientId = value;
+                this.userSpecifiedClientID = true;
+                CheckConnected();
+            }
+        }
+
+        /// <summary>
+        /// The Default Client Id used if the ClientId property is not set explicity.
+        /// </summary>
+        public string DefaultClientId
+        {
+            set
+            {
+                this.info.ClientId = value;
+                this.userSpecifiedClientID = true;
+            }
+        }
+
+        public ConnectionId ConnectionId
+        {
+            get { return info.ConnectionId; }
+        }
+
+        public BrokerInfo BrokerInfo
+        {
+            get { return brokerInfo; }
+        }
+
+        public WireFormatInfo BrokerWireFormat
+        {
+            get { return brokerWireFormatInfo; }
+        }
+
+        public String ResourceManagerId
+        {
+            get
+            {
+                this.brokerInfoReceived.await();
+                return brokerInfo.BrokerId.Value;
+            }
+        }
+
+        /// <summary>
+        /// Get/or set the redelivery policy for this connection.
+        /// </summary>
+        public IRedeliveryPolicy RedeliveryPolicy
+        {
+            get { return this.redeliveryPolicy; }
+            set { this.redeliveryPolicy = value; }
+        }
+
+        public PrefetchPolicy PrefetchPolicy
+        {
+            get { return this.prefetchPolicy; }
+            set { this.prefetchPolicy = value; }
+        }
+
+        public ICompressionPolicy CompressionPolicy
+        {
+            get { return this.compressionPolicy; }
+            set { this.compressionPolicy = value; }
+        }
+
+        internal MessageTransformation MessageTransformation
+        {
+            get { return this.messageTransformation; }
+        }
+
+        internal Scheduler Scheduler
+        {
+            get
+            {
+                Scheduler result = this.scheduler;
+                if (result == null)
+                {
+                    lock (this)
+                    {
+                        result = scheduler;
+                        if (result == null)
+                        {
+                            CheckClosed();
+                            try
+                            {
+                                result = scheduler = new Scheduler(
+                                    "ActiveMQConnection["+this.info.ConnectionId.Value+"] Scheduler");
+                                scheduler.Start();
+                            }
+                            catch(Exception e)
+                            {
+                                throw NMSExceptionSupport.Create(e);
+                            }
+                        }
+                    }
+                }
+                return result;
+            }
+        }
+
+        internal List<Session> Sessions
+        {
+            get
+            {
+                List<Session> copy = new List<Session>();
+                lock(this.sessions.SyncRoot)
+                {
+                    foreach (Session session in sessions)
+                    {
+                        copy.Add(session);
+                    }
+                }
+
+                return copy;
+            }
+        }
+
+        #endregion
+
+        private void SetTransport(ITransport newTransport)
+        {
+            this.transport = newTransport;
+            this.transport.Command = new CommandHandler(OnCommand);
+            this.transport.Exception = new ExceptionHandler(OnTransportException);
+            this.transport.Interrupted = new InterruptedHandler(OnTransportInterrupted);
+            this.transport.Resumed = new ResumedHandler(OnTransportResumed);
+        }
+
+        /// <summary>
+        /// Starts asynchronous message delivery of incoming messages for this connection.
+        /// Synchronous delivery is unaffected.
+        /// </summary>
+        public void Start()
+        {
+            CheckConnected();
+            if(started.CompareAndSet(false, true))
+            {
+                lock(sessions.SyncRoot)
+                {
+                    foreach(Session session in sessions)
+                    {
+                        session.Start();
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// This property determines if the asynchronous message delivery of incoming
+        /// messages has been started for this connection.
+        /// </summary>
+        public bool IsStarted
+        {
+            get { return started.Value; }
+        }
+
+        /// <summary>
+        /// Temporarily stop asynchronous delivery of inbound messages for this connection.
+        /// The sending of outbound messages is unaffected.
+        /// </summary>
+        public void Stop()
+        {
+            if(started.CompareAndSet(true, false))
+            {
+                lock(sessions.SyncRoot)
+                {
+                    foreach(Session session in sessions)
+                    {
+                        session.Stop();
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// Creates a new session to work on this connection
+        /// </summary>
+        public ISession CreateSession()
+        {
+            return CreateActiveMQSession(acknowledgementMode);
+        }
+
+        /// <summary>
+        /// Creates a new session to work on this connection
+        /// </summary>
+        public ISession CreateSession(AcknowledgementMode sessionAcknowledgementMode)
+        {
+            return CreateActiveMQSession(sessionAcknowledgementMode);
+        }
+
+        protected virtual Session CreateActiveMQSession(AcknowledgementMode ackMode)
+        {
+            CheckConnected();
+            return new Session(this, NextSessionId, ackMode);
+        }
+
+        internal void AddSession(Session session)
+        {
+            if(!this.closing.Value)
+            {
+                sessions.Add(session);
+            }
+        }
+
+        internal void RemoveSession(Session session)
+        {
+            if(!this.closing.Value)
+            {
+                sessions.Remove(session);
+                RemoveDispatcher(session);
+            }
+        }
+
+        internal void AddDispatcher(ConsumerId id, IDispatcher dispatcher)
+        {
+            if(!this.closing.Value)
+            {
+                this.dispatchers.Add(id, dispatcher);
+            }
+        }
+
+        internal void RemoveDispatcher(ConsumerId id)
+        {
+            if(!this.closing.Value)
+            {
+                this.dispatchers.Remove(id);
+            }
+        }
+
+        internal void AddProducer(ProducerId id, MessageProducer producer)
+        {
+            if(!this.closing.Value)
+            {
+                this.producers.Add(id, producer);
+            }
+        }
+
+        internal void RemoveProducer(ProducerId id)
+        {
+            if(!this.closing.Value)
+            {
+                this.producers.Remove(id);
+            }
+        }
+
+        internal void RemoveDispatcher(IDispatcher dispatcher)
+        {
+            this.connectionAudit.RemoveDispatcher(dispatcher);
+        }
+
+        internal bool IsDuplicate(IDispatcher dispatcher, Message message)
+        {
+            return this.checkForDuplicates && this.connectionAudit.IsDuplicate(dispatcher, message);
+        }
+
+        internal void RollbackDuplicate(IDispatcher dispatcher, Message message)
+        {
+            this.connectionAudit.RollbackDuplicate(dispatcher, message);
+        }
+
+        public void Close()
+        {
+            if(!this.closed.Value && !transportFailed.Value)
+            {
+                this.Stop();
+            }
+
+            lock(connectedLock)
+            {
+                if(this.closed.Value)
+                {
+                    return;
+                }
+
+                try
+                {
+                    Tracer.InfoFormat("Connection[{0}]: Closing Connection Now.", this.ConnectionId);
+                    this.closing.Value = true;
+
+                    if(this.advisoryConsumer != null)
+                    {
+                        this.advisoryConsumer.Dispose();
+                        this.advisoryConsumer = null;
+                    }
 
                     Scheduler scheduler = this.scheduler;
-                    if (scheduler != null) 
-					{
-                        try 
-						{
+                    if (scheduler != null)
+                    {
+                        try
+                        {
                             scheduler.Stop();
-                        } 
-						catch (Exception e) 
-						{
+                        }
+                        catch (Exception e)
+                        {
                             throw NMSExceptionSupport.Create(e);
                         }
                     }
 
-					lock(sessions.SyncRoot)
-					{
-						foreach(Session session in sessions)
-						{
-							session.Shutdown();
-						}
-					}
-					sessions.Clear();
-
-					if(this.tempDests.Count > 0)
-					{
-						// Make a copy of the destinations to delete, because the act of deleting
-						// them will modify the collection.
-						ActiveMQTempDestination[] tempDestsToDelete = new ActiveMQTempDestination[this.tempDests.Count];
-
-						this.tempDests.Values.CopyTo(tempDestsToDelete, 0);
-						foreach(ActiveMQTempDestination dest in tempDestsToDelete)
-						{
-							dest.Delete();
-						}
-					}
-
-					// Connected is true only when we've successfully sent our ConnectionInfo
-					// to the broker, so if we haven't announced ourselves there's no need to
-					// inform the broker of a remove, and if the transport is failed, why bother.
-					if(connected.Value && !transportFailed.Value)
-					{
-						DisposeOf(ConnectionId);
-						ShutdownInfo shutdowninfo = new ShutdownInfo();
-						transport.Oneway(shutdowninfo);
-					}
-
-					executor.Shutdown();
-					if (!executor.AwaitTermination(TimeSpan.FromMinutes(1)))
-					{
-						Tracer.DebugFormat("Connection[{0}]: Failed to properly shutdown its executor", this.ConnectionId);
-					}
-
-					Tracer.DebugFormat("Connection[{0}]: Disposing of the Transport.", this.ConnectionId);
-					transport.Stop();
-					transport.Dispose();
-				}
-				catch(Exception ex)
-				{
-					Tracer.ErrorFormat("Connection[{0}]: Error during connection close: {1}", ConnectionId, ex);
-				}
-				finally
-				{
-					if(executor != null)
-					{
-						executor.Shutdown();
-					}
-
-					this.transport = null;
-					this.closed.Value = true;
-					this.connected.Value = false;
-					this.closing.Value = false;
-				}
-			}
-		}
-
-		public void Dispose()
-		{
-			Dispose(true);
-			GC.SuppressFinalize(this);
-		}
-
-		protected void Dispose(bool disposing)
-		{
-			if(disposed)
-			{
-				return;
-			}
-
-			if(disposing)
-			{
-				// Dispose managed code here.
-			}
-
-			try
-			{
-				Close();
-			}
-			catch
-			{
-				// Ignore network errors.
-			}
-
-			disposed = true;
-		}
-
-		public void PurgeTempDestinations()
-		{
-			if(this.tempDests == null || this.tempDests.Count == 0)
-			{
-				return;
-			}
-
-			lock(this.tempDests.SyncRoot)
-			{
-				Object[] keys = new Object[this.tempDests.Count];
-				this.tempDests.Keys.CopyTo(keys, 0);
-				foreach(ActiveMQTempDestination dest in keys)
-				{
-					String localConnectionId = info.ConnectionId == null ? "" : info.ConnectionId.ToString();
-					if(dest.PhysicalName.Contains(localConnectionId))
-					{
-						try
-						{
-							DeleteTemporaryDestination(dest);
-						}
-						catch
-						{
-							// The destination may still be in use in which case its
-							// ok that it is not deleted now.
-						}
-					}
-				}
-			}
-		}
-
-		// Implementation methods
-
-		/// <summary>
-		/// Performs a synchronous request-response with the broker
-		/// </summary>
-		///
-		public Response SyncRequest(Command command)
-		{
-			return SyncRequest(command, this.RequestTimeout);
-		}
-
-		/// <summary>
-		/// Performs a synchronous request-response with the broker for requested timeout duration.
-		/// </summary>
-		/// <param name="command"></param>
-		/// <param name="requestTimeout"></param>
-		/// <returns></returns>
-		public Response SyncRequest(Command command, TimeSpan requestTimeout)
-		{
-			CheckConnected();
-
-			try
-			{
-				Response response = transport.Request(command, requestTimeout);
-				if(response is ExceptionResponse)
-				{
-					ExceptionResponse exceptionResponse = (ExceptionResponse) response;
-					Exception exception = CreateExceptionFromBrokerError(exceptionResponse.Exception);
+                    lock(sessions.SyncRoot)
+                    {
+                        foreach(Session session in sessions)
+                        {
+                            session.Shutdown();
+                        }
+                    }
+                    sessions.Clear();
+
+                    if(this.tempDests.Count > 0)
+                    {
+                        // Make a copy of the destinations to delete, because the act of deleting
+                        // them will modify the collection.
+                        ActiveMQTempDestination[] tempDestsToDelete = new ActiveMQTempDestination[this.tempDests.Count];
+
+                        this.tempDests.Values.CopyTo(tempDestsToDelete, 0);
+                        foreach(ActiveMQTempDestination dest in tempDestsToDelete)
+                        {
+                            dest.Delete();
+                        }
+                    }
+
+                    // Connected is true only when we've successfully sent our ConnectionInfo
+                    // to the broker, so if we haven't announced ourselves there's no need to
+                    // inform the broker of a remove, and if the transport is failed, why bother.
+                    if(connected.Value && !transportFailed.Value)
+                    {
+                        DisposeOf(ConnectionId);
+                        ShutdownInfo shutdowninfo = new ShutdownInfo();
+                        transport.Oneway(shutdowninfo);
+                    }
+
+                    executor.Shutdown();
+                    if (!executor.AwaitTermination(TimeSpan.FromMinutes(1)))
+                    {
+                        Tracer.DebugFormat("Connection[{0}]: Failed to properly shutdown its executor", this.ConnectionId);
+                    }
+
+                    Tracer.DebugFormat("Connection[{0}]: Disposing of the Transport.", this.ConnectionId);
+                    transport.Stop();
+                    transport.Dispose();
+                }
+                catch(Exception ex)
+                {
+                    Tracer.ErrorFormat("Connection[{0}]: Error during connection close: {1}", ConnectionId, ex);
+                }
+                finally
+                {
+                    if(executor != null)
+                    {
+                        executor.Shutdown();
+                    }
+
+                    this.transport = null;
+                    this.closed.Value = true;
+                    this.connected.Value = false;
+                    this.closing.Value = false;
+                }
+            }
+        }
+
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
+        protected void Dispose(bool disposing)
+        {
+            if(disposed)
+            {
+                return;
+            }
+
+            if(disposing)
+            {
+                // Dispose managed code here.
+            }
+
+            try
+            {
+                Close();
+            }
+            catch
+            {
+                // Ignore network errors.
+            }
+
+            disposed = true;
+        }
+
+        public void PurgeTempDestinations()
+        {
+            if(this.tempDests == null || this.tempDests.Count == 0)
+            {
+                return;
+            }
+
+            lock(this.tempDests.SyncRoot)
+            {
+                Object[] keys = new Object[this.tempDests.Count];
+                this.tempDests.Keys.CopyTo(keys, 0);
+                foreach(ActiveMQTempDestination dest in keys)
+                {
+                    String localConnectionId = info.ConnectionId == null ? "" : info.ConnectionId.ToString();
+                    if(dest.PhysicalName.Contains(localConnectionId))
+                    {
+                        try
+                        {
+                            DeleteTemporaryDestination(dest);
+                        }
+                        catch
+                        {
+                            // The destination may still be in use in which case its
+                            // ok that it is not deleted now.
+                        }
+                    }
+                }
+            }
+        }
+
+        // Implementation methods
+
+        /// <summary>
+        /// Performs a synchronous request-response with the broker
+        /// </summary>
+        ///
+        public Response SyncRequest(Command command)
+        {
+            return SyncRequest(command, this.RequestTimeout);
+        }
+
+        /// <summary>
+        /// Performs a synchronous request-response with the broker for requested timeout duration.
+        /// </summary>
+        /// <param name="command"></param>
+        /// <param name="requestTimeout"></param>
+        /// <returns></returns>
+        public Response SyncRequest(Command command, TimeSpan requestTimeout)
+        {
+            CheckConnected();
+
+            try
+            {
+                Response response = transport.Request(command, requestTimeout);
+                if(response is ExceptionResponse)
+                {
+                    ExceptionResponse exceptionResponse = (ExceptionResponse) response;
+                    Exception exception = CreateExceptionFromBrokerError(exceptionResponse.Exception);
 
                     Tracer.DebugFormat("Error returned for request {0} error type: {1}",
                                        command, exception);
 
-					// Security exception on connect means this Connection is unusable, close the
-					// transport now to free its resources.
-					if (exception is NMSSecurityException && command.IsConnectionInfo)
-					{
-						try
-						{
-							transport.Dispose();
-						}
-						catch
-						{
-						}
-					}
-
-					throw exception;
-				}
-
-				return response;
-			}
-			catch(NMSException)
-			{
-				throw;
-			}
-			catch(Exception ex)
-			{
-				throw NMSExceptionSupport.Create(ex);
-			}
-		}
-
-		public void Oneway(Command command)
-		{
-			CheckConnected();
-
-			try
-			{
-				transport.Oneway(command);
-			}
-			catch(Exception ex)
-			{
-				throw NMSExceptionSupport.Create(ex);
-			}
-		}
-
-		private void DisposeOf(DataStructure objectId)
-		{
-			try
-			{
-				RemoveInfo command = new RemoveInfo();
-				command.ObjectId = objectId;
-				if(asyncClose)
-				{
-					Tracer.DebugFormat("Connection[{0}]: Asynchronously disposing of Connection.", this.ConnectionId);
-					if(connected.Value)
-					{
-						transport.Oneway(command);
-						if(Tracer.IsDebugEnabled)
-						{
-							Tracer.DebugFormat("Connection[{0}]: Oneway command sent to broker: {1}",
-											   this.ConnectionId, command);
-						}
-					}
-				}
-				else
-				{
-					// Ensure that the object is disposed to avoid potential race-conditions
-					// of trying to re-create the same object in the broker faster than
-					// the broker can dispose of the object.  Allow up to 5 seconds to process.
-					Tracer.DebugFormat("Connection[{0}]: Synchronously disposing of Connection.", this.ConnectionId);
-					SyncRequest(command, TimeSpan.FromSeconds(5));
-					Tracer.DebugFormat("Connection[{0}]: Synchronously closed of Connection.", this.ConnectionId);
-				}
-			}
-			catch // (BrokerException)
-			{
-				// Ignore exceptions while shutting down.
-			}
-		}
-
-		/// <summary>
-		/// Check and ensure that the connection object is connected.  If it is not
-		/// connected or is closed or closing, a ConnectionClosedException is thrown.
-		/// </summary>
-		internal void CheckConnected()
-		{
-			if(closed.Value)
-			{
-				throw new ConnectionClosedException();
-			}
-
-			if(!connected.Value)
-			{
-				DateTime timeoutTime = DateTime.Now + this.RequestTimeout;
-				int waitCount = 1;
-
-				while(true)
-				{
-					if(Monitor.TryEnter(connectedLock))
-					{
-						try
-						{
-							if(closed.Value || closing.Value)
-							{
-								break;
-							}
-							else if(!connected.Value)
-							{
-								if(!this.userSpecifiedClientID)
-								{
-									this.info.ClientId = this.clientIdGenerator.GenerateId();
-								}
-
-								try
-								{
-									if(null != transport)
-									{
-										// Make sure the transport is started.
-										if(!this.transport.IsStarted)
-										{
-											this.transport.Start();
-										}
-
-										// Send the connection and see if an ack/nak is returned.
-										Response response = transport.Request(this.info, this.RequestTimeout);
-										if(!(response is ExceptionResponse))
-										{
-											connected.Value = true;
-											if(this.watchTopicAdviosires)
-											{
-												ConsumerId id = new ConsumerId(
-													new SessionId(info.ConnectionId, -1),
-													Interlocked.Increment(ref this.consumerIdCounter));
-												this.advisoryConsumer = new AdvisoryConsumer(this, id);
-											}
-										}
-										else
-										{
-											ExceptionResponse error = response as ExceptionResponse;
-											NMSException exception = CreateExceptionFromBrokerError(error.Exception);
+                    // Security exception on connect means this Connection is unusable, close the
+                    // transport now to free its resources.
+                    if (exception is NMSSecurityException && command.IsConnectionInfo)
+                    {
+                        try
+                        {
+                            transport.Dispose();
+                        }
+                        catch
+                        {
+                        }
+                    }
+
+                    throw exception;
+                }
+
+                return response;
+            }
+            catch(NMSException)
+            {
+                throw;
+            }
+            catch(Exception ex)
+            {
+                throw NMSExceptionSupport.Create(ex);
+            }
+        }
+
+        public void Oneway(Command command)
+        {
+            CheckConnected();
+
+            try
+            {
+                transport.Oneway(command);
+            }
+            catch(Exception ex)
+            {
+                throw NMSExceptionSupport.Create(ex);
+            }
+        }
+
+        private void DisposeOf(DataStructure objectId)
+        {
+            try
+            {
+                RemoveInfo command = new RemoveInfo();
+                command.ObjectId = objectId;
+                if(asyncClose)
+                {
+                    Tracer.DebugFormat("Connection[{0}]: Asynchronously disposing of Connection.", this.ConnectionId);
+                    if(connected.Value)
+                    {
+                        transport.Oneway(command);
+                        if(Tracer.IsDebugEnabled)
+                        {
+                            Tracer.DebugFormat("Connection[{0}]: Oneway command sent to broker: {1}",
+                                               this.ConnectionId, command);
+                        }
+                    }
+                }
+                else
+                {
+                    // Ensure that the object is disposed to avoid potential race-conditions
+                    // of trying to re-create the same object in the broker faster than
+                    // the broker can dispose of the object.  Allow up to 5 seconds to process.
+                    Tracer.DebugFormat("Connection[{0}]: Synchronously disposing of Connection.", this.ConnectionId);
+                    SyncRequest(command, TimeSpan.FromSeconds(5));
+                    Tracer.DebugFormat("Connection[{0}]: Synchronously closed of Connection.", this.ConnectionId);
+                }
+            }
+            catch // (BrokerException)
+            {
+                // Ignore exceptions while shutting down.
+            }
+        }
+
+        /// <summary>
+        /// Check and ensure that the connection object is connected.  If it is not
+        /// connected or is closed or closing, a ConnectionClosedException is thrown.
+        /// </summary>
+        internal void CheckConnected()
+        {
+            if(closed.Value)
+            {
+                throw new ConnectionClosedException();
+            }
+
+            if(!connected.Value)
+            {
+                DateTime timeoutTime = DateTime.Now + this.RequestTimeout;
+                int waitCount = 1;
+
+                while(true)
+                {
+                    if(Monitor.TryEnter(connectedLock))
+                    {
+                        try
+                        {
+                            if(closed.Value || closing.Value)
+                            {
+                                break;
+                            }
+                            else if(!connected.Value)
+                            {
+                                if(!this.userSpecifiedClientID)
+                                {
+                                    this.info.ClientId = this.clientIdGenerator.GenerateId();
+                                }
+
+                                try
+                                {
+                                    if(null != transport)
+                                    {
+                                        // Make sure the transport is started.
+                                        if(!this.transport.IsStarted)
+                                        {
+                                            this.transport.Start();
+                                        }
+
+                                        // Send the connection and see if an ack/nak is returned.
+                                        Response response = transport.Request(this.info, this.RequestTimeout);
+                                        if(!(response is ExceptionResponse))
+                                        {
+                                            connected.Value = true;
+                                            if(this.watchTopicAdviosires)
+                                            {
+                                                ConsumerId id = new ConsumerId(
+                                                    new SessionId(info.ConnectionId, -1),
+                                                    Interlocked.Increment(ref this.consumerIdCounter));
+                                                this.advisoryConsumer = new AdvisoryConsumer(this, id);
+                                            }
+                                        }
+                                        else
+                                        {
+                                            ExceptionResponse error = response as ExceptionResponse;
+                                            NMSException exception = CreateExceptionFromBrokerError(error.Exception);
                                             if (exception is NMSSecurityException)
                                             {
                                                 try
@@ -998,593 +1015,593 @@ namespace Apache.NMS.ActiveMQ
 
                                                 throw exception;
                                             }
-											else if(exception is InvalidClientIDException)
-											{
-												// This is non-recoverable.
-												// Shutdown the transport connection, and re-create it, but don't start it.
-												// It will be started if the connection is re-attempted.
-												this.transport.Stop();
-												ITransport newTransport = TransportFactory.CreateTransport(this.brokerUri);
-												SetTransport(newTransport);
-												throw exception;
-											}
-										}
-									}
-								}
-								catch(BrokerException)
-								{
-									// We Swallow the generic version and throw ConnectionClosedException
-								}
-								catch(NMSException)
-								{
-									throw;
-								}
-							}
-						}
-						finally
-						{
-							Monitor.Exit(connectedLock);
-						}
-					}
-
-					if(connected.Value || closed.Value || closing.Value
-						|| (DateTime.Now > timeoutTime && this.RequestTimeout != InfiniteTimeSpan))
-					{
-						break;
-					}
-
-					// Back off from being overly aggressive.  Having too many threads
-					// aggressively trying to connect to a down broker pegs the CPU.
-					Thread.Sleep(5 * (waitCount++));
-				}
-
-				if(!connected.Value)
-				{
-					throw new ConnectionClosedException();
-				}
-			}
-		}
-
-		/// <summary>
-		/// Handle incoming commands
-		/// </summary>
-		/// <param name="commandTransport">An ITransport</param>
-		/// <param name="command">A  Command</param>
-		protected void OnCommand(ITransport commandTransport, Command command)
-		{
-			if(command.IsMessageDispatch)
-			{
-				WaitForTransportInterruptionProcessingToComplete();
-				DispatchMessage((MessageDispatch) command);
-			}
-			else if(command.IsKeepAliveInfo)
-			{
-				OnKeepAliveCommand(commandTransport, (KeepAliveInfo) command);
-			}
-			else if(command.IsWireFormatInfo)
-			{
-				this.brokerWireFormatInfo = (WireFormatInfo) command;
-			}
-			else if(command.IsBrokerInfo)
-			{
-				this.brokerInfo = (BrokerInfo) command;
-				this.brokerInfoReceived.countDown();
-			}
-			else if(command.IsShutdownInfo)
-			{
-				// Only terminate the connection if the transport we use is not fault
-				// tolerant otherwise we let the transport deal with the broker closing
-				// our connection and deal with IOException if it is sent to use.
-				if(!closing.Value && !closed.Value && this.transport != null && !this.transport.IsFaultTolerant)
-				{
-					OnException(new NMSException("Broker closed this connection via Shutdown command."));
-				}
-			}
-			else if(command.IsProducerAck)
-			{
-				ProducerAck ack = (ProducerAck) command as ProducerAck;
-				if(ack.ProducerId != null)
-				{
-					MessageProducer producer = producers[ack.ProducerId] as MessageProducer;
-					if(producer != null)
-					{
-						if(Tracer.IsDebugEnabled)
-						{
-							Tracer.DebugFormat("Connection[{0}]: Received a new ProducerAck -> ",
-											   this.ConnectionId, ack);
-						}
-
-						producer.OnProducerAck(ack);
-					}
-				}
-			}
-			else if(command.IsConnectionError)
-			{
-				if(!closing.Value && !closed.Value)
-				{
-					ConnectionError connectionError = (ConnectionError) command;
-					BrokerError brokerError = connectionError.Exception;
-					string message = "Broker connection error.";
-					string cause = "";
-
-					if(null != brokerError)
-					{
-						message = brokerError.Message;
-						if(null != brokerError.Cause)
-						{
-							cause = brokerError.Cause.Message;
-						}
-					}
-
-					Tracer.ErrorFormat("Connection[{0}]: ConnectionError: {1} : {2}", this.ConnectionId, message, cause);
-					OnAsyncException(CreateExceptionFromBrokerError(brokerError));
-				}
-			}
-			else
-			{
-				Tracer.ErrorFormat("Connection[{0}]: Unknown command: {1}", this.ConnectionId, command);
-			}
-		}
-
-		protected void DispatchMessage(MessageDispatch dispatch)
-		{
-			lock(dispatchers.SyncRoot)
-			{
-				if(dispatchers.Contains(dispatch.ConsumerId))
-				{
-					IDispatcher dispatcher = (IDispatcher) dispatchers[dispatch.ConsumerId];
-
-					// Can be null when a consumer has sent a MessagePull and there was
-					// no available message at the broker to dispatch or when signalled
-					// that the end of a Queue browse has been reached.
-					if(dispatch.Message != null)
-					{
-						dispatch.Message.ReadOnlyBody = true;
-						dispatch.Message.ReadOnlyProperties = true;
-						dispatch.Message.RedeliveryCounter = dispatch.RedeliveryCounter;
-					}
-
-					dispatcher.Dispatch(dispatch);
-
-					return;
-				}
-			}
-
-			Tracer.ErrorFormat("Connection[{0}]: No such consumer active: {1}", this.ConnectionId, dispatch.ConsumerId);
-		}
-
-		protected void OnKeepAliveCommand(ITransport commandTransport, KeepAliveInfo info)
-		{
-			try
-			{
-				if(connected.Value)
-				{
-					info.ResponseRequired = false;
-					transport.Oneway(info);
-				}
-			}
-			catch(Exception ex)
-			{
-				if(!closing.Value && !closed.Value)
-				{
-					OnException(ex);
-				}
-			}
-		}
-
-		internal void OnAsyncException(Exception error)
-		{
-			if(!this.closed.Value && !this.closing.Value)
-			{
-				if(this.ExceptionListener != null)
-				{
-					if(!(error is NMSException))
-					{
-						error = NMSExceptionSupport.Create(error);
-					}
-					NMSException e = (NMSException) error;
-
-					// Called in another thread so that processing can continue
-					// here, ensures no lock contention.
-					executor.QueueUserWorkItem(AsyncCallExceptionListener, e);
-				}
-				else
-				{
-					Tracer.DebugFormat("Connection[{0}]: Async exception with no exception listener: {1}", this.ConnectionId, error);
-				}
-			}
-		}
-
-		private void AsyncCallExceptionListener(object error)
-		{
-			NMSException exception = error as NMSException;
-			this.ExceptionListener(exception);
-		}
-
-		internal void OnTransportException(ITransport source, Exception cause)
-		{
-			this.OnException(cause);
-		}
-
-		internal void OnException(Exception error)
-		{
-			// Will fire an exception listener callback if there's any set.
-			OnAsyncException(error);
-
-			if(!this.closing.Value && !this.closed.Value)
-			{
-				// Perform the actual work in another thread to avoid lock contention
-				// and allow the caller to continue on in its error cleanup.
-				executor.QueueUserWorkItem(AsyncOnExceptionHandler, error);
-			}
-		}
-
-		private void AsyncOnExceptionHandler(object error)
-		{
-			Exception cause = error as Exception;
-
-			MarkTransportFailed(cause);
-
-			try
-			{
-				this.transport.Dispose();
-			}
-			catch(Exception ex)
-			{
-				Tracer.DebugFormat("Connection[{0}]: Caught Exception While disposing of Transport: {1}", this.ConnectionId, ex);
-			}
-
-			this.brokerInfoReceived.countDown();
-
-			IList sessionsCopy = null;
-			lock(this.sessions.SyncRoot)
-			{
-				sessionsCopy = new ArrayList(this.sessions);
-			}
-
-			// Use a copy so we don't concurrently modify the Sessions list if the
-			// client is closing at the same time.
-			foreach(Session session in sessionsCopy)
-			{
-				try
-				{
-					session.Shutdown();
-				}
-				catch(Exception ex)
-				{
-					Tracer.DebugFormat("Connection[{0}]: Caught Exception While disposing of Sessions: {1}", this.ConnectionId, ex);
-				}
-			}
-		}
-
-		private void MarkTransportFailed(Exception error)
-		{
-			this.transportFailed.Value = true;
-			if(this.firstFailureError == null)
-			{
-				this.firstFailureError = error;
-			}
-		}
-
-		protected void OnTransportInterrupted(ITransport sender)
-		{
-			Tracer.DebugFormat("Connection[{0}]: Transport has been Interrupted.", this.info.ConnectionId);
-
-			// Ensure that if there's an advisory consumer we don't add it to the
-			// set of consumers that need interruption processing.
-			Interlocked.Exchange(ref transportInterruptionProcessingComplete, 1);
-
-			if(Tracer.IsDebugEnabled)
-			{
-				Tracer.DebugFormat("Connection[{0}]: Transport interrupted, dispatchers: {1}", this.ConnectionId, dispatchers.Count);
-			}
-
-			foreach(Session session in this.sessions)
-			{
-				try
-				{
-					session.ClearMessagesInProgress(ref transportInterruptionProcessingComplete);
-				}
-				catch(Exception ex)
-				{
-					Tracer.WarnFormat("Connection[{0}]: Exception while clearing messages: {1}", this.ConnectionId, ex.Message);
-					Tracer.Warn(ex.StackTrace);
-				}
-			}
-
-			if (Interlocked.Decrement(ref transportInterruptionProcessingComplete) > 0)
-			{
-				Tracer.DebugFormat("Transport interrupted - processing required, dispatchers: {0}",
-				                   Interlocked.Read(ref transportInterruptionProcessingComplete));
-
-				SignalInterruptionProcessingNeeded();
-			}
-
-			if(this.ConnectionInterruptedListener != null && !this.closing.Value)
-			{
-				try
-				{
-					this.ConnectionInterruptedListener();
-				}
-				catch
-				{
-				}
-			}
-		}
-
-		protected void OnTransportResumed(ITransport sender)
-		{
-			Tracer.DebugFormat("Connection[{0}]: Transport has resumed normal operation.", this.info.ConnectionId);
-
-			if(this.ConnectionResumedListener != null && !this.closing.Value)
-			{
-				try
-				{
-					this.ConnectionResumedListener();
-				}
-				catch
-				{
-				}
-			}
-		}
-
-		internal void OnSessionException(Session sender, Exception exception)
-		{
-			if(ExceptionListener != null)
-			{
-				try
-				{
-					ExceptionListener(exception);
-				}
-				catch
-				{
-					sender.Close();
-				}
-			}
-		}
-
-		/// <summary>
-		/// Creates a new local transaction ID
-		/// </summary>
-		public LocalTransactionId CreateLocalTransactionId()
-		{
-			LocalTransactionId id = new LocalTransactionId();
-			id.ConnectionId = ConnectionId;
-			id.Value = Interlocked.Increment(ref localTransactionCounter);
-			return id;
-		}
-
-		protected SessionId NextSessionId
-		{
-			get { return new SessionId(this.info.ConnectionId, Interlocked.Increment(ref this.sessionCounter)); }
-		}
-
-		public ActiveMQTempDestination CreateTemporaryDestination(bool topic)
-		{
-			ActiveMQTempDestination destination = null;
-
-			if(topic)
-			{
-				destination = new ActiveMQTempTopic(
-					info.ConnectionId.Value + ":" + Interlocked.Increment(ref temporaryDestinationCounter));
-			}
-			else
-			{
-				destination = new ActiveMQTempQueue(
-					info.ConnectionId.Value + ":" + Interlocked.Increment(ref temporaryDestinationCounter));
-			}
-
-			DestinationInfo command = new DestinationInfo();
-			command.ConnectionId = ConnectionId;
-			command.OperationType = DestinationInfo.ADD_OPERATION_TYPE; // 0 is add
-			command.Destination = destination;
-
-			this.SyncRequest(command);
-
-			destination = this.AddTempDestination(destination);
-			destination.Connection = this;
-
-			return destination;
-		}
-
-		public void DeleteTemporaryDestination(IDestination destination)
-		{
-			CheckClosedOrFailed();
-
-			ActiveMQTempDestination temp = destination as ActiveMQTempDestination;
-
-			foreach(Session session in this.sessions)
-			{
-				if(session.IsInUse(temp))
-				{
-					throw new NMSException("A consumer is consuming from the temporary destination");
-				}
-			}
-
-			this.tempDests.Remove(destination as ActiveMQTempDestination);
-			this.DeleteDestination(destination);
-		}
-
-		public void DeleteDestination(IDestination destination)
-		{
-			DestinationInfo command = new DestinationInfo();
-			command.ConnectionId = this.ConnectionId;
-			command.OperationType = DestinationInfo.REMOVE_OPERATION_TYPE; // 1 is remove
-			command.Destination = (ActiveMQDestination) destination;
-
-			this.Oneway(command);
-		}
-
-		private void WaitForTransportInterruptionProcessingToComplete()
-		{
-			if(!closed.Value && !transportFailed.Value && Interlocked.Read(ref transportInterruptionProcessingComplete) > 0)
-			{
-				Tracer.WarnFormat("Connection[{0}]: Dispatch with outstanding dispatch interruption processing count: {1}",
-				                  this.ConnectionId, Interlocked.Read(ref transportInterruptionProcessingComplete));
-				SignalInterruptionProcessingComplete();
-			}
-		}
-
-		internal void TransportInterruptionProcessingComplete()
-		{
-			if (Interlocked.Decrement(ref transportInterruptionProcessingComplete) == 0)
-			{
-				SignalInterruptionProcessingComplete();
-			}
-		}
-
-		private void SignalInterruptionProcessingComplete()
-		{
-			Tracer.DebugFormat("Connection[{0}]: signalled TransportInterruptionProcessingComplete: {1}",
-			                   this.ConnectionId, Interlocked.Read(ref transportInterruptionProcessingComplete));
-
-			FailoverTransport failoverTransport = transport.Narrow(typeof(FailoverTransport)) as FailoverTransport;
-			if(failoverTransport != null)
-			{
-				failoverTransport.ConnectionInterruptProcessingComplete(this.info.ConnectionId);
-				if(Tracer.IsDebugEnabled)
-				{
-					Tracer.DebugFormat("Connection[{0}]: notified failover transport ({1})" +
-									   " of interruption completion.", this.ConnectionId, failoverTransport);
-				}
-			}
-
-			Interlocked.Exchange(ref transportInterruptionProcessingComplete, 0);
-		}
-
-		private void SignalInterruptionProcessingNeeded()
-		{
-			FailoverTransport failoverTransport = transport.Narrow(typeof(FailoverTransport)) as FailoverTransport;
-
-			if(failoverTransport != null)
-			{
-				failoverTransport.StateTracker.TransportInterrupted(this.info.ConnectionId);
-				if(Tracer.IsDebugEnabled)
-				{
-					Tracer.DebugFormat("Connection[{0}]: notified failover transport ({1})" +
-									   " of pending interruption processing.", this.ConnectionId, failoverTransport);
-				}
-			}
-		}
-
-		internal ActiveMQTempDestination AddTempDestination(ActiveMQTempDestination dest)
-		{
-			ActiveMQTempDestination addedDest = dest;
-
-			// .NET lacks a putIfAbsent operation for Maps.
-			lock(tempDests.SyncRoot)
-			{
-				if(!this.tempDests.Contains(dest))
-				{
-					this.tempDests.Add(dest, dest);
-				}
-				else
-				{
-					addedDest = this.tempDests[dest] as ActiveMQTempDestination;
-				}
-			}
-
-			return addedDest;
-		}
-
-		internal void RemoveTempDestination(ActiveMQTempDestination dest)
-		{
-			this.tempDests.Remove(dest);
-		}
-
-		internal bool IsTempDestinationActive(ActiveMQTempDestination dest)
-		{
-			if(this.advisoryConsumer == null)
-			{
-				return true;
-			}
-
-			return this.tempDests.Contains(dest);
-		}
-
-		protected void CheckClosedOrFailed()
-		{
-			CheckClosed();
-			if(transportFailed.Value)
-			{
-				throw new ConnectionFailedException(firstFailureError.Message);
-			}
-		}
-
-		protected void CheckClosed()
-		{
-			if(closed.Value)
-			{
-				throw new ConnectionClosedException();
-			}
-		}
-
-		private NMSException CreateExceptionFromBrokerError(BrokerError brokerError)
-		{
-			String exceptionClassName = brokerError.ExceptionClass;
-
-			if(String.IsNullOrEmpty(exceptionClassName))
-			{
-				return new BrokerException(brokerError);
-			}
-
-			NMSException exception = null;
-			String message = brokerError.Message;
-
-			// We only create instances of exceptions from the NMS API
-			Assembly nmsAssembly = Assembly.GetAssembly(typeof(NMSException));
-
-			// First try and see if it's one we populated ourselves in which case
-			// it will have the correct namespace and exception name.
-			Type exceptionType = nmsAssembly.GetType(exceptionClassName, false, true);
-
-			// Exceptions from the broker don't have the same namespace, so we
-			// trim that and try using the NMS namespace to see if we can get an
-			// NMSException based version of the same type.  We have to convert
-			// the JMS prefixed exceptions to NMS also.
-			if(null == exceptionType)
-			{
-				if(exceptionClassName.StartsWith("java.lang.SecurityException"))
-				{
-					exceptionClassName = "Apache.NMS.NMSSecurityException";
-				}
-				else if(!exceptionClassName.StartsWith("Apache.NMS"))
-				{
-					string transformClassName;
-
-					if(exceptionClassName.Contains("."))
-					{
-						int pos = exceptionClassName.LastIndexOf(".");
-						transformClassName = exceptionClassName.Substring(pos + 1).Replace("JMS", "NMS");
-					}
-					else
-					{
-						transformClassName = exceptionClassName;
-					}
-
-					exceptionClassName = "Apache.NMS." + transformClassName;
-				}
-
-				exceptionType = nmsAssembly.GetType(exceptionClassName, false, true);
-			}
-
-			if(exceptionType != null)
-			{
-				object[] args = null;
-				if(!String.IsNullOrEmpty(message))
-				{
-					args = new object[1];
-					args[0] = message;
-				}
-
-				exception = Activator.CreateInstance(exceptionType, args) as NMSException;
-			}
-			else
-			{
-				exception = new BrokerException(brokerError);
-			}
-
-			return exception;
-		}
-	}
+                                            else if(exception is InvalidClientIDException)
+                                            {
+                                                // This is non-recoverable.
+                                                // Shutdown the transport connection, and re-create it, but don't start it.
+                                                // It will be started if the connection is re-attempted.
+                                                this.transport.Stop();
+                                                ITransport newTransport = TransportFactory.CreateTransport(this.brokerUri);
+                                                SetTransport(newTransport);
+                                                throw exception;
+                                            }
+                                        }
+                                    }
+                                }
+                                catch(BrokerException)
+                                {
+                                    // We Swallow the generic version and throw ConnectionClosedException
+                                }
+                                catch(NMSException)
+                                {
+                                    throw;
+                                }
+                            }
+                        }
+                        finally
+                        {
+                            Monitor.Exit(connectedLock);
+                        }
+                    }
+
+                    if(connected.Value || closed.Value || closing.Value
+                        || (DateTime.Now > timeoutTime && this.RequestTimeout != InfiniteTimeSpan))
+                    {
+                        break;
+                    }
+
+                    // Back off from being overly aggressive.  Having too many threads
+                    // aggressively trying to connect to a down broker pegs the CPU.
+                    Thread.Sleep(5 * (waitCount++));
+                }
+
+                if(!connected.Value)
+                {
+                    throw new ConnectionClosedException();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Handle incoming commands
+        /// </summary>
+        /// <param name="commandTransport">An ITransport</param>
+        /// <param name="command">A  Command</param>
+        protected void OnCommand(ITransport commandTransport, Command command)
+        {
+            if(command.IsMessageDispatch)
+            {
+                WaitForTransportInterruptionProcessingToComplete();
+                DispatchMessage((MessageDispatch) command);
+            }
+            else if(command.IsKeepAliveInfo)
+            {
+                OnKeepAliveCommand(commandTransport, (KeepAliveInfo) command);
+            }
+            else if(command.IsWireFormatInfo)
+            {
+                this.brokerWireFormatInfo = (WireFormatInfo) command;
+            }
+            else if(command.IsBrokerInfo)
+            {
+                this.brokerInfo = (BrokerInfo) command;
+                this.brokerInfoReceived.countDown();
+            }
+            else if(command.IsShutdownInfo)
+            {
+                // Only terminate the connection if the transport we use is not fault
+                // tolerant otherwise we let the transport deal with the broker closing
+                // our connection and deal with IOException if it is sent to use.
+                if(!closing.Value && !closed.Value && this.transport != null && !this.transport.IsFaultTolerant)
+                {
+                    OnException(new NMSException("Broker closed this connection via Shutdown command."));
+                }
+            }
+            else if(command.IsProducerAck)
+            {
+                ProducerAck ack = (ProducerAck) command as ProducerAck;
+                if(ack.ProducerId != null)
+                {
+                    MessageProducer producer = producers[ack.ProducerId] as MessageProducer;
+                    if(producer != null)
+                    {
+                        if(Tracer.IsDebugEnabled)
+                        {
+                            Tracer.DebugFormat("Connection[{0}]: Received a new ProducerAck -> ",
+                                               this.ConnectionId, ack);
+                        }
+
+                        producer.OnProducerAck(ack);
+                    }
+                }
+            }
+            else if(command.IsConnectionError)
+            {
+                if(!closing.Value && !closed.Value)
+                {
+                    ConnectionError connectionError = (ConnectionError) command;
+                    BrokerError brokerError = connectionError.Exception;
+                    string message = "Broker connection error.";
+                    string cause = "";
+
+                    if(null != brokerError)
+                    {
+                        message = brokerError.Message;
+                        if(null != brokerError.Cause)
+                        {
+                            cause = brokerError.Cause.Message;
+                        }
+                    }
+
+                    Tracer.ErrorFormat("Connection[{0}]: ConnectionError: {1} : {2}", this.ConnectionId, message, cause);
+                    OnAsyncException(CreateExceptionFromBrokerError(brokerError));
+                }
+            }
+            else
+            {
+                Tracer.ErrorFormat("Connection[{0}]: Unknown command: {1}", this.ConnectionId, command);
+            }
+        }
+
+        protected void DispatchMessage(MessageDispatch dispatch)
+        {
+            lock(dispatchers.SyncRoot)
+            {
+                if(dispatchers.Contains(dispatch.ConsumerId))
+                {
+                    IDispatcher dispatcher = (IDispatcher) dispatchers[dispatch.ConsumerId];
+
+                    // Can be null when a consumer has sent a MessagePull and there was
+                    // no available message at the broker to dispatch or when signalled
+                    // that the end of a Queue browse has been reached.
+                    if(dispatch.Message != null)
+                    {
+                        dispatch.Message.ReadOnlyBody = true;
+                        dispatch.Message.ReadOnlyProperties = true;
+                        dispatch.Message.RedeliveryCounter = dispatch.RedeliveryCounter;
+                    }
+
+                    dispatcher.Dispatch(dispatch);
+
+                    return;
+                }
+            }
+
+            Tracer.ErrorFormat("Connection[{0}]: No such consumer active: {1}", this.ConnectionId, dispatch.ConsumerId);
+        }
+
+        protected void OnKeepAliveCommand(ITransport commandTransport, KeepAliveInfo info)
+        {
+            try
+            {
+                if(connected.Value)
+                {
+                    info.ResponseRequired = false;
+                    transport.Oneway(info);
+                }
+            }
+            catch(Exception ex)
+            {
+                if(!closing.Value && !closed.Value)
+                {
+                    OnException(ex);
+                }
+            }
+        }
+
+        internal void OnAsyncException(Exception error)
+        {
+            if(!this.closed.Value && !this.closing.Value)
+            {
+                if(this.ExceptionListener != null)
+                {
+                    if(!(error is NMSException))
+                    {
+                        error = NMSExceptionSupport.Create(error);
+                    }
+                    NMSException e = (NMSException) error;
+
+                    // Called in another thread so that processing can continue
+                    // here, ensures no lock contention.
+                    executor.QueueUserWorkItem(AsyncCallExceptionListener, e);
+                }
+                else
+                {
+                    Tracer.DebugFormat("Connection[{0}]: Async exception with no exception listener: {1}", this.ConnectionId, error);
+                }
+            }
+        }
+
+        private void AsyncCallExceptionListener(object error)
+        {
+            NMSException exception = error as NMSException;
+            this.ExceptionListener(exception);
+        }
+
+        internal void OnTransportException(ITransport source, Exception cause)
+        {
+            this.OnException(cause);
+        }
+
+        internal void OnException(Exception error)
+        {
+            // Will fire an exception listener callback if there's any set.
+            OnAsyncException(error);
+
+            if(!this.closing.Value && !this.closed.Value)
+            {
+                // Perform the actual work in another thread to avoid lock contention
+                // and allow the caller to continue on in its error cleanup.
+                executor.QueueUserWorkItem(AsyncOnExceptionHandler, error);
+            }
+        }
+
+        private void AsyncOnExceptionHandler(object error)
+        {
+            Exception cause = error as Exception;
+
+            MarkTransportFailed(cause);
+
+            try
+            {
+                this.transport.Dispose();
+            }
+            catch(Exception ex)
+            {
+                Tracer.DebugFormat("Connection[{0}]: Caught Exception While disposing of Transport: {1}", this.ConnectionId, ex);
+            }
+
+            this.brokerInfoReceived.countDown();
+
+            IList sessionsCopy = null;
+            lock(this.sessions.SyncRoot)
+            {
+                sessionsCopy = new ArrayList(this.sessions);
+            }
+
+            // Use a copy so we don't concurrently modify the Sessions list if the
+            // client is closing at the same time.
+            foreach(Session session in sessionsCopy)
+            {
+                try
+                {
+                    session.Shutdown();
+                }
+                catch(Exception ex)
+                {
+                    Tracer.DebugFormat("Connection[{0}]: Caught Exception While disposing of Sessions: {1}", this.ConnectionId, ex);
+                }
+            }
+        }
+
+        private void MarkTransportFailed(Exception error)
+        {
+            this.transportFailed.Value = true;
+            if(this.firstFailureError == null)
+            {
+   

<TRUNCATED>

[48/50] [abbrv] activemq-nms-openwire git commit: Bump the branch to 1.7.3-SNAPSHOT

Posted by ta...@apache.org.
Bump the branch to 1.7.3-SNAPSHOT


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/976c9628
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/976c9628
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/976c9628

Branch: refs/heads/1.7.x
Commit: 976c96289c65d671829a7b21ce159d0340bb6f36
Parents: 27da61a
Author: Timothy A. Bish <ta...@apache.org>
Authored: Fri Apr 1 19:52:47 2016 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Fri Apr 1 19:52:47 2016 +0000

----------------------------------------------------------------------
 nant.build  | 2 +-
 package.ps1 | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/976c9628/nant.build
----------------------------------------------------------------------
diff --git a/nant.build b/nant.build
index 5fe5e4d..cc3e2f6 100644
--- a/nant.build
+++ b/nant.build
@@ -22,7 +22,7 @@
     <property name="basedir" value="${project::get-base-directory()}" />
     <property name="project.name" value="Apache.NMS.ActiveMQ" />
     <property name="project.group" value="org.apache.activemq" />
-    <property name="project.version" value="1.7.2" unless="${property::exists('project.version')}" />
+    <property name="project.version" value="1.7.3" unless="${property::exists('project.version')}" />
     <property name="project.release.type" value="SNAPSHOT" unless="${property::exists('project.release.type')}" />
     <property name="project.short_description" value="Apache NMS for ActiveMQ Class Library" />
     <property name="project.description" value="Apache NMS for ActiveMQ Class Library (.Net Messaging Library Implementation): An implementation of the NMS API for ActiveMQ" />

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/976c9628/package.ps1
----------------------------------------------------------------------
diff --git a/package.ps1 b/package.ps1
index 631da31..b6db58b 100644
--- a/package.ps1
+++ b/package.ps1
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 $pkgname = "Apache.NMS.ActiveMQ"
-$pkgver = "1.7.2-SNAPSHOT"
+$pkgver = "1.7.3-SNAPSHOT"
 $configurations = "release", "debug"
 $frameworks = "mono-2.0", "net-2.0", "net-3.5", "net-4.0"
 


[26/50] [abbrv] activemq-nms-openwire git commit: AMQNET-504 test svngit2jira

Posted by ta...@apache.org.
AMQNET-504 test svngit2jira


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/cfa43da8
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/cfa43da8
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/cfa43da8

Branch: refs/heads/master
Commit: cfa43da8f5e69f520d964894ed2f19790703dc27
Parents: f188232
Author: Timothy A. Bish <ta...@apache.org>
Authored: Tue Jul 14 15:48:44 2015 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Tue Jul 14 15:48:44 2015 +0000

----------------------------------------------------------------------
 test.txt | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/cfa43da8/test.txt
----------------------------------------------------------------------
diff --git a/test.txt b/test.txt
deleted file mode 100644
index e69de29..0000000


[23/50] [abbrv] activemq-nms-openwire git commit: Set the socket exception error code to RTSSL_HANDSHAKE_FAILURE. Fixes [AMQNET-502]. (See https://issues.apache.org/jira/browse/AMQNET-502)

Posted by ta...@apache.org.
Set the socket exception error code to RTSSL_HANDSHAKE_FAILURE.
Fixes [AMQNET-502]. (See https://issues.apache.org/jira/browse/AMQNET-502)



Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/8f10900a
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/8f10900a
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/8f10900a

Branch: refs/heads/1.7.x
Commit: 8f10900a5c11a5ee812b5ae3bb227c97d3a86d09
Parents: 66662a5
Author: Jim Gomes <jg...@apache.org>
Authored: Wed Jul 8 19:44:54 2015 +0000
Committer: Jim Gomes <jg...@apache.org>
Committed: Wed Jul 8 19:44:54 2015 +0000

----------------------------------------------------------------------
 src/main/csharp/Transport/Tcp/TcpTransportFactory.cs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/8f10900a/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs b/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs
index 786e4e2..2907a65 100644
--- a/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs
+++ b/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs
@@ -372,7 +372,8 @@ namespace Apache.NMS.ActiveMQ.Transport.Tcp
 
                 if(null == socket)
                 {
-                    throw new SocketException();
+                    const int RTSSL_HANDSHAKE_FAILURE = -2;
+                    throw new SocketException(RTSSL_HANDSHAKE_FAILURE);
                 }
             }
             catch(Exception ex)


[03/50] [abbrv] activemq-nms-openwire git commit: https://issues.apache.org/jira/browse/AMQNET-471

Posted by ta...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/c6595f25/src/main/csharp/MessageConsumer.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/MessageConsumer.cs b/src/main/csharp/MessageConsumer.cs
index 3d77291..9b03735 100755
--- a/src/main/csharp/MessageConsumer.cs
+++ b/src/main/csharp/MessageConsumer.cs
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 using System;
 using System.Threading;
 using System.Collections.Generic;
@@ -25,69 +26,71 @@ using Apache.NMS.Util;
 
 namespace Apache.NMS.ActiveMQ
 {
-	public enum AckType
-	{
-		DeliveredAck = 0, // Message delivered but not consumed
-		PoisonAck = 1, // Message could not be processed due to poison pill but discard anyway
-		ConsumedAck = 2, // Message consumed, discard
-		RedeliveredAck = 3, // Message has been Redelivered and is not yet poisoned.
-		IndividualAck = 4 // Only the given message is to be treated as consumed.
-	}
-
-	/// <summary>
-	/// An object capable of receiving messages from some destination
-	/// </summary>
-	public class MessageConsumer : IMessageConsumer, IDispatcher
-	{
+    public enum AckType
+    {
+        DeliveredAck = 0, // Message delivered but not consumed
+        PoisonAck = 1, // Message could not be processed due to poison pill but discard anyway
+        ConsumedAck = 2, // Message consumed, discard
+        RedeliveredAck = 3, // Message has been Redelivered and is not yet poisoned.
+        IndividualAck = 4, // Only the given message is to be treated as consumed.
+        UnmatchedAck = 5, // Case where durable topic subscription does not match selector
+        ExpiredAck = 6 // Case where message has expired before being dispatched to a consumer.
+    }
+
+    /// <summary>
+    /// An object capable of receiving messages from some destination
+    /// </summary>
+    public class MessageConsumer : IMessageConsumer, IDispatcher
+    {
         private const int NO_MAXIMUM_REDELIVERIES = -1;
 
         private readonly MessageTransformation messageTransformation;
         private readonly MessageDispatchChannel unconsumedMessages;
-        private readonly LinkedList<MessageDispatch> dispatchedMessages = new LinkedList<MessageDispatch>();
+        private readonly LinkedList<MessageDispatch> deliveredMessages = new LinkedList<MessageDispatch>();
         private readonly ConsumerInfo info;
         private readonly Session session;
 
-		private MessageAck pendingAck = null;
-
-		private readonly Atomic<bool> started = new Atomic<bool>();
-		private readonly Atomic<bool> deliveringAcks = new Atomic<bool>();
-
-		private int redeliveryTimeout = 500;
-		protected bool disposed = false;
-		private long lastDeliveredSequenceId = 0;
-		private int ackCounter = 0;
-		private int deliveredCounter = 0;
-		private int additionalWindowSize = 0;
-		private long redeliveryDelay = 0;
-		private int dispatchedCount = 0;
-		private volatile bool synchronizationRegistered = false;
-		private bool clearDispatchList = false;
-		private bool inProgressClearRequiredFlag;
-		private bool optimizeAcknowledge;
-		private DateTime optimizeAckTimestamp = DateTime.Now;
-	    private long optimizeAcknowledgeTimeOut = 0;
-	    private long optimizedAckScheduledAckInterval = 0;
-	    private WaitCallback optimizedAckTask = null;
-	    private long failoverRedeliveryWaitPeriod = 0;
-	    private bool transactedIndividualAck = false;
-	    private bool nonBlockingRedelivery = false;
+        private MessageAck pendingAck = null;
+
+        private readonly Atomic<bool> started = new Atomic<bool>();
+        private readonly Atomic<bool> deliveringAcks = new Atomic<bool>();
+
+        private int redeliveryTimeout = 500;
+        protected bool disposed = false;
+        private long lastDeliveredSequenceId = 0;
+        private int ackCounter = 0;
+        private int deliveredCounter = 0;
+        private int additionalWindowSize = 0;
+        private long redeliveryDelay = 0;
+        private int dispatchedCount = 0;
+        private volatile bool synchronizationRegistered = false;
+        private bool clearDeliveredList = false;
+        private bool inProgressClearRequiredFlag;
+        private bool optimizeAcknowledge;
+        private DateTime optimizeAckTimestamp = DateTime.Now;
+        private long optimizeAcknowledgeTimeOut = 0;
+        private long optimizedAckScheduledAckInterval = 0;
+        private WaitCallback optimizedAckTask = null;
+        private long failoverRedeliveryWaitPeriod = 0;
+        private bool transactedIndividualAck = false;
+        private bool nonBlockingRedelivery = false;
 
         private Exception failureError;
-		private ThreadPoolExecutor executor;
+        private ThreadPoolExecutor executor;
 
-		private event MessageListener listener;
+        private event MessageListener listener;
 
-		private IRedeliveryPolicy redeliveryPolicy;
-		private PreviouslyDeliveredMap previouslyDeliveredMessages;
+        private IRedeliveryPolicy redeliveryPolicy;
+        private PreviouslyDeliveredMap previouslyDeliveredMessages;
 
-		// Constructor internal to prevent clients from creating an instance.
-		internal MessageConsumer(Session session, ConsumerId id, ActiveMQDestination destination,
-								 String name, String selector, int prefetch, int maxPendingMessageCount,
-								 bool noLocal, bool browser, bool dispatchAsync )
-		{
-			if(destination == null)
-			{
-				throw new InvalidDestinationException("Consumer cannot receive on Null Destinations.");
+        // Constructor internal to prevent clients from creating an instance.
+        internal MessageConsumer(Session session, ConsumerId id, ActiveMQDestination destination,
+                                 String name, String selector, int prefetch, int maxPendingMessageCount,
+                                 bool noLocal, bool browser, bool dispatchAsync )
+        {
+            if(destination == null)
+            {
+                throw new InvalidDestinationException("Consumer cannot receive on Null Destinations.");
             }
             else if(destination.PhysicalName == null)
             {
@@ -101,126 +104,126 @@ namespace Apache.NMS.ActiveMQ
                 {
                     throw new InvalidDestinationException("Physical name of Destination should be valid: " + destination);
                 }
-    
+
                 String connectionID = session.Connection.ConnectionId.Value;
 
                 if(physicalName.IndexOf(connectionID) < 0)
                 {
                     throw new InvalidDestinationException("Cannot use a Temporary destination from another Connection");
                 }
-    
+
                 if(!session.Connection.IsTempDestinationActive(destination as ActiveMQTempDestination))
                 {
                     throw new InvalidDestinationException("Cannot use a Temporary destination that has been deleted");
                 }
             }
 
-			this.session = session;
-			this.redeliveryPolicy = this.session.Connection.RedeliveryPolicy;
-			this.messageTransformation = this.session.Connection.MessageTransformation;
-
-			if(session.Connection.MessagePrioritySupported)
-			{
-				this.unconsumedMessages = new SimplePriorityMessageDispatchChannel();
-			}
-			else
-			{
-				this.unconsumedMessages = new FifoMessageDispatchChannel();
-			}
-
-			this.info = new ConsumerInfo();
-			this.info.ConsumerId = id;
-			this.info.Destination = destination;
-			this.info.SubscriptionName = name;
-			this.info.Selector = selector;
-			this.info.PrefetchSize = prefetch;
-			this.info.MaximumPendingMessageLimit = maxPendingMessageCount;
-			this.info.NoLocal = noLocal;
-			this.info.Browser = browser;
-			this.info.DispatchAsync = dispatchAsync;
-			this.info.Retroactive = session.Retroactive;
-			this.info.Exclusive = session.Exclusive;
-			this.info.Priority = session.Priority;
-			this.info.ClientId = session.Connection.ClientId;
-
-			// If the destination contained a URI query, then use it to set public properties
-			// on the ConsumerInfo
-			if(destination.Options != null)
-			{
-				// Get options prefixed with "consumer.*"
-				StringDictionary options = URISupport.GetProperties(destination.Options, "consumer.");
-				// Extract out custom extension options "consumer.nms.*"
-				StringDictionary customConsumerOptions = URISupport.ExtractProperties(options, "nms.");
-
-				URISupport.SetProperties(this.info, options);
-				URISupport.SetProperties(this, customConsumerOptions, "nms.");
-			}
-
-	        this.optimizeAcknowledge = session.Connection.OptimizeAcknowledge && 
-									   session.IsAutoAcknowledge && !this.info.Browser;
-	        
-			if (this.optimizeAcknowledge) {
-	            this.optimizeAcknowledgeTimeOut = session.Connection.OptimizeAcknowledgeTimeOut;
-	            OptimizedAckScheduledAckInterval = session.Connection.OptimizedAckScheduledAckInterval;
-	        }
-
-	        this.info.OptimizedAcknowledge = this.optimizeAcknowledge;
-	        this.failoverRedeliveryWaitPeriod = session.Connection.ConsumerFailoverRedeliveryWaitPeriod;
-	        this.nonBlockingRedelivery = session.Connection.NonBlockingRedelivery;
-	        this.transactedIndividualAck = session.Connection.TransactedIndividualAck || this.nonBlockingRedelivery;
-		}
-
-		~MessageConsumer()
-		{
-			Dispose(false);
-		}
-
-		#region Property Accessors
-
-		public long LastDeliveredSequenceId
-		{
-			get { return this.lastDeliveredSequenceId; }
-		}
-
-		public ConsumerId ConsumerId
-		{
-			get { return this.info.ConsumerId; }
-		}
-
-		public ConsumerInfo ConsumerInfo
-		{
-			get { return this.info; }
-		}
-
-		public int RedeliveryTimeout
-		{
-			get { return redeliveryTimeout; }
-			set { redeliveryTimeout = value; }
-		}
-
-		public int PrefetchSize
-		{
-			get { return this.info.PrefetchSize; }
-		}
-
-		public IRedeliveryPolicy RedeliveryPolicy
-		{
-			get { return this.redeliveryPolicy; }
-			set { this.redeliveryPolicy = value; }
-		}
-
-		public long UnconsumedMessageCount
-		{
-			get { return this.unconsumedMessages.Count; }
-		}
-
-		// Custom Options
-		private bool ignoreExpiration = false;
-		public bool IgnoreExpiration
-		{
-			get { return ignoreExpiration; }
-			set { ignoreExpiration = value; }
-		}
+            this.session = session;
+            this.redeliveryPolicy = this.session.Connection.RedeliveryPolicy;
+            this.messageTransformation = this.session.Connection.MessageTransformation;
+
+            if(session.Connection.MessagePrioritySupported)
+            {
+                this.unconsumedMessages = new SimplePriorityMessageDispatchChannel();
+            }
+            else
+            {
+                this.unconsumedMessages = new FifoMessageDispatchChannel();
+            }
+
+            this.info = new ConsumerInfo();
+            this.info.ConsumerId = id;
+            this.info.Destination = destination;
+            this.info.SubscriptionName = name;
+            this.info.Selector = selector;
+            this.info.PrefetchSize = prefetch;
+            this.info.MaximumPendingMessageLimit = maxPendingMessageCount;
+            this.info.NoLocal = noLocal;
+            this.info.Browser = browser;
+            this.info.DispatchAsync = dispatchAsync;
+            this.info.Retroactive = session.Retroactive;
+            this.info.Exclusive = session.Exclusive;
+            this.info.Priority = session.Priority;
+            this.info.ClientId = session.Connection.ClientId;
+
+            // If the destination contained a URI query, then use it to set public properties
+            // on the ConsumerInfo
+            if(destination.Options != null)
+            {
+                // Get options prefixed with "consumer.*"
+                StringDictionary options = URISupport.GetProperties(destination.Options, "consumer.");
+                // Extract out custom extension options "consumer.nms.*"
+                StringDictionary customConsumerOptions = URISupport.ExtractProperties(options, "nms.");
+
+                URISupport.SetProperties(this.info, options);
+                URISupport.SetProperties(this, customConsumerOptions, "nms.");
+            }
+
+            this.optimizeAcknowledge = session.Connection.OptimizeAcknowledge &&
+                                       session.IsAutoAcknowledge && !this.info.Browser;
+
+            if (this.optimizeAcknowledge) {
+                this.optimizeAcknowledgeTimeOut = session.Connection.OptimizeAcknowledgeTimeOut;
+                OptimizedAckScheduledAckInterval = session.Connection.OptimizedAckScheduledAckInterval;
+            }
+
+            this.info.OptimizedAcknowledge = this.optimizeAcknowledge;
+            this.failoverRedeliveryWaitPeriod = session.Connection.ConsumerFailoverRedeliveryWaitPeriod;
+            this.nonBlockingRedelivery = session.Connection.NonBlockingRedelivery;
+            this.transactedIndividualAck = session.Connection.TransactedIndividualAck || this.nonBlockingRedelivery;
+        }
+
+        ~MessageConsumer()
+        {
+            Dispose(false);
+        }
+
+        #region Property Accessors
+
+        public long LastDeliveredSequenceId
+        {
+            get { return this.lastDeliveredSequenceId; }
+        }
+
+        public ConsumerId ConsumerId
+        {
+            get { return this.info.ConsumerId; }
+        }
+
+        public ConsumerInfo ConsumerInfo
+        {
+            get { return this.info; }
+        }
+
+        public int RedeliveryTimeout
+        {
+            get { return redeliveryTimeout; }
+            set { redeliveryTimeout = value; }
+        }
+
+        public int PrefetchSize
+        {
+            get { return this.info.PrefetchSize; }
+        }
+
+        public IRedeliveryPolicy RedeliveryPolicy
+        {
+            get { return this.redeliveryPolicy; }
+            set { this.redeliveryPolicy = value; }
+        }
+
+        public long UnconsumedMessageCount
+        {
+            get { return this.unconsumedMessages.Count; }
+        }
+
+        // Custom Options
+        private bool ignoreExpiration = false;
+        public bool IgnoreExpiration
+        {
+            get { return ignoreExpiration; }
+            set { ignoreExpiration = value; }
+        }
 
         public Exception FailureError
         {
@@ -228,1657 +231,1674 @@ namespace Apache.NMS.ActiveMQ
             set { this.failureError = value; }
         }
 
-		public bool OptimizeAcknowledge
-		{
-			get { return this.optimizeAcknowledge; }
-			set 
-			{
-				if (optimizeAcknowledge && !value)
-				{
-					DeliverAcks();
-				}
-				this.optimizeAcknowledge = value;
-			}
-		}
-
-		public long OptimizeAcknowledgeTimeOut
-		{
-			get { return this.optimizeAcknowledgeTimeOut; }
-			set { this.optimizeAcknowledgeTimeOut = value; }
-		}
-	    
-		public long OptimizedAckScheduledAckInterval
-		{
-			get { return this.optimizedAckScheduledAckInterval; }
-			set 
-			{ 
-				this.optimizedAckScheduledAckInterval = value; 
-
-		        if (this.optimizedAckTask != null) 
-				{
-					this.session.Scheduler.Cancel(this.optimizedAckTask);
-					this.optimizedAckTask = null;
-		        }
-
-		        // Should we periodically send out all outstanding acks.
-		        if (this.optimizeAcknowledge && this.optimizedAckScheduledAckInterval > 0)
-				{
-					this.optimizedAckTask = new WaitCallback(DoOptimizedAck);
-					this.session.Scheduler.ExecutePeriodically(
-						optimizedAckTask, null, TimeSpan.FromMilliseconds(optimizedAckScheduledAckInterval));
-				}
-			}
-		}
-	    
-		public long FailoverRedeliveryWaitPeriod 
-		{
-			get { return this.failoverRedeliveryWaitPeriod; }
-			set { this.failoverRedeliveryWaitPeriod = value; }
-		}
-	    
-		public bool TransactedIndividualAck
-		{
-			get { return this.transactedIndividualAck; }
-			set { this.transactedIndividualAck = value; }
-		}
-	    
-		public bool NonBlockingRedelivery
-		{
-			get { return this.nonBlockingRedelivery; }
-			set { this.nonBlockingRedelivery = value; }
-		}
-
-		#endregion
-
-		#region IMessageConsumer Members
-
-		private ConsumerTransformerDelegate consumerTransformer;
-		/// <summary>
-		/// A Delegate that is called each time a Message is dispatched to allow the client to do
-		/// any necessary transformations on the received message before it is delivered.
-		/// </summary>
-		public ConsumerTransformerDelegate ConsumerTransformer
-		{
-			get { return this.consumerTransformer; }
-			set { this.consumerTransformer = value; }
-		}
-
-		public event MessageListener Listener
-		{
-			add
-			{
-				CheckClosed();
-
-				if(this.PrefetchSize == 0)
-				{
-					throw new NMSException("Cannot set Asynchronous Listener on a Consumer with a zero Prefetch size");
-				}
-
-				bool wasStarted = this.session.Started;
-
-				if(wasStarted)
-				{
-					this.session.Stop();
-				}
-
-				listener += value;
-				this.session.Redispatch(this.unconsumedMessages);
-
-				if(wasStarted)
-				{
-					this.session.Start();
-				}
-			}
-			remove { listener -= value; }
-		}
-
-		public IMessage Receive()
-		{
-			CheckClosed();
-			CheckMessageListener();
-
-			SendPullRequest(0);
-			MessageDispatch dispatch = this.Dequeue(TimeSpan.FromMilliseconds(-1));
-
-			if(dispatch == null)
-			{
-				return null;
-			}
-
-			BeforeMessageIsConsumed(dispatch);
-			AfterMessageIsConsumed(dispatch, false);
-
-			return CreateActiveMQMessage(dispatch);
-		}
-
-		public IMessage Receive(TimeSpan timeout)
-		{
-			CheckClosed();
-			CheckMessageListener();
-
-			MessageDispatch dispatch = null;
-			SendPullRequest((long) timeout.TotalMilliseconds);
-
-			if(this.PrefetchSize == 0)
-			{
-				dispatch = this.Dequeue(TimeSpan.FromMilliseconds(-1));
-			}
-			else
-			{
-				dispatch = this.Dequeue(timeout);
-			}
-
-			if(dispatch == null)
-			{
-				return null;
-			}
-
-			BeforeMessageIsConsumed(dispatch);
-			AfterMessageIsConsumed(dispatch, false);
-
-			return CreateActiveMQMessage(dispatch);
-		}
-
-		public IMessage ReceiveNoWait()
-		{
-			CheckClosed();
-			CheckMessageListener();
-
-			MessageDispatch dispatch = null;
-			SendPullRequest(-1);
-
-			if(this.PrefetchSize == 0)
-			{
-				dispatch = this.Dequeue(TimeSpan.FromMilliseconds(-1));
-			}
-			else
-			{
-				dispatch = this.Dequeue(TimeSpan.Zero);
-			}
-
-			if(dispatch == null)
-			{
-				return null;
-			}
-
-			BeforeMessageIsConsumed(dispatch);
-			AfterMessageIsConsumed(dispatch, false);
-
-			return CreateActiveMQMessage(dispatch);
-		}
-
-		public void Dispose()
-		{
-			Dispose(true);
-			GC.SuppressFinalize(this);
-		}
-
-		protected void Dispose(bool disposing)
-		{
-			if(disposed)
-			{
-				return;
-			}
-
-			try
-			{
-				Close();
-			}
-			catch
-			{
-				// Ignore network errors.
-			}
-
-			disposed = true;
-		}
-
-		public virtual void Close()
-		{
-			if(!this.unconsumedMessages.Closed)
-			{
-				if(this.dispatchedMessages.Count != 0 && this.session.IsTransacted && this.session.TransactionContext.InTransaction)
-				{
-                    Tracer.DebugFormat("Consumer {0} Registering new ConsumerCloseSynchronization",
-                                       this.info.ConsumerId);
-                    this.session.TransactionContext.AddSynchronization(new ConsumerCloseSynchronization(this));
-				}
-				else
-				{
-                    Tracer.DebugFormat("Consumer {0} No Active TX or pending acks, closing normally.",
-                                       this.info.ConsumerId);
-                    this.DoClose();
-				}
-			}
-		}
-
-		internal void DoClose()
-		{
-	        Shutdown();
-			RemoveInfo removeCommand = new RemoveInfo();
-			removeCommand.ObjectId = this.ConsumerId;
-	        if (Tracer.IsDebugEnabled) 
-			{
-                Tracer.DebugFormat("Remove of Consumer[{0}] of destination [{1}] sent last delivered Id[{2}].", 
-				                   this.ConsumerId, this.info.Destination, this.lastDeliveredSequenceId);
-	        }
-	        removeCommand.LastDeliveredSequenceId = lastDeliveredSequenceId;
-	        this.session.Connection.Oneway(removeCommand);
-		}
-		
-		/// <summary>
-		/// Called from the parent Session of this Consumer to indicate that its
-		/// parent session is closing and this Consumer should close down but not
-		/// send any message to the Broker as the parent close will take care of
-		/// removing its child resources at the broker.
-		/// </summary>
-		internal void Shutdown()
-		{
-			if(!this.unconsumedMessages.Closed)
-			{
-				if(Tracer.IsDebugEnabled)
-				{
-					Tracer.DebugFormat("Shutdown of Consumer[{0}] started.", ConsumerId);
-				}
-
-				// Do we have any acks we need to send out before closing?
-				// Ack any delivered messages now.
-				if(!this.session.IsTransacted)
-				{
-					DeliverAcks();
-					if(this.IsAutoAcknowledgeBatch)
-					{
-						Acknowledge();
-					}
-				}
-
-	            if (this.executor != null) 
-				{
-					this.executor.Shutdown();
-					this.executor.AwaitTermination(TimeSpan.FromMinutes(1));
-					this.executor = null;
-	            }
-				if (this.optimizedAckTask != null)
-				{
-					this.session.Scheduler.Cancel(this.optimizedAckTask);
-				}
-
-	            if (this.session.IsClientAcknowledge)
-				{
-	                if (!this.info.Browser) 
-					{
-	                    // rollback duplicates that aren't acknowledged
-	                    LinkedList<MessageDispatch> temp = null;
-					    lock(this.dispatchedMessages)
-						{
-	                        temp = new LinkedList<MessageDispatch>(this.dispatchedMessages);
-	                    }
-	                    foreach (MessageDispatch old in temp) 
-						{
-	                        this.session.Connection.RollbackDuplicate(this, old.Message);
-	                    }
-	                    temp.Clear();
-	                }
-	            }
-
-				if(!this.session.IsTransacted)
-				{
-					lock(this.dispatchedMessages)
-					{
-						dispatchedMessages.Clear();
-					}
-				}
-
-				this.session.RemoveConsumer(this);
-				this.unconsumedMessages.Close();
-
-	            MessageDispatch[] unconsumed = unconsumedMessages.RemoveAll();
-	            if (!this.info.Browser) 
-				{
-	                foreach (MessageDispatch old in unconsumed) 
-					{
-	                    // ensure we don't filter this as a duplicate
-	                    session.Connection.RollbackDuplicate(this, old.Message);
-	                }
-	            }
-				if(Tracer.IsDebugEnabled)
-				{
-					Tracer.DebugFormat("Shutdown of Consumer[{0}] completed.", ConsumerId);
-				}
-			}			
-		}
-
-		#endregion
-
-		protected void SendPullRequest(long timeout)
-		{
-			if(this.info.PrefetchSize == 0 && this.unconsumedMessages.Empty)
-			{
-				MessagePull messagePull = new MessagePull();
-				messagePull.ConsumerId = this.info.ConsumerId;
-				messagePull.Destination = this.info.Destination;
-				messagePull.Timeout = timeout;
-				messagePull.ResponseRequired = false;
-
-				if(Tracer.IsDebugEnabled)
-				{
-					Tracer.Debug("Sending MessagePull: " + messagePull);
-				}
-
-				session.Connection.Oneway(messagePull);
-			}
-		}
-
-		protected void DoIndividualAcknowledge(ActiveMQMessage message)
-		{
-			MessageDispatch dispatch = null;
-
-			lock(this.dispatchedMessages)
-			{
-				foreach(MessageDispatch originalDispatch in this.dispatchedMessages)
-				{
-					if(originalDispatch.Message.MessageId.Equals(message.MessageId))
-					{
-						dispatch = originalDispatch;
-						this.dispatchedMessages.Remove(originalDispatch);
-						break;
-					}
-				}
-			}
-
-			if(dispatch == null)
-			{
-				Tracer.DebugFormat("Attempt to Ack MessageId[{0}] failed because the original dispatch is not in the Dispatch List", message.MessageId);
-				return;
-			}
-
-			MessageAck ack = new MessageAck(dispatch, (byte) AckType.IndividualAck, 1);
-			Tracer.Debug("Sending Individual Ack for MessageId: " + ack.LastMessageId.ToString());
-			this.session.SendAck(ack);
-		}
-
-		protected void DoNothingAcknowledge(ActiveMQMessage message)
-		{
-		}
-
-		protected void DoClientAcknowledge(ActiveMQMessage message)
-		{
-			this.CheckClosed();
-			Tracer.Debug("Sending Client Ack:");
-			this.session.Acknowledge();
-		}
-
-		public void Start()
-		{
-			if(this.unconsumedMessages.Closed)
-			{
-				return;
-			}
-
-			this.started.Value = true;
-			this.unconsumedMessages.Start();
-			this.session.Executor.Wakeup();
-		}
-
-		public void Stop()
-		{
-			this.started.Value = false;
-			this.unconsumedMessages.Stop();
-		}
-
-		public void DeliverAcks()
-		{
-			MessageAck ack = null;
-
-			if(this.deliveringAcks.CompareAndSet(false, true))
-			{
-				if(this.IsAutoAcknowledgeEach)
-				{
-					lock(this.dispatchedMessages)
-					{
-						ack = MakeAckForAllDeliveredMessages(AckType.ConsumedAck);
-						if(ack != null)
-						{
-                            Tracer.Debug("Consumer - DeliverAcks clearing the Dispatch list");
-							this.dispatchedMessages.Clear();
-							this.ackCounter = 0;
-						}
-						else
-						{
-							ack = this.pendingAck;
-							this.pendingAck = null;
-						}
-					}
-				}
-				else if(pendingAck != null && pendingAck.AckType == (byte) AckType.ConsumedAck)
-				{
-					ack = pendingAck;
-					pendingAck = null;
-				}
-
-				if(ack != null)
-				{
-	                if (this.executor == null) 
-					{
-						this.executor = new ThreadPoolExecutor();
-	                }
-
-					this.executor.QueueUserWorkItem(AsyncDeliverAck, ack);
-				}
-				else
-				{
-					this.deliveringAcks.Value = false;
-				}
-			}
-		}
-
-		private void AsyncDeliverAck(object ack)
-		{
-			MessageAck pending = ack as MessageAck;
-			try
-			{
-				this.session.SendAck(pending, true);
-			}
-			catch
-			{
-				Tracer.ErrorFormat("Consumer {0} Failed to deliver async Ack {1}",
-                                   this.info.ConsumerId, pending);
-			}
-			finally
-			{
-				this.deliveringAcks.Value = false;
-			}
-		}
-
-		internal void InProgressClearRequired()
-		{
-			inProgressClearRequiredFlag = true;
-			// deal with delivered messages async to avoid lock contention with in progress acks
-			clearDispatchList = true;
-		}
-
-		internal void ClearMessagesInProgress()
-		{
-			if(inProgressClearRequiredFlag)
-			{
-				// Called from a thread in the ThreadPool, so we wait until we can
-				// get a lock on the unconsumed list then we clear it.
-				lock(this.unconsumedMessages.SyncRoot)
-				{
-					if(inProgressClearRequiredFlag)
-					{
-						if(Tracer.IsDebugEnabled)
-						{
-							Tracer.Debug(this.ConsumerId + " clearing dispatched list (" +
-										 this.unconsumedMessages.Count + ") on transport interrupt");
-						}
-
-    	                // ensure unconsumed are rolledback up front as they may get redelivered to another consumer
-	                    MessageDispatch[] list = this.unconsumedMessages.RemoveAll();
-	                    if (!this.info.Browser) 
-						{
-	                        foreach (MessageDispatch old in list) 
-							{
-	                            session.Connection.RollbackDuplicate(this, old.Message);
-	                        }
-	                    }
-
-						// allow dispatch on this connection to resume
-						this.session.Connection.TransportInterruptionProcessingComplete();
-						this.inProgressClearRequiredFlag = false;
-					}
-				}
-			}
-		}
-
-	    private void ClearDispatchList() 
-		{
-	        if (this.clearDispatchList) 
-			{
-				lock(this.dispatchedMessages)
-				{
-	                if (this.clearDispatchList) 
-					{
-	                    if (dispatchedMessages.Count != 0) 
-						{
-	                        if (session.IsTransacted) 
-							{
-	                            if (Tracer.IsDebugEnabled) 
-								{
-									Tracer.DebugFormat("Consumer[{0}]: tracking existing transacted delivered list {1} on transport interrupt",
-									                   this.info.ConsumerId, dispatchedMessages.Count);
-	                            }
-	                            if (previouslyDeliveredMessages == null) 
-								{
-	                                previouslyDeliveredMessages = new PreviouslyDeliveredMap(session.TransactionContext.TransactionId);
-	                            }
-	                            foreach (MessageDispatch delivered in dispatchedMessages) 
-								{
-	                                this.previouslyDeliveredMessages[delivered.Message.MessageId] = false;
-	                            }
-	                        } 
-							else 
-							{
-	                            if (Tracer.IsDebugEnabled) 
-								{
-									Tracer.DebugFormat("Consumer[{0}]: clearing delivered list {1} on transport interrupt",
-									                   this.info.ConsumerId, dispatchedMessages.Count);
-	                            }
-								this.dispatchedMessages.Clear();
-	                            this.pendingAck = null;
-	                        }
-	                    }
-	                    this.clearDispatchList = false;
-	                }
-	            }
-	        }
-	    }
-
-		public virtual void Dispatch(MessageDispatch dispatch)
-		{
-			MessageListener listener = this.listener;
-			bool dispatchMessage = false;
-
-			try
-			{
-				ClearMessagesInProgress();
-				ClearDispatchList();
-
-				lock(this.unconsumedMessages.SyncRoot)
-				{
-					if(!this.unconsumedMessages.Closed)
-					{
-	                    if(this.info.Browser || !session.Connection.IsDuplicate(this, dispatch.Message)) 
-						{
-							if(listener != null && this.unconsumedMessages.Running)
-							{
-                                if (RedeliveryExceeded(dispatch)) 
-                                {
-                                    PosionAck(dispatch, "dispatch to " + ConsumerId + " exceeds redelivery policy limit:" + redeliveryPolicy.MaximumRedeliveries);
-                                    return;
-                                } 
-                                else
-                                {
-								    dispatchMessage = true;
-                                }
-							}
-							else
-							{
-	                            if (!this.unconsumedMessages.Running) 
-								{
-	                                // delayed redelivery, ensure it can be re delivered
-	                                session.Connection.RollbackDuplicate(this, dispatch.Message);
-	                            }
-								this.unconsumedMessages.Enqueue(dispatch);
-							}
-						}
-						else 
-						{
-	                        if (!this.session.IsTransacted) 
-							{
-	                            Tracer.Warn("Duplicate dispatch on connection: " + session.Connection.ConnectionId +
-	                                        " to consumer: " + ConsumerId + ", ignoring (auto acking) duplicate: " + dispatch);
-	                            MessageAck ack = new MessageAck(dispatch, (byte) AckType.IndividualAck, 1);
-	                            session.SendAck(ack);
-	                        } 
-							else
-							{
-	                            if (Tracer.IsDebugEnabled)
-								{
-									Tracer.DebugFormat("Consumer[{0}]: tracking transacted redelivery of duplicate: {1}",
-									                   this.info.ConsumerId, dispatch.Message);
-	                            }
-	                            bool needsPoisonAck = false;
-	                            lock(this.dispatchedMessages)
-								{
-	                                if (previouslyDeliveredMessages != null) 
-									{
-	                                    previouslyDeliveredMessages[dispatch.Message.MessageId] = true;
-	                                } 
-									else 
-									{
-	                                    // delivery while pending redelivery to another consumer on the same connection
-	                                    // not waiting for redelivery will help here
-	                                    needsPoisonAck = true;
-	                                }
-	                            }
-	                            if (needsPoisonAck) 
-								{
-	                                MessageAck poisonAck = new MessageAck(dispatch, (byte) AckType.PoisonAck, 1);
-	                                poisonAck.FirstMessageId = dispatch.Message.MessageId;
-									BrokerError cause = new BrokerError();
-									cause.ExceptionClass = "javax.jms.JMSException";
-									cause.Message = "Duplicate dispatch with transacted redeliver pending on another consumer, connection: " + 
-													session.Connection.ConnectionId;
-	                                Tracer.Warn("Acking duplicate delivery as poison, redelivery must be pending to another" +
-	                                            " consumer on this connection, failoverRedeliveryWaitPeriod=" +
-	                                            failoverRedeliveryWaitPeriod + ". Message: " + dispatch + ", poisonAck: " + poisonAck);
-	                                this.session.SendAck(poisonAck);
-	                            } 
-								else 
-								{
-	                                if (transactedIndividualAck) 
-									{
-	                                    ImmediateIndividualTransactedAck(dispatch);
-	                                } 
-									else 
-									{
-	                                    this.session.SendAck(new MessageAck(dispatch, (byte) AckType.DeliveredAck, 1));
-	                                }
-	                            }
-	                        }
-						}
-					}
-				}
-
-				if(dispatchMessage)
-				{
-					ActiveMQMessage message = CreateActiveMQMessage(dispatch);
-
-					this.BeforeMessageIsConsumed(dispatch);
-
-					try
-					{
-						bool expired = (!IgnoreExpiration && message.IsExpired());
-
-						if(!expired)
-						{
-							listener(message);
-						}
-
-						this.AfterMessageIsConsumed(dispatch, expired);
-					}
-					catch(Exception e)
-					{
-						if(IsAutoAcknowledgeBatch || IsAutoAcknowledgeEach || IsIndividualAcknowledge)
-						{
-                            // Schedule redelivery and possible dlq processing
-                            dispatch.RollbackCause = e;
-                            Rollback();
-						}
-						else
-						{
-							// Transacted or Client ack: Deliver the next message.
-							this.AfterMessageIsConsumed(dispatch, false);
-						}
-
-						Tracer.Error(this.info.ConsumerId + " Exception while processing message: " + e);
-
-						// If aborted we stop the abort here and let normal processing resume.
-						// This allows the session to shutdown normally and ack all messages
-						// that have outstanding acks in this consumer.
-						if((Thread.CurrentThread.ThreadState & ThreadState.AbortRequested) == ThreadState.AbortRequested)
-						{
-							Thread.ResetAbort();
-						}
-					}
-				}
-
-				if(++dispatchedCount % 1000 == 0)
-				{
-					dispatchedCount = 0;
-					Thread.Sleep(1);
-				}
-			}
-			catch(Exception e)
-			{
-				this.session.Connection.OnSessionException(this.session, e);
-			}
-		}
-
-		public bool Iterate()
-		{
-			if(this.listener != null)
-			{
-				MessageDispatch dispatch = this.unconsumedMessages.DequeueNoWait();
-				if(dispatch != null)
-				{
-					this.Dispatch(dispatch);
-					return true;
-				}
-			}
-
-			return false;
-		}
-
-		/// <summary>
-		/// Used to get an enqueued message from the unconsumedMessages list. The
-		/// amount of time this method blocks is based on the timeout value.  if
-		/// timeout == Timeout.Infinite then it blocks until a message is received.
-		/// if timeout == 0 then it it tries to not block at all, it returns a
-		/// message if it is available if timeout > 0 then it blocks up to timeout
-		/// amount of time.  Expired messages will consumed by this method.
-		/// </summary>
-		/// <param name="timeout">
-		/// A <see cref="System.TimeSpan"/>
-		/// </param>
-		/// <returns>
-		/// A <see cref="MessageDispatch"/>
-		/// </returns>
-		private MessageDispatch Dequeue(TimeSpan timeout)
-		{
-			DateTime deadline = DateTime.Now;
-
-			if(timeout > TimeSpan.Zero)
-			{
-				deadline += timeout;
-			}
-
-			while(true)
-			{
-				MessageDispatch dispatch = this.unconsumedMessages.Dequeue(timeout);
-
-				// Grab a single date/time for calculations to avoid timing errors.
-				DateTime dispatchTime = DateTime.Now;
-
-				if(dispatch == null)
-				{
-					if(timeout > TimeSpan.Zero && !this.unconsumedMessages.Closed)
-					{
-						if(dispatchTime > deadline)
-						{
-							// Out of time.
-							timeout = TimeSpan.Zero;
-						}
-						else
-						{
-							// Adjust the timeout to the remaining time.
-							timeout = deadline - dispatchTime;
-						}
-					}
-					else
-					{
-                        // Informs the caller of an error in the event that an async exception
-                        // took down the parent connection.
-                        if(this.failureError != null)
-                        {
-                            throw NMSExceptionSupport.Create(this.failureError);
-                        }
+        public bool OptimizeAcknowledge
+        {
+            get { return this.optimizeAcknowledge; }
+            set
+            {
+                if (optimizeAcknowledge && !value)
+                {
+                    DeliverAcks();
+                }
+                this.optimizeAcknowledge = value;
+            }
+        }
 
-						return null;
-					}
-				}
-				else if(dispatch.Message == null)
-				{
-					return null;
-				}
-				else if(!IgnoreExpiration && dispatch.Message.IsExpired())
-				{
-					Tracer.DebugFormat("{0} received expired message: {1}", info.ConsumerId, dispatch.Message.MessageId);
-
-					BeforeMessageIsConsumed(dispatch);
-					AfterMessageIsConsumed(dispatch, true);
-					// Refresh the dispatch time
-					dispatchTime = DateTime.Now;
-
-					if(timeout > TimeSpan.Zero && !this.unconsumedMessages.Closed)
-					{
-						if(dispatchTime > deadline)
-						{
-							// Out of time.
-							timeout = TimeSpan.Zero;
-						}
-						else
-						{
-							// Adjust the timeout to the remaining time.
-							timeout = deadline - dispatchTime;
-						}
-					}
-				}
-                else if (RedeliveryExceeded(dispatch))
+        public long OptimizeAcknowledgeTimeOut
+        {
+            get { return this.optimizeAcknowledgeTimeOut; }
+            set { this.optimizeAcknowledgeTimeOut = value; }
+        }
+
+        public long OptimizedAckScheduledAckInterval
+        {
+            get { return this.optimizedAckScheduledAckInterval; }
+            set
+            {
+                this.optimizedAckScheduledAckInterval = value;
+
+                if (this.optimizedAckTask != null)
                 {
-                    Tracer.DebugFormat("[{0}] received with excessive redelivered: {1}", ConsumerId, dispatch);
-                    PosionAck(dispatch, "dispatch to " + ConsumerId + " exceeds redelivery policy limit:" + redeliveryPolicy.MaximumRedeliveries);
-                }
-				else
-				{
-					return dispatch;
-				}
-			}
-		}
-
-		public virtual void BeforeMessageIsConsumed(MessageDispatch dispatch)
-		{
-			this.lastDeliveredSequenceId = dispatch.Message.MessageId.BrokerSequenceId;
-
-			if (!IsAutoAcknowledgeBatch)
-			{
-			    lock(this.dispatchedMessages)
-				{
-					this.dispatchedMessages.AddFirst(dispatch);
-				}
-
-				if (this.session.IsTransacted)
-				{
-                	if (this.transactedIndividualAck) 
-					{
-                    	ImmediateIndividualTransactedAck(dispatch);
-                	} 
-					else 
-					{
-						this.AckLater(dispatch, AckType.DeliveredAck);
-                	}
-				}
-			}
-		}
-
-		private bool IsOptimizedAckTime()
-		{
-            // evaluate both expired and normal msgs as otherwise consumer may get stalled
-            if (ackCounter + deliveredCounter >= (this.info.PrefetchSize * .65))
-			{
-				return true;
-			}
-
-			if (optimizeAcknowledgeTimeOut > 0)
-			{
-				DateTime deadline = optimizeAckTimestamp + 
-					TimeSpan.FromMilliseconds(optimizeAcknowledgeTimeOut);
-
-				if (DateTime.Now >= deadline)
-				{
-					return true;
-				}
-			}
-
-			return false;
-		}
-
-		public virtual void AfterMessageIsConsumed(MessageDispatch dispatch, bool expired)
-		{
-			if(this.unconsumedMessages.Closed)
-			{
-				return;
-			}
-
-			if(expired)
-			{
-				lock(this.dispatchedMessages)
-				{
-					this.dispatchedMessages.Remove(dispatch);
-				}
-
-				Acknowledge(dispatch, AckType.DeliveredAck);
-			}
-			else
-			{
-				if(this.session.IsTransacted)
-				{
-					// Do nothing.
-				}
-				else if(this.IsAutoAcknowledgeEach)
-				{
-					if(this.deliveringAcks.CompareAndSet(false, true))
-					{
-						lock(this.dispatchedMessages)
-						{
-							if(this.dispatchedMessages.Count != 0)
-							{
-	                            if (this.optimizeAcknowledge) 
-								{
-	                                this.ackCounter++;
-
-	                                if (IsOptimizedAckTime())
-									{
-	                                    MessageAck ack = MakeAckForAllDeliveredMessages(AckType.ConsumedAck);
-	                                    if (ack != null) 
-										{
-	                                        this.dispatchedMessages.Clear();
-	                                        this.ackCounter = 0;
-	                                        this.session.SendAck(ack);
-	                                        this.optimizeAckTimestamp = DateTime.Now;
-	                                    }
-	                                    // as further optimization send ack for expired msgs wehn
-	                                    // there are any.  This resets the deliveredCounter to 0 so 
-										// that we won't sent standard acks with every msg just
-	                                    // because the deliveredCounter just below 0.5 * prefetch 
-										// as used in ackLater()
-	                                    if (this.pendingAck != null && this.deliveredCounter > 0) 
-										{
-	                                        this.session.SendAck(pendingAck);
-	                                        this.pendingAck = null;
-	                                        this.deliveredCounter = 0;
-	                                    }
-	                                }
-	                            }
-								else 
-								{
-	                                MessageAck ack = MakeAckForAllDeliveredMessages(AckType.ConsumedAck);
-	                                if (ack != null) 
-									{
-	                                    this.dispatchedMessages.Clear();
-	                                    this.session.SendAck(ack);
-	                                }
-	                            }
-							}
-						}
-						this.deliveringAcks.Value = false;
-					}
-				}
-				else if(this.IsAutoAcknowledgeBatch)
-				{
-					AckLater(dispatch, AckType.ConsumedAck);
-				}
-				else if(IsClientAcknowledge || IsIndividualAcknowledge)
-				{
-					bool messageAckedByConsumer = false;
-
-					lock(this.dispatchedMessages)
-					{
-						messageAckedByConsumer = this.dispatchedMessages.Contains(dispatch);
-					}
-
-					if(messageAckedByConsumer)
-					{
-						AckLater(dispatch, AckType.DeliveredAck);
-					}
-				}
-				else
-				{
-					throw new NMSException("Invalid session state.");
-				}
-			}
-		}
-
-		private MessageAck MakeAckForAllDeliveredMessages(AckType type)
-		{
-			lock(this.dispatchedMessages)
-			{
-				if(this.dispatchedMessages.Count == 0)
-				{
-					return null;
-				}
-
-				MessageDispatch dispatch = this.dispatchedMessages.First.Value;
-				MessageAck ack = new MessageAck(dispatch, (byte) type, this.dispatchedMessages.Count);
-				ack.FirstMessageId = this.dispatchedMessages.Last.Value.Message.MessageId;
-				return ack;
-			}
-		}
-
-		private void AckLater(MessageDispatch dispatch, AckType type)
-		{
-			// Don't acknowledge now, but we may need to let the broker know the
-			// consumer got the message to expand the pre-fetch window
-			if(this.session.IsTransacted)
-			{
-				RegisterSync();
-			}
-
-			this.deliveredCounter++;
-
-			MessageAck oldPendingAck = pendingAck;
-
-        	pendingAck = new MessageAck(dispatch, (byte) type, deliveredCounter);
-
-			if(this.session.IsTransacted && this.session.TransactionContext.InTransaction)
-			{
-				pendingAck.TransactionId = this.session.TransactionContext.TransactionId;
-			}
-
-			if(oldPendingAck == null)
-			{
-				pendingAck.FirstMessageId = pendingAck.LastMessageId;
-			}
-			else if(oldPendingAck.AckType == pendingAck.AckType)
-			{
-				pendingAck.FirstMessageId = oldPendingAck.FirstMessageId;
-			}
-			else
-			{
-				// old pending ack being superseded by ack of another type, if is is not a delivered
-				// ack and hence important, send it now so it is not lost.
-				if(oldPendingAck.AckType != (byte) AckType.DeliveredAck)
-				{
-					if(Tracer.IsDebugEnabled)
-					{
-						Tracer.Debug("Sending old pending ack " + oldPendingAck + ", new pending: " + pendingAck);
-					}
-
-					this.session.SendAck(oldPendingAck);
-				}
-				else
-				{
-					if(Tracer.IsDebugEnabled)
-					{
-						Tracer.Debug("dropping old pending ack " + oldPendingAck + ", new pending: " + pendingAck);
-					}
-				}
-			}
-
-	        // evaluate both expired and normal msgs as otherwise consumer may get stalled
-			if ((0.5 * this.info.PrefetchSize) <= (this.deliveredCounter + this.ackCounter - this.additionalWindowSize))
-			{
-				this.session.SendAck(pendingAck);
-				this.pendingAck = null;
-				this.deliveredCounter = 0;
-				this.additionalWindowSize = 0;
-			}
-		}
-
-	    private void ImmediateIndividualTransactedAck(MessageDispatch dispatch)
-		{
-	        // acks accumulate on the broker pending transaction completion to indicate
-	        // delivery status
-	        RegisterSync();
-	        MessageAck ack = new MessageAck(dispatch, (byte) AckType.IndividualAck, 1);
-			ack.TransactionId = session.TransactionContext.TransactionId;
-	        this.session.Connection.SyncRequest(ack);
-	    }
+                    this.session.Scheduler.Cancel(this.optimizedAckTask);
+                    this.optimizedAckTask = null;
+                }
 
-        private void PosionAck(MessageDispatch dispatch, string cause)
+                // Should we periodically send out all outstanding acks.
+                if (this.optimizeAcknowledge && this.optimizedAckScheduledAckInterval > 0)
+                {
+                    this.optimizedAckTask = new WaitCallback(DoOptimizedAck);
+                    this.session.Scheduler.ExecutePeriodically(
+                        optimizedAckTask, null, TimeSpan.FromMilliseconds(optimizedAckScheduledAckInterval));
+                }
+            }
+        }
+
+        public long FailoverRedeliveryWaitPeriod
         {
-            BrokerError poisonCause = new BrokerError();
-            poisonCause.ExceptionClass = "javax.jms.JMSException";
-            poisonCause.Message = cause;
+            get { return this.failoverRedeliveryWaitPeriod; }
+            set { this.failoverRedeliveryWaitPeriod = value; }
+        }
 
-            MessageAck posionAck = new MessageAck(dispatch, (byte) AckType.PoisonAck, 1);
-            posionAck.FirstMessageId = dispatch.Message.MessageId;
-            posionAck.PoisonCause = poisonCause;
-            this.session.Connection.SyncRequest(posionAck);
+        public bool TransactedIndividualAck
+        {
+            get { return this.transactedIndividualAck; }
+            set { this.transactedIndividualAck = value; }
         }
 
-	    private void RegisterSync()
-		{
-			// Don't acknowledge now, but we may need to let the broker know the
-			// consumer got the message to expand the pre-fetch window
-			if(this.session.IsTransacted)
-			{
-				this.session.DoStartTransaction();
+        public bool NonBlockingRedelivery
+        {
+            get { return this.nonBlockingRedelivery; }
+            set { this.nonBlockingRedelivery = value; }
+        }
 
-				if(!synchronizationRegistered)
-				{
-                    Tracer.DebugFormat("Consumer {0} Registering new MessageConsumerSynchronization",
-                                       this.info.ConsumerId);
-					this.synchronizationRegistered = true;
-					this.session.TransactionContext.AddSynchronization(new MessageConsumerSynchronization(this));
-				}
-			}
-		}
-
-	    private void Acknowledge(MessageDispatch dispatch, AckType ackType)
-		{
-	        MessageAck ack = new MessageAck(dispatch, (byte) ackType, 1);
-	        this.session.SendAck(ack);
-	        lock(this.dispatchedMessages)
-			{
-	            dispatchedMessages.Remove(dispatch);
-	        }
-	    }
-
-		internal void Acknowledge()
-		{
-        	ClearDispatchList();
-        	WaitForRedeliveries();
-
-			lock(this.dispatchedMessages)
-			{
-				// Acknowledge all messages so far.
-				MessageAck ack = MakeAckForAllDeliveredMessages(AckType.ConsumedAck);
-
-				if(ack == null)
-				{
-					return; // no msgs
-				}
-
-				if(this.session.IsTransacted)
-				{
-                	RollbackOnFailedRecoveryRedelivery();
-                    if (!this.session.TransactionContext.InTransaction)
-                    {
-                        this.session.DoStartTransaction();
-                    }
-				    ack.TransactionId = this.session.TransactionContext.TransactionId;
-				}
-
-				this.session.SendAck(ack);
-				this.pendingAck = null;
-
-				// Adjust the counters
-				this.deliveredCounter = Math.Max(0, this.deliveredCounter - this.dispatchedMessages.Count);
-				this.additionalWindowSize = Math.Max(0, this.additionalWindowSize - this.dispatchedMessages.Count);
-
-				if(!this.session.IsTransacted)
-				{
-					this.dispatchedMessages.Clear();
-				}
-			}
-		}
-
-		internal void Commit()
-		{
-			lock(this.dispatchedMessages)
-			{
-				this.dispatchedMessages.Clear();
-				ClearPreviouslyDelivered();
-			}
-
-			this.redeliveryDelay = 0;
-		}
-
-		internal void Rollback()
-		{
-			lock(this.unconsumedMessages.SyncRoot)
-			{
-	            if (this.optimizeAcknowledge) 
-				{
-	                // remove messages read but not acked at the broker yet through optimizeAcknowledge
-	                if (!this.info.Browser) 
-					{
-	                    lock(this.dispatchedMessages)
-						{
-	                        for (int i = 0; (i < this.dispatchedMessages.Count) && (i < ackCounter); i++)
-							{
-	                            // ensure we don't filter this as a duplicate
-								MessageDispatch dispatch = this.dispatchedMessages.Last.Value;
-								this.dispatchedMessages.RemoveLast();
-	                            session.Connection.RollbackDuplicate(this, dispatch.Message);
-	                        }
-	                    }
-	                }
-	            }
-				lock(this.dispatchedMessages)
-				{
-                	RollbackPreviouslyDeliveredAndNotRedelivered();
-					if(this.dispatchedMessages.Count == 0)
-					{
-                        Tracer.DebugFormat("Consumer {0} Rolled Back, no dispatched Messages",
-                                           this.info.ConsumerId);
-						return;
-					}
-
-					// Only increase the redelivery delay after the first redelivery..
-					MessageDispatch lastMd = this.dispatchedMessages.First.Value;
-					int currentRedeliveryCount = lastMd.Message.RedeliveryCounter;
-
-					redeliveryDelay = this.redeliveryPolicy.RedeliveryDelay(currentRedeliveryCount);
-
-					MessageId firstMsgId = this.dispatchedMessages.Last.Value.Message.MessageId;
-
-					foreach(MessageDispatch dispatch in this.dispatchedMessages)
-					{
-						// Allow the message to update its internal to reflect a Rollback.
-						dispatch.Message.OnMessageRollback();
-                    	// ensure we don't filter this as a duplicate
-                    	session.Connection.RollbackDuplicate(this, dispatch.Message);
-					}
-
-					if(this.redeliveryPolicy.MaximumRedeliveries >= 0 &&
-					   lastMd.Message.RedeliveryCounter > this.redeliveryPolicy.MaximumRedeliveries)
-					{
-						// We need to NACK the messages so that they get sent to the DLQ.
-                    	MessageAck ack = new MessageAck(lastMd, (byte) AckType.PoisonAck, dispatchedMessages.Count);
-                    	
-                        if(Tracer.IsDebugEnabled)
-                        {
-							Tracer.DebugFormat("Consumer {0} Poison Ack of {1} messages aft max redeliveries: {2}",
-                                               this.info.ConsumerId, this.dispatchedMessages.Count, this.redeliveryPolicy.MaximumRedeliveries);
-                        }
+        #endregion
 
-                        BrokerError poisonCause = new BrokerError();
-                        poisonCause.ExceptionClass = "javax.jms.JMSException";
-                        poisonCause.Message = "Exceeded RedeliveryPolicy limit: " + RedeliveryPolicy.MaximumRedeliveries;
+        #region IMessageConsumer Members
 
-						if (lastMd.RollbackCause != null)
-						{
-							BrokerError cause = new BrokerError();
-                            poisonCause.ExceptionClass = "javax.jms.JMSException";
-                            poisonCause.Message = lastMd.RollbackCause.Message;
-                            poisonCause.Cause = cause;
-						}
-                    	ack.FirstMessageId = firstMsgId;
-                        ack.PoisonCause = poisonCause;
+        private ConsumerTransformerDelegate consumerTransformer;
+        /// <summary>
+        /// A Delegate that is called each time a Message is dispatched to allow the client to do
+        /// any necessary transformations on the received message before it is delivered.
+        /// </summary>
+        public ConsumerTransformerDelegate ConsumerTransformer
+        {
+            get { return this.consumerTransformer; }
+            set { this.consumerTransformer = value; }
+        }
 
-						this.session.SendAck(ack);
-
-						// Adjust the window size.
-						additionalWindowSize = Math.Max(0, this.additionalWindowSize - this.dispatchedMessages.Count);
-
-						this.redeliveryDelay = 0;
-                    	this.deliveredCounter -= this.dispatchedMessages.Count;
-                    	this.dispatchedMessages.Clear();
-					}
-					else
-					{
-						// We only send a RedeliveryAck after the first redelivery
-						if(currentRedeliveryCount > 0)
-						{
-                        	MessageAck ack = new MessageAck(lastMd, (byte) AckType.RedeliveredAck, dispatchedMessages.Count);
-							ack.FirstMessageId = firstMsgId;
-							this.session.SendAck(ack);
-						}
-
-						if (this.nonBlockingRedelivery)
-						{
-							if(redeliveryDelay == 0)
-							{
-								redeliveryDelay = RedeliveryPolicy.InitialRedeliveryDelay;
-							}
-
-	                        if(Tracer.IsDebugEnabled)
-	                        {
-								Tracer.DebugFormat("Consumer {0} Rolled Back, Re-enque {1} messages in Non-Blocking mode, delay: {2}",
-	                                               this.info.ConsumerId, this.dispatchedMessages.Count, redeliveryDelay);
-	                        }
+        public event MessageListener Listener
+        {
+            add
+            {
+                CheckClosed();
 
-                            List<MessageDispatch> pendingRedeliveries =
-                                new List<MessageDispatch>(this.dispatchedMessages);
-							pendingRedeliveries.Reverse();
-
-							this.deliveredCounter -= this.dispatchedMessages.Count;
-							this.dispatchedMessages.Clear();
-
-							this.session.Scheduler.ExecuteAfterDelay(
-								NonBlockingRedeliveryCallback, 
-								pendingRedeliveries, 
-								TimeSpan.FromMilliseconds(redeliveryDelay));
-						}
-						else 
-						{
-							// stop the delivery of messages.
-							this.unconsumedMessages.Stop();
-
-	                        if(Tracer.IsDebugEnabled)
-	                        {
-	                            Tracer.DebugFormat("Consumer {0} Rolled Back, Re-enque {1} messages",
-	                                               this.info.ConsumerId, this.dispatchedMessages.Count);
-	                        }
-
-							foreach(MessageDispatch dispatch in this.dispatchedMessages)
-							{
-	                            this.unconsumedMessages.EnqueueFirst(dispatch);
-							}
-
-							this.deliveredCounter -= this.dispatchedMessages.Count;
-							this.dispatchedMessages.Clear();
-
-							if(redeliveryDelay > 0 && !this.unconsumedMessages.Closed)
-							{
-								DateTime deadline = DateTime.Now.AddMilliseconds(redeliveryDelay);
-								ThreadPool.QueueUserWorkItem(this.RollbackHelper, deadline);
-							}
-							else
-							{
-								Start();
-							}
-						}
-					}
-				}
-			}
-
-			// Only redispatch if there's an async listener otherwise a synchronous
-			// consumer will pull them from the local queue.
-			if(this.listener != null)
-			{
-				this.session.Redispatch(this.unconsumedMessages);
-			}
-		}
-
-		private void RollbackHelper(Object arg)
-		{
-			try
-			{
-				TimeSpan waitTime = (DateTime) arg - DateTime.Now;
-
-				if(waitTime.CompareTo(TimeSpan.Zero) > 0)
-				{
-					Thread.Sleep(waitTime);
-				}
-
-				this.Start();
-			}
-			catch(Exception e)
-			{
-				if(!this.unconsumedMessages.Closed)
-				{
-					this.session.Connection.OnSessionException(this.session, e);
-				}
-			}
-		}
-
-        private void NonBlockingRedeliveryCallback(object arg) 
-		{
-            try 
-			{
-                if (!this.unconsumedMessages.Closed) 
-				{
-					List<MessageDispatch> pendingRedeliveries = arg as List<MessageDispatch>;
-
-                    foreach (MessageDispatch dispatch in pendingRedeliveries) 
-					{
-                        session.Dispatch(dispatch);
-                    }
+                if(this.PrefetchSize == 0)
+                {
+                    throw new NMSException("Cannot set Asynchronous Listener on a Consumer with a zero Prefetch size");
                 }
-            } 
-			catch (Exception e) 
-			{
-				session.Connection.OnAsyncException(e);
-            }
-        }
-
-		private ActiveMQMessage CreateActiveMQMessage(MessageDispatch dispatch)
-		{
-			ActiveMQMessage message = dispatch.Message.Clone() as ActiveMQMessage;
-
-			if(this.ConsumerTransformer != null)
-			{
-				IMessage newMessage = ConsumerTransformer(this.session, this, message);
-				if(newMessage != null)
-				{
-					message = this.messageTransformation.TransformMessage<ActiveMQMessage>(newMessage);
-				}
-			}
-
-			message.Connection = this.session.Connection;
-
-			if(IsClientAcknowledge)
-			{
-				message.Acknowledger += new AcknowledgeHandler(DoClientAcknowledge);
-			}
-			else if(IsIndividualAcknowledge)
-			{
-				message.Acknowledger += new AcknowledgeHandler(DoIndividualAcknowledge);
-			}
-			else
-			{
-				message.Acknowledger += new AcknowledgeHandler(DoNothingAcknowledge);
-			}
-
-			return message;
-		}
-
-		private void CheckClosed()
-		{
-			if(this.unconsumedMessages.Closed)
-			{
-				throw new NMSException("The Consumer has been Closed");
-			}
-		}
-
-		private void CheckMessageListener()
-		{
-			if(this.listener != null)
-			{
-				throw new NMSException("Cannot set Async listeners on Consumers with a prefetch limit of zero");
-			}
-		}
-
-		protected bool IsAutoAcknowledgeEach
-		{
-			get
-			{
-				return this.session.IsAutoAcknowledge ||
-					   (this.session.IsDupsOkAcknowledge && this.info.Destination.IsQueue);
-			}
-		}
-
-	    protected bool IsAutoAcknowledgeBatch
-		{
-			get { return this.session.IsDupsOkAcknowledge && !this.info.Destination.IsQueue; }
-		}
 
-        protected bool IsIndividualAcknowledge
-		{
-			get { return this.session.IsIndividualAcknowledge; }
-		}
+                bool wasStarted = this.session.Started;
 
-        protected bool IsClientAcknowledge
-		{
-			get { return this.session.IsClientAcknowledge; }
-		}
+                if(wasStarted)
+                {
+                    this.session.Stop();
+                }
 
-        internal bool IsInUse(ActiveMQTempDestination dest)
-        {
-            return this.info.Destination.Equals(dest);
+                listener += value;
+                this.session.Redispatch(this, this.unconsumedMessages);
+
+                if(wasStarted)
+                {
+                    this.session.Start();
+                }
+            }
+            remove { listener -= value; }
         }
 
-	    internal bool Closed
-	    {
-            get { return this.unconsumedMessages.Closed; }
-	    }
-
-	    private void DoOptimizedAck(object state)
-		{
-			if (this.optimizeAcknowledge && !this.unconsumedMessages.Closed)
-			{
-				DeliverAcks();
-			}
-		}
-	    
-	    private void WaitForRedeliveries() 
-		{
-	        if (failoverRedeliveryWaitPeriod > 0 && previouslyDeliveredMessages != null) 
-			{
-				DateTime expiry = DateTime.Now + TimeSpan.FromMilliseconds(failoverRedeliveryWaitPeriod);
-	            int numberNotReplayed;
-	            do 
-				{
-	                numberNotReplayed = 0;
-	                lock(this.dispatchedMessages)
-					{
-	                    if (previouslyDeliveredMessages != null) 
-						{
-							foreach(KeyValuePair<MessageId, bool> entry in previouslyDeliveredMessages)
-							{
-								if (!entry.Value)
-								{
-									numberNotReplayed++;
-								}
-							}
-	                    }
-	                }
-	                if (numberNotReplayed > 0) 
-					{
-	                    Tracer.Info("waiting for redelivery of " + numberNotReplayed + " in transaction: " +
-	                                previouslyDeliveredMessages.TransactionId +  ", to consumer :" + 
-						            this.info.ConsumerId);
-	                    Thread.Sleep((int) Math.Max(500, failoverRedeliveryWaitPeriod/4));
-	                }
-	            } 
-				while (numberNotReplayed > 0 && expiry > DateTime.Now);
-	        }
-	    }
-
-     	// called with deliveredMessages locked
-	    private void RollbackOnFailedRecoveryRedelivery() 
-		{
-	        if (previouslyDeliveredMessages != null) 
-			{
-	            // if any previously delivered messages was not re-delivered, transaction is 
-				// invalid and must rollback as messages have been dispatched else where.
-	            int numberNotReplayed = 0;
-				foreach(KeyValuePair<MessageId, bool> entry in previouslyDeliveredMessages)
-				{
-					if (!entry.Value)
-					{
-						numberNotReplayed++;
-	                    if (Tracer.IsDebugEnabled) 
-						{
-	                        Tracer.DebugFormat("previously delivered message has not been replayed in transaction: " +
-	                            previouslyDeliveredMessages.TransactionId + " , messageId: " + entry.Key);
-	                    }
-					}
-				}
-
-	            if (numberNotReplayed > 0) 
-				{
-	                String message = "rolling back transaction (" +
-	                     previouslyDeliveredMessages.TransactionId + ") post failover recovery. " + numberNotReplayed +
-	                     " previously delivered message(s) not replayed to consumer: " + this.info.ConsumerId;
-	                Tracer.Warn(message);
-	                throw new TransactionRolledBackException(message);
-	            }
-	        }
-	    }
-
-	     // called with unconsumedMessages && dispatchedMessages locked
-	     // remove any message not re-delivered as they can't be replayed to this
-	     // consumer on rollback
-	    private void RollbackPreviouslyDeliveredAndNotRedelivered() 
-		{
-	        if (previouslyDeliveredMessages != null) 
-			{
-				foreach(KeyValuePair<MessageId, bool> entry in previouslyDeliveredMessages)
-				{
-	                if (!entry.Value) 
-					{
-	                    RemoveFromDeliveredMessages(entry.Key);
-	                }
-	            }
-
-	            ClearPreviouslyDelivered();
-	        }
-	    }
-
-		// Must be called with dispatchedMessages locked
-	    private void RemoveFromDeliveredMessages(MessageId key) 
-		{
-			MessageDispatch toRemove = null;
-			foreach(MessageDispatch candidate in this.dispatchedMessages)
-			{
-				if (candidate.Message.MessageId.Equals(key))
-				{
-                	session.Connection.RollbackDuplicate(this, candidate.Message);
-					toRemove = candidate;
-					break;
-				}
-			}
-
-			if (toRemove != null)
-			{
-				this.dispatchedMessages.Remove(toRemove);
-			}
-	    }
-
-	    // called with deliveredMessages locked
-	    private void ClearPreviouslyDelivered() 
-		{
-	        if (previouslyDeliveredMessages != null) 
-			{
-	            previouslyDeliveredMessages.Clear();
-	            previouslyDeliveredMessages = null;
-	        }
-	    }
-
-		#region Transaction Redelivery Tracker
-
-		class PreviouslyDeliveredMap : Dictionary<MessageId, bool>
-		{
-			private TransactionId transactionId;
-			public TransactionId TransactionId
-			{
-				get { return this.transactionId; }
-			}
-
-			public PreviouslyDeliveredMap(TransactionId transactionId) : base()
-			{
-				this.transactionId = transactionId;
-			}
-		}
-
-        private bool RedeliveryExceeded(MessageDispatch dispatch) 
-        {
-            try 
+        public IMessage Receive()
+        {
+            CheckClosed();
+            CheckMessageListener();
+
+            SendPullRequest(0);
+            MessageDispatch dispatch = this.Dequeue(TimeSpan.FromMilliseconds(-1));
+
+            if(dispatch == null)
             {
-                ActiveMQMessage amqMessage = dispatch.Message as ActiveMQMessage;
+                return null;
+            }
 
-                return session.IsTransacted && redeliveryPolicy != null &&
-                       redeliveryPolicy.MaximumRedeliveries != NO_MAXIMUM_REDELIVERIES &&
-                       dispatch.RedeliveryCounter > redeliveryPolicy.MaximumRedeliveries &&
-                       // redeliveryCounter > x expected after resend via brokerRedeliveryPlugin
-                       !amqMessage.Properties.Contains("redeliveryDelay");
+            BeforeMessageIsConsumed(dispatch);
+            AfterMessageIsConsumed(dispatch, false);
+
+            return CreateActiveMQMessage(dispatch);
+        }
+
+        public IMessage Receive(TimeSpan timeout)
+        {
+            CheckClosed();
+            CheckMessageListener();
+
+            MessageDispatch dispatch = null;
+            SendPullRequest((long) timeout.TotalMilliseconds);
+
+            if(this.PrefetchSize == 0)
+            {
+                dispatch = this.Dequeue(TimeSpan.FromMilliseconds(-1));
             }
-            catch (Exception ignored) 
+            else
             {
-                return false;
+                dispatch = this.Dequeue(timeout);
+            }
+
+            if(dispatch == null)
+            {
+                return null;
             }
+
+            BeforeMessageIsConsumed(dispatch);
+            AfterMessageIsConsumed(dispatch, false);
+
+            return CreateActiveMQMessage(dispatch);
         }
 
-		#endregion
+        public IMessage ReceiveNoWait()
+        {
+            CheckClosed();
+            CheckMessageListener();
+
+            MessageDispatch dispatch = null;
+            SendPullRequest(-1);
+
+            if(this.PrefetchSize == 0)
+            {
+                dispatch = this.Dequeue(TimeSpan.FromMilliseconds(-1));
+            }
+            else
+            {
+                dispatch = this.Dequeue(TimeSpan.Zero);
+            }
+
+            if(dispatch == null)
+            {
+                return null;
+            }
 
-		#region Nested ISyncronization Types
+            BeforeMessageIsConsumed(dispatch);
+            AfterMessageIsConsumed(dispatch, false);
 
-		class MessageConsumerSynchronization : ISynchronization
-		{
-			private readonly MessageConsumer consumer;
+            return CreateActiveMQMessage(dispatch);
+        }
 
-			public MessageConsumerSynchronization(MessageConsumer consumer)
-			{
-				this.consumer = consumer;
-			}
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
 
-			public void BeforeEnd()
-			{
-                Tracer.DebugFormat("MessageConsumerSynchronization - BeforeEnd Called for Consumer {0}.",
-                                   this.consumer.ConsumerId);
+        protected void Dispose(bool disposing)
+        {
+            if(disposed)
+            {
+                return;
+            }
 
-                if (this.consumer.TransactedIndividualAck) 
-				{
-                    this.consumer.ClearDispatchList();
-                    this.consumer.WaitForRedeliveries();
-                    lock(this.consumer.dispatchedMessages)
-					{
-                        this.consumer.RollbackOnFailedRecoveryRedelivery();
-                    }
-                } 
-				else 
-				{
-					this.consumer.Acknowledge();
+            try
+            {
+                Close();
+            }
+            catch
+            {
+                // Ignore network errors.
+            }
+
+            disposed = true;
+        }
+
+        public virtual void Close()
+        {
+            if(!this.unconsumedMessages.Closed)
+            {
+                if(this.deliveredMessages.Count != 0 && this.session.IsTransacted && this.session.TransactionContext.InTransaction)
+                {
+                    Tracer.DebugFormat("Consumer[{0}] Registering new ConsumerCloseSynchronization",
+                                       this.info.ConsumerId);
+                    this.session.TransactionContext.AddSynchronization(new ConsumerCloseSynchronization(this));
+                }
+                else
+                {
+                    Tracer.DebugFormat("Consumer[{0}] No Active TX or pending acks, closing normally.",
+                                       this.info.ConsumerId);
+                    this.DoClose();
                 }
+            }
+        }
 
-				this.consumer.synchronizationRegistered = false;
-			}
+        internal void DoClose()
+        {
+            Shutdown();
+            RemoveInfo removeCommand = new RemoveInfo();
+            removeCommand.ObjectId = this.ConsumerId;
+            if (Tracer.IsDebugEnabled)
+            {
+                Tracer.DebugFormat("Remove of Consumer[{0}] of destination [{1}] sent last delivered Id[{2}].",
+                                   this.ConsumerId, this.info.Destination, this.lastDeliveredSequenceId);
+            }
+            removeCommand.LastDeliveredSequenceId = lastDeliveredSequenceId;
+            this.session.Connection.Oneway(removeCommand);
+        }
 
-			public void AfterCommit()
-			{
-                Tracer.DebugFormat("MessageConsumerSynchronization - AfterCommit Called for Consumer {0}.",
-                                   this.consumer.ConsumerId);
-				this.consumer.Commit();
-				this.consumer.synchronizationRegistered = false;
-			}
+        /// <summary>
+        /// Called from the parent Session of this Consumer to indicate that its
+        /// parent session is closing and this Consumer should close down but not
+        /// send any message to the Broker as the parent close will take care of
+        /// removing its child resources at the broker.
+        /// </summary>
+        internal void Shutdown()
+        {
+            if(!this.unconsumedMessages.Closed)
+            {
+                if(Tracer.IsDebugEnabled)
+                {
+                    Tracer.DebugFormat("Shutdown of Consumer[{0}] started.", ConsumerId);
+                }
 
-			public void AfterRollback()
-			{
-                Tracer.DebugFormat("MessageConsumerSynchronization - AfterRollback Called for Consumer {0}.",
-                                   this.consumer.ConsumerId);
-				this.consumer.Rollback();
-				this.consumer.synchronizationRegistered = false;
-			}
-		}
+                // Do we have any acks we need to send out before closing?
+                // Ack any delivered messages now.
+                if(!this.session.IsTransacted)
+                {
+                    DeliverAcks();
+                    if(this.IsAutoAcknowledgeBatch)
+                    {
+                        Acknowledge();
+                    }
+                }
+
+                if (this.executor != null)
+                {
+                    this.executor.Shutdown();
+                    this.executor.AwaitTermination(TimeSpan.FromMinutes(1));
+                    this.executor = null;
+                }
+                if (this.optimizedAckTask != null)
+                {
+                    this.session.Scheduler.Cancel(this.optimizedAckTask);
+                }
 
-		protected class ConsumerCloseSynchronization : ISynchronization
-		{
-			private readonly MessageConsumer consumer;
+                if (this.session.IsClientAcknowledge)
+                {
+                    if (!this.info.Browser)
+                    {
+                        // rollback duplicates that aren't acknowledged
+                        LinkedList<MessageDispatch> temp = null;
+                        lock(this.deliveredMessages)
+                        {
+                            temp = new LinkedList<MessageDispatch>(this.deliveredMessages);
+                        }
+                        foreach (MessageDispatch old in temp)
+                        {
+                            this.session.Connection.RollbackDuplicate(this, old.Message);
+                        }
+                        temp.Clear();
+                    }
+                }
 
-			public ConsumerCloseSynchronization(MessageConsumer consumer)
-			{
-				this.consumer = consumer;
-			}
+                if(!this.session.IsTransacted)
+                {
+                    lock(this.deliveredMessages)
+                    {
+                        deliveredMessages.Clear();
+                    }
+                }
 
-			public void BeforeEnd()
-			{
-			}
+                this.session.RemoveConsumer(this);
+                this.unconsumedMessages.Close();
 
-			public void AfterCommit()
-			{
-                if (!this.consumer.Closed) 
+                MessageDispatch[] unconsumed = unconsumedMessages.RemoveAll();
+                if (!this.info.Browser)
                 {
-                    Tracer.DebugFormat("ConsumerCloseSynchronization - AfterCommit Called for Consumer {0}.",
-                                       this.consumer.ConsumerId);
-                    this.consumer.DoClose();
+                    foreach (MessageDispatch old in unconsumed)
+                    {
+                        // ensure we don't filter this as a duplicate
+                        session.Connection.RollbackDuplicate(this, old.Message);
+                    }
+                }
+                if(Tracer.IsDebugEnabled)
+                {
+                    Tracer.DebugFormat("Shutdown of Consumer[{0}] completed.", ConsumerId);
                 }
-			}
+            }
+        }
+
+        #endregion
+
+        protected void SendPullRequest(long timeout)
+        {
+            if(this.info.PrefetchSize == 0 && this.unconsumedMessages.Empty)
+            {
+                MessagePull messagePull = new MessagePull();
+                messagePull.ConsumerId = this.info.ConsumerId;
+                messagePull.Destination = this.info.Destination;
+                messagePull.Timeout = timeout;
+                messagePull.ResponseRequired = false;
+
+                Tracer.DebugFormat("Consumer[{0}] sending MessagePull: {1}", ConsumerId, messagePull);
+
+                session.Connection.Oneway(messagePull);
+            }
+        }
+
+        protected void DoIndividualAcknowledge(ActiveMQMessage message)
+        {
+            MessageDispatch dispatch = null;
 
-			public void AfterRollback()
-			{
-                if (!this.consumer.Closed) 
+            lock(this.deliveredMessages)
+            {
+                foreach(MessageDispatch originalDispatch in this.deliveredMessages)
                 {
-                    Tracer.DebugFormat("ConsumerCloseSynchronization - AfterRollback Called for Consumer {0}.",
-                                       this.consumer.ConsumerId);
-                    this.consumer.DoClose();
+                    if(originalDispatch.Message.MessageId.Equals(message.MessageId))
+                    {
+                        dispatch = originalDispatch;
+                        this.deliveredMessages.Remove(originalDispatch);
+                        break;
+                    }
                 }
-			}
-		}
+            }
+
+            if(dispatch == null)
+            {
+                Tracer.DebugFormat("Consumer[{0}] attempt to Ack MessageId[{1}] failed " +
+                                   "because the original dispatch is not in the Dispatch List",
+                                   ConsumerId, message.MessageId);
+                return;
+            }
+
+            MessageAck ack = new MessageAck(dispatch, (byte) AckType.IndividualAck, 1);
+            Tracer.DebugFormat("Consumer[{0}] sending Individual Ack for MessageId: {1}",
+                               ConsumerId, ack.LastMessageId);
+            this.session.SendAck(ack);
+        }
+
+        protected void DoNothingAcknowledge(ActiveMQMessage message)
+        {
+        }
+
+        protected void DoClientAcknowledge(ActiveMQMessage message)
+        {
+            this.CheckClosed();
+            Tracer.DebugFormat("Consumer[{0}] sending Client Ack", ConsumerId);
+            this.session.Acknowledge();
+        }
+
+        public void Start()
+        {
+            if(this.unconsumedMessages.Closed)
+            {
+                return;
+            }
+
+            this.started.Value = true;
+            this.unconsumedMessages.Start();
+            this.session.Executor.Wakeup();
+        }
+
+        public void Stop()
+        {
+            this.started.Value = false;
+            this.unconsumedMessages.Stop();
+        }
+
+        public void DeliverAcks()
+        {
+            MessageAck ack = null;
+
+            if(this.deliveringAcks.CompareAndSet(false, true))
+            {
+                if(this.IsAutoAcknowledgeEach)
+                {
+                    lock(this.deliveredMessages)
+                    {
+                        ack = MakeAckForAllDeliveredMessages(AckType.ConsumedAck);
+                        if(ack != null)
+                        {
+                            Tracer.DebugFormat("Consumer[{0}] DeliverAcks clearing the Dispatch list", ConsumerId);
+                            this.deliveredMessages.Clear();
+                            this.ackCounter = 0;
+                        }
+                        else
+                        {
+                            ack = this.pendingAck;
+                            this.pendingAck = null;
+                        }
+                    }
+                }
+                else if(pendingAck != null && pendingAck.AckType == (byte) AckType.ConsumedAck)
+                {
+                    ack = pendingAck;
+                    pendingAck = null;
+                }
+
+                if(ack != null)
+                {
+                    if (this.executor == null)
+                    {
+                        this.executor = new ThreadPoolExecutor();
+                    }
+
+                    this.executor.QueueUserWorkItem(AsyncDeliverAck, ack);
+                }
+                else
+                {
+                    this.deliveringAcks.Value = false;
+                }
+            }
+        }
+
+        private void AsyncDeliverAck(object ack)
+        {
+            MessageAck pending = ack as MessageAck;
+            try
+            {
+                this.session.SendAck(pending, true);
+            }
+            catch
+            {
+                Tracer.ErrorFormat("Consumer[{0}] Failed to deliver async Ack {1}",
+                                   this.info.ConsumerId, pending);
+            }
+            finally
+            {
+                this.deliveringAcks.Value = false;
+            }
+        }
+
+        internal void InProgressClearRequired()
+        {
+            inProgressClearRequiredFlag = true;
+            // deal with delivered messages async to avoid lock contention with in progress acks
+            clearDeliveredList = true;
+        }
+
+        internal void ClearMessagesInProgress()
+        {
+            if(inProgressClearRequiredFlag)
+            {
+                // Called from a thread in the ThreadPool, so we wait until we can
+                // get a lock on the unconsumed list then we clear it.
+                lock(this.unconsumedMessages.SyncRoot)
+                {
+                    if(inProgressClearRequiredFlag)
+                    {
+                        Tracer.DebugFormat("Consumer[{0}] clearing unconsumed list ({1}) on transport interrupt",
+                                           ConsumerId, this.unconsumedMessages.Count);
+
+                        // ensure unconsumed are rolledback up front as they may get redelivered to another consumer
+                        MessageDispatch[] list = this.unconsumedMessages.RemoveAll();
+                        if (!this.info.Browser)
+                        {
+                            foreach (MessageDispatch unconsumed in list)
+                            {
+                                session.Connection.RollbackDuplicate(this, unconsumed.Message);
+                            }
+                        }
+
+                        // allow dispatch on this connection to resume
+                        this.session.Connection.TransportInterruptionProcessingComplete();
+                        this.inProgressClearRequiredFlag = false;
+
+                        // Wake up anyone blocked on the message channel.
+                        this.unconsumedMessages.Signal();
+                    }
+                }
+            }
+            ClearDeliveredList();
+        }
+
+        private void ClearDeliveredList()
+        {
+            if (this.clearDeliveredList)
+            {
+                lock(this.deliveredMessages)
+                {
+                    if (!this.clearDeliveredList || deliveredMessages.Count == 0)
+                    {
+                        clearDeliveredList = false;
+                        return;
+                    }
+
+                    if (session.IsTransacted)
+                    {
+                        Tracer.DebugFormat("Consumer[{0}]: tracking existing transacted delivered list {1} on transport interrupt",
+                                           this.info.ConsumerId, deliveredMessages.Count);
+
+                        if (previouslyDeliveredMessages == null)
+                        {
+                            previouslyDeliveredMessages = new PreviouslyDeliveredMap(session.TransactionContext.TransactionId);
+                        }
+
+                        foreach (MessageDispatch delivered in deliveredMessages)
+                        {
+                            this.previouslyDeliveredMessages[delivered.Message.MessageId] = false;
+                        }
+                    }
+                    else
+                    {
+                        if (this.session.IsClientAcknowledge)
+                        {
+                            Tracer.DebugFormat("Consumer[{0}] rolling back delivered list " +
+                                               "({1}) on transport interrupt",
+                                               ConsumerId, deliveredMessages.Count);
+
+                            // allow redelivery
+                            if (!this.info.Browser)
+                            {
+                                foreach (MessageDispatch dispatch in deliveredMessages)
+                                {
+                                    this.session.Connection.RollbackDuplicate(this, dispatch.Message);
+                                }
+                            }
+                        }
+                        Tracer.DebugFormat("Consumer[{0}]: clearing delivered list {1} on transport interrupt",
+                                           this.info.ConsumerId, deliveredMessages.Count);
+                        this.deliveredMessages.Clear();
+                        this.pendingAck = null;
+                    }
+
+                    this.clearDeliveredList = false;
+                }
+            }
+        }
+
+        public virtual void Dispatch(MessageDispatch dispatch)
+        {
+            MessageListener listener = this.listener;
+            bool dispatchMessage = false;
+
+            try
+            {
+                ClearMessagesInProgress();
+                ClearDeliveredList();
+
+                lock(this.unconsumedMessages.SyncRoot)
+                {
+                    if(!this.unconsumedMessages.Closed)
+                    {
+                        if(this.info.Browser || !session.Connection.IsDuplicate(this, dispatch.Message))
+                        {
+                            if(listener != null && this.unconsumedMessages.Running)
+                            {
+                                if (RedeliveryExceeded(dispatch))
+                                {
+                                    PosionAck(dispatch, "dispatch to " + ConsumerId + " exceeds redelivery policy limit:" + redeliveryPolicy.MaximumRedeliveries);
+                                    return;
+                                }
+                                else
+                                {
+                                    dispatchMessage = true;
+                                }
+                            }
+                            else
+                            {
+                                if (!this.unconsumedMessages.Running)
+                                {
+                                    // delayed redelivery, ensure it can be re delivered
+                                    session.Connection.RollbackDuplicate(this, dispatch.Message);
+                                }
+                                this.unconsumedMessages.Enqueue(dispatch);
+                                // TODO - Signal message available when we have that event hook.
+                            }
+                        }
+                        else
+                        {
+                            // deal with duplicate delivery
+                            ConsumerId consumerWithPendingTransaction;
+                            if (RedeliveryExpectedInCurrentTransaction(dispatch, true))
+                            {
+                                Tracer.DebugFormat("Consumer[{0}] tracking transacted({1}) redelivery [{2}]",
+                                                   ConsumerId, previouslyDeliveredMessages.TransactionId, dispatch.Message);
+                                if (TransactedIndividualAck)
+                                {
+                                    ImmediateIndividualTransactedAck(dispatch);
+                                }
+                                else
+                                {
+                                    this.session.SendAck(new MessageAck(dispatch, (byte) AckType.DeliveredAck, 1));
+                                }
+                            }
+                            else if ((consumerWithPendingTransaction = RedeliveryPendingInCompetingTransaction(dispatch)) != null)
+                            {
+                                Tracer.WarnFormat("Consumer[{0}] delivering duplicate [{1}], pending transaction completion on ({1}) will rollback",
+                                                  ConsumerId, dispatch.Message, consumerWithPendingTransaction);
+                                this.session.Connection.RollbackDuplicate(this, dispatch.Message);
+                                Dispatch(dispatch);
+                            }
+                            else
+                            {
+                                Tracer.WarnFormat("Consumer[{0}] suppressing duplicate delivery on connection, poison acking: ({1})",
+                                                  ConsumerId, dispatch);
+                                PosionAck(dispatch, "Suppressing duplicate delivery on connection, consumer " + ConsumerId);
+                            }
+                        }
+                    }
+                }
+
+                if(dispatchMessage)
+                {
+                    ActiveMQMessage message = CreateActiveMQMessage(dispatch);
+
+                    this.BeforeMessageIsConsumed(dispatch);
+
+                    try
+                    {
+                        bool expired = (!IgnoreExpiration && message.IsExpired());
+
+                        if(!expired)
+                        {
+                            listener(message);
+                        }
+
+                        this.AfterMessageIsConsumed(dispatch, expired);
+                    }
+                    catch(Exception e)
+                    {
+                        if(IsAutoAcknowledgeBatch || IsAutoAcknowledgeEach || IsIndividualAcknowledge)
+                        {
+                            // Schedule redelivery and possible dlq processing
+                            dispatch.RollbackCause

<TRUNCATED>

[47/50] [abbrv] activemq-nms-openwire git commit: Update tree

Posted by ta...@apache.org.
Update tree


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/27da61af
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/27da61af
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/27da61af

Branch: refs/heads/1.7.x
Commit: 27da61af787e0796745d9cb9eaa1dd9a2e79abbb
Parents: d1ee5ba
Author: Timothy A. Bish <ta...@apache.org>
Authored: Fri Apr 1 19:46:57 2016 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Fri Apr 1 19:46:57 2016 +0000

----------------------------------------------------------------------

----------------------------------------------------------------------



[02/50] [abbrv] activemq-nms-openwire git commit: https://issues.apache.org/jira/browse/AMQNET-471

Posted by ta...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/c6595f25/src/main/csharp/Session.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Session.cs b/src/main/csharp/Session.cs
index 8fff1da..c704b83 100755
--- a/src/main/csharp/Session.cs
+++ b/src/main/csharp/Session.cs
@@ -17,6 +17,7 @@
 
 using System;
 using System.Collections;
+using System.Collections.Generic;
 using System.Collections.Specialized;
 using System.Threading;
 using Apache.NMS.Util;
@@ -57,6 +58,7 @@ namespace Apache.NMS.ActiveMQ
         protected bool disposed = false;
         protected bool closed = false;
         protected bool closing = false;
+        protected Atomic<bool> clearInProgress = new Atomic<bool>();
         private TimeSpan disposeStopTimeout = TimeSpan.FromMilliseconds(30000);
         private TimeSpan closeStopTimeout = TimeSpan.FromMilliseconds(Timeout.Infinite);
         private TimeSpan requestTimeout;
@@ -73,8 +75,8 @@ namespace Apache.NMS.ActiveMQ
             this.requestTimeout = connection.RequestTimeout;
             this.dispatchAsync = connection.DispatchAsync;
             this.transactionContext = CreateTransactionContext();
-			this.exclusive = connection.ExclusiveConsumer;
-			this.retroactive = connection.UseRetroactiveConsumer;
+            this.exclusive = connection.ExclusiveConsumer;
+            this.retroactive = connection.UseRetroactiveConsumer;
 
             Uri brokerUri = connection.BrokerUri;
 
@@ -282,10 +284,26 @@ namespace Apache.NMS.ActiveMQ
             set { this.producerTransformer = value; }
         }
 
-		internal Scheduler Scheduler
-		{
-			get { return this.connection.Scheduler; }
-		}
+        internal Scheduler Scheduler
+        {
+            get { return this.connection.Scheduler; }
+        }
+
+        internal List<MessageConsumer> Consumers
+        {
+            get
+            {
+                List<MessageConsumer> copy = new List<MessageConsumer>();
+                lock(consumers.SyncRoot)
+                {
+                    foreach(MessageConsumer consumer in consumers.Values)
+                    {
+                        copy.Add(consumer);
+                    }
+                }
+                return copy;
+            }
+        }
 
         #endregion
 
@@ -338,13 +356,13 @@ namespace Apache.NMS.ActiveMQ
 
         internal void DoClose()
         {
-			Shutdown();
+            Shutdown();
             RemoveInfo removeInfo = new RemoveInfo();
             removeInfo.ObjectId = this.info.SessionId;
             removeInfo.LastDeliveredSequenceId = this.lastDeliveredSequenceId;
             this.connection.Oneway(removeInfo);
-		}
-		
+        }
+
         internal void Shutdown()
         {
             Tracer.InfoFormat("Executing Shutdown on Session with Id {0}", this.info.SessionId);
@@ -524,18 +542,18 @@ namespace Apache.NMS.ActiveMQ
                 throw new InvalidDestinationException("Cannot create a Consumer with a Null destination");
             }
 
-			if (IsIndividualAcknowledge)
-			{
-				throw new NMSException("Cannot create a durable consumer for a session that is using " +
-				                       "Individual Acknowledgement mode.");
-			}
+            if (IsIndividualAcknowledge)
+            {
+                throw new NMSException("Cannot create a durable consumer for a session that is using " +
+                                       "Individual Acknowledgement mode.");
+            }
 
             ActiveMQDestination dest = ActiveMQDestination.Transform(destination);
             MessageConsumer consumer = null;
 
             try
             {
-                consumer = DoCreateMessageConsumer(GetNextConsumerId(), dest, name, selector, 
+                consumer = DoCreateMessageConsumer(GetNextConsumerId(), dest, name, selector,
                                                    this.connection.PrefetchPolicy.DurableTopicPrefetch,
                                                    this.connection.PrefetchPolicy.MaximumPendingMessageLimit,
                                                    noLocal);
@@ -564,7 +582,7 @@ namespace Apache.NMS.ActiveMQ
         }
 
         internal virtual MessageConsumer DoCreateMessageConsumer(
-            ConsumerId id, ActiveMQDestination destination, string name, string selector, 
+            ConsumerId id, ActiveMQDestination destination, string name, string selector,
             int prefetch, int maxPending, bool noLocal)
         {
             return new MessageConsumer(this, id, destination, name, selector, prefetch,
@@ -825,7 +843,7 @@ namespace Apache.NMS.ActiveMQ
             {
                 consumers.Remove(consumer.ConsumerId);
             }
-			connection.RemoveDispatcher(consumer);
+            connection.RemoveDispatcher(consumer);
         }
 
         public void AddProducer(MessageProducer producer)
@@ -878,13 +896,13 @@ namespace Apache.NMS.ActiveMQ
 
         public void Start()
         {
-			lock(this.consumers.SyncRoot)
-			{
-				foreach(MessageConsumer consumer in this.consumers.Values)
-				{
-					consumer.Start();
-				}
-			}
+            lock(this.consumers.SyncRoot)
+            {
+                foreach(MessageConsumer consumer in this.consumers.Values)
+                {
+                    consumer.Start();
+                }
+            }
 
             if(this.executor != null)
             {
@@ -900,9 +918,13 @@ namespace Apache.NMS.ActiveMQ
             }
         }
 
-        internal void Redispatch(MessageDispatchChannel channel)
+        internal void Redispatch(IDispatcher dispatcher, MessageDispatchChannel channel)
         {
             MessageDispatch[] messages = channel.RemoveAll();
+            foreach (MessageDispatch dispatch in messages)
+            {
+                this.connection.RollbackDuplicate(dispatcher, dispatch.Message);
+            }
             System.Array.Reverse(messages);
 
             foreach(MessageDispatch message in messages)
@@ -926,20 +948,31 @@ namespace Apache.NMS.ActiveMQ
                 this.executor.ClearMessagesInProgress();
             }
 
+            if (this.consumers.Count == 0)
+            {
+                return;
+            }
+
             // Because we are called from inside the Transport Reconnection logic
             // we spawn the Consumer clear to another Thread so that we can avoid
             // any lock contention that might exist between the consumer and the
-            // connection that is reconnecting.  Use the Connection Scheduler so 
-			// that the clear calls are done one at a time to avoid further 
-			// contention on the Connection and Session resources.
-            lock(this.consumers.SyncRoot)
+            // connection that is reconnecting.  Use the Connection Scheduler so
+            // that the clear calls are done one at a time to avoid further
+            // contention on the Connection and Session resources.
+            if (clearInProgress.CompareAndSet(false, true))
             {
-                foreach(MessageConsumer consumer in this.consumers.Values)
+                lock(this.consumers.SyncRoot)
                 {
-                    consumer.InProgressClearRequired();
-					Interlocked.Increment(ref transportInterruptionProcessingComplete);
-					Scheduler.ExecuteAfterDelay(ClearMessages, consumer, 0);
+                    foreach(MessageConsumer consumer in this.consumers.Values)
+                    {
+                        consumer.InProgressClearRequired();
+                        Interlocked.Increment(ref transportInterruptionProcessingComplete);
+                        Scheduler.ExecuteAfterDelay(ClearMessages, consumer, 0);
+                    }
                 }
+
+                // Clear after all consumer have had their ClearMessagesInProgress method called.
+                Scheduler.ExecuteAfterDelay(ResetClearInProgressFlag, clearInProgress, 0);
             }
         }
 
@@ -955,6 +988,12 @@ namespace Apache.NMS.ActiveMQ
             consumer.ClearMessagesInProgress();
         }
 
+        private static void ResetClearInProgressFlag(object value)
+        {
+            Atomic<bool> clearInProgress = value as Atomic<bool>;
+            clearInProgress.Value = false;
+        }
+
         internal void Acknowledge()
         {
             lock(this.consumers.SyncRoot)
@@ -986,10 +1025,10 @@ namespace Apache.NMS.ActiveMQ
 
         internal void SendAck(MessageAck ack, bool lazy)
         {
-			if(Tracer.IsDebugEnabled)
-			{
-				Tracer.Debug("Session sending Ack: " + ack);
-			}
+            if(Tracer.IsDebugEnabled)
+            {
+                Tracer.Debug("Session sending Ack: " + ack);
+            }
 
             if(lazy || connection.SendAcksAsync || this.IsTransacted )
             {
@@ -1001,10 +1040,10 @@ namespace Apache.NMS.ActiveMQ
             }
         }
 
-		protected virtual TransactionContext CreateTransactionContext()
-		{
-			return new TransactionContext(this);
-		}
+        protected virtual TransactionContext CreateTransactionContext()
+        {
+            return new TransactionContext(this);
+        }
 
         private void CheckClosed()
         {
@@ -1055,16 +1094,16 @@ namespace Apache.NMS.ActiveMQ
 
         internal bool IsInUse(ActiveMQTempDestination dest)
         {
-			lock(this.consumers.SyncRoot)
-			{
-				foreach(MessageConsumer consumer in this.consumers.Values)
-				{
-					if(consumer.IsInUse(dest))
-					{
-						return true;
-					}
-				}
-			}
+            lock(this.consumers.SyncRoot)
+            {
+                foreach(MessageConsumer consumer in this.consumers.Values)
+                {
+                    if(consumer.IsInUse(dest))
+                    {
+                        return true;
+                    }
+                }
+            }
 
             return false;
         }

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/c6595f25/src/main/csharp/TransactionContext.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/TransactionContext.cs b/src/main/csharp/TransactionContext.cs
index 47836d7..4079814 100644
--- a/src/main/csharp/TransactionContext.cs
+++ b/src/main/csharp/TransactionContext.cs
@@ -15,12 +15,13 @@
  * limitations under the License.
  */
 
+using System;
 using System.Collections;
 using Apache.NMS.ActiveMQ.Commands;
 
 namespace Apache.NMS.ActiveMQ
 {
-	public enum TransactionType
+    public enum TransactionType
     {
         Begin = 0, Prepare = 1, CommitOnePhase = 2, CommitTwoPhase = 3, Rollback = 4, Recover=5, Forget = 6, End = 7
     }
@@ -28,7 +29,7 @@ namespace Apache.NMS.ActiveMQ
 
 namespace Apache.NMS.ActiveMQ
 {
-	public class TransactionContext
+    public class TransactionContext
     {
         protected TransactionId transactionId;
         protected readonly Session session;
@@ -36,47 +37,48 @@ namespace Apache.NMS.ActiveMQ
         protected readonly ArrayList synchronizations = ArrayList.Synchronized(new ArrayList());
 
         public TransactionContext(Session session)
-		{
+        {
             this.session = session;
             this.connection = session.Connection;
         }
 
         public bool InTransaction
         {
-            get{ return this.transactionId != null; }
+            get { return this.transactionId != null; }
         }
 
         public virtual bool InLocalTransaction
         {
-            get{ return this.transactionId != null; }
+            get { return this.transactionId != null; }
         }
 
         public TransactionId TransactionId
         {
             get { return transactionId; }
+            protected set { this.transactionId = value; }
         }
-        
+
         public void AddSynchronization(ISynchronization synchronization)
         {
             synchronizations.Add(synchronization);
         }
-        
+
         public void RemoveSynchronization(ISynchronization synchronization)
         {
             synchronizations.Remove(synchronization);
         }
-        
+
         public virtual void Begin()
         {
             if(!InTransaction)
             {
                 this.transactionId = this.session.Connection.CreateLocalTransactionId();
-                
+
                 TransactionInfo info = new TransactionInfo();
                 info.ConnectionId = this.session.Connection.ConnectionId;
                 info.TransactionId = transactionId;
                 info.Type = (int) TransactionType.Begin;
-                
+
                 this.session.Connection.Oneway(info);
 
                 SignalTransactionStarted();
@@ -87,54 +89,78 @@ namespace Apache.NMS.ActiveMQ
                 }
             }
         }
-        
+
         public virtual void Rollback()
         {
             if(InTransaction)
             {
-                this.BeforeEnd();
-    
+                try
+                {
+                    this.BeforeEnd();
+                }
+                catch (TransactionRolledBackException canOccurOnFailover)
+                {
+                    Tracer.WarnFormat("Rollback processing error {0}", canOccurOnFailover.Message);
+                }
+
                 if(Tracer.IsDebugEnabled)
                 {
                     Tracer.Debug("Rollback: "  + this.transactionId +
                                  " syncCount: " +
                                  (synchronizations != null ? synchronizations.Count : 0));
                 }
-    
+
                 TransactionInfo info = new TransactionInfo();
                 info.ConnectionId = this.session.Connection.ConnectionId;
                 info.TransactionId = transactionId;
                 info.Type = (int) TransactionType.Rollback;
-                
+
                 this.transactionId = null;
                 this.session.Connection.SyncRequest(info);
-    
+
                 this.AfterRollback();
             }
         }
-        
+
         public virtual void Commit()
         {
             if(InTransaction)
             {
-                this.BeforeEnd();
-    
+                try
+                {
+                    this.BeforeEnd();
+                }
+                catch
+                {
+                    Rollback();
+                    throw;
+                }
+
                 if(Tracer.IsDebugEnabled)
                 {
                     Tracer.Debug("Commit: "  + this.transactionId +
                                  " syncCount: " +
                                  (synchronizations != null ? synchronizations.Count : 0));
                 }
-    
+
                 TransactionInfo info = new TransactionInfo();
                 info.ConnectionId = this.session.Connection.ConnectionId;
                 info.TransactionId = transactionId;
                 info.Type = (int) TransactionType.CommitOnePhase;
-                
-                this.transactionId = null;
-                this.session.Connection.SyncRequest(info);
-                
-                this.AfterCommit();
+
+                try
+                {
+                    this.TransactionId = null;
+                    this.session.Connection.SyncRequest(info);
+                    this.AfterCommit();
+                }
+                catch (Exception e)
+                {
+                    Tracer.InfoFormat("Commit failed for transaction {0} - {1}",
+                                      info.TransactionId, e.Message);
+                    AfterRollback();
+                    throw;
+                }
             }
         }
 
@@ -219,7 +245,7 @@ namespace Apache.NMS.ActiveMQ
             }
         }
 
-	    #endregion
+        #endregion
 
     }
 }

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/c6595f25/src/main/csharp/Util/FifoMessageDispatchChannel.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Util/FifoMessageDispatchChannel.cs b/src/main/csharp/Util/FifoMessageDispatchChannel.cs
index db6e5c7..d69eaab 100644
--- a/src/main/csharp/Util/FifoMessageDispatchChannel.cs
+++ b/src/main/csharp/Util/FifoMessageDispatchChannel.cs
@@ -38,18 +38,18 @@ namespace Apache.NMS.ActiveMQ.Util
         {
             get{ return this.mutex; }
         }
-        
+
         public bool Closed
         {
-            get 
+            get
             {
                 lock(this.mutex)
                 {
-                    return this.closed; 
+                    return this.closed;
                 }
             }
-            
-            set 
+
+            set
             {
                 lock(this.mutex)
                 {
@@ -67,7 +67,7 @@ namespace Apache.NMS.ActiveMQ.Util
                     return this.running;
                 }
             }
-            
+
             set
             {
                 lock(this.mutex)
@@ -130,12 +130,12 @@ namespace Apache.NMS.ActiveMQ.Util
                 {
                     this.running = false;
                     this.closed = true;
-                }          
+                }
 
                 Monitor.PulseAll(this.mutex);
-            }            
+            }
         }
-        
+
         public void Enqueue(MessageDispatch dispatch)
         {
             lock(this.mutex)
@@ -163,27 +163,27 @@ namespace Apache.NMS.ActiveMQ.Util
                 {
                     Monitor.Wait(this.mutex, timeout);
                 }
-        
-                if( Closed || !Running || Empty ) 
+
+                if( Closed || !Running || Empty )
                 {
                     return null;
                 }
-        
-                return DequeueNoWait();                      
+
+                return DequeueNoWait();
             }
         }
 
         public MessageDispatch DequeueNoWait()
         {
             MessageDispatch result = null;
-            
+
             lock(this.mutex)
             {
-                if( Closed || !Running || Empty ) 
+                if( Closed || !Running || Empty )
                 {
                     return null;
                 }
-                
+
                 result = channel.First.Value;
                 this.channel.RemoveFirst();
             }
@@ -195,11 +195,11 @@ namespace Apache.NMS.ActiveMQ.Util
         {
             lock(this.mutex)
             {
-                if( Closed || !Running || Empty ) 
+                if( Closed || !Running || Empty )
                 {
                     return null;
                 }
-                
+
                 return channel.First.Value;
             }
         }
@@ -215,7 +215,7 @@ namespace Apache.NMS.ActiveMQ.Util
         public MessageDispatch[] RemoveAll()
         {
             MessageDispatch[] result;
-            
+
             lock(mutex)
             {
                 result = new MessageDispatch[this.Count];
@@ -225,6 +225,14 @@ namespace Apache.NMS.ActiveMQ.Util
 
             return result;
         }
+
+        public void Signal()
+        {
+            lock(mutex)
+            {
+                Monitor.PulseAll(this.mutex);
+            }
+        }
     }
 }
 

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/c6595f25/src/main/csharp/Util/MessageDispatchChannel.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Util/MessageDispatchChannel.cs b/src/main/csharp/Util/MessageDispatchChannel.cs
index 66eb633..973db3e 100644
--- a/src/main/csharp/Util/MessageDispatchChannel.cs
+++ b/src/main/csharp/Util/MessageDispatchChannel.cs
@@ -33,7 +33,7 @@ namespace Apache.NMS.ActiveMQ.Util
         {
             get;
         }
-        
+
         bool Closed
         {
             get;
@@ -61,7 +61,7 @@ namespace Apache.NMS.ActiveMQ.Util
         void Stop();
 
         void Close();
-        
+
         void Enqueue(MessageDispatch dispatch);
 
         void EnqueueFirst(MessageDispatch dispatch);
@@ -75,5 +75,7 @@ namespace Apache.NMS.ActiveMQ.Util
         void Clear();
 
         MessageDispatch[] RemoveAll();
+
+        void Signal();
     }
 }

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/c6595f25/src/main/csharp/Util/SimplePriorityMessageDispatchChannel.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Util/SimplePriorityMessageDispatchChannel.cs b/src/main/csharp/Util/SimplePriorityMessageDispatchChannel.cs
index e3c3c87..39ef789 100644
--- a/src/main/csharp/Util/SimplePriorityMessageDispatchChannel.cs
+++ b/src/main/csharp/Util/SimplePriorityMessageDispatchChannel.cs
@@ -46,15 +46,15 @@ namespace Apache.NMS.ActiveMQ.Util
         {
             get{ return this.mutex; }
         }
-        
+
         public bool Closed
         {
-            get 
+            get
             {
-                return this.closed; 
+                return this.closed;
             }
-            
-            set 
+
+            set
             {
                 lock(this.mutex)
                 {
@@ -69,7 +69,7 @@ namespace Apache.NMS.ActiveMQ.Util
             {
                 return this.running;
             }
-            
+
             set
             {
                 lock(this.mutex)
@@ -126,12 +126,12 @@ namespace Apache.NMS.ActiveMQ.Util
                 {
                     this.running = false;
                     this.closed = true;
-                }          
+                }
 
                 Monitor.PulseAll(this.mutex);
-            }            
+            }
         }
-        
+
         public void Enqueue(MessageDispatch dispatch)
         {
             lock(this.mutex)
@@ -161,12 +161,12 @@ namespace Apache.NMS.ActiveMQ.Util
                 {
                     Monitor.Wait(this.mutex, timeout);
                 }
-        
-                if( Closed || !Running || Empty ) 
+
+                if( Closed || !Running || Empty )
                 {
                     return null;
                 }
-        
+
                 return RemoveFirst();
             }
         }
@@ -174,14 +174,14 @@ namespace Apache.NMS.ActiveMQ.Util
         public MessageDispatch DequeueNoWait()
         {
             MessageDispatch result = null;
-            
+
             lock(this.mutex)
             {
-                if( Closed || !Running || Empty ) 
+                if( Closed || !Running || Empty )
                 {
                     return null;
                 }
-                
+
                 result = RemoveFirst();
             }
 
@@ -192,11 +192,11 @@ namespace Apache.NMS.ActiveMQ.Util
         {
             lock(this.mutex)
             {
-                if( Closed || !Running || Empty ) 
+                if( Closed || !Running || Empty )
                 {
                     return null;
                 }
-                
+
                 return GetFirst();
             }
         }
@@ -215,7 +215,7 @@ namespace Apache.NMS.ActiveMQ.Util
         public MessageDispatch[] RemoveAll()
         {
             MessageDispatch[] result;
-            
+
             lock(mutex)
             {
                 result = new MessageDispatch[this.size];
@@ -234,6 +234,14 @@ namespace Apache.NMS.ActiveMQ.Util
             return result;
         }
 
+        public void Signal()
+        {
+            lock(mutex)
+            {
+                Monitor.PulseAll(this.mutex);
+            }
+        }
+
         protected int GetPriority(MessageDispatch message)
         {
             int priority = (int) MsgPriority.Lowest;

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/c6595f25/src/test/csharp/Transport/failover/FailoverTransactionTest.cs
----------------------------------------------------------------------
diff --git a/src/test/csharp/Transport/failover/FailoverTransactionTest.cs b/src/test/csharp/Transport/failover/FailoverTransactionTest.cs
index cacfddb..408b748 100644
--- a/src/test/csharp/Transport/failover/FailoverTransactionTest.cs
+++ b/src/test/csharp/Transport/failover/FailoverTransactionTest.cs
@@ -72,7 +72,7 @@ namespace Apache.NMS.ActiveMQ.Test
                 using(ISession session = connection.CreateSession())
                 {
                     IDestination destination = session.GetQueue(destinationName);
-                    PurgeQueue(connection, destination);
+                    DeleteQueue(connection, destination);
                 }
 
                 Tracer.Debug("Test is putting " + MSG_COUNT + " messages on the queue: " + destinationName);
@@ -89,10 +89,12 @@ namespace Apache.NMS.ActiveMQ.Test
                     }
                     catch(TransactionRolledBackException)
                     {
+                        Tracer.Info("TEST: Caught expected TransactionRolledBackException");
                     }
-                    catch
+                    catch(Exception ex)
                     {
-                        Assert.Fail("Should have thrown a TransactionRolledBackException");
+                        Assert.Fail("Should have thrown a TransactionRolledBackException, but was: " +
+                                    ex.GetType().Name);
                     }
                 }
 
@@ -240,6 +242,50 @@ namespace Apache.NMS.ActiveMQ.Test
             Assert.IsTrue(this.resumed);
         }
 
+        [Test]
+        public void TestMessageDeliveredAfterCommitFailsAndRollback()
+        {
+            string uri = "failover:(tcpfaulty://${activemqhost}:61616?transport.useLogging=true)";
+            IConnectionFactory factory = new ConnectionFactory(NMSTestSupport.ReplaceEnvVar(uri));
+            using(connection = factory.CreateConnection() as Connection)
+            {
+                using(ISession session = connection.CreateSession())
+                {
+                    IDestination destination = session.GetQueue(destinationName);
+                    DeleteQueue(connection, destination);
+                    PutOneMsgIntoQueue(session, destination);
+                }
+
+                using(ISession session = connection.CreateSession(AcknowledgementMode.Transactional))
+                {
+                    connection.Start();
+
+                    ITransport transport = (connection as Connection).ITransport;
+                    TcpFaultyTransport tcpFaulty = transport.Narrow(typeof(TcpFaultyTransport)) as TcpFaultyTransport;
+                    Assert.IsNotNull(tcpFaulty);
+                    tcpFaulty.OnewayCommandPreProcessor += this.FailOnCommitTransportHook;
+
+                    IMessageConsumer consumer = session.CreateConsumer(session.GetQueue(destinationName));
+                    IMessage message = consumer.Receive(TimeSpan.FromSeconds(30));
+                    Assert.IsNotNull(message, "Message was not delivered");
+                    Tracer.Debug("Commiting transaction");
+
+                    try
+                    {
+                        Tracer.Info("Now attempting to commit the transaction");
+                        session.Commit();
+                    }
+                    catch (Exception ex)
+                    {
+                        Tracer.InfoFormat("Commit failed as expected. {0}", ex.Message);
+                    }
+
+                    message = consumer.Receive(TimeSpan.FromSeconds(30));
+                    Assert.IsNotNull(message, "message was not redilivered");
+                }
+            }
+        }
+
         public void TransportInterrupted()
         {
             this.interrupted = true;
@@ -252,15 +298,25 @@ namespace Apache.NMS.ActiveMQ.Test
 
         private void PutMsgIntoQueue(ISession session, IDestination destination)
         {
-            PutMsgIntoQueue(session, destination, true);
+            PutMsgIntoQueue(session, destination, true, MSG_COUNT);
+        }
+
+        private void PutOneMsgIntoQueue(ISession session, IDestination destination)
+        {
+            PutMsgIntoQueue(session, destination, true, 1);
         }
 
         private void PutMsgIntoQueue(ISession session, IDestination destination, bool commit)
         {
+            PutMsgIntoQueue(session, destination, commit, MSG_COUNT);
+        }
+
+        private void PutMsgIntoQueue(ISession session, IDestination destination, bool commit, int count)
+        {
             using(IMessageProducer producer = session.CreateProducer(destination))
             {
                 ITextMessage message = session.CreateTextMessage();
-                for(int i = 0; i < MSG_COUNT; ++i)
+                for(int i = 0; i < count; ++i)
                 {
                     message.Text = "Test message " + (i + 1);
                     producer.Send(message);
@@ -284,6 +340,14 @@ namespace Apache.NMS.ActiveMQ.Test
             }
         }
 
+        private void DeleteQueue(IConnection connection, IDestination queue)
+        {
+            using (ISession session = connection.CreateSession())
+            {
+                session.DeleteDestination(queue);
+            }
+        }
+
         private void BreakConnection()
         {
             TcpTransport transport = this.connection.ITransport.Narrow(typeof(TcpTransport)) as TcpTransport;
@@ -303,13 +367,13 @@ namespace Apache.NMS.ActiveMQ.Test
                 TransactionInfo txInfo = command as TransactionInfo;
                 if (txInfo.Type == (byte)TransactionType.CommitOnePhase)
                 {
-                    Tracer.Debug("Closing the TcpTransport to simulate an connection drop.");
+                    Tracer.Debug("Exception from the Commit to simulate an connection drop.");
                     commitFailed = true;
-                    (transport as TcpTransport).Close();
+                    TcpTransport tcpTransport = transport as TcpTransport;
+                    tcpTransport.Close();
                 }
             }
         }
-
     }
 }
 


[09/50] [abbrv] activemq-nms-openwire git commit: Add missing file to project

Posted by ta...@apache.org.
Add missing file to project


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/f2606ebf
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/f2606ebf
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/f2606ebf

Branch: refs/heads/1.6.x
Commit: f2606ebf325efe60b6a47e1474292028351a225b
Parents: c0258fa
Author: Timothy A. Bish <ta...@apache.org>
Authored: Tue Dec 16 21:25:00 2014 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Tue Dec 16 21:25:00 2014 +0000

----------------------------------------------------------------------
 vs2008-activemq-test.csproj | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/f2606ebf/vs2008-activemq-test.csproj
----------------------------------------------------------------------
diff --git a/vs2008-activemq-test.csproj b/vs2008-activemq-test.csproj
index 4c1cf1e..00753b4 100644
--- a/vs2008-activemq-test.csproj
+++ b/vs2008-activemq-test.csproj
@@ -140,6 +140,7 @@
     <Compile Include="src\test\csharp\Util\SimplePriorityMessageDispatchChannelTest.cs" />
     <Compile Include="src\test\csharp\VirtualTopicTest.cs" />
     <Compile Include="src\test\csharp\ZeroPrefetchConsumerTest.cs" />
+    <Compile Include="src\test\csharp\OpenWire\BaseDataStreamMarshallerTest.cs" />
   </ItemGroup>
   <ItemGroup>
     <Content Include="nmsprovider-test.config">


[18/50] [abbrv] activemq-nms-openwire git commit: Merged revision(s) 1689517 from activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk: Apply patch from Jose Alvarado. Thanks, Jose! Fixes [AMQNET-503]. (See https://issues.apache.org/jira/browse/AMQNET-503)

Posted by ta...@apache.org.
Merged revision(s) 1689517 from activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk:
Apply patch from Jose Alvarado. Thanks, Jose!
Fixes [AMQNET-503]. (See https://issues.apache.org/jira/browse/AMQNET-503)


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/d13fe5c9
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/d13fe5c9
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/d13fe5c9

Branch: refs/heads/1.7.x
Commit: d13fe5c9717e96d371897f0db8e28bc2b758a1f6
Parents: 03dbbaf
Author: Jim Gomes <jg...@apache.org>
Authored: Tue Jul 7 00:02:01 2015 +0000
Committer: Jim Gomes <jg...@apache.org>
Committed: Tue Jul 7 00:02:01 2015 +0000

----------------------------------------------------------------------
 nant.build                                    |  2 +-
 src/main/csharp/NetTxConnection.cs            | 15 ++++++++++++
 src/main/csharp/NetTxMessageConsumer.cs       | 27 +++++++++++++++++++---
 src/main/csharp/NetTxSession.cs               | 10 ++++++++
 src/test/csharp/DtcTransactionsTestSupport.cs | 11 +++++----
 5 files changed, 56 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/d13fe5c9/nant.build
----------------------------------------------------------------------
diff --git a/nant.build b/nant.build
index f9247cb..073ec67 100644
--- a/nant.build
+++ b/nant.build
@@ -51,7 +51,7 @@
         <!-- Property grouping for 'vendor.apache.org' -->
         <property name="vendor.apache.org.name" value="Apache.NMS" />
         <property name="vendor.apache.org.group" value="org.apache.activemq" />
-        <property name="vendor.apache.org.version" value="1.7.0" />
+        <property name="vendor.apache.org.version" value="1.7.1" />
         <if test="${current.build.framework == 'mono-2.0' or current.build.framework == 'mono-4.0'}">
             <property name="vendor.apache.org.filenames" value="Apache.NMS.dll,Apache.NMS.dll.mdb,Apache.NMS.Test.dll,Apache.NMS.Test.dll.mdb" />
         </if>

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/d13fe5c9/src/main/csharp/NetTxConnection.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/NetTxConnection.cs b/src/main/csharp/NetTxConnection.cs
index bc174b7..8f1976c 100644
--- a/src/main/csharp/NetTxConnection.cs
+++ b/src/main/csharp/NetTxConnection.cs
@@ -51,6 +51,21 @@ namespace Apache.NMS.ActiveMQ
             return session;
         }
 
+        public INetTxSession CreateNetTxSession(Transaction tx, bool enlistNativeMsDtcResource)
+        {
+            NetTxSession session = (NetTxSession)CreateSession(AcknowledgementMode.Transactional);
+            session.Enlist(tx);
+            session.EnlistsMsDtcNativeResource = enlistNativeMsDtcResource;
+            return session;
+        }
+
+        public INetTxSession CreateNetTxSession(bool enlistNativeMsDtcResource)
+        {
+            NetTxSession session = (NetTxSession)CreateSession(AcknowledgementMode.Transactional);
+            session.EnlistsMsDtcNativeResource = enlistNativeMsDtcResource;
+            return session;
+        }
+
         protected override Session CreateActiveMQSession(AcknowledgementMode ackMode)
         {
             CheckConnected();

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/d13fe5c9/src/main/csharp/NetTxMessageConsumer.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/NetTxMessageConsumer.cs b/src/main/csharp/NetTxMessageConsumer.cs
index 6a9a65c..f4ef109 100644
--- a/src/main/csharp/NetTxMessageConsumer.cs
+++ b/src/main/csharp/NetTxMessageConsumer.cs
@@ -18,6 +18,7 @@
 using System;
 using System.Collections.Generic;
 using System.Text;
+using System.Transactions;
 using Apache.NMS.ActiveMQ.Commands;
 
 namespace Apache.NMS.ActiveMQ
@@ -75,9 +76,29 @@ namespace Apache.NMS.ActiveMQ
                         // distributed TX manager we need to wait whenever the TX is being
                         // controlled by the DTC as it completes all operations async and
                         // we cannot start consumption again until all its tasks have completed.)
-                        waitForDtcWaitHandle = this.transactionContext.InNetTransaction &&
-                                               this.transactionContext.NetTxState ==
-                                               NetTxTransactionContext.TxState.Pending;
+                        var currentTransactionId = transactionContext.TransactionId as XATransactionId;
+                        string currentLocalTxId = currentTransactionId != null
+                            ? UTF8Encoding.UTF8.GetString(currentTransactionId.GlobalTransactionId)
+                            : "NONE";
+
+                        if (Transaction.Current != null)
+                        {
+                            waitForDtcWaitHandle = this.transactionContext.InNetTransaction &&
+                                               this.transactionContext.NetTxState == NetTxTransactionContext.TxState.Pending ||
+                                               currentLocalTxId != Transaction.Current.TransactionInformation.LocalIdentifier;
+                        }
+                        else
+                        {
+                            waitForDtcWaitHandle = this.transactionContext.InNetTransaction &&
+                                               this.transactionContext.NetTxState == NetTxTransactionContext.TxState.Pending;
+                        }
+                        
+                    }
+
+                    //if session EnlistMsDtcNativeResource the transaction does not need to wait
+                    if (this.session.EnlistsMsDtcNativeResource)
+                    {
+                        waitForDtcWaitHandle = false;
                     }
 
                     if (waitForDtcWaitHandle)

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/d13fe5c9/src/main/csharp/NetTxSession.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/NetTxSession.cs b/src/main/csharp/NetTxSession.cs
index 8da035b..f7e754b 100644
--- a/src/main/csharp/NetTxSession.cs
+++ b/src/main/csharp/NetTxSession.cs
@@ -32,6 +32,7 @@ namespace Apache.NMS.ActiveMQ
         {
             this.transactionContext = TransactionContext as NetTxTransactionContext;
             this.transactionContext.InitializeDtcTxContext();
+            this.enlistMsDtcNativeResources = false;
         }
 
         /// <summary>
@@ -51,6 +52,14 @@ namespace Apache.NMS.ActiveMQ
             this.EnrollInSpecifiedTransaction(tx);
         }
 
+        private bool enlistMsDtcNativeResources;
+
+        public bool EnlistsMsDtcNativeResource
+        {
+            get { return enlistMsDtcNativeResources; }
+            set { enlistMsDtcNativeResources = value; }
+        }
+
         /// <summary>
         /// Reports Transacted whenever there is an Ambient Transaction or the internal
         /// TransactionContext is still involed in a .NET Transaction beyond the lifetime
@@ -173,6 +182,7 @@ namespace Apache.NMS.ActiveMQ
             this.currentTransactionId = tx.TransactionInformation.LocalIdentifier; 
             transactionContext.Begin(tx);
         }
+        
     }
 }
 

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/d13fe5c9/src/test/csharp/DtcTransactionsTestSupport.cs
----------------------------------------------------------------------
diff --git a/src/test/csharp/DtcTransactionsTestSupport.cs b/src/test/csharp/DtcTransactionsTestSupport.cs
index 2ce121f..030a9d3 100644
--- a/src/test/csharp/DtcTransactionsTestSupport.cs
+++ b/src/test/csharp/DtcTransactionsTestSupport.cs
@@ -53,7 +53,8 @@ namespace Apache.NMS.ActiveMQ.Test
         private ITrace oldTracer;
 
         protected const string sqlConnectionString =
-            "Data Source=localhost;Initial Catalog=TestDB;User ID=user;Password=password";
+            // "Data Source=localhost;Initial Catalog=TestDB;User ID=user;Password=password";
+            "Data Source=.\\SQLEXPRESS;Initial Catalog=TestDB;Integrated Security = true";
         protected const string testTable = "TestTable";
         protected const string testColumn = "TestID";
         protected const string testQueueName = "TestQueue";
@@ -484,7 +485,7 @@ namespace Apache.NMS.ActiveMQ.Test
         {
             IList entries = ExtractDataSet();
 
-            using (INetTxSession session = connection.CreateNetTxSession())
+            using (INetTxSession session = connection.CreateNetTxSession(true))
             {
                 IQueue queue = session.GetQueue(testQueueName);
 
@@ -531,7 +532,7 @@ namespace Apache.NMS.ActiveMQ.Test
         {
             IList entries = ExtractDataSet();
 
-            using (INetTxSession session = connection.CreateNetTxSession())
+            using (INetTxSession session = connection.CreateNetTxSession(true))
             {
                 IQueue queue = session.GetQueue(testQueueName);
 
@@ -578,7 +579,7 @@ namespace Apache.NMS.ActiveMQ.Test
 
         protected static void ReadFromQueueAndInsertIntoDbWithCommit(INetTxConnection connection)
         {
-            using (INetTxSession session = connection.CreateNetTxSession())
+            using (INetTxSession session = connection.CreateNetTxSession(true))
             {
                 IQueue queue = session.GetQueue(testQueueName);
 
@@ -619,7 +620,7 @@ namespace Apache.NMS.ActiveMQ.Test
 
         protected static void ReadFromQueueAndInsertIntoDbWithScopeAborted(INetTxConnection connection)
         {
-            using (INetTxSession session = connection.CreateNetTxSession())
+            using (INetTxSession session = connection.CreateNetTxSession(true))
             {
                 IQueue queue = session.GetQueue(testQueueName);
 


[46/50] [abbrv] activemq-nms-openwire git commit: AdvisoryConsumer not sending back acks correctly leading to stall in receiving new advisory messages. Fixes [AMQNET-AMQNET-522]. (See https://issues.apache.org/jira/browse/AMQNET-AMQNET-522)

Posted by ta...@apache.org.
AdvisoryConsumer not sending back acks correctly leading to stall in receiving new advisory messages. 
Fixes [AMQNET-AMQNET-522]. (See https://issues.apache.org/jira/browse/AMQNET-AMQNET-522)



Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/d1ee5ba0
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/d1ee5ba0
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/d1ee5ba0

Branch: refs/heads/1.7.x
Commit: d1ee5ba0b552584090559034018f197d4fa4c27a
Parents: 399c1db
Author: Timothy A. Bish <ta...@apache.org>
Authored: Fri Apr 1 19:03:10 2016 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Fri Apr 1 19:03:10 2016 +0000

----------------------------------------------------------------------
 src/main/csharp/AdvisoryConsumer.cs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/d1ee5ba0/src/main/csharp/AdvisoryConsumer.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/AdvisoryConsumer.cs b/src/main/csharp/AdvisoryConsumer.cs
index 8f8f4f5..90c9046 100644
--- a/src/main/csharp/AdvisoryConsumer.cs
+++ b/src/main/csharp/AdvisoryConsumer.cs
@@ -79,7 +79,7 @@ namespace Apache.NMS.ActiveMQ
                     ack.AckType = (byte)AckType.ConsumedAck;
 					ack.ConsumerId = messageDispatch.ConsumerId;
 					ack.Destination = messageDispatch.Destination;
-                    ack.FirstMessageId = messageDispatch.Message.MessageId;
+                    ack.LastMessageId = messageDispatch.Message.MessageId;
                     ack.MessageCount = deliveredCounter;
 
                     this.connection.Oneway(ack);


[49/50] [abbrv] activemq-nms-openwire git commit: Create MessageProducer with a sync call in order to catch creation errors. Fixes [AMQNET-AMQNET-523]. (See https://issues.apache.org/jira/browse/AMQNET-AMQNET-523)

Posted by ta...@apache.org.
Create MessageProducer with a sync call in order to catch creation errors.
Fixes [AMQNET-AMQNET-523]. (See https://issues.apache.org/jira/browse/AMQNET-AMQNET-523)



Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/a3bfe8be
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/a3bfe8be
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/a3bfe8be

Branch: refs/heads/master
Commit: a3bfe8bed822f84d0d9deef18fd585b238c3f633
Parents: 9adb656
Author: Timothy A. Bish <ta...@apache.org>
Authored: Fri Apr 1 20:14:57 2016 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Fri Apr 1 20:14:57 2016 +0000

----------------------------------------------------------------------
 src/main/csharp/Session.cs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/a3bfe8be/src/main/csharp/Session.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Session.cs b/src/main/csharp/Session.cs
index ef91700..e09f6b1 100755
--- a/src/main/csharp/Session.cs
+++ b/src/main/csharp/Session.cs
@@ -460,7 +460,7 @@ namespace Apache.NMS.ActiveMQ
                 producer.ProducerTransformer = this.ProducerTransformer;
 
                 this.AddProducer(producer);
-                this.Connection.Oneway(producer.ProducerInfo);
+                this.Connection.SyncRequest(producer.ProducerInfo);
             }
             catch(Exception)
             {


[12/50] [abbrv] activemq-nms-openwire git commit: Move trunk to 1.8-SNAPSHOT

Posted by ta...@apache.org.
Move trunk to 1.8-SNAPSHOT


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/f4332dd5
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/f4332dd5
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/f4332dd5

Branch: refs/heads/master
Commit: f4332dd5a05a8e0c2ab0fb10075ec841a9a802c4
Parents: b9d7a80
Author: Timothy A. Bish <ta...@apache.org>
Authored: Fri Jan 9 15:30:06 2015 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Fri Jan 9 15:30:06 2015 +0000

----------------------------------------------------------------------
 nant.build  | 4 ++--
 package.ps1 | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/f4332dd5/nant.build
----------------------------------------------------------------------
diff --git a/nant.build b/nant.build
index d50b870..16dd773 100644
--- a/nant.build
+++ b/nant.build
@@ -22,7 +22,7 @@
     <property name="basedir" value="${project::get-base-directory()}" />
     <property name="project.name" value="Apache.NMS.ActiveMQ" />
     <property name="project.group" value="org.apache.activemq" />
-    <property name="project.version" value="1.7.0" unless="${property::exists('project.version')}" />
+    <property name="project.version" value="1.8.0" unless="${property::exists('project.version')}" />
     <property name="project.release.type" value="SNAPSHOT" unless="${property::exists('project.release.type')}" />
     <property name="project.short_description" value="Apache NMS for ActiveMQ Class Library" />
     <property name="project.description" value="Apache NMS for ActiveMQ Class Library (.Net Messaging Library Implementation): An implementation of the NMS API for ActiveMQ" />
@@ -51,7 +51,7 @@
         <!-- Property grouping for 'vendor.apache.org' -->
         <property name="vendor.apache.org.name" value="Apache.NMS" />
         <property name="vendor.apache.org.group" value="org.apache.activemq" />
-        <property name="vendor.apache.org.version" value="1.7.0" />
+        <property name="vendor.apache.org.version" value="1.8.0" />
         <if test="${current.build.framework == 'mono-2.0' or current.build.framework == 'mono-4.0'}">
             <property name="vendor.apache.org.filenames" value="Apache.NMS.dll,Apache.NMS.dll.mdb,Apache.NMS.Test.dll,Apache.NMS.Test.dll.mdb" />
         </if>

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/f4332dd5/package.ps1
----------------------------------------------------------------------
diff --git a/package.ps1 b/package.ps1
index 4304132..09be8bf 100644
--- a/package.ps1
+++ b/package.ps1
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 $pkgname = "Apache.NMS.ActiveMQ"
-$pkgver = "1.7-SNAPSHOT"
+$pkgver = "1.8-SNAPSHOT"
 $configurations = "release", "debug"
 $frameworks = "mono-2.0", "net-2.0", "net-3.5", "net-4.0"
 


[20/50] [abbrv] activemq-nms-openwire git commit: Merged revision(s) 1689923 from activemq/activemq-dotnet/Apache.NMS.ActiveMQ/branches/1.7.x: Applied patch from Enrique Garcia to copy the 509 certificates to internal list. Thanks, Enrique! Fixes [AMQNET

Posted by ta...@apache.org.
Merged revision(s) 1689923 from activemq/activemq-dotnet/Apache.NMS.ActiveMQ/branches/1.7.x:
Applied patch from Enrique Garcia to copy the 509 certificates to internal list. Thanks, Enrique!
Fixes [AMQNET-500]. (See https://issues.apache.org/jira/browse/AMQNET-500)


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/ecc841b6
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/ecc841b6
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/ecc841b6

Branch: refs/heads/master
Commit: ecc841b68499e1310f8c9fb3f9d57bf642611c56
Parents: 19306fb
Author: Jim Gomes <jg...@apache.org>
Authored: Wed Jul 8 17:40:43 2015 +0000
Committer: Jim Gomes <jg...@apache.org>
Committed: Wed Jul 8 17:40:43 2015 +0000

----------------------------------------------------------------------
 src/main/csharp/Transport/Tcp/SslTransport.cs | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/ecc841b6/src/main/csharp/Transport/Tcp/SslTransport.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Transport/Tcp/SslTransport.cs b/src/main/csharp/Transport/Tcp/SslTransport.cs
index caa3ec7..17f2e06 100644
--- a/src/main/csharp/Transport/Tcp/SslTransport.cs
+++ b/src/main/csharp/Transport/Tcp/SslTransport.cs
@@ -314,7 +314,9 @@ namespace Apache.NMS.ActiveMQ.Transport.Tcp
 
                 X509Store store = new X509Store(name, location);
                 store.Open(OpenFlags.ReadOnly);
-                collection = store.Certificates;
+                X509Certificate2[] certificates = new X509Certificate2[store.Certificates.Count];
+                store.Certificates.CopyTo(certificates, 0);
+                collection.AddRange(certificates);
                 store.Close();
             }
 


[29/50] [abbrv] activemq-nms-openwire git commit: Fix warning in test case Fixes [AMQNET-505]. (See https://issues.apache.org/jira/browse/AMQNET-505)

Posted by ta...@apache.org.
Fix warning in test case
Fixes [AMQNET-505]. (See https://issues.apache.org/jira/browse/AMQNET-505)



Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/edb4f051
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/edb4f051
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/edb4f051

Branch: refs/heads/master
Commit: edb4f0519976e5822e6e3f728760de4269e9c574
Parents: ed48f03
Author: Timothy A. Bish <ta...@apache.org>
Authored: Wed Aug 12 22:34:49 2015 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Wed Aug 12 22:34:49 2015 +0000

----------------------------------------------------------------------
 src/test/csharp/QueueBrowserTests.cs | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/edb4f051/src/test/csharp/QueueBrowserTests.cs
----------------------------------------------------------------------
diff --git a/src/test/csharp/QueueBrowserTests.cs b/src/test/csharp/QueueBrowserTests.cs
index 2d9919b..5e9bf6c 100644
--- a/src/test/csharp/QueueBrowserTests.cs
+++ b/src/test/csharp/QueueBrowserTests.cs
@@ -250,7 +250,6 @@ namespace Apache.NMS.ActiveMQ.Test
                 IEnumerator enumeration = browser.GetEnumerator();
                 while (enumeration.MoveNext())
                 {
-                    ITextMessage message = enumeration.Current as ITextMessage;
                     browsed++;
                 }
             }


[45/50] [abbrv] activemq-nms-openwire git commit: AdvisoryConsumer not sending back acks correctly leading to stall in receiving new advisory messages. Fixes [AMQNET-AMQNET-522]. (See https://issues.apache.org/jira/browse/AMQNET-AMQNET-522)

Posted by ta...@apache.org.
AdvisoryConsumer not sending back acks correctly leading to stall in receiving new advisory messages. 
Fixes [AMQNET-AMQNET-522]. (See https://issues.apache.org/jira/browse/AMQNET-AMQNET-522)



Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/9adb6565
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/9adb6565
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/9adb6565

Branch: refs/heads/master
Commit: 9adb65657365375cba3bbe9b95643e9df62e6037
Parents: 37c86bd
Author: Timothy A. Bish <ta...@apache.org>
Authored: Fri Apr 1 19:01:57 2016 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Fri Apr 1 19:01:57 2016 +0000

----------------------------------------------------------------------
 src/main/csharp/AdvisoryConsumer.cs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/9adb6565/src/main/csharp/AdvisoryConsumer.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/AdvisoryConsumer.cs b/src/main/csharp/AdvisoryConsumer.cs
index 8f8f4f5..90c9046 100644
--- a/src/main/csharp/AdvisoryConsumer.cs
+++ b/src/main/csharp/AdvisoryConsumer.cs
@@ -79,7 +79,7 @@ namespace Apache.NMS.ActiveMQ
                     ack.AckType = (byte)AckType.ConsumedAck;
 					ack.ConsumerId = messageDispatch.ConsumerId;
 					ack.Destination = messageDispatch.Destination;
-                    ack.FirstMessageId = messageDispatch.Message.MessageId;
+                    ack.LastMessageId = messageDispatch.Message.MessageId;
                     ack.MessageCount = deliveredCounter;
 
                     this.connection.Oneway(ack);


[50/50] [abbrv] activemq-nms-openwire git commit: Create MessageProducer with a sync call in order to catch creation errors. Fixes [AMQNET-AMQNET-523]. (See https://issues.apache.org/jira/browse/AMQNET-AMQNET-523)

Posted by ta...@apache.org.
Create MessageProducer with a sync call in order to catch creation errors.
Fixes [AMQNET-AMQNET-523]. (See https://issues.apache.org/jira/browse/AMQNET-AMQNET-523)



Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/dab33daf
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/dab33daf
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/dab33daf

Branch: refs/heads/1.7.x
Commit: dab33daf2be080b0a044f2fd51fc62b69b9505c0
Parents: 976c962
Author: Timothy A. Bish <ta...@apache.org>
Authored: Fri Apr 1 20:16:25 2016 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Fri Apr 1 20:16:25 2016 +0000

----------------------------------------------------------------------
 src/main/csharp/Session.cs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/dab33daf/src/main/csharp/Session.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Session.cs b/src/main/csharp/Session.cs
index ef91700..e09f6b1 100755
--- a/src/main/csharp/Session.cs
+++ b/src/main/csharp/Session.cs
@@ -460,7 +460,7 @@ namespace Apache.NMS.ActiveMQ
                 producer.ProducerTransformer = this.ProducerTransformer;
 
                 this.AddProducer(producer);
-                this.Connection.Oneway(producer.ProducerInfo);
+                this.Connection.SyncRequest(producer.ProducerInfo);
             }
             catch(Exception)
             {


[27/50] [abbrv] activemq-nms-openwire git commit: Ensure that a QueueBrowser does not filter expired messages, instead deliver the complete Queue snapshot. Fixes [AMQNET-AMQNET-505]. (See https://issues.apache.org/jira/browse/AMQNET-AMQNET-505)

Posted by ta...@apache.org.
Ensure that a QueueBrowser does not filter expired messages, instead deliver the complete Queue snapshot.
Fixes [AMQNET-AMQNET-505]. (See https://issues.apache.org/jira/browse/AMQNET-AMQNET-505)



Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/a8b0e617
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/a8b0e617
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/a8b0e617

Branch: refs/heads/master
Commit: a8b0e61792a2b047df253062e2c2e91ccd74a380
Parents: cfa43da
Author: Timothy A. Bish <ta...@apache.org>
Authored: Wed Aug 12 21:05:05 2015 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Wed Aug 12 21:05:05 2015 +0000

----------------------------------------------------------------------
 src/main/csharp/MessageConsumer.cs   | 12 +++++-
 src/test/csharp/QueueBrowserTests.cs | 72 ++++++++++++++++++++++++++++++-
 2 files changed, 82 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/a8b0e617/src/main/csharp/MessageConsumer.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/MessageConsumer.cs b/src/main/csharp/MessageConsumer.cs
index a500b4f..62e64d0 100755
--- a/src/main/csharp/MessageConsumer.cs
+++ b/src/main/csharp/MessageConsumer.cs
@@ -1035,7 +1035,7 @@ namespace Apache.NMS.ActiveMQ
                 {
                     return null;
                 }
-                else if(!IgnoreExpiration && dispatch.Message.IsExpired())
+                else if(ConsumeExpiredMessage(dispatch))
                 {
                     Tracer.DebugFormat("Consumer[{0}] received expired message: {1}",
                                        ConsumerId, dispatch.Message.MessageId);
@@ -1073,6 +1073,16 @@ namespace Apache.NMS.ActiveMQ
             }
         }
 
+        private bool ConsumeExpiredMessage(MessageDispatch dispatch) 
+        {
+            if (dispatch.Message.IsExpired()) 
+            {
+                return !info.Browser && !IgnoreExpiration;
+            }
+
+            return false;
+        }
+
         public virtual void BeforeMessageIsConsumed(MessageDispatch dispatch)
         {
             dispatch.DeliverySequenceId = session.NextDeliveryId;

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/a8b0e617/src/test/csharp/QueueBrowserTests.cs
----------------------------------------------------------------------
diff --git a/src/test/csharp/QueueBrowserTests.cs b/src/test/csharp/QueueBrowserTests.cs
index 3faaa12..2d9919b 100644
--- a/src/test/csharp/QueueBrowserTests.cs
+++ b/src/test/csharp/QueueBrowserTests.cs
@@ -205,6 +205,76 @@ namespace Apache.NMS.ActiveMQ.Test
                 IQueueBrowser browser = session.CreateBrowser(queue);
 				browser.Close();
             }
-        }		
+        }
+
+        [Test]
+        public void TestBrowsingExpiration()
+        {
+            const int MESSAGES_TO_SEND = 50;
+            const string QUEUE_NAME = "TEST.TestBrowsingExpiration";
+
+            SendTestMessages(MESSAGES_TO_SEND, QUEUE_NAME);
+
+            // Browse the queue.
+            using (Connection connection = CreateConnection() as Connection)
+            using (ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+            {
+                connection.Start();
+                int browsed = Browse(QUEUE_NAME, connection);
+
+                // The number of messages browsed should be equal to the number of
+                // messages sent.
+                Assert.AreEqual(MESSAGES_TO_SEND, browsed);
+
+                // Broker expired message period is 30 seconds by default
+                for (int i = 0; i < 12; ++i)
+                {
+                    Thread.Sleep(5000);
+                    browsed = Browse(QUEUE_NAME, connection);
+                }
+
+                session.DeleteDestination(session.GetQueue(QUEUE_NAME));
+
+                Assert.AreEqual(0, browsed);
+            }
+        }
+
+        private int Browse(String queueName, Connection connection)
+        {
+            int browsed = 0;
+
+            using (ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+            using (IQueue queue = session.GetQueue(queueName))
+            using (IQueueBrowser browser = session.CreateBrowser(queue))
+            {
+                IEnumerator enumeration = browser.GetEnumerator();
+                while (enumeration.MoveNext())
+                {
+                    ITextMessage message = enumeration.Current as ITextMessage;
+                    browsed++;
+                }
+            }
+
+            return browsed;
+        }
+
+        protected void SendTestMessages(int count, String queueName)
+        {
+            // Send the messages to the Queue.
+            using (Connection connection = CreateConnection() as Connection)
+            using (ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+            using (IQueue queue = session.GetQueue(queueName))
+            using (IMessageProducer producer = session.CreateProducer(queue))
+            {
+                for (int i = 1; i <= count; i++) 
+                {
+                    String msgStr = "Message: " + i;
+                    producer.Send(session.CreateTextMessage(msgStr), 
+                                  MsgDeliveryMode.NonPersistent, 
+                                  MsgPriority.Normal, 
+                                  TimeSpan.FromMilliseconds(1500));
+                }
+            }
+        }
 	}
 }


[36/50] [abbrv] activemq-nms-openwire git commit: NO-JIRA Fix failing test but ensuring that priority processing is enabled.

Posted by ta...@apache.org.
NO-JIRA Fix failing test but ensuring that priority processing is enabled.


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/80368b05
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/80368b05
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/80368b05

Branch: refs/heads/1.7.x
Commit: 80368b054fb5f883ab97aa8e94085cf09e8cb68b
Parents: 418832a
Author: Timothy A. Bish <ta...@apache.org>
Authored: Tue Sep 29 22:31:21 2015 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Tue Sep 29 22:31:21 2015 +0000

----------------------------------------------------------------------
 src/test/csharp/QueueConsumerPriorityTest.cs | 4 ++++
 1 file changed, 4 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/80368b05/src/test/csharp/QueueConsumerPriorityTest.cs
----------------------------------------------------------------------
diff --git a/src/test/csharp/QueueConsumerPriorityTest.cs b/src/test/csharp/QueueConsumerPriorityTest.cs
index 266fd91..2d6b947 100644
--- a/src/test/csharp/QueueConsumerPriorityTest.cs
+++ b/src/test/csharp/QueueConsumerPriorityTest.cs
@@ -101,6 +101,10 @@ namespace Apache.NMS.ActiveMQ.Test
         {
             IConnection conn = createConnection(true);
 
+            Connection connection = conn as Connection;
+            Assert.IsNotNull(connection);
+            connection.MessagePrioritySupported = true;
+
             ISession receiverSession = conn.CreateSession();
             ISession senderSession = conn.CreateSession();
 


[17/50] [abbrv] activemq-nms-openwire git commit: Apply patch from Jose Alvarado. Thanks, Jose! Fixes [AMQNET-503]. (See https://issues.apache.org/jira/browse/AMQNET-503)

Posted by ta...@apache.org.
Apply patch from Jose Alvarado. Thanks, Jose!
Fixes [AMQNET-503]. (See https://issues.apache.org/jira/browse/AMQNET-503)



Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/19306fb5
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/19306fb5
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/19306fb5

Branch: refs/heads/master
Commit: 19306fb56a2fd041402df27cf154989f4a298a4e
Parents: b20dde9
Author: Jim Gomes <jg...@apache.org>
Authored: Mon Jul 6 22:41:41 2015 +0000
Committer: Jim Gomes <jg...@apache.org>
Committed: Mon Jul 6 22:41:41 2015 +0000

----------------------------------------------------------------------
 src/main/csharp/NetTxConnection.cs            | 15 ++++++++++++
 src/main/csharp/NetTxMessageConsumer.cs       | 27 +++++++++++++++++++---
 src/main/csharp/NetTxSession.cs               | 10 ++++++++
 src/test/csharp/DtcTransactionsTestSupport.cs | 11 +++++----
 4 files changed, 55 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/19306fb5/src/main/csharp/NetTxConnection.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/NetTxConnection.cs b/src/main/csharp/NetTxConnection.cs
index bc174b7..8f1976c 100644
--- a/src/main/csharp/NetTxConnection.cs
+++ b/src/main/csharp/NetTxConnection.cs
@@ -51,6 +51,21 @@ namespace Apache.NMS.ActiveMQ
             return session;
         }
 
+        public INetTxSession CreateNetTxSession(Transaction tx, bool enlistNativeMsDtcResource)
+        {
+            NetTxSession session = (NetTxSession)CreateSession(AcknowledgementMode.Transactional);
+            session.Enlist(tx);
+            session.EnlistsMsDtcNativeResource = enlistNativeMsDtcResource;
+            return session;
+        }
+
+        public INetTxSession CreateNetTxSession(bool enlistNativeMsDtcResource)
+        {
+            NetTxSession session = (NetTxSession)CreateSession(AcknowledgementMode.Transactional);
+            session.EnlistsMsDtcNativeResource = enlistNativeMsDtcResource;
+            return session;
+        }
+
         protected override Session CreateActiveMQSession(AcknowledgementMode ackMode)
         {
             CheckConnected();

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/19306fb5/src/main/csharp/NetTxMessageConsumer.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/NetTxMessageConsumer.cs b/src/main/csharp/NetTxMessageConsumer.cs
index 6a9a65c..f4ef109 100644
--- a/src/main/csharp/NetTxMessageConsumer.cs
+++ b/src/main/csharp/NetTxMessageConsumer.cs
@@ -18,6 +18,7 @@
 using System;
 using System.Collections.Generic;
 using System.Text;
+using System.Transactions;
 using Apache.NMS.ActiveMQ.Commands;
 
 namespace Apache.NMS.ActiveMQ
@@ -75,9 +76,29 @@ namespace Apache.NMS.ActiveMQ
                         // distributed TX manager we need to wait whenever the TX is being
                         // controlled by the DTC as it completes all operations async and
                         // we cannot start consumption again until all its tasks have completed.)
-                        waitForDtcWaitHandle = this.transactionContext.InNetTransaction &&
-                                               this.transactionContext.NetTxState ==
-                                               NetTxTransactionContext.TxState.Pending;
+                        var currentTransactionId = transactionContext.TransactionId as XATransactionId;
+                        string currentLocalTxId = currentTransactionId != null
+                            ? UTF8Encoding.UTF8.GetString(currentTransactionId.GlobalTransactionId)
+                            : "NONE";
+
+                        if (Transaction.Current != null)
+                        {
+                            waitForDtcWaitHandle = this.transactionContext.InNetTransaction &&
+                                               this.transactionContext.NetTxState == NetTxTransactionContext.TxState.Pending ||
+                                               currentLocalTxId != Transaction.Current.TransactionInformation.LocalIdentifier;
+                        }
+                        else
+                        {
+                            waitForDtcWaitHandle = this.transactionContext.InNetTransaction &&
+                                               this.transactionContext.NetTxState == NetTxTransactionContext.TxState.Pending;
+                        }
+                        
+                    }
+
+                    //if session EnlistMsDtcNativeResource the transaction does not need to wait
+                    if (this.session.EnlistsMsDtcNativeResource)
+                    {
+                        waitForDtcWaitHandle = false;
                     }
 
                     if (waitForDtcWaitHandle)

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/19306fb5/src/main/csharp/NetTxSession.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/NetTxSession.cs b/src/main/csharp/NetTxSession.cs
index 8da035b..f7e754b 100644
--- a/src/main/csharp/NetTxSession.cs
+++ b/src/main/csharp/NetTxSession.cs
@@ -32,6 +32,7 @@ namespace Apache.NMS.ActiveMQ
         {
             this.transactionContext = TransactionContext as NetTxTransactionContext;
             this.transactionContext.InitializeDtcTxContext();
+            this.enlistMsDtcNativeResources = false;
         }
 
         /// <summary>
@@ -51,6 +52,14 @@ namespace Apache.NMS.ActiveMQ
             this.EnrollInSpecifiedTransaction(tx);
         }
 
+        private bool enlistMsDtcNativeResources;
+
+        public bool EnlistsMsDtcNativeResource
+        {
+            get { return enlistMsDtcNativeResources; }
+            set { enlistMsDtcNativeResources = value; }
+        }
+
         /// <summary>
         /// Reports Transacted whenever there is an Ambient Transaction or the internal
         /// TransactionContext is still involed in a .NET Transaction beyond the lifetime
@@ -173,6 +182,7 @@ namespace Apache.NMS.ActiveMQ
             this.currentTransactionId = tx.TransactionInformation.LocalIdentifier; 
             transactionContext.Begin(tx);
         }
+        
     }
 }
 

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/19306fb5/src/test/csharp/DtcTransactionsTestSupport.cs
----------------------------------------------------------------------
diff --git a/src/test/csharp/DtcTransactionsTestSupport.cs b/src/test/csharp/DtcTransactionsTestSupport.cs
index 2ce121f..030a9d3 100644
--- a/src/test/csharp/DtcTransactionsTestSupport.cs
+++ b/src/test/csharp/DtcTransactionsTestSupport.cs
@@ -53,7 +53,8 @@ namespace Apache.NMS.ActiveMQ.Test
         private ITrace oldTracer;
 
         protected const string sqlConnectionString =
-            "Data Source=localhost;Initial Catalog=TestDB;User ID=user;Password=password";
+            // "Data Source=localhost;Initial Catalog=TestDB;User ID=user;Password=password";
+            "Data Source=.\\SQLEXPRESS;Initial Catalog=TestDB;Integrated Security = true";
         protected const string testTable = "TestTable";
         protected const string testColumn = "TestID";
         protected const string testQueueName = "TestQueue";
@@ -484,7 +485,7 @@ namespace Apache.NMS.ActiveMQ.Test
         {
             IList entries = ExtractDataSet();
 
-            using (INetTxSession session = connection.CreateNetTxSession())
+            using (INetTxSession session = connection.CreateNetTxSession(true))
             {
                 IQueue queue = session.GetQueue(testQueueName);
 
@@ -531,7 +532,7 @@ namespace Apache.NMS.ActiveMQ.Test
         {
             IList entries = ExtractDataSet();
 
-            using (INetTxSession session = connection.CreateNetTxSession())
+            using (INetTxSession session = connection.CreateNetTxSession(true))
             {
                 IQueue queue = session.GetQueue(testQueueName);
 
@@ -578,7 +579,7 @@ namespace Apache.NMS.ActiveMQ.Test
 
         protected static void ReadFromQueueAndInsertIntoDbWithCommit(INetTxConnection connection)
         {
-            using (INetTxSession session = connection.CreateNetTxSession())
+            using (INetTxSession session = connection.CreateNetTxSession(true))
             {
                 IQueue queue = session.GetQueue(testQueueName);
 
@@ -619,7 +620,7 @@ namespace Apache.NMS.ActiveMQ.Test
 
         protected static void ReadFromQueueAndInsertIntoDbWithScopeAborted(INetTxConnection connection)
         {
-            using (INetTxSession session = connection.CreateNetTxSession())
+            using (INetTxSession session = connection.CreateNetTxSession(true))
             {
                 IQueue queue = session.GetQueue(testQueueName);
 


[14/50] [abbrv] activemq-nms-openwire git commit: Move branch to v1.6.6 SNAPSHOT

Posted by ta...@apache.org.
Move branch to  v1.6.6 SNAPSHOT


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/1e6374d2
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/1e6374d2
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/1e6374d2

Branch: refs/heads/1.6.x
Commit: 1e6374d21ef2d2cf73796952caf8022b69567af3
Parents: 417e279
Author: Timothy A. Bish <ta...@apache.org>
Authored: Mon Feb 2 15:12:43 2015 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Mon Feb 2 15:12:43 2015 +0000

----------------------------------------------------------------------
 nant.build  | 2 +-
 package.ps1 | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/1e6374d2/nant.build
----------------------------------------------------------------------
diff --git a/nant.build b/nant.build
index 4e794f1..881253c 100644
--- a/nant.build
+++ b/nant.build
@@ -22,7 +22,7 @@
     <property name="basedir" value="${project::get-base-directory()}" />
     <property name="project.name" value="Apache.NMS.ActiveMQ" />
     <property name="project.group" value="org.apache.activemq" />
-    <property name="project.version" value="1.6.5" unless="${property::exists('project.version')}" />
+    <property name="project.version" value="1.6.6" unless="${property::exists('project.version')}" />
     <property name="project.release.type" value="SNAPSHOT" unless="${property::exists('project.release.type')}" />
     <property name="project.short_description" value="Apache NMS for ActiveMQ Class Library" />
     <property name="project.description" value="Apache NMS for ActiveMQ Class Library (.Net Messaging Library Implementation): An implementation of the NMS API for ActiveMQ" />

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/1e6374d2/package.ps1
----------------------------------------------------------------------
diff --git a/package.ps1 b/package.ps1
index ad51e9f..df46425 100644
--- a/package.ps1
+++ b/package.ps1
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 $pkgname = "Apache.NMS.ActiveMQ"
-$pkgver = "1.6.5-SNAPSHOT"
+$pkgver = "1.6.6-SNAPSHOT"
 $configurations = "release", "debug"
 $frameworks = "mono-2.0", "net-2.0", "net-3.5", "net-4.0"
 


[13/50] [abbrv] activemq-nms-openwire git commit: Move head of 1.7.x branch to 1.7.1-SNAPSHOT

Posted by ta...@apache.org.
Move head of 1.7.x branch to 1.7.1-SNAPSHOT


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/03dbbaf2
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/03dbbaf2
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/03dbbaf2

Branch: refs/heads/1.7.x
Commit: 03dbbaf2311fb6fe8d63eeb62143f69669e17f1d
Parents: 1d3049b
Author: Timothy A. Bish <ta...@apache.org>
Authored: Fri Jan 9 15:47:41 2015 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Fri Jan 9 15:47:41 2015 +0000

----------------------------------------------------------------------
 nant.build  | 2 +-
 package.ps1 | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/03dbbaf2/nant.build
----------------------------------------------------------------------
diff --git a/nant.build b/nant.build
index d50b870..f9247cb 100644
--- a/nant.build
+++ b/nant.build
@@ -22,7 +22,7 @@
     <property name="basedir" value="${project::get-base-directory()}" />
     <property name="project.name" value="Apache.NMS.ActiveMQ" />
     <property name="project.group" value="org.apache.activemq" />
-    <property name="project.version" value="1.7.0" unless="${property::exists('project.version')}" />
+    <property name="project.version" value="1.7.1" unless="${property::exists('project.version')}" />
     <property name="project.release.type" value="SNAPSHOT" unless="${property::exists('project.release.type')}" />
     <property name="project.short_description" value="Apache NMS for ActiveMQ Class Library" />
     <property name="project.description" value="Apache NMS for ActiveMQ Class Library (.Net Messaging Library Implementation): An implementation of the NMS API for ActiveMQ" />

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/03dbbaf2/package.ps1
----------------------------------------------------------------------
diff --git a/package.ps1 b/package.ps1
index 4304132..97c2087 100644
--- a/package.ps1
+++ b/package.ps1
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 $pkgname = "Apache.NMS.ActiveMQ"
-$pkgver = "1.7-SNAPSHOT"
+$pkgver = "1.7.1-SNAPSHOT"
 $configurations = "release", "debug"
 $frameworks = "mono-2.0", "net-2.0", "net-3.5", "net-4.0"
 


[32/50] [abbrv] activemq-nms-openwire git commit: Fix test so that it removes the test Queue first and add a bit of logging. Fixes [AMQNET-505]. (See https://issues.apache.org/jira/browse/AMQNET-505)

Posted by ta...@apache.org.
Fix test so that it removes the test Queue first and add a bit of logging.  
Fixes [AMQNET-505]. (See https://issues.apache.org/jira/browse/AMQNET-505)



Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/262ebde7
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/262ebde7
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/262ebde7

Branch: refs/heads/master
Commit: 262ebde72bf5a2a5ac67f29dbad2b364345a0bc3
Parents: 009fa01
Author: Timothy A. Bish <ta...@apache.org>
Authored: Thu Aug 13 16:39:19 2015 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Thu Aug 13 16:39:19 2015 +0000

----------------------------------------------------------------------
 src/test/csharp/QueueBrowserTests.cs | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/262ebde7/src/test/csharp/QueueBrowserTests.cs
----------------------------------------------------------------------
diff --git a/src/test/csharp/QueueBrowserTests.cs b/src/test/csharp/QueueBrowserTests.cs
index 5e9bf6c..c737090 100644
--- a/src/test/csharp/QueueBrowserTests.cs
+++ b/src/test/csharp/QueueBrowserTests.cs
@@ -213,12 +213,15 @@ namespace Apache.NMS.ActiveMQ.Test
             const int MESSAGES_TO_SEND = 50;
             const string QUEUE_NAME = "TEST.TestBrowsingExpiration";
 
-            SendTestMessages(MESSAGES_TO_SEND, QUEUE_NAME);
-
             // Browse the queue.
             using (Connection connection = CreateConnection() as Connection)
             using (ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
+            using (IQueue queue = session.GetQueue(QUEUE_NAME))
             {
+                session.DeleteDestination(queue);
+
+                SendTestMessages(MESSAGES_TO_SEND, QUEUE_NAME);
+
                 connection.Start();
                 int browsed = Browse(QUEUE_NAME, connection);
 
@@ -250,6 +253,8 @@ namespace Apache.NMS.ActiveMQ.Test
                 IEnumerator enumeration = browser.GetEnumerator();
                 while (enumeration.MoveNext())
                 {
+                    ITextMessage message = enumeration.Current as ITextMessage;
+                    Tracer.DebugFormat("Browsed message: {0}", message.NMSMessageId);
                     browsed++;
                 }
             }


[28/50] [abbrv] activemq-nms-openwire git commit: Ensure the unacknowledged message are rolled back from the duplicate tracker on consumer close. Fixes [AMQNET-AMQNET-506]. (See https://issues.apache.org/jira/browse/AMQNET-AMQNET-506)

Posted by ta...@apache.org.
Ensure the unacknowledged message are rolled back from the duplicate tracker on consumer close.
Fixes [AMQNET-AMQNET-506]. (See https://issues.apache.org/jira/browse/AMQNET-AMQNET-506)



Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/ed48f032
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/ed48f032
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/ed48f032

Branch: refs/heads/master
Commit: ed48f032697e1df3217ee85ba3c8822de9880068
Parents: a8b0e61
Author: Timothy A. Bish <ta...@apache.org>
Authored: Wed Aug 12 22:00:20 2015 +0000
Committer: Timothy A. Bish <ta...@apache.org>
Committed: Wed Aug 12 22:00:20 2015 +0000

----------------------------------------------------------------------
 src/main/csharp/MessageConsumer.cs   |  2 +-
 src/test/csharp/IndividualAckTest.cs | 57 +++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/ed48f032/src/main/csharp/MessageConsumer.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/MessageConsumer.cs b/src/main/csharp/MessageConsumer.cs
index 62e64d0..41df167 100755
--- a/src/main/csharp/MessageConsumer.cs
+++ b/src/main/csharp/MessageConsumer.cs
@@ -507,7 +507,7 @@ namespace Apache.NMS.ActiveMQ
                     this.session.Scheduler.Cancel(this.optimizedAckTask);
                 }
 
-                if (this.session.IsClientAcknowledge)
+                if (this.session.IsClientAcknowledge || this.session.IsIndividualAcknowledge)
                 {
                     if (!this.info.Browser)
                     {

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/ed48f032/src/test/csharp/IndividualAckTest.cs
----------------------------------------------------------------------
diff --git a/src/test/csharp/IndividualAckTest.cs b/src/test/csharp/IndividualAckTest.cs
index fe95593..a1c68fb 100644
--- a/src/test/csharp/IndividualAckTest.cs
+++ b/src/test/csharp/IndividualAckTest.cs
@@ -260,5 +260,62 @@ namespace Apache.NMS.ActiveMQ.Test
             Assert.IsNull(msg);
             session.Close();
         }
+
+        [Test]
+        public void TestIndividualAcksWithClosedConsumerAndAuditSync()
+        {
+            const int MSG_COUNT = 20;
+            const string QUEUE_NAME = "TEST.TestIndividualAcksWithClosedConsumerAndAuditSync";
+
+            ProduceSomeMessages(MSG_COUNT, QUEUE_NAME);
+
+            string uri = "failover:(tcp://${activemqhost}:61616)";
+            IConnectionFactory factory = new ConnectionFactory(NMSTestSupport.ReplaceEnvVar(uri));
+
+            using (IConnection connection = factory.CreateConnection() as Connection)
+            using (ISession session = connection.CreateSession(AcknowledgementMode.IndividualAcknowledge))
+            using (IQueue queue = session.GetQueue(QUEUE_NAME))
+            {
+                connection.Start();
+
+                // Consume all messages with no ACK
+                using (IMessageConsumer consumer = session.CreateConsumer(queue))
+                {
+                    for (int i = 0; i < MSG_COUNT; ++i)
+                    {
+                        IMessage message = consumer.Receive(TimeSpan.FromMilliseconds(3000));
+                        Assert.NotNull(message);
+                        Tracer.DebugFormat("Received message: {0}", message.NMSMessageId);
+                    }
+                }
+
+                // Consumer the same batch again.
+                using (IMessageConsumer consumer = session.CreateConsumer(queue))
+                {
+                    for (int i = 0; i < MSG_COUNT; ++i)
+                    {
+                        IMessage message = consumer.Receive(TimeSpan.FromMilliseconds(3000));
+                        Assert.NotNull(message);
+                        Tracer.DebugFormat("Received message: {0}", message.NMSMessageId);
+                    }
+                }
+
+                session.DeleteDestination(queue);
+            }
+        }
+
+        private void ProduceSomeMessages(int count, string queueName)
+        {
+            using (IConnection connection = CreateConnection())
+            using (ISession session = connection.CreateSession(AcknowledgementMode.IndividualAcknowledge))
+            using (IQueue queue = session.GetQueue(queueName))
+            using (IMessageProducer producer = session.CreateProducer(queue))
+            {
+                for (int i = 0; i < count; ++i)
+                {
+                    producer.Send(session.CreateMessage());
+                }
+            }
+        }
     }
 }


[34/50] [abbrv] activemq-nms-openwire git commit: Bump branch version from 1.7.1 to 1.7.2.

Posted by ta...@apache.org.
Bump branch version from 1.7.1 to 1.7.2.


Project: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/commit/418832ad
Tree: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/tree/418832ad
Diff: http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/diff/418832ad

Branch: refs/heads/1.7.x
Commit: 418832ad9718ff97c5d5bf04d19922c508968e18
Parents: 58728fe
Author: Jim Gomes <jg...@apache.org>
Authored: Mon Aug 31 21:20:15 2015 +0000
Committer: Jim Gomes <jg...@apache.org>
Committed: Mon Aug 31 21:20:15 2015 +0000

----------------------------------------------------------------------
 nant.build  | 2 +-
 package.ps1 | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/418832ad/nant.build
----------------------------------------------------------------------
diff --git a/nant.build b/nant.build
index 073ec67..5fe5e4d 100644
--- a/nant.build
+++ b/nant.build
@@ -22,7 +22,7 @@
     <property name="basedir" value="${project::get-base-directory()}" />
     <property name="project.name" value="Apache.NMS.ActiveMQ" />
     <property name="project.group" value="org.apache.activemq" />
-    <property name="project.version" value="1.7.1" unless="${property::exists('project.version')}" />
+    <property name="project.version" value="1.7.2" unless="${property::exists('project.version')}" />
     <property name="project.release.type" value="SNAPSHOT" unless="${property::exists('project.release.type')}" />
     <property name="project.short_description" value="Apache NMS for ActiveMQ Class Library" />
     <property name="project.description" value="Apache NMS for ActiveMQ Class Library (.Net Messaging Library Implementation): An implementation of the NMS API for ActiveMQ" />

http://git-wip-us.apache.org/repos/asf/activemq-nms-openwire/blob/418832ad/package.ps1
----------------------------------------------------------------------
diff --git a/package.ps1 b/package.ps1
index 97c2087..631da31 100644
--- a/package.ps1
+++ b/package.ps1
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 $pkgname = "Apache.NMS.ActiveMQ"
-$pkgver = "1.7.1-SNAPSHOT"
+$pkgver = "1.7.2-SNAPSHOT"
 $configurations = "release", "debug"
 $frameworks = "mono-2.0", "net-2.0", "net-3.5", "net-4.0"