Sync TIBCO EMS implementation with Apache NMS
This commit is contained in:
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
|
using Spring.Core.TypeResolution;
|
||||||
using TIBCO.EMS;
|
using TIBCO.EMS;
|
||||||
using Spring.Core.TypeConversion;
|
using Spring.Core.TypeConversion;
|
||||||
using Spring.Messaging.Ems.Listener;
|
using Spring.Messaging.Ems.Listener;
|
||||||
@@ -89,8 +90,12 @@ namespace Spring.Messaging.Ems.Config
|
|||||||
|
|
||||||
private readonly string CONNECTION_FACTORY_ATTRIBUTE = "connection-factory";
|
private readonly string CONNECTION_FACTORY_ATTRIBUTE = "connection-factory";
|
||||||
|
|
||||||
|
private readonly string CONTAINER_CUSTOM_TYPE = "container-custom-type";
|
||||||
|
|
||||||
private readonly string PUBSUB_DOMAIN_ATTRIBUTE = "pubsub-domain";
|
private readonly string PUBSUB_DOMAIN_ATTRIBUTE = "pubsub-domain";
|
||||||
|
|
||||||
|
private readonly string AUTO_STARTUP = "auto-startup";
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region IObjectDefinitionParser Members
|
#region IObjectDefinitionParser Members
|
||||||
@@ -201,13 +206,44 @@ namespace Spring.Messaging.Ems.Config
|
|||||||
private ObjectDefinitionBuilder ParseContainer(XmlElement listenerElement, XmlElement containerElement,
|
private ObjectDefinitionBuilder ParseContainer(XmlElement listenerElement, XmlElement containerElement,
|
||||||
ParserContext parserContext)
|
ParserContext parserContext)
|
||||||
{
|
{
|
||||||
|
//Only support SimpleMessageListenerContainer or container-custom-type
|
||||||
|
|
||||||
|
Type containerType = typeof(SimpleMessageListenerContainer);
|
||||||
|
if (containerElement.HasAttribute(CONTAINER_CUSTOM_TYPE))
|
||||||
|
{
|
||||||
|
string customType = containerElement.GetAttribute(CONTAINER_CUSTOM_TYPE);
|
||||||
|
if (!StringUtils.HasLength(customType))
|
||||||
|
{
|
||||||
|
parserContext.ReaderContext.ReportException(containerElement, CONTAINER_CUSTOM_TYPE,
|
||||||
|
"Listener container '" + CONTAINER_CUSTOM_TYPE +
|
||||||
|
"' attribute contains empty value.");
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
containerType = TypeResolutionUtils.ResolveType(customType);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
parserContext.ReaderContext.ReportException(containerElement, CONTAINER_CUSTOM_TYPE,
|
||||||
|
"Invalid container-custom-type value [" + customType + "]", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
//Only support SimpleMessageListenerContainer
|
//Only support SimpleMessageListenerContainer
|
||||||
ObjectDefinitionBuilder containerDef =
|
ObjectDefinitionBuilder containerDef =
|
||||||
parserContext.ParserHelper.CreateRootObjectDefinitionBuilder(typeof (SimpleMessageListenerContainer));
|
parserContext.ParserHelper.CreateRootObjectDefinitionBuilder(containerType);
|
||||||
|
|
||||||
ParseListenerConfiguration(listenerElement, parserContext, containerDef);
|
ParseListenerConfiguration(listenerElement, parserContext, containerDef);
|
||||||
ParseContainerConfiguration(containerElement, parserContext, containerDef);
|
ParseContainerConfiguration(containerElement, parserContext, containerDef);
|
||||||
|
|
||||||
|
if (containerElement.HasAttribute(AUTO_STARTUP))
|
||||||
|
{
|
||||||
|
string autoStartup = containerElement.GetAttribute(AUTO_STARTUP);
|
||||||
|
if (!StringUtils.HasText(autoStartup))
|
||||||
|
{
|
||||||
|
containerDef.AddPropertyValue("AutoStartup", autoStartup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
string connectionFactoryObjectName = "connectionFactory";
|
string connectionFactoryObjectName = "connectionFactory";
|
||||||
if (containerElement.HasAttribute(CONNECTION_FACTORY_ATTRIBUTE))
|
if (containerElement.HasAttribute(CONNECTION_FACTORY_ATTRIBUTE))
|
||||||
{
|
{
|
||||||
@@ -236,7 +272,7 @@ namespace Spring.Messaging.Ems.Config
|
|||||||
containerDef.AddPropertyValue("SessionAcknowledgeMode", acknowledgementMode);
|
containerDef.AddPropertyValue("SessionAcknowledgeMode", acknowledgementMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
int[] concurrency = ParseConcurrency(containerElement, parserContext);
|
string concurrency = ParseConcurrency(containerElement, parserContext);
|
||||||
if (concurrency != null)
|
if (concurrency != null)
|
||||||
{
|
{
|
||||||
containerDef.AddPropertyValue("ConcurrentConsumers", concurrency[1]);
|
containerDef.AddPropertyValue("ConcurrentConsumers", concurrency[1]);
|
||||||
@@ -358,60 +394,42 @@ namespace Spring.Messaging.Ems.Config
|
|||||||
return Session.AUTO_ACKNOWLEDGE;
|
return Session.AUTO_ACKNOWLEDGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int[] ParseConcurrency(XmlElement ele, ParserContext parserContext)
|
private string ParseConcurrency(XmlElement ele, ParserContext parserContext)
|
||||||
{
|
{
|
||||||
string concurrency = ele.GetAttribute(CONCURRENCY_ATTRIBUTE);
|
string concurrency = ele.GetAttribute(CONCURRENCY_ATTRIBUTE);
|
||||||
if (!StringUtils.HasText(concurrency))
|
if (!StringUtils.HasText(concurrency))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try
|
else
|
||||||
{
|
{
|
||||||
return new int[] {1, Int32.Parse(concurrency)};
|
return concurrency;
|
||||||
}
|
|
||||||
catch (FormatException ex)
|
|
||||||
{
|
|
||||||
parserContext.ReaderContext.ReportException(ele, CONCURRENCY_ATTRIBUTE,
|
|
||||||
"Invalid concurrency value [" + concurrency + "]: only " +
|
|
||||||
"integer (e.g. \"5\") values upported.", ex);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private TimeSpan ParseRecoveryInterval(XmlElement ele, ParserContext parserContext)
|
private string ParseRecoveryInterval(XmlElement ele, ParserContext parserContext)
|
||||||
{
|
{
|
||||||
string recoveryInterval = ele.GetAttribute(RECOVERY_INTERVAL_ATTRIBUTE);
|
string recoveryInterval = ele.GetAttribute(RECOVERY_INTERVAL_ATTRIBUTE);
|
||||||
if (!StringUtils.HasText(recoveryInterval))
|
if (StringUtils.HasText(recoveryInterval))
|
||||||
{
|
{
|
||||||
return SimpleMessageListenerContainer.DEFAULT_RECOVERY_INTERVAL;
|
return recoveryInterval;
|
||||||
|
|
||||||
}
|
}
|
||||||
try
|
else
|
||||||
{
|
{
|
||||||
TimeSpanConverter tsc = new TimeSpanConverter();
|
|
||||||
return (TimeSpan)tsc.ConvertFrom(recoveryInterval);
|
|
||||||
} catch (Exception ex)
|
|
||||||
{
|
|
||||||
parserContext.ReaderContext.ReportException(ele, RECOVERY_INTERVAL_ATTRIBUTE,
|
|
||||||
"Invalid recovery-interval value [" + recoveryInterval + "]", ex);
|
|
||||||
return SimpleMessageListenerContainer.DEFAULT_RECOVERY_INTERVAL;
|
return SimpleMessageListenerContainer.DEFAULT_RECOVERY_INTERVAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private TimeSpan ParseMaxRecoveryTime(XmlElement ele, ParserContext parserContext)
|
|
||||||
|
private string ParseMaxRecoveryTime(XmlElement ele, ParserContext parserContext)
|
||||||
{
|
{
|
||||||
string recoverTime = ele.GetAttribute(MAX_RECOVERY_TIME_ATTRIBUTE);
|
string recoverTime = ele.GetAttribute(MAX_RECOVERY_TIME_ATTRIBUTE);
|
||||||
if (!StringUtils.HasText(recoverTime))
|
if (StringUtils.HasText(recoverTime))
|
||||||
{
|
{
|
||||||
return SimpleMessageListenerContainer.DEFAULT_MAX_RECOVERY_TIME;
|
return recoverTime;
|
||||||
}
|
}
|
||||||
try
|
else
|
||||||
{
|
{
|
||||||
TimeSpanConverter tsc = new TimeSpanConverter();
|
|
||||||
return (TimeSpan)tsc.ConvertFrom(recoverTime);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
parserContext.ReaderContext.ReportException(ele, MAX_RECOVERY_TIME_ATTRIBUTE,
|
|
||||||
"Invalid max-recovery-time value [" + recoverTime + "]", ex);
|
|
||||||
return SimpleMessageListenerContainer.DEFAULT_MAX_RECOVERY_TIME;
|
return SimpleMessageListenerContainer.DEFAULT_MAX_RECOVERY_TIME;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,26 @@
|
|||||||
</xsd:restriction>
|
</xsd:restriction>
|
||||||
</xsd:simpleType>
|
</xsd:simpleType>
|
||||||
</xsd:attribute>
|
</xsd:attribute>
|
||||||
<xsd:attribute name="connection-factory" type="xsd:string" default="ConnectionFactory">
|
<xsd:attribute name="container-custom-type" type="xsd:string">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
<![CDATA[
|
||||||
|
A custom listener container implementation class as fully qualified type name.
|
||||||
|
Default is Spring's SimpleMessageListenerContainer.
|
||||||
|
]]>
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="auto-startup" type="xsd:boolean" default="true">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
<![CDATA[
|
||||||
|
Set whether to automatically start the listeners after initialization. Default is true, optionally set to false.
|
||||||
|
]]>
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="connection-factory" type="xsd:string" default="ConnectionFactory">
|
||||||
<xsd:annotation>
|
<xsd:annotation>
|
||||||
<xsd:documentation><![CDATA[
|
<xsd:documentation><![CDATA[
|
||||||
A reference to the ConnectionFactory object.
|
A reference to the ConnectionFactory object.
|
||||||
|
|||||||
@@ -198,8 +198,8 @@ namespace Spring.Messaging.Ems.Connections
|
|||||||
if (resourceHolderToUse != resourceHolder)
|
if (resourceHolderToUse != resourceHolder)
|
||||||
{
|
{
|
||||||
TransactionSynchronizationManager.RegisterSynchronization(
|
TransactionSynchronizationManager.RegisterSynchronization(
|
||||||
new EmsResourceSynchronization(resourceKey, resourceHolderToUse,
|
new EmsResourceSynchronization(resourceHolderToUse,
|
||||||
resourceFactory.SynchedLocalTransactionAllowed));
|
resourceKey, resourceFactory.SynchedLocalTransactionAllowed));
|
||||||
resourceHolderToUse.SynchronizedWithTransaction = true;
|
resourceHolderToUse.SynchronizedWithTransaction = true;
|
||||||
TransactionSynchronizationManager.BindResource(resourceKey, resourceHolderToUse);
|
TransactionSynchronizationManager.BindResource(resourceKey, resourceHolderToUse);
|
||||||
}
|
}
|
||||||
@@ -316,7 +316,7 @@ namespace Spring.Messaging.Ems.Connections
|
|||||||
|
|
||||||
private bool holderActive = true;
|
private bool holderActive = true;
|
||||||
|
|
||||||
public EmsResourceSynchronization(object resourceKey, EmsResourceHolder resourceHolder, bool transacted)
|
public EmsResourceSynchronization(EmsResourceHolder resourceHolder, object resourceKey, bool transacted)
|
||||||
{
|
{
|
||||||
this.resourceKey = resourceKey;
|
this.resourceKey = resourceKey;
|
||||||
this.resourceHolder = resourceHolder;
|
this.resourceHolder = resourceHolder;
|
||||||
|
|||||||
@@ -273,6 +273,9 @@ namespace Spring.Messaging.Ems.Connections
|
|||||||
{
|
{
|
||||||
ConnectionFactoryUtils.ReleaseConnection(connection, connectionFactory, true);
|
ConnectionFactoryUtils.ReleaseConnection(connection, connectionFactory, true);
|
||||||
}
|
}
|
||||||
|
this.connections.Clear();
|
||||||
|
this.sessions.Clear();
|
||||||
|
this.sessionsPerConnection.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ namespace Spring.Messaging.Ems.Core
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private EmsTemplate jmsTemplate;
|
private EmsTemplate emsTemplate;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -53,8 +53,8 @@ namespace Spring.Messaging.Ems.Core
|
|||||||
/// <value>The EMS template.</value>
|
/// <value>The EMS template.</value>
|
||||||
public EmsTemplate EmsTemplate
|
public EmsTemplate EmsTemplate
|
||||||
{
|
{
|
||||||
get { return jmsTemplate; }
|
get { return emsTemplate; }
|
||||||
set { jmsTemplate = value; }
|
set { emsTemplate = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -66,11 +66,11 @@ namespace Spring.Messaging.Ems.Core
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return (jmsTemplate != null ? this.jmsTemplate.ConnectionFactory : null);
|
return (emsTemplate != null ? this.emsTemplate.ConnectionFactory : null);
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
this.jmsTemplate = CreateEmsTemplate(value);
|
this.emsTemplate = CreateEmsTemplate(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ namespace Spring.Messaging.Ems.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual void AfterPropertiesSet()
|
public virtual void AfterPropertiesSet()
|
||||||
{
|
{
|
||||||
if (jmsTemplate == null)
|
if (emsTemplate == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentException("connectionFactory or jmsTemplate is required");
|
throw new ArgumentException("connectionFactory or jmsTemplate is required");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,11 +45,11 @@ namespace Spring.Messaging.Ems.Listener
|
|||||||
///
|
///
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <author>Mark Pollack</author>
|
/// <author>Mark Pollack</author>
|
||||||
public abstract class AbstractEmsListeningContainer : EmsDestinationAccessor, ILifecycle, IObjectNameAware, IDisposable
|
public abstract class AbstractListenerContainer : EmsDestinationAccessor, ILifecycle, IObjectNameAware, IDisposable
|
||||||
{
|
{
|
||||||
#region Logging
|
#region Logging
|
||||||
|
|
||||||
private readonly ILog logger = LogManager.GetLogger(typeof(AbstractEmsListeningContainer));
|
private readonly ILog logger = LogManager.GetLogger(typeof(AbstractListenerContainer));
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ namespace Spring.Messaging.Ems.Listener
|
|||||||
/// a standard EMS MessageListener or a Spring-specific
|
/// a standard EMS MessageListener or a Spring-specific
|
||||||
/// <see cref="ISessionAwareMessageListener"/>
|
/// <see cref="ISessionAwareMessageListener"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class AbstractMessageListenerContainer : AbstractEmsListeningContainer
|
public abstract class AbstractMessageListenerContainer : AbstractListenerContainer
|
||||||
{
|
{
|
||||||
#region Logging
|
#region Logging
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ namespace Spring.Messaging.Ems.Listener.Adapter
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static string ORIGINAL_DEFAULT_HANDLER_METHOD = "HandleMessage";
|
public static string ORIGINAL_DEFAULT_HANDLER_METHOD = "HandleMessage";
|
||||||
|
|
||||||
|
#region Fields
|
||||||
|
|
||||||
private object handlerObject;
|
private object handlerObject;
|
||||||
|
|
||||||
private string defaultHandlerMethod = ORIGINAL_DEFAULT_HANDLER_METHOD;
|
private string defaultHandlerMethod = ORIGINAL_DEFAULT_HANDLER_METHOD;
|
||||||
@@ -70,6 +72,10 @@ namespace Spring.Messaging.Ems.Listener.Adapter
|
|||||||
|
|
||||||
private IMessageConverter messageConverter;
|
private IMessageConverter messageConverter;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="MessageListenerAdapter"/> class with default settings.
|
/// Initializes a new instance of the <see cref="MessageListenerAdapter"/> class with default settings.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -77,7 +83,6 @@ namespace Spring.Messaging.Ems.Listener.Adapter
|
|||||||
{
|
{
|
||||||
InitDefaultStrategies();
|
InitDefaultStrategies();
|
||||||
handlerObject = this;
|
handlerObject = this;
|
||||||
processingExpression = Expression.Parse(defaultHandlerMethod + "(#convertedObject)");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -90,6 +95,10 @@ namespace Spring.Messaging.Ems.Listener.Adapter
|
|||||||
this.handlerObject = handlerObject;
|
this.handlerObject = handlerObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the handler object to delegate message listening to.
|
/// Gets or sets the handler object to delegate message listening to.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -118,6 +127,7 @@ namespace Spring.Messaging.Ems.Listener.Adapter
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
defaultHandlerMethod = value;
|
defaultHandlerMethod = value;
|
||||||
|
processingExpression = Expression.Parse(defaultHandlerMethod + "(#convertedObject)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,6 +208,8 @@ namespace Spring.Messaging.Ems.Listener.Adapter
|
|||||||
set { messageConverter = value; }
|
set { messageConverter = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Standard JMS {@link MessageListener} entry point.
|
/// Standard JMS {@link MessageListener} entry point.
|
||||||
@@ -267,11 +279,6 @@ namespace Spring.Messaging.Ems.Listener.Adapter
|
|||||||
IDictionary vars = new Hashtable();
|
IDictionary vars = new Hashtable();
|
||||||
vars["convertedObject"] = convertedMessage;
|
vars["convertedObject"] = convertedMessage;
|
||||||
|
|
||||||
//Need to parse each time since have overloaded methods and
|
|
||||||
//expression processor caches target of first invocation.
|
|
||||||
//TODO - check JIRA as I believe this has been fixed, otherwise, use regular reflection. -MLP
|
|
||||||
processingExpression = Expression.Parse(defaultHandlerMethod + "(#convertedObject)");
|
|
||||||
|
|
||||||
//Invoke message handler method and get result.
|
//Invoke message handler method and get result.
|
||||||
object result;
|
object result;
|
||||||
try
|
try
|
||||||
@@ -317,6 +324,7 @@ namespace Spring.Messaging.Ems.Listener.Adapter
|
|||||||
protected virtual void InitDefaultStrategies()
|
protected virtual void InitDefaultStrategies()
|
||||||
{
|
{
|
||||||
MessageConverter = new SimpleMessageConverter();
|
MessageConverter = new SimpleMessageConverter();
|
||||||
|
processingExpression = Expression.Parse(defaultHandlerMethod + "(#convertedObject)");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -442,7 +450,7 @@ namespace Spring.Messaging.Ems.Listener.Adapter
|
|||||||
/// <para>The default implementation first checks the JMS Reply-To
|
/// <para>The default implementation first checks the JMS Reply-To
|
||||||
/// Destination of the supplied request; if that is not <code>null</code>
|
/// Destination of the supplied request; if that is not <code>null</code>
|
||||||
/// it is returned; if it is <code>null</code>, then the configured
|
/// it is returned; if it is <code>null</code>, then the configured
|
||||||
/// <see cref="ResolveDefaultResponseDestination"/> default response destination}
|
/// <see cref="DefaultResponseDestination"/> default response destination}
|
||||||
/// is returned; if this too is <code>null</code>, then an
|
/// is returned; if this too is <code>null</code>, then an
|
||||||
/// <see cref="InvalidDestinationException"/>is thrown.
|
/// <see cref="InvalidDestinationException"/>is thrown.
|
||||||
/// </para>
|
/// </para>
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ namespace Spring.Messaging.Ems.Listener
|
|||||||
/// MessageConsumer.Listener method to create concurrent
|
/// MessageConsumer.Listener method to create concurrent
|
||||||
/// MessageConsumers for the specified listeners.
|
/// MessageConsumers for the specified listeners.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <author>Juergen Hoeller</author>
|
||||||
|
/// <author>Mark Pollack (.NET)</author>
|
||||||
public class SimpleMessageListenerContainer : AbstractMessageListenerContainer, IExceptionListener
|
public class SimpleMessageListenerContainer : AbstractMessageListenerContainer, IExceptionListener
|
||||||
{
|
{
|
||||||
#region Logging
|
#region Logging
|
||||||
@@ -47,12 +49,12 @@ namespace Spring.Messaging.Ems.Listener
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The default recovery time interval between connection reconnection attempts
|
/// The default recovery time interval between connection reconnection attempts
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static TimeSpan DEFAULT_RECOVERY_INTERVAL = new TimeSpan(0, 0, 0, 5, 0);
|
public static string DEFAULT_RECOVERY_INTERVAL = "5s";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The total time connection recovery will be attempted.
|
/// The total time connection recovery will be attempted.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static TimeSpan DEFAULT_MAX_RECOVERY_TIME = new TimeSpan(0, 0, 10, 0, 0);
|
public static string DEFAULT_MAX_RECOVERY_TIME = "10m";
|
||||||
|
|
||||||
private bool pubSubNoLocal = false;
|
private bool pubSubNoLocal = false;
|
||||||
|
|
||||||
@@ -64,9 +66,9 @@ namespace Spring.Messaging.Ems.Listener
|
|||||||
|
|
||||||
private object consumersMonitor = new object();
|
private object consumersMonitor = new object();
|
||||||
|
|
||||||
private TimeSpan recoveryInterval = DEFAULT_RECOVERY_INTERVAL;
|
private TimeSpan recoveryInterval = new TimeSpan(0, 0, 0, 5, 0);
|
||||||
|
|
||||||
private TimeSpan maxRecoveryTime = DEFAULT_MAX_RECOVERY_TIME;
|
private TimeSpan maxRecoveryTime = new TimeSpan(0, 0, 10, 0, 0);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -318,18 +320,27 @@ namespace Spring.Messaging.Ems.Listener
|
|||||||
/// <throws>EMSException if destruction failed </throws>
|
/// <throws>EMSException if destruction failed </throws>
|
||||||
protected override void DoShutdown()
|
protected override void DoShutdown()
|
||||||
{
|
{
|
||||||
logger.Debug("Closing EMS MessageConsumers");
|
lock (consumersMonitor)
|
||||||
foreach (MessageConsumer messageConsumer in consumers)
|
|
||||||
{
|
{
|
||||||
EmsUtils.CloseMessageConsumer(messageConsumer);
|
if (consumers != null)
|
||||||
|
{
|
||||||
|
logger.Debug("Closing NMS MessageConsumers");
|
||||||
|
foreach (MessageConsumer messageConsumer in consumers)
|
||||||
|
{
|
||||||
|
EmsUtils.CloseMessageConsumer(messageConsumer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sessions != null)
|
||||||
|
{
|
||||||
|
logger.Debug("Closing NMS Sessions");
|
||||||
|
foreach (Session session in sessions)
|
||||||
|
{
|
||||||
|
EmsUtils.CloseSession(session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
consumers = null;
|
||||||
|
sessions = null;
|
||||||
}
|
}
|
||||||
logger.Debug("Closing EMS Sessions");
|
|
||||||
foreach (Session session in sessions)
|
|
||||||
{
|
|
||||||
EmsUtils.CloseSession(session);
|
|
||||||
}
|
|
||||||
consumers = null;
|
|
||||||
sessions = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
#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.Messaging.Ems.Support.Converter
|
||||||
|
{
|
||||||
|
/// <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
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the name of the field in the message that has type information..
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The name of the type id field.</value>
|
||||||
|
string TypeIdFieldName
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert from a type to a string.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="typeOfObjectToConvert">The type of object to convert.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
string FromType(Type typeOfObjectToConvert);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert from a string to a type
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="typeId">The type id.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Type ToType(string typeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Runtime.Serialization;
|
|
||||||
using TIBCO.EMS;
|
using TIBCO.EMS;
|
||||||
|
|
||||||
namespace Spring.Messaging.Ems.Support.Converter
|
namespace Spring.Messaging.Ems.Support.Converter
|
||||||
@@ -56,27 +55,23 @@ namespace Spring.Messaging.Ems.Support.Converter
|
|||||||
{
|
{
|
||||||
return (Message) objectToConvert;
|
return (Message) objectToConvert;
|
||||||
}
|
}
|
||||||
else if (objectToConvert is string)
|
if (objectToConvert is string)
|
||||||
{
|
{
|
||||||
return CreateMessageForString((string) objectToConvert, session);
|
return CreateMessageForString((string) objectToConvert, session);
|
||||||
}
|
}
|
||||||
else if (objectToConvert is sbyte[])
|
if (objectToConvert is sbyte[])
|
||||||
{
|
{
|
||||||
return CreateMessageForByteArray((byte[]) objectToConvert, session);
|
return CreateMessageForByteArray((byte[]) objectToConvert, session);
|
||||||
}
|
}
|
||||||
else if (objectToConvert is IDictionary)
|
if (objectToConvert is IDictionary)
|
||||||
{
|
{
|
||||||
return CreateMessageForMap((IDictionary) objectToConvert, session);
|
return CreateMessageForMap((IDictionary) objectToConvert, session);
|
||||||
}
|
}
|
||||||
else if (objectToConvert is ISerializable)
|
if (objectToConvert != null && objectToConvert.GetType().IsSerializable)
|
||||||
{
|
{
|
||||||
return
|
return CreateMessageForSerializable(objectToConvert, session);
|
||||||
CreateMessageForSerializable(((ISerializable) objectToConvert), session);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new MessageConversionException("Cannot convert object [" + objectToConvert + "] to EMS message");
|
|
||||||
}
|
}
|
||||||
|
throw new MessageConversionException("Cannot convert object [" + objectToConvert + "] to EMS message");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Convert from a EMS Message to a .NET object.</summary>
|
/// <summary> Convert from a EMS Message to a .NET object.</summary>
|
||||||
@@ -91,22 +86,19 @@ namespace Spring.Messaging.Ems.Support.Converter
|
|||||||
{
|
{
|
||||||
return ExtractStringFromMessage((TextMessage) messageToConvert);
|
return ExtractStringFromMessage((TextMessage) messageToConvert);
|
||||||
}
|
}
|
||||||
else if (messageToConvert is BytesMessage)
|
if (messageToConvert is BytesMessage)
|
||||||
{
|
{
|
||||||
return ExtractByteArrayFromMessage((BytesMessage) messageToConvert);
|
return ExtractByteArrayFromMessage((BytesMessage) messageToConvert);
|
||||||
}
|
}
|
||||||
else if (messageToConvert is MapMessage)
|
if (messageToConvert is MapMessage)
|
||||||
{
|
{
|
||||||
return ExtractMapFromMessage((MapMessage) messageToConvert);
|
return ExtractMapFromMessage((MapMessage) messageToConvert);
|
||||||
}
|
}
|
||||||
else if (messageToConvert is ObjectMessage)
|
if (messageToConvert is ObjectMessage)
|
||||||
{
|
{
|
||||||
return ExtractSerializableFromMessage((ObjectMessage) messageToConvert);
|
return ExtractSerializableFromMessage((ObjectMessage) messageToConvert);
|
||||||
}
|
}
|
||||||
else
|
return messageToConvert;
|
||||||
{
|
|
||||||
return messageToConvert;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region To Converter Methods
|
#region To Converter Methods
|
||||||
@@ -172,7 +164,7 @@ namespace Spring.Messaging.Ems.Support.Converter
|
|||||||
/// </returns>
|
/// </returns>
|
||||||
/// <throws> EMSException if thrown by EMS methods </throws>
|
/// <throws> EMSException if thrown by EMS methods </throws>
|
||||||
protected virtual ObjectMessage CreateMessageForSerializable(
|
protected virtual ObjectMessage CreateMessageForSerializable(
|
||||||
ISerializable objectToSend, Session session)
|
object objectToSend, Session session)
|
||||||
{
|
{
|
||||||
return session.CreateObjectMessage(objectToSend);
|
return session.CreateObjectMessage(objectToSend);
|
||||||
}
|
}
|
||||||
@@ -232,7 +224,7 @@ namespace Spring.Messaging.Ems.Support.Converter
|
|||||||
protected virtual object ExtractSerializableFromMessage(
|
protected virtual object ExtractSerializableFromMessage(
|
||||||
ObjectMessage message)
|
ObjectMessage message)
|
||||||
{
|
{
|
||||||
return message.TheObject as ISerializable;
|
return message.TheObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -0,0 +1,200 @@
|
|||||||
|
#region License
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright <20> 2002-2006 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;
|
||||||
|
using System.Collections;
|
||||||
|
using Spring.Core.TypeResolution;
|
||||||
|
|
||||||
|
namespace Spring.Messaging.Ems.Support.Converter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides a layer of indirection when adding the 'type' of the object as a message property.
|
||||||
|
/// </summary>
|
||||||
|
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;
|
||||||
|
|
||||||
|
private string defaultHashtableTypeId = "Hashtable";
|
||||||
|
|
||||||
|
private Type defaultHashtableClass = typeof(Hashtable);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="TypeMapper"/>
|
||||||
|
/// </summary>
|
||||||
|
public TypeMapper()
|
||||||
|
{
|
||||||
|
idTypeMapping = new Hashtable();
|
||||||
|
typeIdMapping = new Hashtable();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the id type mapping.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The id type mapping.</value>
|
||||||
|
public IDictionary IdTypeMapping
|
||||||
|
{
|
||||||
|
get { return idTypeMapping; }
|
||||||
|
set { idTypeMapping = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the name of the field in the message that has type information..
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The name of the type id field.</value>
|
||||||
|
public string TypeIdFieldName
|
||||||
|
{
|
||||||
|
get { return "__TypeId__"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the default hashtable class.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The default hashtable class.</value>
|
||||||
|
public Type DefaultHashtableClass
|
||||||
|
{
|
||||||
|
set { defaultHashtableClass = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert from a type to a string.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="typeOfObjectToConvert">The type of object to convert.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert from a string to a type
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="typeId">The type id.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the default namespace.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The default namespace.</value>
|
||||||
|
public string DefaultNamespace
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return defaultNamespace;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
defaultNamespace = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the default name of the assembly.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The default name of the assembly.</value>
|
||||||
|
public string DefaultAssemblyName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return defaultAssemblyName;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
defaultAssemblyName = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Afters the properties set.
|
||||||
|
/// </summary>
|
||||||
|
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,181 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
using TIBCO.EMS;
|
||||||
|
|
||||||
|
namespace Spring.Messaging.Ems.Support.Converter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Convert an object via XML serialization for sending via an ITextMessage
|
||||||
|
/// </summary>
|
||||||
|
/// <author>Mark Pollack</author>
|
||||||
|
public class XmlMessageConverter : IMessageConverter
|
||||||
|
{
|
||||||
|
private IMessageConverter defaultMessageConverter = new SimpleMessageConverter();
|
||||||
|
|
||||||
|
|
||||||
|
private ITypeMapper typeMapper;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the type mapper.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The type mapper.</value>
|
||||||
|
public ITypeMapper TypeMapper
|
||||||
|
{
|
||||||
|
set { typeMapper = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert a .NET object to a NMS Message using the supplied session
|
||||||
|
/// to create the message object.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="objectToConvert">the object to convert</param>
|
||||||
|
/// <param name="session">the Session to use for creating a NMS Message</param>
|
||||||
|
/// <returns>the NMS Message</returns>
|
||||||
|
/// <throws>NMSException if thrown by NMS API methods </throws>
|
||||||
|
/// <throws>MessageConversionException in case of conversion failure </throws>
|
||||||
|
public Message ToMessage(object objectToConvert, Session 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);
|
||||||
|
Message msg = session.CreateTextMessage(xmlString);
|
||||||
|
msg.SetStringProperty(typeMapper.TypeIdFieldName, typeMapper.FromType(objectToConvert.GetType()));
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new MessageConversionException("Can't convert object of type " + objectToConvert.GetType(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the XML string for an object
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="objectToConvert">The object to convert.</param>
|
||||||
|
/// <returns>XML string</returns>
|
||||||
|
protected virtual 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();
|
||||||
|
}
|
||||||
|
return xmlString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert from a NMS Message to a .NET object.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="messageToConvert">the message to convert</param>
|
||||||
|
/// <returns>the converted .NET object</returns>
|
||||||
|
/// <throws>MessageConversionException in case of conversion failure </throws>
|
||||||
|
public object FromMessage(Message messageToConvert)
|
||||||
|
{
|
||||||
|
if (messageToConvert == null)
|
||||||
|
{
|
||||||
|
throw new MessageConversionException("Can't convert null message");
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string converterId = messageToConvert.GetStringProperty(typeMapper.TypeIdFieldName);
|
||||||
|
if (converterId == null)
|
||||||
|
{
|
||||||
|
return defaultMessageConverter.FromMessage(messageToConvert);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TextMessage textMessage = messageToConvert as TextMessage;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the type of the target given the message.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message.</param>
|
||||||
|
/// <returns>Type of the target</returns>
|
||||||
|
protected virtual Type GetTargetType(TextMessage message)
|
||||||
|
{
|
||||||
|
return typeMapper.ToType(message.GetStringProperty(typeMapper.TypeIdFieldName));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts a byte array to a UTF8 string.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="characters">The characters.</param>
|
||||||
|
/// <returns>UTF8 string</returns>
|
||||||
|
protected virtual String UTF8ByteArrayToString(Byte[] characters)
|
||||||
|
{
|
||||||
|
UTF8Encoding encoding = new UTF8Encoding();
|
||||||
|
|
||||||
|
String constructedString = encoding.GetString(characters);
|
||||||
|
|
||||||
|
return (constructedString);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts a UTF8 string to a byte array
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="xmlString">The p XML string.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected virtual Byte[] StringToUTF8ByteArray(String xmlString)
|
||||||
|
{
|
||||||
|
UTF8Encoding encoding = new UTF8Encoding();
|
||||||
|
|
||||||
|
Byte[] byteArray = encoding.GetBytes(xmlString);
|
||||||
|
|
||||||
|
return byteArray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,7 +4,8 @@
|
|||||||
xmlns:nms="http://www.springframework.net/ems">
|
xmlns:nms="http://www.springframework.net/ems">
|
||||||
|
|
||||||
<nms:listener-container connection-factory="testConnectionFactory"
|
<nms:listener-container connection-factory="testConnectionFactory"
|
||||||
destination-resolver="testDestinationResolver" message-converter="testMessageConverter">
|
destination-resolver="testDestinationResolver" message-converter="testMessageConverter"
|
||||||
|
auto-startup="false" concurrency="${concurrency}">
|
||||||
<nms:listener id="listener1" destination="testDestination" ref="testObject1" method="SetName"/>
|
<nms:listener id="listener1" destination="testDestination" ref="testObject1" method="SetName"/>
|
||||||
<nms:listener id="listener2" destination="testDestination" ref="testObject2" method="SetName"
|
<nms:listener id="listener2" destination="testDestination" ref="testObject2" method="SetName"
|
||||||
response-destination="responseDestination"/>
|
response-destination="responseDestination"/>
|
||||||
@@ -36,5 +37,15 @@
|
|||||||
|
|
||||||
<object id="testObject3" type="Spring.Messaging.Ems.Connections.TestMessageListener, Spring.Messaging.Ems.Tests"/>
|
<object id="testObject3" type="Spring.Messaging.Ems.Connections.TestMessageListener, Spring.Messaging.Ems.Tests"/>
|
||||||
|
|
||||||
|
<object type="Spring.Objects.Factory.Config.VariablePlaceholderConfigurer, Spring.Core">
|
||||||
|
<property name="VariableSources">
|
||||||
|
<list>
|
||||||
|
<object type="Spring.Objects.Factory.Config.ConfigSectionVariableSource, Spring.Core">
|
||||||
|
<property name="SectionNames" value="NmsConfiguration" />
|
||||||
|
</object>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</object>
|
||||||
|
|
||||||
</objects>
|
</objects>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user