diff --git a/doc/reference/src/index.xml b/doc/reference/src/index.xml
index 8c7df74c..1312c3c1 100644
--- a/doc/reference/src/index.xml
+++ b/doc/reference/src/index.xml
@@ -43,7 +43,7 @@
-
+
@@ -381,9 +381,9 @@
-
+
@@ -398,7 +398,7 @@
&tx-quickstart;
&quartz-quickstart;
&nms-quickstart;
-
+ &msmq-quickstart;
&wcf-quickstart;
diff --git a/doc/reference/src/msmq-quickstart.xml b/doc/reference/src/msmq-quickstart.xml
index 7211b3bc..60b3a6d1 100644
--- a/doc/reference/src/msmq-quickstart.xml
+++ b/doc/reference/src/msmq-quickstart.xml
@@ -1,5 +1,22 @@
-
+
+MSMQ QuickStart
@@ -8,7 +25,7 @@
The MSMQ quick start application demonstrates how to use
asynchronous messaging to implement a system for purchasing a stock. Is
follows the same basic approach as in the NMS QuickStart but is adapted as need for
+ linkend="nms-quickstart">NMS QuickStart but is adapted as need for
use with MSMQ. Please read the introduction in that chapter to get an
overview of the system.
@@ -23,11 +40,11 @@
To communicate between th client and server a pair of queues will be
used. Messages sent from the client to the server will use the
transactional queue named
- .\Private$\request.txqueue. Messages sent from the
+ .\Private$\request.txqueue. Messages sent from the
server to the client will use the transactional queue
- .\Private$\response.joe.txqueue. The queue for
+ .\Private$\response.joe.txqueue. The queue for
messages that cannot be processed, so called 'poison messages' will be
- sent to the queue .\Private$\dead.queue. You can
+ sent to the queue .\Private$\dead.queue. You can
create these queues using the computer management administration console.
Private queues are used to simplify the application setup
requirements.
@@ -80,55 +97,55 @@
configuration example for types generated from the XML Schema and a plain
string.
- <object id="xmlMessageConverter" type="Spring.Messaging.Support.Converters.XmlMessageConverter, Spring.Messaging">
- <property name="TargetTypes">
- <list>
- <value>Spring.MsmqQuickStart.Common.Data.TradeRequest, Spring.MsmqQuickStart.Common</value>
- <value>Spring.MsmqQuickStart.Common.Data.TradeResponse, Spring.MsmqQuickStart.Common</value>
- <value>System.String, mscorlib</value>
- </list>
- </property>
- </object>
+ <object id="xmlMessageConverter" type="Spring.Messaging.Support.Converters.XmlMessageConverter, Spring.Messaging">
+ <property name="TargetTypes">
+ <list>
+ <value>Spring.MsmqQuickStart.Common.Data.TradeRequest, Spring.MsmqQuickStart.Common</value>
+ <value>Spring.MsmqQuickStart.Common.Data.TradeResponse, Spring.MsmqQuickStart.Common</value>
+ <value>System.String, mscorlib</value>
+ </list>
+ </property>
+</object>Messaging InfrastructureThe implementations of the gateway interfaces inherit from Spring's
- helper class MessageQueueGatewaySupport in order to
- get easy access to a MessageQueueTemplate for
- sending. The implementation of the IStockService
+ helper class MessageQueueGatewaySupport in order to
+ get easy access to a MessageQueueTemplate for
+ sending. The implementation of the IStockService
interface is shown below
- public class MsmqStockServiceGateway : MessageQueueGatewaySupport, IStockService
+ public class MsmqStockServiceGateway : MessageQueueGatewaySupport, IStockService
+{
+ private Random random = new Random();
+
+ private string defaultResponseQueueObjectName;
+
+ public string DefaultResponseQueueObjectName
{
- private Random random = new Random();
+ set { defaultResponseQueueObjectName = value; }
+ }
- private string defaultResponseQueueObjectName;
+ public void Send(TradeRequest tradeRequest)
+ {
+ MessageQueueTemplate.ConvertAndSend(tradeRequest, delegate(Message message)
+ {
+ message.ResponseQueue = GetResponseQueue();
+ message.AppSpecific = random.Next();
+ return message;
+ });
+ }
+
+ private MessageQueue GetResponseQueue()
+ {
+ return MessageQueueFactory.CreateMessageQueue(defaultResponseQueueObjectName);
+ }
+
+}
- public string DefaultResponseQueueObjectName
- {
- set { defaultResponseQueueObjectName = value; }
- }
-
- public void Send(TradeRequest tradeRequest)
- {
- MessageQueueTemplate.ConvertAndSend(tradeRequest, delegate(Message message)
- {
- message.ResponseQueue = GetResponseQueue();
- message.AppSpecific = random.Next();
- return message;
- });
- }
-
- private MessageQueue GetResponseQueue()
- {
- return MessageQueueFactory.CreateMessageQueue(defaultResponseQueueObjectName);
- }
-
- }
-
- The Send method is using
+ The Send method is using
MessageQueueTemplate's ConvertAndSend(object obj,
MessagePostProcessorDelegate messagePostProcessorDelegate)
method. The anonymous delegate allows you to modify the message
@@ -137,85 +154,83 @@
anonymous delegate allows makes it very easy to apply any post processing
logic to the converted message.
- The configuration for MsmqStockServiceGateway
+ The configuration for MsmqStockServiceGateway
and all its dependencies is shown below, highlighting important dependency
links.
- <object name="stockServiceGateway" type="Spring.MsmqQuickStart.Client.Gateways.MsmqStockServiceGateway, Spring.MsmqQuickStart.Client">
- <property name="MessageQueueTemplate" ref="messageQueueTemplate"/>
- <property name="DefaultResponseQueueObjectName" value="responseTxQueue"/>
- </object>
+ <object name="stockServiceGateway" type="Spring.MsmqQuickStart.Client.Gateways.MsmqStockServiceGateway, Spring.MsmqQuickStart.Client">
+ <property name="MessageQueueTemplate" ref="messageQueueTemplate"/>
+ <property name="DefaultResponseQueueObjectName" value="responseTxQueue"/>
+</object>
- <object id="messageQueueTemplate" type="Spring.Messaging.Core.MessageQueueTemplate, Spring.Messaging">
- <property name="DefaultMessageQueueObjectName" value="requestTxQueue"/>
- <property name="MessageConverterObjectName" value="xmlMessageConverter"/>
- </object>
+<object id="messageQueueTemplate" type="Spring.Messaging.Core.MessageQueueTemplate, Spring.Messaging">
+ <property name="DefaultMessageQueueObjectName" value="requestTxQueue"/>
+ <property name="MessageConverterObjectName" value="xmlMessageConverter"/>
+</object>
- <object id="xmlMessageConverter" type="Spring.Messaging.Support.Converters.XmlMessageConverter, Spring.Messaging">
- <property name="TargetTypes">
- <list>
- <value>Spring.MsmqQuickStart.Common.Data.TradeRequest, Spring.MsmqQuickStart.Common</value>
- <value>Spring.MsmqQuickStart.Common.Data.TradeResponse, Spring.MsmqQuickStart.Common</value>
- <value>System.String, mscorlib</value>
- </list>
- </property>
- </object>
+<object id="xmlMessageConverter" type="Spring.Messaging.Support.Converters.XmlMessageConverter, Spring.Messaging">
+ <property name="TargetTypes">
+ <list>
+ <value>Spring.MsmqQuickStart.Common.Data.TradeRequest, Spring.MsmqQuickStart.Common</value>
+ <value>Spring.MsmqQuickStart.Common.Data.TradeResponse, Spring.MsmqQuickStart.Common</value>
+ <value>System.String, mscorlib</value>
+ </list>
+ </property>
+</object>
- <object id="requestTxQueue" type="Spring.Messaging.Support.MessageQueueFactoryObject, Spring.Messaging">
- <property name="Path" value=".\Private$\request.txqueue"/>
- <property name="MessageReadPropertyFilterSetAll" value="true"/>
- </object>
+<object id="requestTxQueue" type="Spring.Messaging.Support.MessageQueueFactoryObject, Spring.Messaging">
+ <property name="Path" value=".\Private$\request.txqueue"/>
+ <property name="MessageReadPropertyFilterSetAll" value="true"/>
+</object>
- <object id="responseTxQueue" type="Spring.Messaging.Support.MessageQueueFactoryObject, Spring.Messaging">
- <property name="Path" value=".\Private$\response.joe.txqueue"/>
- <property name="MessageReadPropertyFilterSetAll" value="true"/>
- </object>
+<object id="responseTxQueue" type="Spring.Messaging.Support.MessageQueueFactoryObject, Spring.Messaging">
+ <property name="Path" value=".\Private$\response.joe.txqueue"/>
+ <property name="MessageReadPropertyFilterSetAll" value="true"/>
+</object>Since the client also needs to listen to incoming messages on the
responseTxQueue, a
- TransactionalMessageListenerContainer is
+ TransactionalMessageListenerContainer is
configured. The configuration for the message listener container and all
its dependencies is shown below, highlighting important dependency
links.
- <!-- MSMQ Transaction Manager -->
- <object id="messageQueueTransactionManager" type="Spring.Messaging.Core.MessageQueueTransactionManager, Spring.Messaging"/>
+ <!-- MSMQ Transaction Manager -->
+<object id="messageQueueTransactionManager" type="Spring.Messaging.Core.MessageQueueTransactionManager, Spring.Messaging"/>
- <!-- Message Listener Container that uses MSMQ transactional for receives -->
- <object id="transactionalMessageListenerContainer" type="Spring.Messaging.Listener.TransactionalMessageListenerContainer, Spring.Messaging">
- <property name="MessageQueueObjectName" value="responseTxQueue"/>
- <property name="PlatformTransactionManager" ref="messageQueueTransactionManager"/>
- <property name="MessageListener" ref="messageListenerAdapter"/>
- <property name="MessageTransactionExceptionHandler" ref="sendToQueueExceptionHandler"/>
+<!-- Message Listener Container that uses MSMQ transactional for receives -->
+<object id="transactionalMessageListenerContainer" type="Spring.Messaging.Listener.TransactionalMessageListenerContainer, Spring.Messaging">
+ <property name="MessageQueueObjectName" value="responseTxQueue"/>
+ <property name="PlatformTransactionManager" ref="messageQueueTransactionManager"/>
+ <property name="MessageListener" ref="messageListenerAdapter"/>
+ <property name="MessageTransactionExceptionHandler" ref="sendToQueueExceptionHandler"/>
- </object>
+</object>
- <!-- Delegate to plain .NET object for message handling -->
- <object id="messageListenerAdapter" type="Spring.Messaging.Listener.MessageListenerAdapter, Spring.Messaging">
- <property name="HandlerObject" ref="stockAppHandler"/>
- <property name="DefaultHandlerMethod" value="Handle"/>
- <property name="MessageConverterObjectName" value="xmlMessageConverter"/>
- </object>
+<!-- Delegate to plain .NET object for message handling -->
+<object id="messageListenerAdapter" type="Spring.Messaging.Listener.MessageListenerAdapter, Spring.Messaging">
+ <property name="HandlerObject" ref="stockAppHandler"/>
+ <property name="DefaultHandlerMethod" value="Handle"/>
+ <property name="MessageConverterObjectName" value="xmlMessageConverter"/>
+</object>
- <object id="sendToQueueExceptionHandler" type="Spring.Messaging.Listener.SendToQueueExceptionHandler, Spring.Messaging">
- <property name="MessageQueueObjectName" value="deadTxQueue"/>
- </object>
+<object id="sendToQueueExceptionHandler" type="Spring.Messaging.Listener.SendToQueueExceptionHandler, Spring.Messaging">
+ <property name="MessageQueueObjectName" value="deadTxQueue"/>
+</object>
- <object id="deadTxQueue" type="Spring.Messaging.Support.MessageQueueFactoryObject, Spring.Messaging">
- <property name="Path" value=".\Private$\dead.queue"/>
- <property name="MessageReadPropertyFilterSetAll" value="true"/>
- </object>
+<object id="deadTxQueue" type="Spring.Messaging.Support.MessageQueueFactoryObject, Spring.Messaging">
+ <property name="Path" value=".\Private$\dead.queue"/>
+ <property name="MessageReadPropertyFilterSetAll" value="true"/>
+</object>A similar configuration is used on the server to configure the class
- Spring.MsmqQuickStart.Server.Gateways.MarketDataServiceGateway
- that implements the IMarketDataService
+ Spring.MsmqQuickStart.Server.Gateways.MarketDataServiceGateway
+ that implements the IMarketDataService
interface and a
- TransactionalMessageListenerContainer to process
+ TransactionalMessageListenerContainer to process
messages on the requestTxQueue. You can increase the number of processing
- thread in the TransactionalMessageListenerContainer
- by setting the property MaxConcurrentListeners, the
+ thread in the TransactionalMessageListenerContainer
+ by setting the property MaxConcurrentListeners, the
default value is 1.