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 2013/04/29 19:31:08 UTC

svn commit: r1477221 - in /activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src: main/csharp/State/ main/csharp/Util/ test/csharp/State/

Author: tabish
Date: Mon Apr 29 17:31:07 2013
New Revision: 1477221

URL: http://svn.apache.org/r1477221
Log:
Fix for https://issues.apache.org/jira/browse/AMQNET-435

Fix caching size limit issue and cleanup the code a bit and add more tests.

Added:
    activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/
    activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/ConnectionStateTest.cs   (with props)
    activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/ConnectionStateTrackerTest.cs   (with props)
    activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/ConsumerStateTest.cs   (with props)
    activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/ProducerStateTest.cs   (with props)
    activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/SessionStateTest.cs   (with props)
    activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/TransactionStateTest.cs   (with props)
Modified:
    activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/State/ConnectionState.cs
    activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/State/ConnectionStateTracker.cs
    activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/State/SessionState.cs
    activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/State/TransactionState.cs
    activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Util/LRUCache.cs

Modified: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/State/ConnectionState.cs
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/State/ConnectionState.cs?rev=1477221&r1=1477220&r2=1477221&view=diff
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/State/ConnectionState.cs (original)
+++ activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/State/ConnectionState.cs Mon Apr 29 17:31:07 2013
@@ -25,18 +25,22 @@ namespace Apache.NMS.ActiveMQ.State
 	public class ConnectionState
 	{
 		private ConnectionInfo info;
-		private readonly AtomicDictionary<TransactionId, TransactionState> transactions = new AtomicDictionary<TransactionId, TransactionState>();
-		private readonly AtomicDictionary<SessionId, SessionState> sessions = new AtomicDictionary<SessionId, SessionState>();
-		private readonly AtomicCollection<DestinationInfo> tempDestinations = new AtomicCollection<DestinationInfo>();
-		private readonly Atomic<bool> _shutdown = new Atomic<bool>(false);
+		private readonly AtomicDictionary<TransactionId, TransactionState> transactions = 
+			new AtomicDictionary<TransactionId, TransactionState>();
+		private readonly AtomicDictionary<SessionId, SessionState> sessions = 
+			new AtomicDictionary<SessionId, SessionState>();
+		private readonly AtomicCollection<DestinationInfo> tempDestinations = 
+			new AtomicCollection<DestinationInfo>();
+		private readonly Atomic<bool> isShutdown = new Atomic<bool>(false);
 	    private bool connectionInterruptProcessingComplete = true;
-		private readonly Dictionary<ConsumerId, ConsumerInfo> recoveringPullConsumers = new Dictionary<ConsumerId, ConsumerInfo>();
+		private readonly Dictionary<ConsumerId, ConsumerInfo> recoveringPullConsumers = 
+			new Dictionary<ConsumerId, ConsumerInfo>();
 
 		public ConnectionState(ConnectionInfo info)
 		{
 			this.info = info;
 			// Add the default session id.
-			addSession(new SessionInfo(info, -1));
+			AddSession(new SessionInfo(info, -1));
 		}
 
 		public override String ToString()
@@ -44,22 +48,22 @@ namespace Apache.NMS.ActiveMQ.State
 			return info.ToString();
 		}
 
-		public void reset(ConnectionInfo info)
+		public void Reset(ConnectionInfo info)
 		{
 			this.info = info;
 			transactions.Clear();
 			sessions.Clear();
 			tempDestinations.Clear();
-			_shutdown.Value = false;
+			isShutdown.Value = false;
 		}
 
-		public void addTempDestination(DestinationInfo info)
+		public void AddTempDestination(DestinationInfo info)
 		{
-			checkShutdown();
+			CheckShutdown();
 			tempDestinations.Add(info);
 		}
 
-		public void removeTempDestination(IDestination destination)
+		public void RemoveTempDestination(IDestination destination)
 		{
 			for(int i = tempDestinations.Count - 1; i >= 0; i--)
 			{
@@ -71,9 +75,9 @@ namespace Apache.NMS.ActiveMQ.State
 			}
 		}
 
-		public void addTransactionState(TransactionId id)
+		public void AddTransactionState(TransactionId id)
 		{
-			checkShutdown();
+			CheckShutdown();
 			TransactionState transactionState = new TransactionState(id);
 
 			if(transactions.ContainsKey(id))
@@ -128,7 +132,7 @@ namespace Apache.NMS.ActiveMQ.State
 			}
 		}
 
-		public TransactionState removeTransactionState(TransactionId id)
+		public TransactionState RemoveTransactionState(TransactionId id)
 		{
 			TransactionState ret = null;
 
@@ -140,9 +144,9 @@ namespace Apache.NMS.ActiveMQ.State
 			return ret;
 		}
 
-		public void addSession(SessionInfo info)
+		public void AddSession(SessionInfo info)
 		{
-			checkShutdown();
+			CheckShutdown();
 			SessionState sessionState = new SessionState(info);
 
 			if(sessions.ContainsKey(info.SessionId))
@@ -155,7 +159,7 @@ namespace Apache.NMS.ActiveMQ.State
 			}
 		}
 
-		public SessionState removeSession(SessionId id)
+		public SessionState RemoveSession(SessionId id)
 		{
 			SessionState ret = null;
 
@@ -187,9 +191,9 @@ namespace Apache.NMS.ActiveMQ.State
 			get { return sessions.Values; }
 		}
 
