misc updates for quick start application
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
|
||||
<!-- MVC objects -->
|
||||
<object id="StockController" type="Spring.NmsQuickStart.Client.UI.StockController, Spring.NmsQuickStart.Client">
|
||||
<property name="StockServiceGateway" ref="StockServiceGateway"/>
|
||||
<property name="StockService" ref="StockServiceGateway"/>
|
||||
</object>
|
||||
|
||||
<object name="StockAppHandler" type="Spring.NmsQuickStart.Client.Handlers.StockAppHandler, Spring.NmsQuickStart.Client">
|
||||
|
||||
@@ -24,23 +24,13 @@
|
||||
<property name="MessageConverter" ref="XmlMessageConverter"/>
|
||||
</object>
|
||||
|
||||
<!-- Consume messages on queue APP.STOCK.JOE -->
|
||||
<object id="MessagingContainer" type="Spring.Messaging.Nms.Listener.SimpleMessageListenerContainer, Spring.Messaging.Nms">
|
||||
<property name="ConnectionFactory" ref="ConnectionFactory"/>
|
||||
<property name="DestinationName" value="APP.STOCK.JOE"/>
|
||||
<property name="ConcurrentConsumers" value="1"/>
|
||||
<property name="MessageListener" ref="MessageListenerAdapter"/>
|
||||
</object>
|
||||
|
||||
<!-- Consume messages on topic APP.STOCK.MARKETDATA -->
|
||||
<object id="MessagingContainerMarketData" type="Spring.Messaging.Nms.Listener.SimpleMessageListenerContainer, Spring.Messaging.Nms">
|
||||
<property name="ConnectionFactory" ref="ConnectionFactory"/>
|
||||
<property name="PubSubDomain" value="true"/>
|
||||
<property name="DestinationName" value="APP.STOCK.MARKETDATA"/>
|
||||
<property name="ConcurrentConsumers" value="1"/>
|
||||
<property name="MessageListener" ref="MessageListenerAdapter"/>
|
||||
</object>
|
||||
<nms:listener-container connection-factory="ConnectionFactory">
|
||||
<nms:listener ref="MessageListenerAdapter" destination="APP.STOCK.JOE" />
|
||||
<nms:listener ref="MessageListenerAdapter" destination="APP.STOCK.MARKETDATA" pubsub-domain="true"/>
|
||||
</nms:listener-container>
|
||||
|
||||
|
||||
<!-- Plain object message handler -->
|
||||
<object id="MessageListenerAdapter" type="Spring.Messaging.Nms.Listener.Adapter.MessageListenerAdapter, Spring.Messaging.Nms">
|
||||
<property name="HandlerObject" ref="StockAppHandler"/>
|
||||
@@ -60,20 +50,5 @@
|
||||
<property name="DefaultAssemblyName" value="Spring.NmsQuickStart.Common"/>
|
||||
</object>
|
||||
|
||||
<!--
|
||||
<object name="MultiMessageConverter" type="Spring.NmsQuickStart.Common.Converters.MultiMessageConverter, Spring.NmsQuickStart.Common">
|
||||
<property name="NamedMessageConverters">
|
||||
<list>
|
||||
<ref object="TradeRequestConverter"/>
|
||||
<ref object="TradeConverter"/>
|
||||
</list>
|
||||
</property>
|
||||
</object>
|
||||
|
||||
<object name="TradeRequestConverter" type="Spring.NmsQuickStart.Common.Converters.TradeRequestConverter, Spring.NmsQuickStart.Common"/>
|
||||
<object name="TradeConverter" type="Spring.NmsQuickStart.Common.Converters.TradeConverter, Spring.NmsQuickStart.Common"/>
|
||||
-->
|
||||
|
||||
|
||||
|
||||
</objects>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
|
||||
|
||||
using System;
|
||||
using Apache.NMS;
|
||||
using Spring.Messaging.Nms.Core;
|
||||
using Spring.NmsQuickStart.Common.Data;
|
||||
@@ -8,7 +9,7 @@ using Spring.Objects.Factory;
|
||||
|
||||
namespace Spring.NmsQuickStart.Client.Gateways
|
||||
{
|
||||
public class NmsStockServiceGateway : NmsGatewaySupport, IStockService, IInitializingObject
|
||||
public class NmsStockServiceGateway : NmsGatewaySupport, IStockService
|
||||
{
|
||||
private IDestination defaultReplyToQueue;
|
||||
|
||||
@@ -19,25 +20,12 @@ namespace Spring.NmsQuickStart.Client.Gateways
|
||||
|
||||
public void Send(TradeRequest tradeRequest)
|
||||
{
|
||||
NmsTemplate.ConvertAndSend(tradeRequest, new ReplyToPostProcessor(defaultReplyToQueue));
|
||||
}
|
||||
|
||||
|
||||
public class ReplyToPostProcessor : IMessagePostProcessor
|
||||
{
|
||||
private IDestination replyToDestination;
|
||||
|
||||
public ReplyToPostProcessor(IDestination replyToDestination)
|
||||
{
|
||||
this.replyToDestination = replyToDestination;
|
||||
}
|
||||
|
||||
public IMessage PostProcessMessage(IMessage message)
|
||||
{
|
||||
message.NMSReplyTo = replyToDestination;
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
NmsTemplate.ConvertAndSendWithDelegate(tradeRequest, delegate(IMessage message)
|
||||
{
|
||||
message.NMSReplyTo = defaultReplyToQueue;
|
||||
message.NMSCorrelationID = new Guid().ToString();
|
||||
return message;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,8 @@ namespace Spring.NmsQuickStart.Common.Data {
|
||||
|
||||
private string orderTypeField;
|
||||
|
||||
private string confirmationNumberField;
|
||||
|
||||
private bool errorField;
|
||||
|
||||
private string errorMessageField;
|
||||
@@ -76,6 +78,16 @@ namespace Spring.NmsQuickStart.Common.Data {
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
public string ConfirmationNumber {
|
||||
get {
|
||||
return this.confirmationNumberField;
|
||||
}
|
||||
set {
|
||||
this.confirmationNumberField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
public bool Error {
|
||||
get {
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<xs:element name="Quantity" type="xs:long"/>
|
||||
<xs:element name="Price" type="xs:decimal"/>
|
||||
<xs:element name="OrderType" type="xs:string"/>
|
||||
<xs:element name="ConfirmationNumber" type="xs:string"/>
|
||||
<xs:element name="Error" type="xs:boolean"/>
|
||||
<xs:element name="ErrorMessage" type="xs:string"/>
|
||||
</xs:sequence>
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
|
||||
<context>
|
||||
<resource uri="~/Config/Messaging.xml"/>
|
||||
<resource uri="~/Config/Services.xml"/>
|
||||
<resource uri="~/Config/Handlers.xml"/>
|
||||
<resource uri="~/Config/ServiceStubs.xml"/>
|
||||
</context>
|
||||
|
||||
<parsers>
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
<objects xmlns="http://www.springframework.net">
|
||||
|
||||
<object name="StockAppHandler" type="Spring.NmsQuickStart.Server.Handlers.StockAppHandler, Spring.NmsQuickStart.Server">
|
||||
|
||||
<constructor-arg ref="CreditCheckService"/>
|
||||
<constructor-arg ref="ExecutionVenueService"/>
|
||||
<constructor-arg ref="TradingService"/>
|
||||
</object>
|
||||
|
||||
|
||||
</objects>
|
||||
@@ -6,8 +6,6 @@
|
||||
<constructor-arg index="0" value="tcp://localhost:61616"/>
|
||||
</object>
|
||||
|
||||
|
||||
|
||||
<object name="NmsTemplate" type="Spring.Messaging.Nms.Core.NmsTemplate, Spring.Messaging.Nms">
|
||||
<property name="ConnectionFactory" ref="ConnectionFactory"/>
|
||||
<property name="PubSubDomain" value="true"/>
|
||||
@@ -16,28 +14,15 @@
|
||||
</object>
|
||||
|
||||
|
||||
<object name="MarketDataGateway" type="Spring.NmsQuickStart.Server.Gateways.MarketDataGateway, Spring.NmsQuickStart.Server">
|
||||
<object name="MarketDataGateway" type="Spring.NmsQuickStart.Server.Gateways.MarketDataServiceGateway, Spring.NmsQuickStart.Server">
|
||||
<property name="NmsTemplate" ref="NmsTemplate"/>
|
||||
</object>
|
||||
|
||||
<!-- Consume messages on queue APP.STOCK.REQUEST -->
|
||||
<!--
|
||||
<nms:listener-container connection-factory="ConnectionFactory" concurrency="10">
|
||||
<nms:listener ref="MessageListenerAdapter" destination="APP.STOCK.REQUEST" />
|
||||
</nms:listener-container>
|
||||
-->
|
||||
|
||||
<object id="MessageListenerContainer" type="Spring.Messaging.Nms.Listener.SimpleMessageListenerContainer, Spring.Messaging.Nms">
|
||||
<property name="ConnectionFactory" ref="ConnectionFactory"/>
|
||||
<property name="DestinationName" value="APP.STOCK.REQUEST"/>
|
||||
<property name="ConcurrentConsumers" value="1"/>
|
||||
<property name="MessageListener" ref="MessageListenerAdapter"/>
|
||||
<property name="ExceptionListener" ref="LoggingExceptionListener"/>
|
||||
</object>
|
||||
|
||||
<object name="LoggingExceptionListener" type="Spring.NmsQuickStart.Server.Handlers.LoggingExceptionListener, Spring.NmsQuickStart.Server"/>
|
||||
|
||||
|
||||
|
||||
<!-- Plain object message handler -->
|
||||
<object id="MessageListenerAdapter" type="Spring.Messaging.Nms.Listener.Adapter.MessageListenerAdapter, Spring.Messaging.Nms">
|
||||
<property name="HandlerObject" ref="StockAppHandler"/>
|
||||
@@ -57,19 +42,4 @@
|
||||
<property name="DefaultAssemblyName" value="Spring.NmsQuickStart.Common"/>
|
||||
</object>
|
||||
|
||||
<!--
|
||||
<object name="MultiMessageConverter" type="Spring.NmsQuickStart.Common.Converters.MultiMessageConverter, Spring.NmsQuickStart.Common">
|
||||
<property name="NamedMessageConverters">
|
||||
<list>
|
||||
<ref object="TradeRequestConverter"/>
|
||||
<ref object="TradeConverter"/>
|
||||
</list>
|
||||
</property>
|
||||
</object>
|
||||
|
||||
<object name="TradeRequestConverter" type="Spring.NmsQuickStart.Common.Converters.TradeRequestConverter, Spring.NmsQuickStart.Common"/>
|
||||
<object name="TradeConverter" type="Spring.NmsQuickStart.Common.Converters.TradeConverter, Spring.NmsQuickStart.Common"/>
|
||||
-->
|
||||
|
||||
|
||||
</objects>
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net">
|
||||
|
||||
<object name="CreditCheckService" type="Spring.NmsQuickStart.Server.Services.Stubs.CreditCheckServiceStub, Spring.NmsQuickStart.Server"/>
|
||||
|
||||
<object name="ExecutionVenueService" type="Spring.NmsQuickStart.Server.Services.Stubs.ExecutionVenueServiceStub, Spring.NmsQuickStart.Server"/>
|
||||
|
||||
<object name="TradingService" type="Spring.NmsQuickStart.Server.Services.Stubs.TradingServiceStub, Spring.NmsQuickStart.Server"/>
|
||||
|
||||
</objects>
|
||||
@@ -11,7 +11,7 @@ namespace Spring.NmsQuickStart.Server.Gateways
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof (MarketDataServiceGateway));
|
||||
|
||||
private readonly Random random;
|
||||
private int sleepTimeInSeconds = 2;
|
||||
private TimeSpan sleepTimeInSeconds = new TimeSpan(0,0,0,10,0);
|
||||
|
||||
|
||||
public MarketDataServiceGateway()
|
||||
@@ -19,7 +19,7 @@ namespace Spring.NmsQuickStart.Server.Gateways
|
||||
random = new Random();
|
||||
}
|
||||
|
||||
public int SleepTimeInSeconds
|
||||
public TimeSpan SleepTimeInSeconds
|
||||
{
|
||||
set { sleepTimeInSeconds = value; }
|
||||
}
|
||||
@@ -32,15 +32,15 @@ namespace Spring.NmsQuickStart.Server.Gateways
|
||||
log.Info("Sending market data.");
|
||||
NmsTemplate.ConvertAndSend(data);
|
||||
log.Info("Sleeping " + sleepTimeInSeconds + " seconds before sending more market data.");
|
||||
Thread.Sleep(sleepTimeInSeconds*1000);
|
||||
Thread.Sleep(sleepTimeInSeconds);
|
||||
}
|
||||
}
|
||||
|
||||
private IDictionary GenerateFakeMarketData()
|
||||
{
|
||||
IDictionary md = new Hashtable();
|
||||
md.Add("TICKER", "CSCO");
|
||||
md.Add("PRICE", "22" + string.Format("{0:#.###}", Math.Abs(Gaussian())));
|
||||
md.Add("TICKER", "CSCO");
|
||||
md.Add("PRICE", string.Format("{0:##.##}", 22+Math.Abs(Gaussian())));
|
||||
return md;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
|
||||
|
||||
using System.Collections;
|
||||
using Common.Logging;
|
||||
using Spring.NmsQuickStart.Common.Data;
|
||||
using Spring.NmsQuickStart.Server.Services;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.NmsQuickStart.Server.Handlers
|
||||
{
|
||||
@@ -14,22 +14,30 @@ namespace Spring.NmsQuickStart.Server.Handlers
|
||||
private ICreditCheckService creditCheckService;
|
||||
|
||||
private ITradingService tradingService;
|
||||
|
||||
|
||||
public StockAppHandler(IExecutionVenueService executionVenueService, ICreditCheckService creditCheckService, ITradingService tradingService)
|
||||
{
|
||||
this.executionVenueService = executionVenueService;
|
||||
this.creditCheckService = creditCheckService;
|
||||
this.tradingService = tradingService;
|
||||
}
|
||||
|
||||
public TradeResponse Handle(TradeRequest tradeRequest)
|
||||
{
|
||||
TradeResponse tradeResponse;
|
||||
IList errors = new ArrayList();
|
||||
ArrayList errors = new ArrayList();
|
||||
if (creditCheckService.CanExecute(tradeRequest, errors))
|
||||
{
|
||||
tradeResponse = executionVenueService.ExecuteTradeRequest(tradeRequest);
|
||||
tradingService.ProcessTrade(tradeRequest, tradeResponse);
|
||||
}
|
||||
else
|
||||
{
|
||||
tradeResponse = new TradeResponse();
|
||||
tradeResponse.Error = true;
|
||||
tradeResponse.ErrorMessage = errors[0].ToString();
|
||||
tradeResponse.ErrorMessage = StringUtils.ArrayToCommaDelimitedString(errors.ToArray());
|
||||
|
||||
}
|
||||
tradingService.ProcessTrade(tradeRequest, tradeResponse);
|
||||
return tradeResponse;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Spring.NmsQuickStart.Server
|
||||
ContextRegistry.GetContext().GetObject("MarketDataGateway") as MarketDataServiceGateway;
|
||||
ThreadStart job = new ThreadStart(marketDataService.SendMarketData);
|
||||
Thread thread = new Thread(job);
|
||||
//thread.Start();
|
||||
thread.Start();
|
||||
Console.Out.WriteLine("--- Press <return> to quit ---");
|
||||
Console.ReadLine();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
|
||||
|
||||
using System.Collections;
|
||||
using Spring.NmsQuickStart.Common.Data;
|
||||
using Spring.NmsQuickStart.Server.Services;
|
||||
|
||||
namespace Spring.NmsQuickStart.Server.Services.Stubs
|
||||
{
|
||||
public class CreditCheckServiceStub : ICreditCheckService
|
||||
{
|
||||
public bool CanExecute(TradeRequest tradeRequest, IList errors)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
|
||||
|
||||
using System;
|
||||
using Spring.NmsQuickStart.Common.Data;
|
||||
using Spring.NmsQuickStart.Server.Services;
|
||||
|
||||
namespace Spring.NmsQuickStart.Server.Services.Stubs
|
||||
{
|
||||
public class ExecutionVenueServiceStub : IExecutionVenueService
|
||||
{
|
||||
public TradeResponse ExecuteTradeRequest(TradeRequest request)
|
||||
{
|
||||
TradeResponse response = new TradeResponse();
|
||||
response.OrderType = request.OrderType;
|
||||
response.Price = CalculatePrice(request.Ticker, request.Quantity, request.OrderType, request.Price, request.UserName);
|
||||
response.Quantity = request.Quantity;
|
||||
response.Ticker = request.Ticker;
|
||||
response.ConfirmationNumber = new Guid().ToString();
|
||||
return response;
|
||||
}
|
||||
|
||||
private decimal CalculatePrice(string ticker, long quantity, string ordertype, decimal limitPrice, string userName)
|
||||
{
|
||||
// provide as sophisticed an impl as testing requires...for now all the same price.
|
||||
if (ordertype.CompareTo("LIMIT") == 0)
|
||||
{
|
||||
return limitPrice;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 27.6m;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
|
||||
using Spring.NmsQuickStart.Common.Data;
|
||||
using Spring.NmsQuickStart.Server.Services;
|
||||
|
||||
namespace Spring.NmsQuickStart.Server.Services.Stubs
|
||||
{
|
||||
public class TradingServiceStub : ITradingService
|
||||
{
|
||||
public void ProcessTrade(TradeRequest request, TradeResponse response)
|
||||
{
|
||||
//do nothing implementation, typical implementations would persist state to the database.
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,6 +54,9 @@
|
||||
<Compile Include="Services\ICreditCheckService.cs" />
|
||||
<Compile Include="Services\IExecutionVenueService.cs" />
|
||||
<Compile Include="Services\ITradingService.cs" />
|
||||
<Compile Include="Services\Stubs\CreditCheckServiceStub.cs" />
|
||||
<Compile Include="Services\Stubs\ExecutionVenueServiceStub.cs" />
|
||||
<Compile Include="Services\Stubs\TradingServiceStub.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
@@ -81,10 +84,13 @@
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Config\ServiceStubs.xml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Config\Messaging.xml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Config\Services.xml">
|
||||
<Content Include="Config\Handlers.xml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
@@ -88,6 +88,8 @@ namespace Spring.Messaging.Nms.Config
|
||||
private readonly string MAX_RECOVERY_TIME_ATTRIBUTE = "max-recovery-time";
|
||||
|
||||
private readonly string CONNECTION_FACTORY_ATTRIBUTE = "connection-factory";
|
||||
|
||||
private readonly string PUBSUB_DOMAIN_ATTRIBUTE = "pubsub-domain";
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -190,6 +192,10 @@ namespace Spring.Messaging.Nms.Config
|
||||
parserContext.ReaderContext.GenerateObjectName(containerDefBuilder.RawObjectDefinition);
|
||||
}
|
||||
|
||||
string pubsubDomain = listenerElement.GetAttribute(PUBSUB_DOMAIN_ATTRIBUTE);
|
||||
containerDefBuilder.AddPropertyValue("PubSubDomain", pubsubDomain);
|
||||
|
||||
|
||||
parserContext.Registry.RegisterObjectDefinition(containerObjectName, containerDefBuilder.ObjectDefinition);
|
||||
}
|
||||
|
||||
|
||||
@@ -196,6 +196,16 @@
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="pubsub-domain" type="xsd:boolean" use="optional" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Set to true for the publish-subscribe domain (Topics) or false (the default) for the
|
||||
point-to-point domain (Queues).
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
</xsd:schema>
|
||||
|
||||
Reference in New Issue
Block a user