diff --git a/doc/reference/src/ems-quickstart.xml b/doc/reference/src/ems-quickstart.xml new file mode 100644 index 00000000..1bf0c162 --- /dev/null +++ b/doc/reference/src/ems-quickstart.xml @@ -0,0 +1,213 @@ + + + + TIBCO EMS QuickStart + +
+ Introduction + + The TIBCO EMS quick start application demonstrates how to use + asynchronous messaging to implement a system for purchasing a stock. To + purchase a stock, a client application will send a stock request message + containing the information about the stock, i.e. ticker symbol, quantity, + etc. The client request message will be received by the server where it + will perform business processing on the request, for example to determine + if the user has sufficient credit to purchase the stock or if the user is + even allowed to make the purchase due to existing account restrictions. + These are typically external processes as well. Usually the server + application will persist state about the request and forward it on to an + execute venue where the actual execution of the stock request is + performed. In addition, market data for the stock will be sent from the + server process to the client. The high level exchange of information is + shown below. + + + + + + + + + To follow this EMS QuickStart load the solution file found in the + directory + <spring-install-dir>\examples\Spring\Spring.EmsQuickStart + +
+ +
+ Message Destinations + + To implement this flow using messaging the following queues and + topics will be used. All requests from the client to the server will be + sent on the queue named APP.STOCK.REQUEST. Responses to the requests will + be sent from the server to the client on a queue unique to each client. In + this example the queue name is of the form APP.STOCK.<UserName>, and + more specifically is configured to be APP.STOCK.JOE. Market data does not + need to be delivered to an individual client as many client applications + are interested in this shared information. As such, the server will send + market data information on a topic named APP.STOCK.MARKETDATA. The + messaging communication between the server and the execution venue is not + included as part of the application. An local implementation of the + service interface that represents the execution venue is used instead of + one based on messaging or another middleware technology. The messaging + flow showing the queues and topics used is shown below. + + + + + + + + Queues are shown in red and topics in green. +
+ +
+ Messaging Infrastructure + + Much of this application mirrors the quickstart that is available + with ActiveMQ and you should refer to the NMS QuickStart for the + description on how the application in structured in terms of Gateway, + Message Data formats, Message Handler, and Message Converters. What this + section describeds are the specific configuration related to using TIBCO + EMS. + + The implementations of the gateway interfaces inherit from Spring's + helper class EmsGatewaySupport in order to get easy + access to a EmsTemplate for sending. The + implementation of the IStockService interface is shown + below + + public class EmsStockServiceGateway : EmsGatewaySupport, IStockService + { + private Destination defaultReplyToQueue; + + public Destination DefaultReplyToQueue + { + set { defaultReplyToQueue = value; } + } + + public void Send(TradeRequest tradeRequest) + { + EmsTemplate.ConvertAndSendWithDelegate(tradeRequest, delegate(Message message) + { + message.ReplyTo = defaultReplyToQueue; + message.CorrelationID = new Guid().ToString(); + return message; + }); + } + } + + The Send method is using EmsTemplate's + ConvertAndSendWithDelegate(object obj, + MessagePostProcessorDelegate messagePostProcessorDelegate) + method. The anonymous delegate allows you to modify the message + properties, such as ReplyTo and CorrelationID after the message has been + converted from an object but before it has been sent. The use of an + anonymous delegate allows makes it very easy to apply any post processing + logic to the converted message. + + The object definition for the + EmsStockServiceGateway is shown below along with its + dependent object definitions of EmsTemplate and the + ConnectionFactory. + + <object id="ConnectionFactory" type="Spring.Messaging.Ems.Common.EmsConnectionFactory, Spring.Messaging.Ems"> + <constructor-arg index="0" value="tcp://localhost:7222"/> + </object> + + <!-- EMS based implementation of technology neutral IStockServiceGateway --> + <object name="StockServiceGateway" type="Spring.EmsQuickStart.Client.Gateways.EmsStockServiceGateway, Spring.EmsQuickStart.Client"> + <property name="EmsTemplate" ref="EmsTemplate"/> + <property name="DefaultReplyToQueue"> + <object type="TIBCO.EMS.Queue, TIBCO.EMS"> + <constructor-arg value="APP.STOCK.JOE"/> + </object> + </property> + </object> + + + <object name="EmsTemplate" type="Spring.Messaging.Ems.Core.EmsTemplate, Spring.Messaging.Ems"> + <property name="ConnectionFactory" ref="ConnectionFactory"/> + <property name="DefaultDestinationName" value="APP.STOCK.REQUEST"/> + <property name="MessageConverter" ref="XmlMessageConverter"/> + </object>In this example the + Spring.Messaging.Ems.Common.EmsConnectionFactory + connection factory was used. It would be more efficient resource + wise to use Spring's CachingConnectionFactory wrapper + class so that connections will not be open and closed for each message + send as well as allowing for the caching of other intermediate EMS API + objects such as sessions and message producers. + + A similar configuration is used on the server to configure the class + Spring.EmsQuickStart.Server.Gateways.MarketDataServiceGateway + that implements the IMarketDataService + interface. + + Since the client is also a consumer of messages, on the topic + APP.STOCK.MARKETDATA and the queue APP.STOCK.JOE (for Trader Joe!), two + message listener containers are defined as shown below. + + <ems:listener-container connection-factory="ConnectionFactory"> + <ems:listener ref="MessageListenerAdapter" destination="APP.STOCK.JOE" /> + <ems:listener ref="MessageListenerAdapter" destination="APP.STOCK.MARKETDATA" pubsub-domain="true"/> + </ems:listener-container> + + Refer to the messages reference + docs for all the available attributes to configure the container + and also the section on registering the EMS schema + with Spring.. + + On the server we define a message listener container for the queue + APP.STOCK.REQUEST but set the concurrency property to 10 so that 10 + threads will be consuming messages from the queue. + + <ems:listener-container connection-factory="ConnectionFactory" concurrency="10"> + <ems:listener ref="MessageListenerAdapter" destination="APP.STOCK.REQUEST" /> + </ems:listener-container> +
+ +
+ Running the application + + To run both the client and server make sure that you select + 'Multiple Startup Projects' within VS.NET. The GUI has a button to make a + hardcoded trade request and show confirmation in a text box. A text area + is used to display the market data. There is a 'Get Portfolio' button that + is not implemented at the moment. A picture of the GUI after it has been + running for a while and trade has been sent and responded to is shown + below + + + + + + + + +
+