-		private void checkShutdown()
+		private void CheckShutdown()
 		{
-			if(_shutdown.Value)
+			if(isShutdown.Value)
 			{
 				throw new ApplicationException("Disposed");
 			}
@@ -206,13 +210,13 @@ namespace Apache.NMS.ActiveMQ.State
 			set { this.connectionInterruptProcessingComplete = value; }
 		}
 
-		public void shutdown()
+		public void Shutdown()
 		{
-			if(_shutdown.CompareAndSet(false, true))
+			if(isShutdown.CompareAndSet(false, true))
 			{
 				foreach(SessionState ss in sessions.Values)
 				{
-					ss.shutdown();
+					ss.Shutdown();
 				}
 			}
 		}

Modified: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/State/ConnectionStateTracker.cs
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/State/ConnectionStateTracker.cs?rev=1477221&r1=1477220&r2=1477221&view=diff
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/State/ConnectionStateTracker.cs (original)
+++ activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/State/ConnectionStateTracker.cs Mon Apr 29 17:31:07 2013
@@ -19,6 +19,7 @@ using System;
 using System.Collections.Generic;
 using Apache.NMS.ActiveMQ.Commands;
 using Apache.NMS.ActiveMQ.Transport;
+using Apache.NMS.ActiveMQ.Util;
 using System.Collections;
 
 namespace Apache.NMS.ActiveMQ.State
@@ -33,30 +34,16 @@ namespace Apache.NMS.ActiveMQ.State
 
         protected Dictionary<ConnectionId, ConnectionState> connectionStates = new Dictionary<ConnectionId, ConnectionState>();
 
-        private bool _trackTransactions;
-        private bool _trackTransactionProducers = true;
-        private bool _restoreSessions = true;
-        private bool _restoreConsumers = true;
-        private bool _restoreProducers = true;
-        private bool _restoreTransaction = true;
-        private bool _trackMessages = true;
-        private int _maxCacheSize = 256;
+        private bool isTrackTransactions;
+        private bool isTrackTransactionProducers = true;
+        private bool isRestoreSessions = true;
+        private bool isRestoreConsumers = true;
+        private bool isRestoreProducers = true;
+        private bool isRestoreTransaction = true;
+        private bool isTrackMessages = true;
+        private int maxCacheSize = 256;
         private int currentCacheSize;
-        private readonly Dictionary<Object, Command> messageCache = new Dictionary<Object, Command>();
-        private readonly Queue<Object> messageCacheFIFO = new Queue<Object>();
-
-        protected void RemoveEldestInCache()
-        {
-            System.Collections.ICollection ic = messageCacheFIFO;
-            lock(ic.SyncRoot)
-            {
-                while(messageCacheFIFO.Count > MaxCacheSize)
-                {
-                    messageCache.Remove(messageCacheFIFO.Dequeue());
-                    currentCacheSize = currentCacheSize - 1;
-                }
-            }
-        }
+        private readonly LRUCache<Object, Command> messageCache = new LRUCache<Object, Command>(256);
 
         private class RemoveTransactionAction : ThreadSimulator
         {
@@ -75,7 +62,7 @@ namespace Apache.NMS.ActiveMQ.State
 
 				if(cst.connectionStates.TryGetValue(info.ConnectionId, out cs))
 				{
-					cs.removeTransactionState(info.TransactionId);
+					cs.RemoveTransactionState(info.TransactionId);
 				}
             }
         }
@@ -176,7 +163,8 @@ namespace Apache.NMS.ActiveMQ.State
                         {
                             if (Tracer.IsDebugEnabled)
                             {
-                                Tracer.Debug("rolling back potentially completed tx: " + transactionState.getId());
+                                Tracer.Debug("rolling back potentially completed tx: " + 
+								             transactionState.Id);
                             }
                             toRollback.Add(transactionInfo);
                             continue;
@@ -345,7 +333,7 @@ namespace Apache.NMS.ActiveMQ.State
 
 				if(connectionStates.TryGetValue(info.ConnectionId, out cs))
 				{
-					cs.addTempDestination(info);
+					cs.AddTempDestination(info);
 				}
             }
             return TRACKED_RESPONSE_MARKER;
@@ -358,7 +346,7 @@ namespace Apache.NMS.ActiveMQ.State
                 ConnectionState cs;
 				if(connectionStates.TryGetValue(info.ConnectionId, out cs))
 				{
-                    cs.removeTempDestination(info.Destination);
+                    cs.RemoveTempDestination(info.Destination);
                 }
             }
             return TRACKED_RESPONSE_MARKER;
@@ -381,7 +369,7 @@ namespace Apache.NMS.ActiveMQ.State
                             SessionState ss = cs[sessionId];
                             if(ss != null)
                             {
-                                ss.addProducer(info);
+                                ss.AddProducer(info);
                             }
                         }
                     }
@@ -407,7 +395,7 @@ namespace Apache.NMS.ActiveMQ.State
                             SessionState ss = cs[sessionId];
                             if(ss != null)
                             {
-                                ss.removeProducer(id);
+                                ss.RemoveProducer(id);
                             }
                         }
                     }
@@ -433,7 +421,7 @@ namespace Apache.NMS.ActiveMQ.State
                             SessionState ss = cs[sessionId];
                             if(ss != null)
                             {
-                                ss.addConsumer(info);
+                                ss.AddConsumer(info);
                             }
                         }
                     }
