SPRNET-1019 - Messaging namespace parser should support use of PropertyPlaceholderConfigurer
SPRNET-1024 - Add AutoStartup as an attribute of the <listener-container> element
This commit is contained in:
@@ -22,6 +22,7 @@ using System;
|
||||
using System.Xml;
|
||||
using Apache.NMS;
|
||||
using Spring.Core.TypeConversion;
|
||||
using Spring.Core.TypeResolution;
|
||||
using Spring.Messaging.Nms.Listener;
|
||||
using Spring.Messaging.Nms.Listener.Adapter;
|
||||
using Spring.Objects.Factory.Config;
|
||||
@@ -89,7 +90,11 @@ namespace Spring.Messaging.Nms.Config
|
||||
|
||||
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 AUTO_STARTUP = "auto-startup";
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -202,13 +207,44 @@ namespace Spring.Messaging.Nms.Config
|
||||
private ObjectDefinitionBuilder ParseContainer(XmlElement listenerElement, XmlElement containerElement,
|
||||
ParserContext parserContext)
|
||||
{
|
||||
//Only support SimpleMessageListenerContainer
|
||||
//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);
|
||||
}
|
||||
}
|
||||
|
||||
ObjectDefinitionBuilder containerDef =
|
||||
parserContext.ParserHelper.CreateRootObjectDefinitionBuilder(typeof (SimpleMessageListenerContainer));
|
||||
parserContext.ParserHelper.CreateRootObjectDefinitionBuilder(containerType);
|
||||
|
||||
ParseListenerConfiguration(listenerElement, 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";
|
||||
if (containerElement.HasAttribute(CONNECTION_FACTORY_ATTRIBUTE))
|
||||
{
|
||||
@@ -219,6 +255,7 @@ namespace Spring.Messaging.Nms.Config
|
||||
"Listener container '" + CONNECTION_FACTORY_ATTRIBUTE +
|
||||
"' attribute contains empty value.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
containerDef.AddPropertyValue("ConnectionFactory", new RuntimeObjectReference(connectionFactoryObjectName));
|
||||
@@ -237,10 +274,10 @@ namespace Spring.Messaging.Nms.Config
|
||||
containerDef.AddPropertyValue("SessionAcknowledgeMode", acknowledgementMode);
|
||||
}
|
||||
|
||||
int[] concurrency = ParseConcurrency(containerElement, parserContext);
|
||||
string concurrency = ParseConcurrency(containerElement, parserContext);
|
||||
if (concurrency != null)
|
||||
{
|
||||
containerDef.AddPropertyValue("ConcurrentConsumers", concurrency[1]);
|
||||
containerDef.AddPropertyValue("ConcurrentConsumers", concurrency);
|
||||
}
|
||||
containerDef.AddPropertyValue("RecoveryInterval", ParseRecoveryInterval(containerElement, parserContext));
|
||||
|
||||
@@ -358,60 +395,40 @@ namespace Spring.Messaging.Nms.Config
|
||||
return AcknowledgementMode.AutoAcknowledge;
|
||||
}
|
||||
|
||||
private int[] ParseConcurrency(XmlElement ele, ParserContext parserContext)
|
||||
private string ParseConcurrency(XmlElement ele, ParserContext parserContext)
|
||||
{
|
||||
string concurrency = ele.GetAttribute(CONCURRENCY_ATTRIBUTE);
|
||||
if (!StringUtils.HasText(concurrency))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
try
|
||||
} else
|
||||
{
|
||||
return new int[] {1, Int32.Parse(concurrency)};
|
||||
}
|
||||
catch (FormatException ex)
|
||||
return concurrency;
|
||||
}
|
||||
}
|
||||
|
||||
private string ParseRecoveryInterval(XmlElement ele, ParserContext parserContext)
|
||||
{
|
||||
string recoveryInterval = ele.GetAttribute(RECOVERY_INTERVAL_ATTRIBUTE);
|
||||
if (StringUtils.HasText(recoveryInterval))
|
||||
{
|
||||
parserContext.ReaderContext.ReportException(ele, CONCURRENCY_ATTRIBUTE,
|
||||
"Invalid concurrency value [" + concurrency + "]: only " +
|
||||
"integer (e.g. \"5\") values upported.", ex);
|
||||
return null;
|
||||
return recoveryInterval;
|
||||
|
||||
} else
|
||||
{
|
||||
return SimpleMessageListenerContainer.DEFAULT_RECOVERY_INTERVAL;
|
||||
}
|
||||
}
|
||||
|
||||
private TimeSpan ParseRecoveryInterval(XmlElement ele, ParserContext parserContext)
|
||||
{
|
||||
string recoveryInterval = ele.GetAttribute(RECOVERY_INTERVAL_ATTRIBUTE);
|
||||
if (!StringUtils.HasText(recoveryInterval))
|
||||
{
|
||||
return SimpleMessageListenerContainer.DEFAULT_RECOVERY_INTERVAL;
|
||||
}
|
||||
try
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
private TimeSpan ParseMaxRecoveryTime(XmlElement ele, ParserContext parserContext)
|
||||
private string ParseMaxRecoveryTime(XmlElement ele, ParserContext parserContext)
|
||||
{
|
||||
string recoverTime = ele.GetAttribute(MAX_RECOVERY_TIME_ATTRIBUTE);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,26 @@
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</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:documentation><![CDATA[
|
||||
A reference to the NMS ConnectionFactory object.
|
||||
|
||||
@@ -49,12 +49,12 @@ namespace Spring.Messaging.Nms.Listener
|
||||
/// <summary>
|
||||
/// The default recovery time interval between connection reconnection attempts
|
||||
/// </summary>
|
||||
public static TimeSpan DEFAULT_RECOVERY_INTERVAL = new TimeSpan(0,0,0,5,0);
|
||||
public static string DEFAULT_RECOVERY_INTERVAL = "5s";
|
||||
|
||||
/// <summary>
|
||||
/// The total time connection recovery will be attempted.
|
||||
/// </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;
|
||||
|
||||
@@ -66,9 +66,9 @@ namespace Spring.Messaging.Nms.Listener
|
||||
|
||||
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
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
xmlns:nms="http://www.springframework.net/nms">
|
||||
|
||||
<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="listener2" destination="testDestination" ref="testObject2" method="SetName"
|
||||
response-destination="responseDestination"/>
|
||||
@@ -36,5 +37,15 @@
|
||||
|
||||
<object id="testObject3" type="Spring.Messaging.Nms.Connections.TestMessageListener, Spring.Messaging.Nms.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>
|
||||
|
||||
|
||||
@@ -17,11 +17,19 @@ limitations under the License.
|
||||
<configuration>
|
||||
|
||||
<configSections>
|
||||
<section name="NmsConfiguration" type="System.Configuration.NameValueSectionHandler"/>
|
||||
|
||||
<sectionGroup name="common">
|
||||
<section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
|
||||
|
||||
<NmsConfiguration>
|
||||
<add key="concurrency" value="4"/>
|
||||
</NmsConfiguration>
|
||||
|
||||
|
||||
<common>
|
||||
<logging>
|
||||
<factoryAdapter type="Common.Logging.Simple.ConsoleOutLoggerFactoryAdapter, Common.Logging">
|
||||
|
||||
Reference in New Issue
Block a user