diff --git a/src/Spring/Spring.Messaging/Messaging/Core/DefaultMessageQueueFactory.cs b/src/Spring/Spring.Messaging/Messaging/Core/DefaultMessageQueueFactory.cs
index 6f272786..26f6e525 100644
--- a/src/Spring/Spring.Messaging/Messaging/Core/DefaultMessageQueueFactory.cs
+++ b/src/Spring/Spring.Messaging/Messaging/Core/DefaultMessageQueueFactory.cs
@@ -66,6 +66,11 @@ namespace Spring.Messaging.Core
MessageQueueFactoryObject mqfo = new MessageQueueFactoryObject();
mqfo.MessageCreatorDelegate = messageQueueCreatorDelegate;
applicationContext.ObjectFactory.RegisterSingleton(messageQueueObjectName, mqfo);
+ IDictionary caches = applicationContext.GetObjectsOfType(typeof(MessageQueueMetadataCache));
+ foreach (DictionaryEntry entry in caches)
+ {
+ ((MessageQueueMetadataCache) entry.Value).Insert(mqfo.Path, new MessageQueueMetadata(mqfo.RemoteQueue, mqfo.RemoteQueueIsTransactional));
+ }
}
///
diff --git a/src/Spring/Spring.Messaging/Messaging/Core/MessageQueueTemplate.cs b/src/Spring/Spring.Messaging/Messaging/Core/MessageQueueTemplate.cs
index 22baa95e..8131184f 100644
--- a/src/Spring/Spring.Messaging/Messaging/Core/MessageQueueTemplate.cs
+++ b/src/Spring/Spring.Messaging/Messaging/Core/MessageQueueTemplate.cs
@@ -27,6 +27,7 @@ using Spring.Messaging.Support;
using Spring.Messaging.Support.Converters;
using Spring.Objects.Factory;
using Spring.Objects.Factory.Config;
+using Spring.Util;
namespace Spring.Messaging.Core
{
@@ -82,12 +83,14 @@ namespace Spring.Messaging.Core
private string messageConverterObjectName;
private IMessageQueueFactory messageQueueFactory;
- protected IApplicationContext applicationContext;
+ protected IConfigurableApplicationContext applicationContext;
private TimeSpan timeout = MessageQueue.InfiniteTimeout;
private MessageQueueMetadataCache metadataCache;
+ public const string METADATA_CACHE_NAME = "__MessageQueueMetadataCache__";
+
#endregion
#region Constructors
@@ -241,7 +244,17 @@ namespace Spring.Messaging.Core
public IApplicationContext ApplicationContext
{
get { return applicationContext; }
- set { applicationContext = value; }
+ set {
+ AssertUtils.ArgumentNotNull(value, "An ApplicationContext instance is required");
+ IConfigurableApplicationContext ctx = value as IConfigurableApplicationContext;
+ if (ctx == null)
+ {
+ throw new InvalidOperationException(
+ "Implementations of IApplicationContext must also implement IConfigurableApplicationContext");
+ }
+
+ applicationContext = ctx;
+ }
}
#endregion
@@ -263,12 +276,10 @@ namespace Spring.Messaging.Core
///
public void AfterPropertiesSet()
{
- if (DefaultMessageQueueObjectName == null)
- {
- throw new ArgumentException("DefaultMessageQueueObjectName is required.");
- }
if (MessageQueueFactory == null)
{
+ AssertUtils.ArgumentNotNull(applicationContext, "MessageQueueTemplate requires the ApplicationContext property to be set if the MessageQueueFactory property is not set for automatic create of the DefaultMessageQueueFactory");
+
DefaultMessageQueueFactory mqf = new DefaultMessageQueueFactory();
mqf.ApplicationContext = applicationContext;
messageQueueFactory = mqf;
@@ -278,12 +289,43 @@ namespace Spring.Messaging.Core
messageConverterObjectName = QueueUtils.RegisterDefaultMessageConverter(applicationContext);
}
//If it has not been set by the user explicitly, then initialize.
+ CreateDefaultMetadataCache();
+ }
+
+ protected virtual void CreateDefaultMetadataCache()
+ {
if (metadataCache == null)
{
- metadataCache = new MessageQueueMetadataCache();
- metadataCache.ApplicationContext = ApplicationContext;
- metadataCache.AfterPropertiesSet();
- metadataCache.Initialize();
+ if (applicationContext.ContainsObject(METADATA_CACHE_NAME))
+ {
+ metadataCache = applicationContext.GetObject(METADATA_CACHE_NAME) as MessageQueueMetadataCache;
+ }
+ else
+ {
+ metadataCache = new MessageQueueMetadataCache();
+ if (ApplicationContext != null)
+ {
+ metadataCache.ApplicationContext = ApplicationContext;
+ metadataCache.AfterPropertiesSet();
+ metadataCache.Initialize();
+ applicationContext.ObjectFactory.RegisterSingleton("__MessageQueueMetadataCache__",
+ metadataCache);
+ }
+ else
+ {
+ #region Logging
+
+ if (LOG.IsWarnEnabled)
+ {
+ LOG.Warn(
+ "The ApplicationContext property has not been set, so the MessageQueueMetadataCache can not be automatically generated. " +
+ "Please explictly set the MessageQueueMetadataCache using the property MetadataCache or set the ApplicationContext property. " +
+ "This will only effect the use of MessageQueueTemplate when publishing to remote queues.");
+ }
+
+ #endregion
+ }
+ }
}
}
@@ -500,19 +542,30 @@ namespace Spring.Messaging.Core
protected virtual void DoSendMessageQueue(MessageQueue mq, Message msg)
{
MessageQueueTransaction transactionToUse = QueueUtils.GetMessageQueueTransaction(null);
- MessageQueueMetadata mqMetadata = metadataCache.Get(mq.Path);
- if (mqMetadata != null)
+ if (metadataCache != null)
{
- if (mqMetadata.RemoteQueue)
+ MessageQueueMetadata mqMetadata = metadataCache.Get(mq.Path);
+ if (mqMetadata != null)
{
- if (mqMetadata.RemoteQueueIsTransactional)
+ if (mqMetadata.RemoteQueue)
{
- // DefaultMessageQueue transaction is externally managed.
- DoSendMessageTransaction(mq, transactionToUse, msg);
+ if (mqMetadata.RemoteQueueIsTransactional)
+ {
+ // DefaultMessageQueue transaction is externally managed.
+ DoSendMessageTransaction(mq, transactionToUse, msg);
+ return;
+ }
+ DoSendMessageQueueNonTransactional(mq, transactionToUse, msg);
return;
}
- DoSendMessageQueueNonTransactional(mq, transactionToUse, msg);
- return;
+ }
+ } else
+ {
+ if (LOG.IsWarnEnabled)
+ {
+ LOG.Warn("MetadataCache has not been initialized. Set the MetadataCache explicitly in standalone usage and/or " +
+ "configure the MessageQueueTemplate in an ApplicationContext. If deployed in an ApplicationContext by default " +
+ "the MetadataCache will automaticaly populated.");
}
}
// Handle assuming these are local queues.
diff --git a/src/Spring/Spring.Messaging/Messaging/Listener/AbstractPeekingMessageListenerContainer.cs b/src/Spring/Spring.Messaging/Messaging/Listener/AbstractPeekingMessageListenerContainer.cs
index 874c0c58..9b4ad481 100644
--- a/src/Spring/Spring.Messaging/Messaging/Listener/AbstractPeekingMessageListenerContainer.cs
+++ b/src/Spring/Spring.Messaging/Messaging/Listener/AbstractPeekingMessageListenerContainer.cs
@@ -445,11 +445,10 @@ namespace Spring.Messaging.Listener
/// messageQueue.Receive().
///
/// It allows subclasses to modify the state of the MessageQueue
- /// before receiving which maybe required when using remote queues, for example
- /// to set a MessageFormatter.
+ /// before receiving which maybe required when using remote queues
///
protected virtual void BeforeMessageReceived(MessageQueue messageQueue)
- {
+ {
}
#endregion
diff --git a/src/Spring/Spring.Messaging/Messaging/Listener/MessageListenerAdapter.cs b/src/Spring/Spring.Messaging/Messaging/Listener/MessageListenerAdapter.cs
index 3deec1b2..1057c647 100644
--- a/src/Spring/Spring.Messaging/Messaging/Listener/MessageListenerAdapter.cs
+++ b/src/Spring/Spring.Messaging/Messaging/Listener/MessageListenerAdapter.cs
@@ -230,6 +230,12 @@ namespace Spring.Messaging.Listener
{
messageConverterObjectName = QueueUtils.RegisterDefaultMessageConverter(applicationContext);
}
+ if (messageQueueTemplate == null)
+ {
+ messageQueueTemplate = new MessageQueueTemplate();
+ messageQueueTemplate.ApplicationContext = ApplicationContext;
+ messageQueueTemplate.AfterPropertiesSet();
+ }
}
#endregion
@@ -351,6 +357,18 @@ namespace Spring.Messaging.Listener
}
}
+ ///
+ /// Sets the message queue template.
+ ///
+ /// If not set, will create one for it own internal use whne MessageListenerAdapter is constructed.
+ /// It maybe useful to share an existing instance if you have an extensively configured MessageQueueTemplate.
+ ///
+ /// The message queue template.
+ public MessageQueueTemplate MessageQueueTemplate
+ {
+ set { messageQueueTemplate = value; }
+ }
+
#region IMessageListener Members
///
@@ -395,7 +413,6 @@ namespace Spring.Messaging.Listener
protected virtual void InitDefaultStrategies()
{
processingExpression = Expression.Parse(defaultHandlerMethod + "(#convertedObject)");
- messageQueueTemplate = new MessageQueueTemplate();
}
///
@@ -435,6 +452,10 @@ namespace Spring.Messaging.Listener
protected virtual void SendResponse(MessageQueue destination, Message response)
{
//Will send with appropriate transaction semantics
+ if (logger.IsDebugEnabled)
+ {
+ logger.Debug("Sending response message to path = [" + destination.Path + "]");
+ }
messageQueueTemplate.Send(destination, response);
}
diff --git a/src/Spring/Spring.Messaging/Messaging/Listener/NonTransactionalMessageListenerContainer.cs b/src/Spring/Spring.Messaging/Messaging/Listener/NonTransactionalMessageListenerContainer.cs
index e2501465..34b45139 100644
--- a/src/Spring/Spring.Messaging/Messaging/Listener/NonTransactionalMessageListenerContainer.cs
+++ b/src/Spring/Spring.Messaging/Messaging/Listener/NonTransactionalMessageListenerContainer.cs
@@ -73,7 +73,7 @@ namespace Spring.Messaging.Listener
/// Perform a receive opertion on the message queue and execute the
/// message listener
///
- /// The DefaultMessageQueue.
+ /// The MessageQueue.
///
/// true if received a message, false otherwise
///
@@ -119,7 +119,7 @@ namespace Spring.Messaging.Listener
if (LOG.IsErrorEnabled)
{
- LOG.Error("Error receiving message from DefaultMessageQueue [" + mq.Path +
+ LOG.Error("Error receiving message from MessageQueue [" + mq.Path +
"], closing queue and clearing connection cache.");
}
diff --git a/test/Spring/Spring.Messaging.Tests/Messaging/Core/MessageQueueMetadataCacheTests.cs b/test/Spring/Spring.Messaging.Tests/Messaging/Core/MessageQueueMetadataCacheTests.cs
index 9195d6a2..96dbdefb 100644
--- a/test/Spring/Spring.Messaging.Tests/Messaging/Core/MessageQueueMetadataCacheTests.cs
+++ b/test/Spring/Spring.Messaging.Tests/Messaging/Core/MessageQueueMetadataCacheTests.cs
@@ -36,7 +36,7 @@ namespace Spring.Messaging.Core
{
protected override string[] ConfigLocations
{
- get { return new[] {"assembly://Spring.Messaging.Tests/Spring.Messaging.Core/MessageQueueTemplateTests.xml"}; }
+ get { return new[] {"assembly://Spring.Messaging.Tests/Spring.Messaging.Core/MessageQueueMetadataCacheTests.xml"}; }
}
[Test]
diff --git a/test/Spring/Spring.Messaging.Tests/Messaging/Core/MessageQueueMetadataCacheTests.xml b/test/Spring/Spring.Messaging.Tests/Messaging/Core/MessageQueueMetadataCacheTests.xml
index da7def1c..5108625e 100644
--- a/test/Spring/Spring.Messaging.Tests/Messaging/Core/MessageQueueMetadataCacheTests.xml
+++ b/test/Spring/Spring.Messaging.Tests/Messaging/Core/MessageQueueMetadataCacheTests.xml
@@ -36,14 +36,4 @@
-
-
-
\ No newline at end of file
diff --git a/test/Spring/Spring.Messaging.Tests/Messaging/Core/MessageQueueTemplateTests.cs b/test/Spring/Spring.Messaging.Tests/Messaging/Core/MessageQueueTemplateTests.cs
index 7709d69c..f4bbf830 100644
--- a/test/Spring/Spring.Messaging.Tests/Messaging/Core/MessageQueueTemplateTests.cs
+++ b/test/Spring/Spring.Messaging.Tests/Messaging/Core/MessageQueueTemplateTests.cs
@@ -116,7 +116,7 @@ namespace Spring.Messaging.Core
[Test]
- [ExpectedException(typeof (ArgumentException), ExpectedMessage = "DefaultMessageQueueObjectName is required.")]
+ [ExpectedException(typeof (ArgumentNullException))]
public void NoMessageQueueNameSpecified()
{
MessageQueueTemplate mqt = new MessageQueueTemplate();
diff --git a/test/Spring/Spring.Messaging.Tests/Messaging/Core/MessageQueueTemplateTests.xml b/test/Spring/Spring.Messaging.Tests/Messaging/Core/MessageQueueTemplateTests.xml
index 305a027a..873708c3 100644
--- a/test/Spring/Spring.Messaging.Tests/Messaging/Core/MessageQueueTemplateTests.xml
+++ b/test/Spring/Spring.Messaging.Tests/Messaging/Core/MessageQueueTemplateTests.xml
@@ -34,6 +34,7 @@
+
diff --git a/test/Spring/Spring.Messaging.Tests/Messaging/Listener/DistributedTxMessageListenerContainerTests.xml b/test/Spring/Spring.Messaging.Tests/Messaging/Listener/DistributedTxMessageListenerContainerTests.xml
index 587ceb34..5de74533 100644
--- a/test/Spring/Spring.Messaging.Tests/Messaging/Listener/DistributedTxMessageListenerContainerTests.xml
+++ b/test/Spring/Spring.Messaging.Tests/Messaging/Listener/DistributedTxMessageListenerContainerTests.xml
@@ -77,7 +77,7 @@
-
+
diff --git a/test/Spring/Spring.Messaging.Tests/Messaging/Listener/NonTransactionalMessageListenerContainerTests.cs b/test/Spring/Spring.Messaging.Tests/Messaging/Listener/NonTransactionalMessageListenerContainerTests.cs
index 11269512..1db7ce59 100644
--- a/test/Spring/Spring.Messaging.Tests/Messaging/Listener/NonTransactionalMessageListenerContainerTests.cs
+++ b/test/Spring/Spring.Messaging.Tests/Messaging/Listener/NonTransactionalMessageListenerContainerTests.cs
@@ -84,19 +84,20 @@ namespace Spring.Messaging.Listener
[Test]
public void SendAndAsyncReceive()
{
+
//MessageQueueTemplate q = applicationContext["testQueueTemplate"] as MessageQueueTemplate;
+
MessageQueueTemplate q = applicationContext["testRemoteTemplate"] as MessageQueueTemplate;
Assert.IsNotNull(q);
-
- /*
+
q.ConvertAndSend("Hello World 1");
q.ConvertAndSend("Hello World 2");
q.ConvertAndSend("Hello World 3");
q.ConvertAndSend("Hello World 4");
q.ConvertAndSend("Hello World 5");
- */
-
+
+
Assert.AreEqual(0, listener.MessageCount);
container.Start();
@@ -107,7 +108,7 @@ namespace Spring.Messaging.Listener
container.Stop();
container.Shutdown();
- Thread.Sleep(2500);
+ Thread.Sleep(2500);
}
diff --git a/test/Spring/Spring.Messaging.Tests/Messaging/Listener/NonTransactionalMessageListenerContainerTests.xml b/test/Spring/Spring.Messaging.Tests/Messaging/Listener/NonTransactionalMessageListenerContainerTests.xml
index cbe1fc27..b6b88940 100644
--- a/test/Spring/Spring.Messaging.Tests/Messaging/Listener/NonTransactionalMessageListenerContainerTests.xml
+++ b/test/Spring/Spring.Messaging.Tests/Messaging/Listener/NonTransactionalMessageListenerContainerTests.xml
@@ -40,34 +40,45 @@
-
+
-
+
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
diff --git a/test/Spring/Spring.Messaging.Tests/Messaging/Listener/SimpleExceptionHandler.cs b/test/Spring/Spring.Messaging.Tests/Messaging/Listener/SimpleExceptionHandler.cs
index 9dc3cf41..06a795b8 100644
--- a/test/Spring/Spring.Messaging.Tests/Messaging/Listener/SimpleExceptionHandler.cs
+++ b/test/Spring/Spring.Messaging.Tests/Messaging/Listener/SimpleExceptionHandler.cs
@@ -28,6 +28,7 @@ namespace Spring.Messaging.Listener
public void OnException(Exception exception, Message message)
{
LOG.Error("Exception Handler processing message id = [" + message.Id + "]");
+ LOG.Error("Exception = ", exception);
messageCount++;
}