@@ -459,7 +447,7 @@ namespace Apache.NMS.ActiveMQ.State
                             SessionState ss = cs[sessionId];
                             if(ss != null)
                             {
-                                ss.removeConsumer(id);
+                                ss.RemoveConsumer(id);
                             }
                         }
                     }
@@ -479,7 +467,7 @@ namespace Apache.NMS.ActiveMQ.State
 
 					if(connectionStates.TryGetValue(connectionId, out cs))
                     {
-                        cs.addSession(info);
+                        cs.AddSession(info);
                     }
                 }
             }
@@ -497,7 +485,7 @@ namespace Apache.NMS.ActiveMQ.State
 
 					if(connectionStates.TryGetValue(connectionId, out cs))
                     {
-                        cs.removeSession(id);
+                        cs.RemoveSession(id);
                     }
                 }
             }
@@ -549,9 +537,9 @@ namespace Apache.NMS.ActiveMQ.State
                             TransactionState transactionState = cs[send.TransactionId];
                             if(transactionState != null)
                             {
-                                transactionState.addCommand(send);
+                                transactionState.AddCommand(send);
 
-                                if (_trackTransactionProducers)
+                                if (isTrackTransactionProducers)
                                 {
                                     SessionState ss = cs[producerId.ParentId];
                                     ProducerState producerState = ss[producerId];
@@ -565,7 +553,6 @@ namespace Apache.NMS.ActiveMQ.State
                 else if(TrackMessages)
                 {
                     messageCache.Add(send.MessageId, (Message) send.Clone());
-                    RemoveEldestInCache();
                 }
             }
             return null;
@@ -585,7 +572,7 @@ namespace Apache.NMS.ActiveMQ.State
                         TransactionState transactionState = cs[ack.TransactionId];
                         if(transactionState != null)
                         {
-                            transactionState.addCommand(ack);
+                            transactionState.AddCommand(ack);
                         }
                     }
                 }
@@ -605,9 +592,9 @@ namespace Apache.NMS.ActiveMQ.State
 
 					if(connectionStates.TryGetValue(connectionId, out cs))
                     {
-                        cs.addTransactionState(info.TransactionId);
+                        cs.AddTransactionState(info.TransactionId);
                         TransactionState state = cs[info.TransactionId];
-                        state.addCommand(info);
+                        state.AddCommand(info);
                     }
                 }
                 return TRACKED_RESPONSE_MARKER;
@@ -629,7 +616,7 @@ namespace Apache.NMS.ActiveMQ.State
                         TransactionState transactionState = cs[info.TransactionId];
                         if(transactionState != null)
                         {
-                            transactionState.addCommand(info);
+                            transactionState.AddCommand(info);
                         }
                     }
                 }
@@ -652,7 +639,7 @@ namespace Apache.NMS.ActiveMQ.State
                         TransactionState transactionState = cs[info.TransactionId];
                         if(transactionState != null)
                         {
-                            transactionState.addCommand(info);
+                            transactionState.AddCommand(info);
                             return new Tracked(new RemoveTransactionAction(info, this));
                         }
                     }
@@ -675,7 +662,7 @@ namespace Apache.NMS.ActiveMQ.State
                         TransactionState transactionState = cs[info.TransactionId];
                         if(transactionState != null)
                         {
-                            transactionState.addCommand(info);
+                            transactionState.AddCommand(info);
                             return new Tracked(new RemoveTransactionAction(info, this));
                         }
                     }
@@ -698,7 +685,7 @@ namespace Apache.NMS.ActiveMQ.State
                         TransactionState transactionState = cs[info.TransactionId];
                         if(transactionState != null)
                         {
-                            transactionState.addCommand(info);
+                            transactionState.AddCommand(info);
                             return new Tracked(new RemoveTransactionAction(info, this));
                         }
                     }
@@ -721,7 +708,7 @@ namespace Apache.NMS.ActiveMQ.State
                         TransactionState transactionState = cs[info.TransactionId];
                         if(transactionState != null)
                         {
-                            transactionState.addCommand(info);
+                            transactionState.AddCommand(info);
                         }
                     }
                 }
@@ -743,50 +730,54 @@ namespace Apache.NMS.ActiveMQ.State
 
         public bool RestoreConsumers
         {
-            get { return _restoreConsumers; }
-            set { _restoreConsumers = value; }
+            get { return isRestoreConsumers; }
+            set { isRestoreConsumers = value; }
         }
 
         public bool RestoreProducers
         {
-            get { return _restoreProducers; }
-            set { _restoreProducers = value; }
+            get { return isRestoreProducers; }
+            set { isRestoreProducers = value; }
         }
 
         public bool RestoreSessions
         {
-            get { return _restoreSessions; }
-            set { _restoreSessions = value; }
+            get { return isRestoreSessions; }
+            set { isRestoreSessions = value; }
         }
 
         public bool TrackTransactions
         {
-            get { return _trackTransactions; }
-            set { _trackTransactions = value; }
+            get { return isTrackTransactions; }
+            set { isTrackTransactions = value; }
         }
 
         public bool TrackTransactionProducers
         {
-            get { return _trackTransactionProducers; }
-            set { _trackTransactionProducers = value; }
+            get { return isTrackTransactionProducers; }
+            set { isTrackTransactionProducers = value; }
         }
 
         public bool RestoreTransaction
         {
-            get { return _restoreTransaction; }
-            set { _restoreTransaction = value; }
+            get { return isRestoreTransaction; }
+            set { isRestoreTransaction = value; }
         }
 
         public bool TrackMessages
         {
-            get { return _trackMessages; }
-            set { _trackMessages = value; }
+            get { return isTrackMessages; }
+            set { isTrackMessages = value; }
         }
 
         public int MaxCacheSize
         {
-            get { return _maxCacheSize; }
-            set { _maxCacheSize = value; }
+            get { return maxCacheSize; }
+            set 
+			{ 
+				this.maxCacheSize = value; 
+				this.messageCache.MaxCacheSize = maxCacheSize;
+			}
         }
 
         public void ConnectionInterruptProcessingComplete(ITransport transport, ConnectionId connectionId)

