make NMS example based of XML schema generated data types not not 'plain' C# objects for future demo with Java.
This commit is contained in:
@@ -21,7 +21,7 @@
|
||||
<object name="NmsTemplate" type="Spring.Messaging.Nms.Core.NmsTemplate, Spring.Messaging.Nms">
|
||||
<property name="ConnectionFactory" ref="ConnectionFactory"/>
|
||||
<property name="DefaultDestinationName" value="APP.STOCK.REQUEST"/>
|
||||
<property name="MessageConverter" ref="MultiMessageConverter"/>
|
||||
<property name="MessageConverter" ref="XmlMessageConverter"/>
|
||||
</object>
|
||||
|
||||
<!-- Consume messages on queue APP.STOCK.JOE -->
|
||||
@@ -46,10 +46,21 @@
|
||||
<property name="HandlerObject" ref="StockAppHandler"/>
|
||||
<property name="DefaultHandlerMethod" value="Handle"/>
|
||||
<!-- converter from JMS object to plain object -->
|
||||
<property name="MessageConverter" ref="MultiMessageConverter"/>
|
||||
<property name="MessageConverter" ref="XmlMessageConverter"/>
|
||||
</object>
|
||||
|
||||
|
||||
<object name="XmlMessageConverter" type="Spring.NmsQuickStart.Common.Converters.XmlMessageConverter, Spring.NmsQuickStart.Common">
|
||||
<property name="TypeMapper" ref="TypeMapper"/>
|
||||
</object>
|
||||
|
||||
<object name="TypeMapper" type="Spring.NmsQuickStart.Common.Converters.TypeMapper, Spring.NmsQuickStart.Common">
|
||||
<!-- use simple configuation style -->
|
||||
<property name="DefaultNamespace" value="Spring.NmsQuickStart.Common.Data"/>
|
||||
<property name="DefaultAssemblyName" value="Spring.NmsQuickStart.Common"/>
|
||||
</object>
|
||||
|
||||
<!--
|
||||
<object name="MultiMessageConverter" type="Spring.NmsQuickStart.Common.Converters.MultiMessageConverter, Spring.NmsQuickStart.Common">
|
||||
<property name="NamedMessageConverters">
|
||||
<list>
|
||||
@@ -61,7 +72,7 @@
|
||||
|
||||
<object name="TradeRequestConverter" type="Spring.NmsQuickStart.Common.Converters.TradeRequestConverter, Spring.NmsQuickStart.Common"/>
|
||||
<object name="TradeConverter" type="Spring.NmsQuickStart.Common.Converters.TradeConverter, Spring.NmsQuickStart.Common"/>
|
||||
|
||||
-->
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#endregion
|
||||
|
||||
using Spring.NmsQuickStart.Common.Bo;
|
||||
using Spring.NmsQuickStart.Common.Data;
|
||||
|
||||
namespace Spring.NmsQuickStart.Client.Gateways
|
||||
{
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
using Apache.NMS;
|
||||
using Spring.Messaging.Nms.Core;
|
||||
using Spring.NmsQuickStart.Common.Bo;
|
||||
using Spring.NmsQuickStart.Common.Data;
|
||||
using Spring.Objects.Factory;
|
||||
|
||||
namespace Spring.NmsQuickStart.Client.Gateways
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
using System.Collections;
|
||||
using Common.Logging;
|
||||
using Spring.NmsQuickStart.Client.UI;
|
||||
using Spring.NmsQuickStart.Common.Bo;
|
||||
using Spring.NmsQuickStart.Common.Data;
|
||||
|
||||
namespace Spring.NmsQuickStart.Client.Handlers
|
||||
{
|
||||
@@ -24,7 +24,7 @@ namespace Spring.NmsQuickStart.Client.Handlers
|
||||
set { stockController = value; }
|
||||
}
|
||||
|
||||
public void HandleObject(IDictionary data)
|
||||
public void Handle(Hashtable data)
|
||||
{
|
||||
log.Info(string.Format("Received market data. Ticker = {0}, Price = {1}", data["TICKER"], data["PRICE"]));
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
using System.Collections;
|
||||
using Spring.NmsQuickStart.Client.Gateways;
|
||||
using Spring.NmsQuickStart.Common.Bo;
|
||||
using Spring.NmsQuickStart.Common.Data;
|
||||
|
||||
namespace Spring.NmsQuickStart.Client.UI
|
||||
{
|
||||
@@ -33,7 +33,7 @@ namespace Spring.NmsQuickStart.Client.UI
|
||||
tradeRequest.BuyRequest = true;
|
||||
tradeRequest.OrderType = "MARKET";
|
||||
tradeRequest.Quantity = 314000000;
|
||||
tradeRequest.RequestId = "REQ-1";
|
||||
tradeRequest.RequestID = "REQ-1";
|
||||
tradeRequest.Ticker = "CSCO";
|
||||
tradeRequest.UserName = "Joe Trader";
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ using System.Collections;
|
||||
using System.Windows.Forms;
|
||||
using Common.Logging;
|
||||
using Spring.Context.Support;
|
||||
using Spring.NmsQuickStart.Common.Bo;
|
||||
using Spring.NmsQuickStart.Common.Data;
|
||||
|
||||
namespace Spring.NmsQuickStart.Client.UI
|
||||
{
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
|
||||
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
|
||||
namespace Spring.NmsQuickStart.Common.Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a layer of indirection when adding the 'type' of the object as a message property.
|
||||
/// </summary>
|
||||
/// <author>Mark Pollack</author>
|
||||
public interface ITypeMapper
|
||||
{
|
||||
string TypeIdFieldName
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
string FromType(Type typeOfObjectToConvert);
|
||||
|
||||
Type ToType(string typeId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Spring.Core.TypeResolution;
|
||||
|
||||
namespace Spring.NmsQuickStart.Common.Converters
|
||||
{
|
||||
public class TypeMapper : ITypeMapper
|
||||
{
|
||||
private string defaultNamespace;
|
||||
private string defaultAssemblyName;
|
||||
|
||||
//Generics not used to support both 1.1 and 2.0
|
||||
private IDictionary idTypeMapping;
|
||||
private IDictionary typeIdMapping;
|
||||
|
||||
|
||||
//TODO generalize?
|
||||
private string defaultHashtableTypeId = "Hashtable";
|
||||
|
||||
private Type defaultHashtableClass = typeof(Hashtable);
|
||||
|
||||
public TypeMapper()
|
||||
{
|
||||
idTypeMapping = new Hashtable();
|
||||
typeIdMapping = new Hashtable();
|
||||
}
|
||||
|
||||
|
||||
public IDictionary IdTypeMapping
|
||||
{
|
||||
get { return idTypeMapping; }
|
||||
set { idTypeMapping = value; }
|
||||
}
|
||||
|
||||
public string TypeIdFieldName
|
||||
{
|
||||
get { return "__TypeId__"; }
|
||||
}
|
||||
|
||||
|
||||
public Type DefaultHashtableClass
|
||||
{
|
||||
set { defaultHashtableClass = value; }
|
||||
}
|
||||
|
||||
public string FromType(Type typeOfObjectToConvert)
|
||||
{
|
||||
|
||||
if (typeIdMapping.Contains(typeOfObjectToConvert))
|
||||
{
|
||||
return typeIdMapping[typeOfObjectToConvert] as string;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( typeof (IDictionary).IsAssignableFrom(typeOfObjectToConvert))
|
||||
{
|
||||
return defaultHashtableTypeId;
|
||||
}
|
||||
return typeOfObjectToConvert.Name;
|
||||
}
|
||||
}
|
||||
|
||||
public Type ToType(string typeId)
|
||||
{
|
||||
if (idTypeMapping.Contains(typeId))
|
||||
{
|
||||
return idTypeMapping[typeId] as Type;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (typeId.Equals(defaultHashtableTypeId))
|
||||
{
|
||||
return defaultHashtableClass;
|
||||
}
|
||||
string fullyQualifiedTypeName = defaultNamespace + "." +
|
||||
typeId + ", " +
|
||||
DefaultAssemblyName;
|
||||
return TypeResolutionUtils.ResolveType(fullyQualifiedTypeName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public string DefaultNamespace
|
||||
{
|
||||
get
|
||||
{
|
||||
return defaultNamespace;
|
||||
}
|
||||
set
|
||||
{
|
||||
defaultNamespace = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public string DefaultAssemblyName
|
||||
{
|
||||
get
|
||||
{
|
||||
return defaultAssemblyName;
|
||||
}
|
||||
set
|
||||
{
|
||||
defaultAssemblyName = value;
|
||||
}
|
||||
}
|
||||
|
||||
public void AfterPropertiesSet()
|
||||
{
|
||||
ValidateIdTypeMapping();
|
||||
if (DefaultAssemblyName != null && DefaultNamespace == null)
|
||||
{
|
||||
throw new ArgumentException("Default Namespace required when DefaultAssemblyName is set.");
|
||||
}
|
||||
if (DefaultNamespace != null && DefaultAssemblyName == null)
|
||||
{
|
||||
throw new ArgumentException("Default Assembly Name required when DefaultNamespace is set.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void ValidateIdTypeMapping()
|
||||
{
|
||||
IDictionary finalIdTypeMapping = new Hashtable();
|
||||
foreach (DictionaryEntry entry in idTypeMapping)
|
||||
{
|
||||
string id = entry.Key.ToString();
|
||||
Type t = entry.Value as Type;
|
||||
if (t == null)
|
||||
{
|
||||
//convert from string value.
|
||||
string typeName = entry.Value.ToString();
|
||||
t = TypeResolutionUtils.ResolveType(typeName);
|
||||
}
|
||||
finalIdTypeMapping.Add(id,t);
|
||||
typeIdMapping.Add(t,id);
|
||||
|
||||
}
|
||||
idTypeMapping = finalIdTypeMapping;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
using Apache.NMS;
|
||||
using Spring.Messaging.Nms.Support.Converter;
|
||||
|
||||
namespace Spring.NmsQuickStart.Common.Converters
|
||||
{
|
||||
public class XmlMessageConverter : IMessageConverter
|
||||
{
|
||||
private IMessageConverter defaultMessageConverter = new SimpleMessageConverter();
|
||||
|
||||
|
||||
private ITypeMapper typeMapper;
|
||||
|
||||
|
||||
public ITypeMapper TypeMapper
|
||||
{
|
||||
set { typeMapper = value; }
|
||||
}
|
||||
|
||||
public IMessage ToMessage(object objectToConvert, ISession session)
|
||||
{
|
||||
if (objectToConvert == null)
|
||||
{
|
||||
throw new MessageConversionException("Can't convert null object");
|
||||
}
|
||||
try
|
||||
{
|
||||
if (objectToConvert.GetType().Equals(typeof (string)) ||
|
||||
typeof (IDictionary).IsAssignableFrom(objectToConvert.GetType()) ||
|
||||
objectToConvert.GetType().Equals(typeof (Byte[])))
|
||||
{
|
||||
return defaultMessageConverter.ToMessage(objectToConvert, session);
|
||||
}
|
||||
else
|
||||
{
|
||||
string xmlString = GetXmlString(objectToConvert);
|
||||
IMessage msg = session.CreateTextMessage(xmlString);
|
||||
msg.Properties.SetString(typeMapper.TypeIdFieldName, typeMapper.FromType(objectToConvert.GetType()));
|
||||
return msg;
|
||||
}
|
||||
} catch (Exception e)
|
||||
{
|
||||
throw new MessageConversionException("Can't convert object of type " + objectToConvert.GetType(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private string GetXmlString(object objectToConvert)
|
||||
{
|
||||
string xmlString;
|
||||
XmlTextWriter xmlTextWriter = null;
|
||||
MemoryStream memoryStream = null;
|
||||
try
|
||||
{
|
||||
memoryStream = new MemoryStream();
|
||||
xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
|
||||
XmlSerializer xs = new XmlSerializer(objectToConvert.GetType());
|
||||
xs.Serialize(xmlTextWriter, objectToConvert);
|
||||
xmlString = UTF8ByteArrayToString(((MemoryStream) xmlTextWriter.BaseStream).ToArray());
|
||||
} catch (Exception e)
|
||||
{
|
||||
throw new MessageConversionException("Can't convert object of type " + objectToConvert.GetType(), e);
|
||||
} finally
|
||||
{
|
||||
if (memoryStream != null) memoryStream.Close();
|
||||
if (xmlTextWriter != null) xmlTextWriter.Close();
|
||||
}
|
||||
return xmlString;
|
||||
}
|
||||
|
||||
public object FromMessage(IMessage messageToConvert)
|
||||
{
|
||||
if (messageToConvert == null)
|
||||
{
|
||||
throw new MessageConversionException("Can't convert null message");
|
||||
}
|
||||
try
|
||||
{
|
||||
string converterId = messageToConvert.Properties.GetString(typeMapper.TypeIdFieldName);
|
||||
if (converterId == null)
|
||||
{
|
||||
return defaultMessageConverter.FromMessage(messageToConvert);
|
||||
}
|
||||
else
|
||||
{
|
||||
ITextMessage textMessage = messageToConvert as ITextMessage;
|
||||
if (textMessage == null)
|
||||
{
|
||||
throw new MessageConversionException("Can't convert message of type " +
|
||||
messageToConvert.GetType());
|
||||
}
|
||||
|
||||
using (MemoryStream memoryStream = new MemoryStream(StringToUTF8ByteArray(textMessage.Text)))
|
||||
{
|
||||
|
||||
XmlSerializer xs = new XmlSerializer(GetTargetType(textMessage));
|
||||
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
|
||||
return xs.Deserialize(memoryStream);
|
||||
}
|
||||
}
|
||||
} catch (Exception e)
|
||||
{
|
||||
throw new MessageConversionException("Can't convert message of type " + messageToConvert.GetType(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private Type GetTargetType(ITextMessage message)
|
||||
{
|
||||
return typeMapper.ToType(message.Properties.GetString(typeMapper.TypeIdFieldName));
|
||||
}
|
||||
|
||||
|
||||
private String UTF8ByteArrayToString(Byte[] characters)
|
||||
{
|
||||
UTF8Encoding encoding = new UTF8Encoding();
|
||||
|
||||
String constructedString = encoding.GetString(characters);
|
||||
|
||||
return (constructedString);
|
||||
}
|
||||
|
||||
|
||||
private Byte[] StringToUTF8ByteArray(String pXmlString)
|
||||
{
|
||||
UTF8Encoding encoding = new UTF8Encoding();
|
||||
|
||||
Byte[] byteArray = encoding.GetBytes(pXmlString);
|
||||
|
||||
return byteArray;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:2.0.50727.1433
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// This source code was auto-generated by xsd, Version=2.0.50727.42.
|
||||
//
|
||||
namespace Spring.NmsQuickStart.Common.Data {
|
||||
using System.Xml.Serialization;
|
||||
|
||||
|
||||
/// <remarks/>
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
|
||||
[System.SerializableAttribute()]
|
||||
[System.Diagnostics.DebuggerStepThroughAttribute()]
|
||||
[System.ComponentModel.DesignerCategoryAttribute("code")]
|
||||
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://www.springframework.net/nms/common/2008-08-05")]
|
||||
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://www.springframework.net/nms/common/2008-08-05", IsNullable=false)]
|
||||
public partial class Trade {
|
||||
|
||||
private string tickerField;
|
||||
|
||||
private string quantityField;
|
||||
|
||||
private decimal priceField;
|
||||
|
||||
private string orderTypeField;
|
||||
|
||||
/// <remarks/>
|
||||
public string Ticker {
|
||||
get {
|
||||
return this.tickerField;
|
||||
}
|
||||
set {
|
||||
this.tickerField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlElementAttribute(DataType="integer")]
|
||||
public string Quantity {
|
||||
get {
|
||||
return this.quantityField;
|
||||
}
|
||||
set {
|
||||
this.quantityField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
public decimal Price {
|
||||
get {
|
||||
return this.priceField;
|
||||
}
|
||||
set {
|
||||
this.priceField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
public string OrderType {
|
||||
get {
|
||||
return this.orderTypeField;
|
||||
}
|
||||
set {
|
||||
this.orderTypeField = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.springframework.net/nms/common/2008-08-05">
|
||||
<xs:element name="Trade">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="Ticker" type="xs:string"/>
|
||||
<xs:element name="Quantity" type="xs:integer"/>
|
||||
<xs:element name="Price" type="xs:decimal"/>
|
||||
<xs:element name="OrderType" type="xs:string"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
</xs:schema>
|
||||
@@ -0,0 +1,123 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:2.0.50727.1433
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// This source code was auto-generated by xsd, Version=2.0.50727.42.
|
||||
//
|
||||
namespace Spring.NmsQuickStart.Common.Data {
|
||||
using System.Xml.Serialization;
|
||||
|
||||
|
||||
/// <remarks/>
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
|
||||
[System.SerializableAttribute()]
|
||||
[System.Diagnostics.DebuggerStepThroughAttribute()]
|
||||
[System.ComponentModel.DesignerCategoryAttribute("code")]
|
||||
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://www.springframework.net/nms/common/2008-08-05")]
|
||||
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://www.springframework.net/nms/common/2008-08-05", IsNullable=false)]
|
||||
public partial class TradeRequest {
|
||||
|
||||
private string tickerField;
|
||||
|
||||
private long quantityField;
|
||||
|
||||
private decimal priceField;
|
||||
|
||||
private string orderTypeField;
|
||||
|
||||
private string accountNameField;
|
||||
|
||||
private bool buyRequestField;
|
||||
|
||||
private string userNameField;
|
||||
|
||||
private string requestIDField;
|
||||
|
||||
/// <remarks/>
|
||||
public string Ticker {
|
||||
get {
|
||||
return this.tickerField;
|
||||
}
|
||||
set {
|
||||
this.tickerField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
public long Quantity {
|
||||
get {
|
||||
return this.quantityField;
|
||||
}
|
||||
set {
|
||||
this.quantityField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
public decimal Price {
|
||||
get {
|
||||
return this.priceField;
|
||||
}
|
||||
set {
|
||||
this.priceField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
public string OrderType {
|
||||
get {
|
||||
return this.orderTypeField;
|
||||
}
|
||||
set {
|
||||
this.orderTypeField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
public string AccountName {
|
||||
get {
|
||||
return this.accountNameField;
|
||||
}
|
||||
set {
|
||||
this.accountNameField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
public bool BuyRequest {
|
||||
get {
|
||||
return this.buyRequestField;
|
||||
}
|
||||
set {
|
||||
this.buyRequestField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
public string UserName {
|
||||
get {
|
||||
return this.userNameField;
|
||||
}
|
||||
set {
|
||||
this.userNameField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
public string RequestID {
|
||||
get {
|
||||
return this.requestIDField;
|
||||
}
|
||||
set {
|
||||
this.requestIDField = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.springframework.net/nms/common/2008-08-05">
|
||||
<xs:element name="TradeRequest">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="Ticker" type="xs:string"/>
|
||||
<xs:element name="Quantity" type="xs:long"/>
|
||||
<xs:element name="Price" type="xs:decimal"/>
|
||||
<xs:element name="OrderType" type="xs:string"/>
|
||||
<xs:element name="AccountName" type="xs:string"/>
|
||||
<xs:element name="BuyRequest" type="xs:boolean"/>
|
||||
<xs:element name="UserName" type="xs:string"/>
|
||||
<xs:element name="RequestID" type="xs:string"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
</xs:schema>
|
||||
@@ -0,0 +1,2 @@
|
||||
xsd.exe -c -l:c# -n:Spring.NmsQuickStart.Common.Data Trade.xsd
|
||||
xsd.exe -c -l:c# -n:Spring.NmsQuickStart.Common.Data TradeRequest.xsd
|
||||
@@ -41,13 +41,15 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Bo\Trade.cs" />
|
||||
<Compile Include="Bo\TradeRequest.cs" />
|
||||
<Compile Include="Converters\AbstractNamedMessageConverter.cs" />
|
||||
<Compile Include="Converters\MultiMessageConverter.cs" />
|
||||
<Compile Include="Converters\INamedMessageConverter.cs" />
|
||||
<Compile Include="Converters\TradeConverter.cs" />
|
||||
<Compile Include="Converters\TradeRequestConverter.cs" />
|
||||
<Compile Include="Converters\ITypeMapper.cs" />
|
||||
<Compile Include="Converters\TypeMapper.cs" />
|
||||
<Compile Include="Converters\XmlMessageConverter.cs" />
|
||||
<Compile Include="Data\Trade.cs">
|
||||
<DependentUpon>Trade.xsd</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Data\TradeRequest.cs">
|
||||
<DependentUpon>TradeRequest.xsd</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -68,6 +70,14 @@
|
||||
<Name>Spring.Messaging.Nms.2005</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Data\Trade.xsd">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
<None Include="Data\TradeRequest.xsd">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
||||
@@ -6,6 +6,19 @@
|
||||
<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"/>
|
||||
<property name="DefaultDestinationName" value="APP.STOCK.MARKETDATA"/>
|
||||
<property name="MessageConverter" ref="XmlMessageConverter"/>
|
||||
</object>
|
||||
|
||||
<object name="MarketDataGateway" type="Spring.NmsQuickStart.Server.Gateways.MarketDataGateway, Spring.NmsQuickStart.Server">
|
||||
<property name="NmsTemplate" ref="NmsTemplate"/>
|
||||
</object>
|
||||
|
||||
<!-- Consume messages on queue APP.STOCK.REQUEST -->
|
||||
<object id="MessageListenerContainer" type="Spring.Messaging.Nms.Listener.SimpleMessageListenerContainer, Spring.Messaging.Nms">
|
||||
<property name="ConnectionFactory" ref="ConnectionFactory"/>
|
||||
@@ -19,9 +32,21 @@
|
||||
<property name="HandlerObject" ref="StockAppHandler"/>
|
||||
<property name="DefaultHandlerMethod" value="Handle"/>
|
||||
<!-- converter from JMS object to plain object -->
|
||||
<property name="MessageConverter" ref="MultiMessageConverter"/>
|
||||
<property name="MessageConverter" ref="XmlMessageConverter"/>
|
||||
</object>
|
||||
|
||||
|
||||
<object name="XmlMessageConverter" type="Spring.NmsQuickStart.Common.Converters.XmlMessageConverter, Spring.NmsQuickStart.Common">
|
||||
<property name="TypeMapper" ref="TypeMapper"/>
|
||||
</object>
|
||||
|
||||
<object name="TypeMapper" type="Spring.NmsQuickStart.Common.Converters.TypeMapper, Spring.NmsQuickStart.Common">
|
||||
<!-- use simple configuation style -->
|
||||
<property name="DefaultNamespace" value="Spring.NmsQuickStart.Common.Data"/>
|
||||
<property name="DefaultAssemblyName" value="Spring.NmsQuickStart.Common"/>
|
||||
</object>
|
||||
|
||||
<!--
|
||||
<object name="MultiMessageConverter" type="Spring.NmsQuickStart.Common.Converters.MultiMessageConverter, Spring.NmsQuickStart.Common">
|
||||
<property name="NamedMessageConverters">
|
||||
<list>
|
||||
@@ -33,7 +58,7 @@
|
||||
|
||||
<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,65 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Threading;
|
||||
using Common.Logging;
|
||||
using Spring.Messaging.Nms.Core;
|
||||
|
||||
namespace Spring.NmsQuickStart.Server.Gateways
|
||||
{
|
||||
public class MarketDataGateway : NmsGatewaySupport
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof (MarketDataGateway));
|
||||
|
||||
private readonly Random random;
|
||||
private int sleepTimeInSeconds = 2;
|
||||
|
||||
|
||||
public MarketDataGateway()
|
||||
{
|
||||
random = new Random();
|
||||
}
|
||||
|
||||
public int SleepTimeInSeconds
|
||||
{
|
||||
set { sleepTimeInSeconds = value; }
|
||||
}
|
||||
|
||||
public void SendMarketData()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
IDictionary data = GenerateFakeMarketData();
|
||||
log.Info("Sending market data.");
|
||||
NmsTemplate.ConvertAndSend(data);
|
||||
log.Info("Sleeping " + sleepTimeInSeconds + " seconds before sending more market data.");
|
||||
Thread.Sleep(sleepTimeInSeconds*1000);
|
||||
}
|
||||
}
|
||||
|
||||
private IDictionary GenerateFakeMarketData()
|
||||
{
|
||||
IDictionary md = new Hashtable();
|
||||
md.Add("TICKER", "CSCO");
|
||||
md.Add("PRICE", "22" + string.Format("{0:#.###}", Math.Abs(Gaussian())));
|
||||
return md;
|
||||
}
|
||||
|
||||
private double Gaussian()
|
||||
{
|
||||
double x1, x2, w;
|
||||
|
||||
do
|
||||
{
|
||||
x1 = 2.0*random.NextDouble() - 1.0;
|
||||
x2 = 2.0*random.NextDouble() - 1.0;
|
||||
w = x1*x1 + x2*x2;
|
||||
} while (w >= 1.0);
|
||||
|
||||
w = Math.Sqrt(-2.0*Math.Log(w)/w);
|
||||
|
||||
// two Gaussian random numbers are generated
|
||||
return x1*w;
|
||||
//y2 = x2 * w;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
|
||||
using Common.Logging;
|
||||
using Spring.NmsQuickStart.Common.Bo;
|
||||
using Spring.NmsQuickStart.Common.Data;
|
||||
|
||||
namespace Spring.NmsQuickStart.Server.Handlers
|
||||
{
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using Spring.Context.Support;
|
||||
using Spring.NmsQuickStart.Server.Gateways;
|
||||
|
||||
namespace Spring.NmsQuickStart.Server
|
||||
{
|
||||
@@ -12,6 +14,11 @@ namespace Spring.NmsQuickStart.Server
|
||||
// Using Spring's IoC container
|
||||
ContextRegistry.GetContext(); // Force Spring to load configuration
|
||||
Console.Out.WriteLine("Server listening...");
|
||||
MarketDataGateway marketDataGateway =
|
||||
ContextRegistry.GetContext().GetObject("MarketDataGateway") as MarketDataGateway;
|
||||
ThreadStart job = new ThreadStart(marketDataGateway.SendMarketData);
|
||||
Thread thread = new Thread(job);
|
||||
thread.Start();
|
||||
Console.Out.WriteLine("--- Press <return> to quit ---");
|
||||
Console.ReadLine();
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Gateways\MarketDataGateway.cs" />
|
||||
<Compile Include="Handlers\StockAppHandler.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
@@ -82,10 +83,6 @@
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Converters\" />
|
||||
<Folder Include="Gateways\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace Spring.Messaging.Nms.Support.Converter
|
||||
/// <summary> Convert a .NET object to a NMS Message using the supplied session
|
||||
/// to create the message object.
|
||||
/// </summary>
|
||||
/// <param name="object">the object to convert
|
||||
/// <param name="objectToConvert">the object to convert
|
||||
/// </param>
|
||||
/// <param name="session">the Session to use for creating a NMS Message
|
||||
/// </param>
|
||||
@@ -50,32 +50,32 @@ namespace Spring.Messaging.Nms.Support.Converter
|
||||
/// </returns>
|
||||
/// <throws>NMSException if thrown by NMS API methods </throws>
|
||||
/// <throws>MessageConversionException in case of conversion failure </throws>
|
||||
public IMessage ToMessage(object @object, ISession session)
|
||||
public IMessage ToMessage(object objectToConvert, ISession session)
|
||||
{
|
||||
if (@object is IMessage)
|
||||
if (objectToConvert is IMessage)
|
||||
{
|
||||
return (IMessage) @object;
|
||||
return (IMessage) objectToConvert;
|
||||
}
|
||||
else if (@object is string)
|
||||
else if (objectToConvert is string)
|
||||
{
|
||||
return CreateMessageForString((string) @object, session);
|
||||
return CreateMessageForString((string) objectToConvert, session);
|
||||
}
|
||||
else if (@object is sbyte[])
|
||||
else if (objectToConvert is sbyte[])
|
||||
{
|
||||
return CreateMessageForByteArray((byte[]) @object, session);
|
||||
return CreateMessageForByteArray((byte[]) objectToConvert, session);
|
||||
}
|
||||
else if (@object is IDictionary)
|
||||
else if (objectToConvert is IDictionary)
|
||||
{
|
||||
return CreateMessageForMap((IDictionary) @object, session);
|
||||
return CreateMessageForMap((IDictionary) objectToConvert, session);
|
||||
}
|
||||
else if (@object is ISerializable)
|
||||
else if (objectToConvert is ISerializable)
|
||||
{
|
||||
return
|
||||
CreateMessageForSerializable(((ISerializable) @object), session);
|
||||
CreateMessageForSerializable(((ISerializable) objectToConvert), session);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new MessageConversionException("Cannot convert object [" + @object + "] to NMS message");
|
||||
throw new MessageConversionException("Cannot convert object [" + objectToConvert + "] to NMS message");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user