Modified: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/State/SessionState.cs
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/State/SessionState.cs?rev=1477221&r1=1477220&r2=1477221&view=diff
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/State/SessionState.cs (original)
+++ activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/State/SessionState.cs Mon Apr 29 17:31:07 2013
@@ -25,9 +25,11 @@ namespace Apache.NMS.ActiveMQ.State
 	{
 	    readonly SessionInfo info;
 
-		private readonly AtomicDictionary<ProducerId, ProducerState> producers = new AtomicDictionary<ProducerId, ProducerState>();
-		private readonly AtomicDictionary<ConsumerId, ConsumerState> consumers = new AtomicDictionary<ConsumerId, ConsumerState>();
-		private readonly Atomic<bool> _shutdown = new Atomic<bool>(false);
+		private readonly AtomicDictionary<ProducerId, ProducerState> producers = 
+			new AtomicDictionary<ProducerId, ProducerState>();
+		private readonly AtomicDictionary<ConsumerId, ConsumerState> consumers = 
+			new AtomicDictionary<ConsumerId, ConsumerState>();
+		private readonly Atomic<bool> isShutdown = new Atomic<bool>(false);
 
 		public SessionState(SessionInfo info)
 		{
@@ -39,9 +41,9 @@ namespace Apache.NMS.ActiveMQ.State
 			return info.ToString();
 		}
 
-		public void addProducer(ProducerInfo info)
+		public void AddProducer(ProducerInfo info)
 		{
-			checkShutdown();
+			CheckShutdown();
 			ProducerState producerState = new ProducerState(info);
 
 			if(producers.ContainsKey(info.ProducerId))
@@ -54,8 +56,9 @@ namespace Apache.NMS.ActiveMQ.State
 			}
 		}
 
-		public ProducerState removeProducer(ProducerId id)
+		public ProducerState RemoveProducer(ProducerId id)
 		{
+			CheckShutdown();
 			ProducerState ret = null;
 
 			if(producers.TryGetValue(id, out ret))
@@ -70,9 +73,9 @@ namespace Apache.NMS.ActiveMQ.State
 			return ret;
 		}
 
-		public void addConsumer(ConsumerInfo info)
+		public void AddConsumer(ConsumerInfo info)
 		{
-			checkShutdown();
+			CheckShutdown();
 			ConsumerState consumerState = new ConsumerState(info);
 
 			if(consumers.ContainsKey(info.ConsumerId))
@@ -85,8 +88,9 @@ namespace Apache.NMS.ActiveMQ.State
 			}
 		}
 
-		public ConsumerState removeConsumer(ConsumerId id)
+		public ConsumerState RemoveConsumer(ConsumerId id)
 		{
+			CheckShutdown();
 			ConsumerState ret = null;
 
 			if(consumers.TryGetValue(id, out ret))
@@ -142,18 +146,19 @@ namespace Apache.NMS.ActiveMQ.State
             get { return consumers[consumerId]; }
 		}
 
-		private void checkShutdown()
+		private void CheckShutdown()
 		{
-			if(_shutdown.Value)
+			if(isShutdown.Value)
 			{
 				throw new ApplicationException("Disposed");
 			}
 		}
 
-		public void shutdown()
+		public void Shutdown()
 		{
-			_shutdown.Value = true;
+			isShutdown.Value = true;
+			producers.Clear();
+			consumers.Clear();
 		}
-
 	}
 }

Modified: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/State/TransactionState.cs
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/State/TransactionState.cs?rev=1477221&r1=1477220&r2=1477221&view=diff
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/State/TransactionState.cs (original)
+++ activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/State/TransactionState.cs Mon Apr 29 17:31:07 2013
@@ -26,10 +26,11 @@ namespace Apache.NMS.ActiveMQ.State
 	{
 		private readonly List<Command> commands = new List<Command>();
 		private readonly TransactionId id;
-		private readonly Atomic<bool> _shutdown = new Atomic<bool>(false);
+		private readonly Atomic<bool> isShutdown = new Atomic<bool>(false);
 		private bool prepared;
 		private int preparedResult;
-        private readonly AtomicDictionary<ProducerId, ProducerState> producers = new AtomicDictionary<ProducerId, ProducerState>();
+        private readonly AtomicDictionary<ProducerId, ProducerState> producers = 
+			new AtomicDictionary<ProducerId, ProducerState>();
 
 		public TransactionState(TransactionId id)
 		{
@@ -41,9 +42,9 @@ namespace Apache.NMS.ActiveMQ.State
 			return id.ToString();
 		}
 
-		public void addCommand(Command operation)
+		public void AddCommand(Command operation)
 		{
-			checkShutdown();
+			CheckShutdown();
 			commands.Add(operation);
 		}
 
@@ -52,22 +53,24 @@ namespace Apache.NMS.ActiveMQ.State
 			get { return commands; }
 		}
 
-		private void checkShutdown()
+		private void CheckShutdown()
 		{
-			if(_shutdown.Value)
+			if(isShutdown.Value)
 			{
 				throw new ApplicationException("Disposed");
 			}
 		}
 
-		public void shutdown()
+		public void Shutdown()
 		{
-			_shutdown.Value = true;
+			isShutdown.Value = true;
+			producers.Clear();
+			commands.Clear();
 		}
 
-		public TransactionId getId()
+		public TransactionId Id
 		{
-			return id;
+			get { return id; }
 		}
 
 		public bool Prepared
@@ -83,7 +86,8 @@ namespace Apache.NMS.ActiveMQ.State
 		}
 
         public void AddProducer(ProducerState producer)
-        {
+        {
+			CheckShutdown();
 			if(this.producers.ContainsKey(producer.Info.ProducerId))
 			{
 				this.producers[producer.Info.ProducerId] = producer;

Modified: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Util/LRUCache.cs
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Util/LRUCache.cs?rev=1477221&r1=1477220&r2=1477221&view=diff
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Util/LRUCache.cs (original)
+++ activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Util/LRUCache.cs Mon Apr 29 17:31:07 2013
@@ -63,7 +63,28 @@ namespace Apache.NMS.ActiveMQ.Util
 		public TValue this[TKey key]
 		{
 			get { return dictionary[key]; }
-			set { this.Add(key, value); }
+			set 
+			{ 
+				TValue currentValue = default (TValue);
+				// 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);
+					entries.Remove(entry);
+				}
+
+				dictionary[key] = value;
+	            entries.AddLast(new KeyValuePair<TKey, TValue>(key, value));
+
+	            KeyValuePair<TKey, TValue> eldest = entries.First.Value;
+
+			    if(this.RemoveEldestEntry(eldest))
+	            {
+	                this.dictionary.Remove(eldest.Key);
+	                this.entries.RemoveFirst();
+	            }
+			}
 		}
 
 		public bool TryGetValue(TKey key, out TValue val)

Added: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/ConnectionStateTest.cs
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/ConnectionStateTest.cs?rev=1477221&view=auto
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/ConnectionStateTest.cs (added)
+++ activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/ConnectionStateTest.cs Mon Apr 29 17:31:07 2013
@@ -0,0 +1,58 @@
+/*
+ * 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.Threading;
+using Apache.NMS.Test;
+using Apache.NMS.ActiveMQ.Commands;
+using Apache.NMS.ActiveMQ.State;
+using NUnit.Framework;
+
+namespace Apache.NMS.ActiveMQ.Test
+{
+    [TestFixture]
+	public class ConnectionStateTest
+	{
+		[Test]
+		public void TestConnectionState()
+		{
+		    // Create a Session
+		    SessionId sid = new SessionId();
+		    sid.ConnectionId = "CONNECTION";
+		    sid.Value = 42;
+			SessionInfo sinfo = new SessionInfo();
+		    sinfo.SessionId = sid;
+
+		    ConnectionId connectionId = new ConnectionId();
+		    connectionId.Value = "CONNECTION";
+		    ConnectionInfo info = new ConnectionInfo();
+		    info.ConnectionId = connectionId;
+
+		    ConnectionState state = new ConnectionState(info);
+
+		    state.AddSession(sinfo);
+		    Assert.AreEqual(2, state.SessionStates.Count);
+		    state.RemoveSession(sinfo.SessionId);
+		    Assert.AreEqual(1, state.SessionStates.Count);
+
+		    state.AddSession(sinfo);
+		    state.AddSession(sinfo);
+		    Assert.AreEqual(2, state.SessionStates.Count);
+		}
+	}
+}
+

Propchange: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/ConnectionStateTest.cs
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/ConnectionStateTrackerTest.cs
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/ConnectionStateTrackerTest.cs?rev=1477221&view=auto
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/ConnectionStateTrackerTest.cs (added)
+++ activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/ConnectionStateTrackerTest.cs Mon Apr 29 17:31:07 2013
@@ -0,0 +1,337 @@
+/*
+ * 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.Collections.Generic;
+using Apache.NMS.Test;
+using Apache.NMS.ActiveMQ.Commands;
+using Apache.NMS.ActiveMQ.State;
+using Apache.NMS.ActiveMQ.Transport;
+using NUnit.Framework;
+
+namespace Apache.NMS.ActiveMQ.Test
+{
+    [TestFixture]
+	public class ConnectionStateTrackerTest
+	{
+	    class TrackingTransport : ITransport 
+		{
+	        public LinkedList<Command> connections = new LinkedList<Command>();
+	        public LinkedList<Command> sessions = new LinkedList<Command>();
+	        public LinkedList<Command> producers = new LinkedList<Command>();
+	        public LinkedList<Command> consumers = new LinkedList<Command>();
+	        public LinkedList<Command> messages = new LinkedList<Command>();
+	        public LinkedList<Command> messagePulls = new LinkedList<Command>();
+
+			public FutureResponse AsyncRequest(Command command)
+			{
+				return null;
+			}
+
+			public Response Request(Command command)
+			{
+				return null;
+			}
+
+			public Response Request(Command command, TimeSpan timeout)
+			{
+				return null;
+			}
+
+        	public Object Narrow(Type type)
+			{
+				return null;
+			}
+
+	        public void Start() 
+			{
+			}
+
+			public bool IsStarted
+			{
+				get { return true; }
+			}
+
+	        public void Stop() 
+			{
+			}
+
+	        public void Dispose() 
+			{
+			}
+
+	        public void Oneway(Command command) 
+			{
+	            if (command.IsConnectionInfo) 
+				{
+	                connections.AddLast(command);
+	            }
+				else if (command.IsSessionInfo) 
+				{
+	                sessions.AddLast(command);
+	            }
+				else if (command.IsProducerInfo) 
+				{
+	                producers.AddLast(command);
+	            }
+				else if (command.IsConsumerInfo) 
+				{
+	                consumers.AddLast(command);
+	            }
+				else if (command.IsMessage) 
+				{
+	                messages.AddLast(command);
+	            }
+				else if (command.IsMessagePull) 
+				{
+	                messagePulls.AddLast(command);
+	            }
+	        }
+
+			public int Timeout
+			{
+				get { return 0; }
+				set {}
+			}
+
+			public int AsyncTimeout
+			{
+				get { return 0; }
+				set {}
+			}
+
+			public CommandHandler Command
+			{
+				get { return null; }
+				set {}
+			}
+
+			public ExceptionHandler Exception
+			{
+				get { return null; }
+				set {}
+			}
+
+			public InterruptedHandler Interrupted
+			{
+				get { return null; }
+				set {}
+			}
+
+			public ResumedHandler Resumed
+			{
+				get { return null; }
+				set {}
+			}
+
+			public bool IsDisposed
+			{
+				get { return false; }
+			}
+
+	        public bool IsFaultTolerant
+	        {
+				get { return false; }
+	        }
+
+	        public bool IsConnected
+	        {
+				get { return false; }
+	        }
+
+	        public Uri RemoteAddress
+	        {
+				get { return null; }
+	        }
+
+		    public bool IsReconnectSupported
+			{
+				get { return false; }
+			}
+
+		    public bool IsUpdateURIsSupported
+			{
+				get { return false; }
+			}
+
+			public void UpdateURIs(bool rebalance, Uri[] updatedURIs)
+			{
+			}
+
+	        public IWireFormat WireFormat
+	        {
+				get { return null; }
+	        }
+
+	    };
+
+	    class ConnectionData 
+		{
+	        public ConnectionInfo connection;
+	        public SessionInfo session;
+	        public ConsumerInfo consumer;
+	        public ProducerInfo producer;
+	    };
+
+	    private ConnectionData CreateConnectionState(ConnectionStateTracker tracker) 
+		{
+	        ConnectionData conn = new ConnectionData();
+
+	        ConnectionId connectionId = new ConnectionId();
+	        connectionId.Value = "CONNECTION";
+	        conn.connection = new ConnectionInfo();
+	        conn.connection.ConnectionId = connectionId;
+
+	        SessionId sessionId = new SessionId();
+	        sessionId.ConnectionId = "CONNECTION";
+	        sessionId.Value = 12345;
+	        conn.session = new SessionInfo();
+	        conn.session.SessionId = sessionId;
+
+	        ConsumerId consumerId = new ConsumerId();
+	        consumerId.ConnectionId = "CONNECTION";
+	        consumerId.SessionId = 12345;
+	        consumerId.Value = 42;
+	        conn.consumer = new ConsumerInfo();
+	        conn.consumer.ConsumerId = consumerId;
+
+	        ProducerId producerId = new ProducerId();
+	        producerId.ConnectionId = "CONNECTION";
+	        producerId.SessionId = 12345;
+	        producerId.Value = 42;
+
+	        conn.producer = new ProducerInfo();
+	        conn.producer.ProducerId = producerId;
+
+	        tracker.processAddConnection(conn.connection);
+	        tracker.processAddSession(conn.session);
+	        tracker.processAddConsumer(conn.consumer);
+	        tracker.processAddProducer(conn.producer);
+
+	        return conn;
+	    }
+
+	    void ClearConnectionState(ConnectionStateTracker tracker, ConnectionData conn) 
+		{
+	        tracker.processRemoveProducer(conn.producer.ProducerId);
+	        tracker.processRemoveConsumer(conn.consumer.ConsumerId);
+	        tracker.processRemoveSession(conn.session.SessionId);
+	        tracker.processRemoveConnection(conn.connection.ConnectionId);
+	    }
+
+		[SetUp]
+		public void SetUp()
+		{
+			Apache.NMS.Tracer.Trace = new NmsConsoleTracer();
+		}
+
+		[Test]
+		public void TestConnectionStateTracker()
+		{
+			ConnectionStateTracker tracker = new ConnectionStateTracker();
+		    ConnectionData conn = CreateConnectionState(tracker);
+		    ClearConnectionState(tracker, conn);
+		}
+
+		[Test]
+		public void TestMessageCache()
+		{
+		    TrackingTransport transport = new TrackingTransport();
+		    ConnectionStateTracker tracker = new ConnectionStateTracker();
+		    tracker.TrackMessages = true;
+
+		    ConnectionData conn = CreateConnectionState(tracker);
+
+		    int messageSize;
+		    {
+		        Message message = new Message();
+		        messageSize = message.Size();
+		    }
+
+			tracker.MaxCacheSize = 4;
+
+		    int sequenceId = 1;
+
+		    for (int i = 0; i < 10; ++i) 
+			{
+		        MessageId id = new MessageId();
+		        id.ProducerId = conn.producer.ProducerId;
+		        id.ProducerSequenceId = sequenceId++;
+		        Message message = new Message();
+		        message.MessageId = id;
+
+		        tracker.processMessage(message);
+		        tracker.TrackBack(message);
+		    }
+
+		    tracker.DoRestore(transport);
+
+			Assert.AreEqual(4, transport.messages.Count);
+		}
+
+		[Test]
+		public void TestMessagePullCache()
+		{
+		    TrackingTransport transport = new TrackingTransport();
+		    ConnectionStateTracker tracker = new ConnectionStateTracker();
+		    tracker.TrackMessages = true;
+
+			tracker.MaxCacheSize = 10;
+		    ConnectionData conn = CreateConnectionState(tracker);
+
+		    for (int i = 0; i < 100; ++i) 
+			{
+		        MessagePull pull = new MessagePull();
+		        ActiveMQDestination destination = new ActiveMQTopic("TEST" + i);
+		        pull.ConsumerId = conn.consumer.ConsumerId;
+		        pull.Destination = destination;
+		        tracker.processMessagePull(pull);
+				tracker.TrackBack(pull);
+		    }
+
+		    tracker.DoRestore(transport);
+
+		    Assert.AreEqual(10, transport.messagePulls.Count);
+		}
+
+		[Test]
+		public void TestMessagePullCache2()
+		{
+		    TrackingTransport transport = new TrackingTransport();
+		    ConnectionStateTracker tracker = new ConnectionStateTracker();
+		    tracker.TrackMessages = true;
+
+			tracker.MaxCacheSize = 10;
+		    ConnectionData conn = CreateConnectionState(tracker);
+
+		    for (int i = 0; i < 100; ++i) 
+			{
+		        MessagePull pull = new MessagePull();
+		        ActiveMQDestination destination = new ActiveMQTopic("TEST");
+		        pull.ConsumerId = conn.consumer.ConsumerId;
+		        pull.Destination = destination;
+		        tracker.processMessagePull(pull);
+				tracker.TrackBack(pull);
+		    }
+
+		    tracker.DoRestore(transport);
+
+		    Assert.AreEqual(1, transport.messagePulls.Count);
+		}
+	}
+}
+

Propchange: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/ConnectionStateTrackerTest.cs
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/ConsumerStateTest.cs
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/ConsumerStateTest.cs?rev=1477221&view=auto
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/ConsumerStateTest.cs (added)
+++ activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/ConsumerStateTest.cs Mon Apr 29 17:31:07 2013
@@ -0,0 +1,52 @@
+/*
+ * 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.Threading;
+using Apache.NMS.Test;
+using Apache.NMS.ActiveMQ.Commands;
+using Apache.NMS.ActiveMQ.State;
+using NUnit.Framework;
+
+namespace Apache.NMS.ActiveMQ.Test
+{
+    [TestFixture]
+	public class ConsumerStateTest
+	{
+		[Test]
+		public void TestConsumerState()
+		{
+			ConsumerState state = new ConsumerState(CreateConsumerInfo(1));
+
+			Assert.IsNotNull(state.Info);
+			Assert.AreEqual(1, state.Info.ConsumerId.Value);
+		}
+
+		private ConsumerInfo CreateConsumerInfo(int value)
+		{
+			ConsumerId cid = new ConsumerId();
+			cid.Value = value;
+			cid.ConnectionId = "CONNECTION";
+			cid.SessionId = 1;
+			ConsumerInfo info = new ConsumerInfo();
+			info.ConsumerId = cid;
+
+			return info;
+		}	
+	}
+}
+

Propchange: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/ConsumerStateTest.cs
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/ProducerStateTest.cs
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/ProducerStateTest.cs?rev=1477221&view=auto
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/ProducerStateTest.cs (added)
+++ activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/ProducerStateTest.cs Mon Apr 29 17:31:07 2013
@@ -0,0 +1,63 @@
+/*
+ * 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.Threading;
+using Apache.NMS.Test;
+using Apache.NMS.ActiveMQ.Commands;
+using Apache.NMS.ActiveMQ.State;
+using NUnit.Framework;
+
+namespace Apache.NMS.ActiveMQ.Test
+{
+    [TestFixture]
+	public class ProducerStateTest
+	{
+		[Test]
+		public void TestProducerState()
+		{
+			ProducerState state = new ProducerState(CreateProducerInfo(1));
+
+			Assert.IsNotNull(state.Info);
+			Assert.AreEqual(1, state.Info.ProducerId.Value);
+
+			state.TransactionState = CreateTXState(1);
+
+			Assert.IsNotNull(state.TransactionState);
+		}
+
+		private TransactionState CreateTXState(int value)
+		{
+		    LocalTransactionId id = new LocalTransactionId();
+		    id.Value = value;
+		    return new TransactionState(id);
+		}
+
+		private ProducerInfo CreateProducerInfo(int value)
+		{
+			ProducerId pid = new ProducerId();
+			pid.Value = value;
+			pid.ConnectionId = "CONNECTION";
+			pid.SessionId = 1;
+			ProducerInfo info = new ProducerInfo();
+			info.ProducerId = pid;
+
+			return info;
+		}	
+	}
+}
+

Propchange: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/ProducerStateTest.cs
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/SessionStateTest.cs
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/SessionStateTest.cs?rev=1477221&view=auto
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/SessionStateTest.cs (added)
+++ activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/SessionStateTest.cs Mon Apr 29 17:31:07 2013
@@ -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.Threading;
+using Apache.NMS.Test;
+using Apache.NMS.ActiveMQ.Commands;
+using Apache.NMS.ActiveMQ.State;
+using NUnit.Framework;
+
+namespace Apache.NMS.ActiveMQ.Test
+{
+    [TestFixture]
+	public class SessionStateTest
+	{
+		[Test]
+		public void TestSessionState()
+		{
+		    // Create a Consumer
+		    ConsumerId cid = new ConsumerId();
+		    cid.ConnectionId = "CONNECTION";
+		    cid.SessionId = 4096;
+		    cid.Value = 42;
+		    ConsumerInfo cinfo = new ConsumerInfo();
+		    cinfo.ConsumerId = cid;
+
+		    // Create a Producer
+		    ProducerId pid = new ProducerId();
+		    pid.ConnectionId = "CONNECTION";
+		    pid.SessionId = 42;
+		    pid.Value = 4096;
+		    ProducerInfo pinfo = new ProducerInfo();
+		    pinfo.ProducerId = pid;
+
+		    // Create a Session
+		    SessionId id = new SessionId();
+		    id.ConnectionId = "CONNECTION";
+		    id.Value = 42;
+		    SessionInfo info = new SessionInfo();
+		    info.SessionId = id;
+
+		    SessionState state = new SessionState(info);
+		    Assert.AreEqual(info, state.Info);
+
+		    state.AddProducer(pinfo);
+		    state.AddConsumer(cinfo);
+
+		    Assert.AreEqual(1, state.ConsumerStates.Count);
+		    Assert.AreEqual(1, state.ProducerStates.Count);
+
+		    state.RemoveProducer(pinfo.ProducerId);
+		    state.RemoveConsumer(cinfo.ConsumerId);
+
+		    Assert.AreEqual(0, state.ConsumerStates.Count);
+		    Assert.AreEqual(0, state.ProducerStates.Count);
+
+		    state.AddConsumer(cinfo);
+		    state.AddProducer(pinfo);
+		    state.AddProducer(pinfo);
+		    Assert.AreEqual(1, state.ProducerStates.Count);
+
+			state.Shutdown();
+		    Assert.AreEqual(0, state.ConsumerStates.Count);
+		    Assert.AreEqual(0, state.ProducerStates.Count);
+
+			try
+			{
+		  		state.AddConsumer(cinfo);
+				Assert.Fail("Should have thrown an exception");
+			}
+			catch
+			{
+			}
+
+			try
+			{
+		    	state.AddProducer(pinfo);
+				Assert.Fail("Should have thrown an exception");
+			}
+			catch
+			{
+			}
+		}
+	}
+}
+

Propchange: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/SessionStateTest.cs
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/TransactionStateTest.cs
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/TransactionStateTest.cs?rev=1477221&view=auto
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/TransactionStateTest.cs (added)
+++ activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/TransactionStateTest.cs Mon Apr 29 17:31:07 2013
@@ -0,0 +1,99 @@
+/*
+ * 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.Threading;
+using Apache.NMS.Test;
+using Apache.NMS.ActiveMQ.Commands;
+using Apache.NMS.ActiveMQ.State;
+using NUnit.Framework;
+
+namespace Apache.NMS.ActiveMQ.Test
+{
+    [TestFixture]
+	public class TransactionStateTest
+	{
+		[Test]
+		public void TestTransactionState()
+		{
+		    LocalTransactionId id = new LocalTransactionId();
+		    id.Value = 42;
+		    TransactionState state = new TransactionState(id);
+
+		    Assert.IsNotNull(state.Id);
+
+			LocalTransactionId temp = state.Id as LocalTransactionId;
+		    Assert.IsNotNull(temp);
+			Assert.AreEqual(id.Value, temp.Value);
+		}
+
+		[Test]
+		public void TestShutdown()
+		{
+		    LocalTransactionId id = new LocalTransactionId();
+		    id.Value = 42;
+		    TransactionState state = new TransactionState(id);
+
+			state.AddCommand(new Message());
+			state.AddCommand(new Message());
+			state.AddCommand(new Message());
+			state.AddCommand(new Message());
+
+			state.AddProducer(new ProducerState(CreateProducerInfo(1)));
+			state.AddProducer(new ProducerState(CreateProducerInfo(2)));
+
+			Assert.AreEqual(4, state.Commands.Count);
+			Assert.AreEqual(2, state.ProducerStates.Count);
+
+			state.Shutdown();
+
+			Assert.AreEqual(0, state.Commands.Count);
+			Assert.AreEqual(0, state.ProducerStates.Count);
+
+			try
+			{
+				state.AddCommand(new Message());
+				Assert.Fail("Should have thrown an exception");
+			}
+			catch
+			{
+			}
+
+			try
+			{
+				state.AddProducer(new ProducerState(CreateProducerInfo(2)));
+				Assert.Fail("Should have thrown an exception");
+			}
+			catch
+			{
+			}
+		}
+
+		private ProducerInfo CreateProducerInfo(int value)
+		{
+			ProducerId pid = new ProducerId();
+			pid.Value = value;
+			pid.ConnectionId = "CONNECTION";
+			pid.SessionId = 1;
+			ProducerInfo info = new ProducerInfo();
+			info.ProducerId = pid;
+
+			return info;
+		}
+	}
+}
+

Propchange: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/State/TransactionStateTest.cs
------------------------------------------------------------------------------
    svn:eol-style = native