TIBCO EMS Integration - SPRNET-982
This commit is contained in:
@@ -0,0 +1,49 @@
|
|||||||
|
#region License
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2007 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 Spring.Objects.Factory.Xml;
|
||||||
|
|
||||||
|
namespace Spring.Messaging.Ems.Config
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Namespace parser for the nms namespace.
|
||||||
|
/// </summary>
|
||||||
|
/// <author>Mark Fisher</author>
|
||||||
|
/// <author>Juergen Hoeller</author>
|
||||||
|
/// <author>Mark Pollack (.NET)</author>
|
||||||
|
[
|
||||||
|
NamespaceParser(
|
||||||
|
Namespace = "http://www.springframework.net/ems",
|
||||||
|
SchemaLocationAssemblyHint = typeof (EmsNamespaceParser),
|
||||||
|
SchemaLocation = "/Spring.Messaging.Ems.Config/spring-ems-1.2.xsd"
|
||||||
|
)
|
||||||
|
]
|
||||||
|
public class EmsNamespaceParser : NamespaceParserSupport
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Register a MessageListenerContainer for the '<code>listener-container</code>' tag.
|
||||||
|
/// </summary>
|
||||||
|
public override void Init()
|
||||||
|
{
|
||||||
|
RegisterObjectDefinitionParser("listener-container", new MessageListenerContainerObjectDefinitionParser());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,414 @@
|
|||||||
|
#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;
|
||||||
|
using System.Xml;
|
||||||
|
using TIBCO.EMS;
|
||||||
|
using Spring.Core.TypeConversion;
|
||||||
|
using Spring.Messaging.Ems.Listener;
|
||||||
|
using Spring.Messaging.Ems.Listener.Adapter;
|
||||||
|
using Spring.Objects.Factory.Config;
|
||||||
|
using Spring.Objects.Factory.Support;
|
||||||
|
using Spring.Objects.Factory.Xml;
|
||||||
|
using Spring.Util;
|
||||||
|
|
||||||
|
namespace Spring.Messaging.Ems.Config
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Parser for the EMS <code><listener-container></code> element.
|
||||||
|
/// </summary>
|
||||||
|
/// <author>Mark Fisher</author>
|
||||||
|
/// <author>Juergen Hoeller</author>
|
||||||
|
/// <author>Mark Pollack (.NET)</author>
|
||||||
|
public class MessageListenerContainerObjectDefinitionParser : IObjectDefinitionParser
|
||||||
|
{
|
||||||
|
#region Fields
|
||||||
|
|
||||||
|
private readonly string LISTENER_ELEMENT = "listener";
|
||||||
|
|
||||||
|
private readonly string ID_ATTRIBUTE = "id";
|
||||||
|
|
||||||
|
private readonly string DESTINATION_ATTRIBUTE = "destination";
|
||||||
|
|
||||||
|
private readonly string SUBSCRIPTION_ATTRIBUTE = "subscription";
|
||||||
|
|
||||||
|
private readonly string SELECTOR_ATTRIBUTE = "selector";
|
||||||
|
|
||||||
|
private readonly string REF_ATTRIBUTE = "ref";
|
||||||
|
|
||||||
|
private readonly string METHOD_ATTRIBUTE = "method";
|
||||||
|
|
||||||
|
private readonly string DESTINATION_RESOLVER_ATTRIBUTE = "destination-resolver";
|
||||||
|
|
||||||
|
private readonly string MESSAGE_CONVERTER_ATTRIBUTE = "message-converter";
|
||||||
|
|
||||||
|
private readonly string RESPONSE_DESTINATION_ATTRIBUTE = "response-destination";
|
||||||
|
|
||||||
|
private readonly string DESTINATION_TYPE_ATTRIBUTE = "destination-type";
|
||||||
|
|
||||||
|
private readonly string DESTINATION_TYPE_QUEUE = "queue";
|
||||||
|
|
||||||
|
private readonly string DESTINATION_TYPE_TOPIC = "topic";
|
||||||
|
|
||||||
|
private readonly string DESTINATION_TYPE_DURABLE_TOPIC = "durableTopic";
|
||||||
|
|
||||||
|
private readonly string CLIENT_ID_ATTRIBUTE = "client-id";
|
||||||
|
|
||||||
|
private readonly string ACKNOWLEDGE_ATTRIBUTE = "acknowledge";
|
||||||
|
|
||||||
|
private readonly string ACKNOWLEDGE_AUTO = "auto";
|
||||||
|
|
||||||
|
private readonly string ACKNOWLEDGE_CLIENT = "client";
|
||||||
|
|
||||||
|
private readonly string ACKNOWLEDGE_DUPS_OK = "dups-ok";
|
||||||
|
|
||||||
|
private readonly string ACKNOWLEDGE_TRANSACTED = "transacted";
|
||||||
|
|
||||||
|
private readonly string CONCURRENCY_ATTRIBUTE = "concurrency";
|
||||||
|
|
||||||
|
private readonly string RECOVERY_INTERVAL_ATTRIBUTE = "recovery-interval";
|
||||||
|
|
||||||
|
private readonly string MAX_RECOVERY_TIME_ATTRIBUTE = "max-recovery-time";
|
||||||
|
|
||||||
|
private readonly string CONNECTION_FACTORY_ATTRIBUTE = "connection-factory";
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IObjectDefinitionParser Members
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parse the specified XmlElement and register the resulting
|
||||||
|
/// ObjectDefinitions with the <see cref="ParserContext.Registry"/> IObjectDefinitionRegistry
|
||||||
|
/// embedded in the supplied <see cref="ParserContext"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="element">The element to be parsed.</param>
|
||||||
|
/// <param name="parserContext">TThe object encapsulating the current state of the parsing process.
|
||||||
|
/// Provides access to a IObjectDefinitionRegistry</param>
|
||||||
|
/// <returns>The primary object definition.</returns>
|
||||||
|
/// <remarks>
|
||||||
|
/// <p>
|
||||||
|
/// This method is never invoked if the parser is namespace aware
|
||||||
|
/// and was called to process the root node.
|
||||||
|
/// </p>
|
||||||
|
/// </remarks>
|
||||||
|
public IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext)
|
||||||
|
{
|
||||||
|
|
||||||
|
XmlNodeList childNodes = element.ChildNodes;
|
||||||
|
foreach (XmlNode childNode in childNodes)
|
||||||
|
{
|
||||||
|
if (childNode.NodeType == XmlNodeType.Element)
|
||||||
|
{
|
||||||
|
string localName = childNode.LocalName;
|
||||||
|
if (LISTENER_ELEMENT.Equals(localName))
|
||||||
|
{
|
||||||
|
ParseListener((XmlElement) childNode, element, parserContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private void ParseListener(XmlElement listenerElement, XmlElement containerElement, ParserContext parserContext)
|
||||||
|
{
|
||||||
|
ObjectDefinitionBuilder listenerDefBuilder =
|
||||||
|
parserContext.ParserHelper.CreateRootObjectDefinitionBuilder(typeof (MessageListenerAdapter));
|
||||||
|
|
||||||
|
string reference = listenerElement.GetAttribute(REF_ATTRIBUTE);
|
||||||
|
if (!StringUtils.HasText(reference))
|
||||||
|
{
|
||||||
|
parserContext.ReaderContext.ReportException(listenerElement, LISTENER_ELEMENT,
|
||||||
|
"Listener '" + REF_ATTRIBUTE +
|
||||||
|
"' attribute contains empty value.");
|
||||||
|
}
|
||||||
|
listenerDefBuilder.AddPropertyValue("HandlerObject", new RuntimeObjectReference(reference));
|
||||||
|
|
||||||
|
string handlerMethod = null;
|
||||||
|
if (listenerElement.HasAttribute(METHOD_ATTRIBUTE))
|
||||||
|
{
|
||||||
|
handlerMethod = listenerElement.GetAttribute(METHOD_ATTRIBUTE);
|
||||||
|
{
|
||||||
|
if (!StringUtils.HasText(handlerMethod))
|
||||||
|
{
|
||||||
|
parserContext.ReaderContext.ReportException(listenerElement, LISTENER_ELEMENT,
|
||||||
|
"Listener '" + METHOD_ATTRIBUTE +
|
||||||
|
"' attribute contains empty value.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
listenerDefBuilder.AddPropertyValue("DefaultHandlerMethod", handlerMethod);
|
||||||
|
|
||||||
|
if (containerElement.HasAttribute(MESSAGE_CONVERTER_ATTRIBUTE))
|
||||||
|
{
|
||||||
|
string messageConverter = containerElement.GetAttribute(MESSAGE_CONVERTER_ATTRIBUTE);
|
||||||
|
listenerDefBuilder.AddPropertyValue("MessageConverter", new RuntimeObjectReference(messageConverter));
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectDefinitionBuilder containerDefBuilder = ParseContainer(listenerElement, containerElement, parserContext);
|
||||||
|
|
||||||
|
if (listenerElement.HasAttribute(RESPONSE_DESTINATION_ATTRIBUTE))
|
||||||
|
{
|
||||||
|
string responseDestination = listenerElement.GetAttribute(RESPONSE_DESTINATION_ATTRIBUTE);
|
||||||
|
bool pubSubDomain = IndicatesPubSub(containerDefBuilder.RawObjectDefinition);
|
||||||
|
listenerDefBuilder.AddPropertyValue(pubSubDomain ? "DefaultResponseTopicName" : "DefaultResponseQueueName",
|
||||||
|
responseDestination);
|
||||||
|
if (containerDefBuilder.RawObjectDefinition.PropertyValues.Contains("DestinationResolver"))
|
||||||
|
{
|
||||||
|
listenerDefBuilder.AddPropertyValue("DestinationResolver",
|
||||||
|
containerDefBuilder.RawObjectDefinition.PropertyValues.GetPropertyValue
|
||||||
|
(
|
||||||
|
"DestinationResolver").Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
containerDefBuilder.AddPropertyValue("MessageListener", listenerDefBuilder.ObjectDefinition);
|
||||||
|
|
||||||
|
string containerObjectName = listenerElement.GetAttribute(ID_ATTRIBUTE);
|
||||||
|
// If no object id is given auto generate one using the ReaderContext's ObjectNameGenerator
|
||||||
|
if (!StringUtils.HasText(containerObjectName))
|
||||||
|
{
|
||||||
|
containerObjectName =
|
||||||
|
parserContext.ReaderContext.GenerateObjectName(containerDefBuilder.RawObjectDefinition);
|
||||||
|
}
|
||||||
|
|
||||||
|
parserContext.Registry.RegisterObjectDefinition(containerObjectName, containerDefBuilder.ObjectDefinition);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ObjectDefinitionBuilder ParseContainer(XmlElement listenerElement, XmlElement containerElement,
|
||||||
|
ParserContext parserContext)
|
||||||
|
{
|
||||||
|
//Only support SimpleMessageListenerContainer
|
||||||
|
ObjectDefinitionBuilder containerDef =
|
||||||
|
parserContext.ParserHelper.CreateRootObjectDefinitionBuilder(typeof (SimpleMessageListenerContainer));
|
||||||
|
|
||||||
|
ParseListenerConfiguration(listenerElement, parserContext, containerDef);
|
||||||
|
ParseContainerConfiguration(containerElement, parserContext, containerDef);
|
||||||
|
|
||||||
|
string connectionFactoryObjectName = "connectionFactory";
|
||||||
|
if (containerElement.HasAttribute(CONNECTION_FACTORY_ATTRIBUTE))
|
||||||
|
{
|
||||||
|
connectionFactoryObjectName = containerElement.GetAttribute(CONNECTION_FACTORY_ATTRIBUTE);
|
||||||
|
if (!StringUtils.HasText(connectionFactoryObjectName))
|
||||||
|
{
|
||||||
|
parserContext.ReaderContext.ReportException(listenerElement, LISTENER_ELEMENT,
|
||||||
|
"Listener container '" + CONNECTION_FACTORY_ATTRIBUTE +
|
||||||
|
"' attribute contains empty value.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
containerDef.AddPropertyValue("ConnectionFactory", new RuntimeObjectReference(connectionFactoryObjectName));
|
||||||
|
|
||||||
|
string destinationResolverBeanName = containerElement.GetAttribute(DESTINATION_RESOLVER_ATTRIBUTE);
|
||||||
|
if (StringUtils.HasText(destinationResolverBeanName))
|
||||||
|
{
|
||||||
|
containerDef.AddPropertyValue("DestinationResolver",
|
||||||
|
new RuntimeObjectReference(destinationResolverBeanName));
|
||||||
|
}
|
||||||
|
|
||||||
|
string acknowledge = containerElement.GetAttribute(ACKNOWLEDGE_ATTRIBUTE);
|
||||||
|
if (StringUtils.HasText(acknowledge))
|
||||||
|
{
|
||||||
|
int acknowledgementMode = ParseAcknowledgementMode(containerElement, parserContext);
|
||||||
|
containerDef.AddPropertyValue("SessionAcknowledgeMode", acknowledgementMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
int[] concurrency = ParseConcurrency(containerElement, parserContext);
|
||||||
|
if (concurrency != null)
|
||||||
|
{
|
||||||
|
containerDef.AddPropertyValue("ConcurrentConsumers", concurrency[1]);
|
||||||
|
}
|
||||||
|
containerDef.AddPropertyValue("RecoveryInterval", ParseRecoveryInterval(containerElement, parserContext));
|
||||||
|
|
||||||
|
containerDef.AddPropertyValue("MaxRecoveryTime", ParseMaxRecoveryTime(containerElement, parserContext));
|
||||||
|
|
||||||
|
return containerDef;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IndicatesPubSub(AbstractObjectDefinition configDef)
|
||||||
|
{
|
||||||
|
return (bool) configDef.PropertyValues.GetPropertyValue("PubSubDomain").Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ParseListenerConfiguration(XmlElement ele, ParserContext parserContext,
|
||||||
|
ObjectDefinitionBuilder containerDef)
|
||||||
|
{
|
||||||
|
string destination = ele.GetAttribute(DESTINATION_ATTRIBUTE);
|
||||||
|
if (!StringUtils.HasText(destination))
|
||||||
|
{
|
||||||
|
parserContext.ReaderContext.ReportException(ele, LISTENER_ELEMENT,
|
||||||
|
"Listener '" + DESTINATION_ATTRIBUTE +
|
||||||
|
"' attribute contains empty value.");
|
||||||
|
}
|
||||||
|
containerDef.AddPropertyValue("DestinationName", destination);
|
||||||
|
|
||||||
|
if (ele.HasAttribute(SUBSCRIPTION_ATTRIBUTE))
|
||||||
|
{
|
||||||
|
string subscription = ele.GetAttribute(SUBSCRIPTION_ATTRIBUTE);
|
||||||
|
if (!StringUtils.HasText(subscription))
|
||||||
|
{
|
||||||
|
parserContext.ReaderContext.ReportException(ele, SUBSCRIPTION_ATTRIBUTE,
|
||||||
|
"Listener '" + SUBSCRIPTION_ATTRIBUTE +
|
||||||
|
"' attribute contains empty value.");
|
||||||
|
}
|
||||||
|
containerDef.AddPropertyValue("DurableSubscriptionName", subscription);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ele.HasAttribute(SELECTOR_ATTRIBUTE))
|
||||||
|
{
|
||||||
|
string selector = ele.GetAttribute(SELECTOR_ATTRIBUTE);
|
||||||
|
if (!StringUtils.HasText(selector))
|
||||||
|
{
|
||||||
|
parserContext.ReaderContext.ReportException(ele, selector,
|
||||||
|
"Listener '" + SELECTOR_ATTRIBUTE +
|
||||||
|
"' attribute contains empty value.");
|
||||||
|
}
|
||||||
|
containerDef.AddPropertyValue("MessageSelector", selector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ParseContainerConfiguration(XmlElement ele, ParserContext parserContext,
|
||||||
|
ObjectDefinitionBuilder containerDef)
|
||||||
|
{
|
||||||
|
string destinationType = ele.GetAttribute(DESTINATION_TYPE_ATTRIBUTE);
|
||||||
|
bool pubSubDomain = false;
|
||||||
|
bool subscriptionDurable = false;
|
||||||
|
if (DESTINATION_TYPE_DURABLE_TOPIC.Equals(destinationType))
|
||||||
|
{
|
||||||
|
pubSubDomain = true;
|
||||||
|
subscriptionDurable = true;
|
||||||
|
}
|
||||||
|
else if (DESTINATION_TYPE_TOPIC.Equals(destinationType))
|
||||||
|
{
|
||||||
|
pubSubDomain = true;
|
||||||
|
}
|
||||||
|
else if ("".Equals(destinationType) || DESTINATION_TYPE_QUEUE.Equals(destinationType))
|
||||||
|
{
|
||||||
|
// the default: queue
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parserContext.ReaderContext.ReportException(ele, destinationType,
|
||||||
|
"Invalid listener container '" + DESTINATION_TYPE_ATTRIBUTE +
|
||||||
|
"': only 'queue', 'topic' and 'durableTopic' supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
containerDef.AddPropertyValue("PubSubDomain", pubSubDomain);
|
||||||
|
containerDef.AddPropertyValue("SubscriptionDurable", subscriptionDurable);
|
||||||
|
|
||||||
|
if (ele.HasAttribute(CLIENT_ID_ATTRIBUTE))
|
||||||
|
{
|
||||||
|
string clientId = ele.GetAttribute(CLIENT_ID_ATTRIBUTE);
|
||||||
|
if (!StringUtils.HasText(clientId))
|
||||||
|
{
|
||||||
|
parserContext.ReaderContext.ReportException(ele, clientId,
|
||||||
|
"Listener '" + CLIENT_ID_ATTRIBUTE +
|
||||||
|
"' attribute contains empty value.");
|
||||||
|
}
|
||||||
|
containerDef.AddPropertyValue("ClientId", clientId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int ParseAcknowledgementMode(XmlElement element, ParserContext parserContext)
|
||||||
|
{
|
||||||
|
string acknowledge = element.GetAttribute(ACKNOWLEDGE_ATTRIBUTE);
|
||||||
|
if (acknowledge.Equals(ACKNOWLEDGE_TRANSACTED))
|
||||||
|
{
|
||||||
|
return Session.SESSION_TRANSACTED;
|
||||||
|
}
|
||||||
|
else if (acknowledge.Equals(ACKNOWLEDGE_DUPS_OK))
|
||||||
|
{
|
||||||
|
return Session.DUPS_OK_ACKNOWLEDGE;
|
||||||
|
}
|
||||||
|
else if (acknowledge.Equals(ACKNOWLEDGE_CLIENT))
|
||||||
|
{
|
||||||
|
return Session.CLIENT_ACKNOWLEDGE;
|
||||||
|
}
|
||||||
|
//TODO other ack modes.
|
||||||
|
else if (!acknowledge.Equals(ACKNOWLEDGE_AUTO))
|
||||||
|
{
|
||||||
|
parserContext.ReaderContext.ReportException(element, ACKNOWLEDGE_ATTRIBUTE,
|
||||||
|
"Invalid listener container 'acknowledge' setting ['" +
|
||||||
|
acknowledge +
|
||||||
|
"]: only \"auto\", \"client\", \"dups-ok\" and \"transacted\" supported.");
|
||||||
|
}
|
||||||
|
return Session.AUTO_ACKNOWLEDGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int[] ParseConcurrency(XmlElement ele, ParserContext parserContext)
|
||||||
|
{
|
||||||
|
string concurrency = ele.GetAttribute(CONCURRENCY_ATTRIBUTE);
|
||||||
|
if (!StringUtils.HasText(concurrency))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return new int[] {1, Int32.Parse(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)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
string recoverTime = ele.GetAttribute(MAX_RECOVERY_TIME_ATTRIBUTE);
|
||||||
|
if (!StringUtils.HasText(recoverTime))
|
||||||
|
{
|
||||||
|
return SimpleMessageListenerContainer.DEFAULT_MAX_RECOVERY_TIME;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,201 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<xsd:schema xmlns="http://www.springframework.net/ems"
|
||||||
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:vs="http://schemas.microsoft.com/Visual-Studio-Intellisense"
|
||||||
|
targetNamespace="http://www.springframework.net/ems"
|
||||||
|
elementFormDefault="qualified"
|
||||||
|
attributeFormDefault="unqualified"
|
||||||
|
vs:friendlyname="Spring.NET TIBCO EMS Configuration" vs:ishtmlschema="false" vs:iscasesensitive="true" vs:requireattributequotes="true" vs:defaultnamespacequalifier="" vs:defaultnsprefix="">
|
||||||
|
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
Defines the configuration elements for the Spring Framework's TIBCO EMS support.
|
||||||
|
Allows for configuring EMS listener containers in XML 'shortcut' style.
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
|
||||||
|
<xsd:element name="listener-container">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
Each listener child element will be hosted by a container whose configuration
|
||||||
|
is determined by this parent element. This variant builds standard
|
||||||
|
listener containers, operating against a specified ConnectionFactory.
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="listener" type="listenerType" minOccurs="0" maxOccurs="unbounded"/>
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="container-type" default="simple">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
The type of this listener container: "simple" is the only option as of Spring.NET 1.2
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:simpleType>
|
||||||
|
<xsd:restriction base="xsd:NMTOKEN">
|
||||||
|
<xsd:enumeration value="simple"/>
|
||||||
|
</xsd:restriction>
|
||||||
|
</xsd:simpleType>
|
||||||
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="connection-factory" type="xsd:string" default="ConnectionFactory">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
A reference to the ConnectionFactory object.
|
||||||
|
Default is "ConnectionFactory".
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="destination-resolver" type="xsd:string">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
A reference to the DestinationResolver strategy for resolving destination names.
|
||||||
|
Default is a DynamicDestinationResolver, using the provider's queue/topic
|
||||||
|
name resolution.]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="message-converter" type="xsd:string">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
A reference to the MessageConverter strategy for converting Messages to
|
||||||
|
listener method arguments. Default is a SimpleMessageConverter.
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="destination-type" default="queue">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
The destination type for this listener: "queue", "topic" or "durableTopic".
|
||||||
|
The default is "queue".
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:simpleType>
|
||||||
|
<xsd:restriction base="xsd:NMTOKEN">
|
||||||
|
<xsd:enumeration value="queue"/>
|
||||||
|
<xsd:enumeration value="topic"/>
|
||||||
|
<xsd:enumeration value="durableTopic"/>
|
||||||
|
</xsd:restriction>
|
||||||
|
</xsd:simpleType>
|
||||||
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="client-id" type="xsd:string">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
The client id for this listener container.
|
||||||
|
Needs to be specified when using durable subscriptions.
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="acknowledge" default="auto">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
The native EMS acknowledge mode: "auto", "client", "dups-ok" or "transacted".
|
||||||
|
A value of "transacted" effectively activates a locally transacted Session;
|
||||||
|
as alternative, specify an external "transaction-manager" via the corresponding
|
||||||
|
attribute. Default is "auto".
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:simpleType>
|
||||||
|
<xsd:restriction base="xsd:NMTOKEN">
|
||||||
|
<xsd:enumeration value="auto"/>
|
||||||
|
<xsd:enumeration value="client"/>
|
||||||
|
<xsd:enumeration value="dups-ok"/>
|
||||||
|
<xsd:enumeration value="transacted"/>
|
||||||
|
</xsd:restriction>
|
||||||
|
</xsd:simpleType>
|
||||||
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="concurrency" type="xsd:string">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
The number of concurrent sessions/consumers to start for each listener.
|
||||||
|
Default is 1; keep concurrency limited to 1 in case of a topic listener
|
||||||
|
or if message ordering is important; consider raising it for general queues.
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="recovery-interval" type="xsd:string">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
<![CDATA[
|
||||||
|
The TimeSpan interval to sleep in between connection recovery attemtps. Default is 5 seconds.
|
||||||
|
]]>
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="max-recovery-time" type="xsd:string">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
<![CDATA[
|
||||||
|
The TimeSpan interval in which connection recovery attempts will be made. Default is 10 minutes.
|
||||||
|
]]>
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
|
||||||
|
|
||||||
|
<xsd:complexType name="listenerType">
|
||||||
|
<xsd:attribute name="id" type="xsd:ID">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
The unique identifier for a listener.
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="destination" type="xsd:string" use="required">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
The destination name for this listener, resolved through the
|
||||||
|
container-wide IDestinationResolver strategy (if any). Required.
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="subscription" type="xsd:string">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
The name for the durable subscription, if any.
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="selector" type="xsd:string">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
The message selector for this listener.
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="ref" type="xsd:string" use="required">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
The object name of the listener object, implementing
|
||||||
|
the IMessageListener/ISessionAwareMessageListener interface
|
||||||
|
or defining the specified listener method. Required.
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="method" type="xsd:string">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
The name of the listener method to invoke. If not specified,
|
||||||
|
the target object is supposed to implement the IMessageListener
|
||||||
|
or ISessionAwareMessageListener interface.
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="response-destination" type="xsd:string">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
The name of the default response destination to send response messages to.
|
||||||
|
This will be applied in case of a request message that does not carry
|
||||||
|
a "ReplyTo" field. The type of this destination will be determined
|
||||||
|
by the listener-container's "destination-type" attribute.
|
||||||
|
Note: This only applies to a listener method with a return value,
|
||||||
|
for which each result object will be converted into a response message.
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
|
</xsd:complexType>
|
||||||
|
|
||||||
|
</xsd:schema>
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
#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 Common.Logging;
|
||||||
|
using Spring.Objects.Factory;
|
||||||
|
using TIBCO.EMS;
|
||||||
|
|
||||||
|
namespace Spring.Messaging.Ems.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Convenient super class for application classes that need EMS access.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Requires a ConnectionFactory or a EmsTemplate instance to be set.
|
||||||
|
/// It will create its own EmsTemplate if a ConnectionFactory is passed in.
|
||||||
|
/// A custom EmsTemplate instance can be created for a given ConnectionFactory
|
||||||
|
/// through overriding the <code>createEmsTemplate</code> method.
|
||||||
|
///
|
||||||
|
/// </remarks>
|
||||||
|
public class EmsGatewaySupport : IInitializingObject
|
||||||
|
{
|
||||||
|
|
||||||
|
#region Logging
|
||||||
|
|
||||||
|
private readonly ILog logger = LogManager.GetLogger(typeof(EmsGatewaySupport));
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private EmsTemplate jmsTemplate;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the EMS template for the gateway.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The EMS template.</value>
|
||||||
|
public EmsTemplate EmsTemplate
|
||||||
|
{
|
||||||
|
get { return jmsTemplate; }
|
||||||
|
set { jmsTemplate = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets he EMS connection factory to be used by the gateway.
|
||||||
|
/// Will automatically create a EmsTemplate for the given ConnectionFactory.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The connection factory.</value>
|
||||||
|
public ConnectionFactory ConnectionFactory
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (jmsTemplate != null ? this.jmsTemplate.ConnectionFactory : null);
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
this.jmsTemplate = CreateEmsTemplate(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a EmsTemplate for the given ConnectionFactory.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Only invoked if populating the gateway with a ConnectionFactory reference.
|
||||||
|
/// Can be overridden in subclasses to provide a different EmsTemplate instance
|
||||||
|
/// </remarks>
|
||||||
|
///
|
||||||
|
/// <param name="connectionFactory">The connection factory.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected virtual EmsTemplate CreateEmsTemplate(ConnectionFactory connectionFactory)
|
||||||
|
{
|
||||||
|
return new EmsTemplate(connectionFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ensures that the JmsTemplate is specified and calls <see cref="InitGateway"/>.
|
||||||
|
/// </summary>
|
||||||
|
public virtual void AfterPropertiesSet()
|
||||||
|
{
|
||||||
|
if (jmsTemplate == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("connectionFactory or jmsTemplate is required");
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
InitGateway();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new ObjectInitializationException("Initialization of the EMS gateway failed: " + e.Message, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Subclasses can override this for custom initialization behavior.
|
||||||
|
/// Gets called after population of this instance's properties.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void InitGateway()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1649
src/Spring/Spring.Messaging.Ems/Messaging/Ems/Core/EmsTemplate.cs
Normal file
1649
src/Spring/Spring.Messaging.Ems/Messaging/Ems/Core/EmsTemplate.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,436 @@
|
|||||||
|
#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 Spring.Messaging.Ems.Core;
|
||||||
|
using TIBCO.EMS;
|
||||||
|
|
||||||
|
namespace Spring.Messaging.Ems.Core
|
||||||
|
{
|
||||||
|
/// <summary>Specifies a basic set of EMS operations.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <p>Implemented by EmsTemplate. Not often used but a useful option
|
||||||
|
/// to enhance testability, as it can easily be mocked or stubbed.</p>
|
||||||
|
///
|
||||||
|
/// <p>Provides <code>EmsTemplate's</code> <code>send(..)</code> and
|
||||||
|
/// <code>receive(..)</code> methods that mirror various EMS API methods.
|
||||||
|
/// See the EMS specification and EMS API docs for details on those methods.
|
||||||
|
/// </p>
|
||||||
|
/// </remarks>
|
||||||
|
/// <author>Mark Pollack</author>
|
||||||
|
/// <author>Juergen Hoeller</author>
|
||||||
|
/// <author>Mark Pollack (.NET)</author>
|
||||||
|
public interface IEmsOperations
|
||||||
|
{
|
||||||
|
/// <summary> Execute the action specified by the given action object within
|
||||||
|
/// a EMS Session.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="del">delegate that exposes the session</param>
|
||||||
|
/// <returns> the result object from working with the session
|
||||||
|
/// </returns>
|
||||||
|
/// <throws>EMSException if there is any problem </throws>
|
||||||
|
object Execute(SessionDelegate del);
|
||||||
|
|
||||||
|
/// <summary> Execute the action specified by the given action object within
|
||||||
|
/// a EMS Session.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="action">callback object that exposes the session
|
||||||
|
/// </param>
|
||||||
|
/// <returns> the result object from working with the session
|
||||||
|
/// </returns>
|
||||||
|
/// <throws>EMSException if there is any problem </throws>
|
||||||
|
object Execute(ISessionCallback action);
|
||||||
|
|
||||||
|
/// <summary> Send a message to a EMS destination. The callback gives access to
|
||||||
|
/// the EMS session and MessageProducer in order to do more complex
|
||||||
|
/// send operations.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="action">callback object that exposes the session/producer pair
|
||||||
|
/// </param>
|
||||||
|
/// <returns> the result object from working with the session
|
||||||
|
/// </returns>
|
||||||
|
/// <throws>EMSException if there is any problem </throws>
|
||||||
|
object Execute(IProducerCallback action);
|
||||||
|
|
||||||
|
/// <summary> Send a message to a EMS destination. The callback gives access to
|
||||||
|
/// the EMS session and MessageProducer in order to do more complex
|
||||||
|
/// send operations.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="del">delegate that exposes the session/producer pair
|
||||||
|
/// </param>
|
||||||
|
/// <returns> the result object from working with the session
|
||||||
|
/// </returns>
|
||||||
|
/// <throws>EMSException if there is any problem </throws>
|
||||||
|
object Execute(ProducerDelegate del);
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
// Convenience methods for sending messages
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// <summary> Send a message to the default destination.
|
||||||
|
/// <p>This will only work with a default destination specified!</p>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="messageCreator">callback to create a message
|
||||||
|
/// </param>
|
||||||
|
/// <throws>EMSException if there is any problem</throws>
|
||||||
|
void Send(IMessageCreator messageCreator);
|
||||||
|
|
||||||
|
/// <summary> Send a message to the specified destination.
|
||||||
|
/// The IMessageCreator callback creates the message given a Session.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="destination">the destination to send this message to
|
||||||
|
/// </param>
|
||||||
|
/// <param name="messageCreator">callback to create a message
|
||||||
|
/// </param>
|
||||||
|
/// <throws>EMSException if there is any problem</throws>
|
||||||
|
void Send(Destination destination, IMessageCreator messageCreator);
|
||||||
|
|
||||||
|
/// <summary> Send a message to the specified destination.
|
||||||
|
/// The IMessageCreator callback creates the message given a Session.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="destinationName">the name of the destination to send this message to
|
||||||
|
/// (to be resolved to an actual destination by a DestinationResolver)
|
||||||
|
/// </param>
|
||||||
|
/// <param name="messageCreator">callback to create a message
|
||||||
|
/// </param>
|
||||||
|
/// <throws>EMSException if there is any problem</throws>
|
||||||
|
void Send(string destinationName, IMessageCreator messageCreator);
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
// Convenience methods for sending messages
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// <summary> Send a message to the default destination.
|
||||||
|
/// <p>This will only work with a default destination specified!</p>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="messageCreatorDelegate">delegate callback to create a message
|
||||||
|
/// </param>
|
||||||
|
/// <throws>EMSException if there is any problem</throws>
|
||||||
|
void SendWithDelegate(MessageCreatorDelegate messageCreatorDelegate);
|
||||||
|
|
||||||
|
/// <summary> Send a message to the specified destination.
|
||||||
|
/// The IMessageCreator callback creates the message given a Session.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="destination">the destination to send this message to
|
||||||
|
/// </param>
|
||||||
|
/// <param name="messageCreatorDelegate">delegate callback to create a message
|
||||||
|
/// </param>
|
||||||
|
/// <throws>EMSException if there is any problem</throws>
|
||||||
|
void SendWithDelegate(Destination destination, MessageCreatorDelegate messageCreatorDelegate);
|
||||||
|
|
||||||
|
/// <summary> Send a message to the specified destination.
|
||||||
|
/// The IMessageCreator callback creates the message given a Session.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="destinationName">the name of the destination to send this message to
|
||||||
|
/// (to be resolved to an actual destination by a DestinationResolver)
|
||||||
|
/// </param>
|
||||||
|
/// <param name="messageCreatorDelegate">delegate callback to create a message
|
||||||
|
/// </param>
|
||||||
|
/// <throws>EMSException if there is any problem</throws>
|
||||||
|
void SendWithDelegate(string destinationName, MessageCreatorDelegate messageCreatorDelegate);
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
// Convenience methods for sending auto-converted messages
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// <summary> Send the given object to the default destination, converting the object
|
||||||
|
/// to a EMS message with a configured IMessageConverter.
|
||||||
|
/// <p>This will only work with a default destination specified!</p>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">the object to convert to a message
|
||||||
|
/// </param>
|
||||||
|
/// <throws>EMSException if there is any problem</throws>
|
||||||
|
void ConvertAndSend(object message);
|
||||||
|
|
||||||
|
/// <summary> Send the given object to the specified destination, converting the object
|
||||||
|
/// to a EMS message with a configured IMessageConverter.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="destination">the destination to send this message to
|
||||||
|
/// </param>
|
||||||
|
/// <param name="message">the object to convert to a message
|
||||||
|
/// </param>
|
||||||
|
/// <throws>EMSException if there is any problem</throws>
|
||||||
|
void ConvertAndSend(Destination destination, object message);
|
||||||
|
|
||||||
|
/// <summary> Send the given object to the specified destination, converting the object
|
||||||
|
/// to a EMS message with a configured IMessageConverter.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="destinationName">the name of the destination to send this message to
|
||||||
|
/// (to be resolved to an actual destination by a DestinationResolver)
|
||||||
|
/// </param>
|
||||||
|
/// <param name="message">the object to convert to a message
|
||||||
|
/// </param>
|
||||||
|
/// <throws>EMSException if there is any problem</throws>
|
||||||
|
void ConvertAndSend(string destinationName, object message);
|
||||||
|
|
||||||
|
/// <summary> Send the given object to the default destination, converting the object
|
||||||
|
/// to a EMS message with a configured IMessageConverter. The IMessagePostProcessor
|
||||||
|
/// callback allows for modification of the message after conversion.
|
||||||
|
/// <p>This will only work with a default destination specified!</p>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">the object to convert to a message
|
||||||
|
/// </param>
|
||||||
|
/// <param name="postProcessor">the callback to modify the message
|
||||||
|
/// </param>
|
||||||
|
/// <throws>EMSException if there is any problem</throws>
|
||||||
|
void ConvertAndSend(object message, IMessagePostProcessor postProcessor);
|
||||||
|
|
||||||
|
/// <summary> Send the given object to the specified destination, converting the object
|
||||||
|
/// to a EMS message with a configured IMessageConverter. The IMessagePostProcessor
|
||||||
|
/// callback allows for modification of the message after conversion.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="destination">the destination to send this message to
|
||||||
|
/// </param>
|
||||||
|
/// <param name="message">the object to convert to a message
|
||||||
|
/// </param>
|
||||||
|
/// <param name="postProcessor">the callback to modify the message
|
||||||
|
/// </param>
|
||||||
|
/// <throws>EMSException if there is any problem</throws>
|
||||||
|
void ConvertAndSend(Destination destination, object message, IMessagePostProcessor postProcessor);
|
||||||
|
|
||||||
|
/// <summary> Send the given object to the specified destination, converting the object
|
||||||
|
/// to a EMS message with a configured IMessageConverter. The IMessagePostProcessor
|
||||||
|
/// callback allows for modification of the message after conversion.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="destinationName">the name of the destination to send this message to
|
||||||
|
/// (to be resolved to an actual destination by a DestinationResolver)
|
||||||
|
/// </param>
|
||||||
|
/// <param name="message">the object to convert to a message.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="postProcessor">the callback to modify the message
|
||||||
|
/// </param>
|
||||||
|
/// <throws>EMSException if there is any problem</throws>
|
||||||
|
void ConvertAndSend(string destinationName, object message, IMessagePostProcessor postProcessor);
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Send the given object to the default destination, converting the object
|
||||||
|
/// to a EMS message with a configured IMessageConverter. The IMessagePostProcessor
|
||||||
|
/// callback allows for modification of the message after conversion.
|
||||||
|
/// <p>This will only work with a default destination specified!</p>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">the object to convert to a message</param>
|
||||||
|
/// <param name="postProcessor">the callback to modify the message</param>
|
||||||
|
/// <throws>EMSException if there is any problem</throws>
|
||||||
|
void ConvertAndSendWithDelegate(object message, MessagePostProcessorDelegate postProcessor);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Send the given object to the specified destination, converting the object
|
||||||
|
/// to a EMS message with a configured IMessageConverter. The IMessagePostProcessor
|
||||||
|
/// callback allows for modification of the message after conversion.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="destination">the destination to send this message to</param>
|
||||||
|
/// <param name="message">the object to convert to a message</param>
|
||||||
|
/// <param name="postProcessor">the callback to modify the message</param>
|
||||||
|
/// <throws>EMSException if there is any problem</throws>
|
||||||
|
void ConvertAndSendWithDelegate(Destination destination, object message, MessagePostProcessorDelegate postProcessor);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Send the given object to the specified destination, converting the object
|
||||||
|
/// to a EMS message with a configured IMessageConverter. The IMessagePostProcessor
|
||||||
|
/// callback allows for modification of the message after conversion.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="destinationName">the name of the destination to send this message to
|
||||||
|
/// (to be resolved to an actual destination by a DestinationResolver)</param>
|
||||||
|
/// <param name="message">the object to convert to a message.</param>
|
||||||
|
/// <param name="postProcessor">the callback to modify the message</param>
|
||||||
|
/// <throws>EMSException if there is any problem</throws>
|
||||||
|
void ConvertAndSendWithDelegate(string destinationName, object message, MessagePostProcessorDelegate postProcessor);
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
// Convenience methods for receiving messages
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// <summary> Receive a message synchronously from the default destination, but only
|
||||||
|
/// wait up to a specified time for delivery.
|
||||||
|
/// <p>This method should be used carefully, since it will block the thread
|
||||||
|
/// until the message becomes available or until the timeout value is exceeded.</p>
|
||||||
|
/// <p>This will only work with a default destination specified!</p>
|
||||||
|
/// </summary>
|
||||||
|
/// <returns> the message received by the consumer, or <code>null</code> if the timeout expires
|
||||||
|
/// </returns>
|
||||||
|
/// <throws>EMSException if there is any problem</throws>
|
||||||
|
Message Receive();
|
||||||
|
|
||||||
|
/// <summary> Receive a message synchronously from the specified destination, but only
|
||||||
|
/// wait up to a specified time for delivery.
|
||||||
|
/// <p>This method should be used carefully, since it will block the thread
|
||||||
|
/// until the message becomes available or until the timeout value is exceeded.</p>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="destination">the destination to receive a message from
|
||||||
|
/// </param>
|
||||||
|
/// <returns> the message received by the consumer, or <code>null</code> if the timeout expires
|
||||||
|
/// </returns>
|
||||||
|
/// <throws>EMSException if there is any problem</throws>
|
||||||
|
Message Receive(Destination destination);
|
||||||
|
|
||||||
|
/// <summary> Receive a message synchronously from the specified destination, but only
|
||||||
|
/// wait up to a specified time for delivery.
|
||||||
|
/// <p>This method should be used carefully, since it will block the thread
|
||||||
|
/// until the message becomes available or until the timeout value is exceeded.</p>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="destinationName">the name of the destination to send this message to
|
||||||
|
/// (to be resolved to an actual destination by a DestinationResolver)
|
||||||
|
/// </param>
|
||||||
|
/// <returns> the message received by the consumer, or <code>null</code> if the timeout expires
|
||||||
|
/// </returns>
|
||||||
|
/// <throws>EMSException if there is any problem</throws>
|
||||||
|
Message Receive(string destinationName);
|
||||||
|
|
||||||
|
/// <summary> Receive a message synchronously from the default destination, but only
|
||||||
|
/// wait up to a specified time for delivery.
|
||||||
|
/// <p>This method should be used carefully, since it will block the thread
|
||||||
|
/// until the message becomes available or until the timeout value is exceeded.</p>
|
||||||
|
/// <p>This will only work with a default destination specified!</p>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="messageSelector">the EMS message selector expression (or <code>null</code> if none).
|
||||||
|
/// See the EMS specification for a detailed definition of selector expressions.
|
||||||
|
/// </param>
|
||||||
|
/// <returns> the message received by the consumer, or <code>null</code> if the timeout expires
|
||||||
|
/// </returns>
|
||||||
|
/// <throws>EMSException if there is any problem</throws>
|
||||||
|
Message ReceiveSelected(string messageSelector);
|
||||||
|
|
||||||
|
/// <summary> Receive a message synchronously from the specified destination, but only
|
||||||
|
/// wait up to a specified time for delivery.
|
||||||
|
/// <p>This method should be used carefully, since it will block the thread
|
||||||
|
/// until the message becomes available or until the timeout value is exceeded.</p>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="destination">the destination to receive a message from
|
||||||
|
/// </param>
|
||||||
|
/// <param name="messageSelector">the EMS message selector expression (or <code>null</code> if none).
|
||||||
|
/// See the EMS specification for a detailed definition of selector expressions.
|
||||||
|
/// </param>
|
||||||
|
/// <returns> the message received by the consumer, or <code>null</code> if the timeout expires
|
||||||
|
/// </returns>
|
||||||
|
/// <throws>EMSException if there is any problem</throws>
|
||||||
|
Message ReceiveSelected(Destination destination, string messageSelector);
|
||||||
|
|
||||||
|
/// <summary> Receive a message synchronously from the specified destination, but only
|
||||||
|
/// wait up to a specified time for delivery.
|
||||||
|
/// <p>This method should be used carefully, since it will block the thread
|
||||||
|
/// until the message becomes available or until the timeout value is exceeded.</p>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="destinationName">the name of the destination to send this message to
|
||||||
|
/// (to be resolved to an actual destination by a DestinationResolver)
|
||||||
|
/// </param>
|
||||||
|
/// <param name="messageSelector">the EMS message selector expression (or <code>null</code> if none).
|
||||||
|
/// See the EMS specification for a detailed definition of selector expressions.
|
||||||
|
/// </param>
|
||||||
|
/// <returns> the message received by the consumer, or <code>null</code> if the timeout expires
|
||||||
|
/// </returns>
|
||||||
|
/// <throws>EMSException if there is any problem</throws>
|
||||||
|
Message ReceiveSelected(string destinationName, string messageSelector);
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
// Convenience methods for receiving auto-converted messages
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// <summary> Receive a message synchronously from the default destination, but only
|
||||||
|
/// wait up to a specified time for delivery. Convert the message into an
|
||||||
|
/// object with a configured IMessageConverter.
|
||||||
|
/// <p>This method should be used carefully, since it will block the thread
|
||||||
|
/// until the message becomes available or until the timeout value is exceeded.</p>
|
||||||
|
/// <p>This will only work with a default destination specified!</p>
|
||||||
|
/// </summary>
|
||||||
|
/// <returns> the message produced for the consumer or <code>null</code> if the timeout expires.
|
||||||
|
/// </returns>
|
||||||
|
/// <throws>EMSException if there is any problem</throws>
|
||||||
|
object ReceiveAndConvert();
|
||||||
|
|
||||||
|
/// <summary> Receive a message synchronously from the specified destination, but only
|
||||||
|
/// wait up to a specified time for delivery. Convert the message into an
|
||||||
|
/// object with a configured IMessageConverter.
|
||||||
|
/// <p>This method should be used carefully, since it will block the thread
|
||||||
|
/// until the message becomes available or until the timeout value is exceeded.</p>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="destination">the destination to receive a message from
|
||||||
|
/// </param>
|
||||||
|
/// <returns> the message produced for the consumer or <code>null</code> if the timeout expires.
|
||||||
|
/// </returns>
|
||||||
|
/// <throws>EMSException if there is any problem</throws>
|
||||||
|
object ReceiveAndConvert(Destination destination);
|
||||||
|
|
||||||
|
/// <summary> Receive a message synchronously from the specified destination, but only
|
||||||
|
/// wait up to a specified time for delivery. Convert the message into an
|
||||||
|
/// object with a configured IMessageConverter.
|
||||||
|
/// <p>This method should be used carefully, since it will block the thread
|
||||||
|
/// until the message becomes available or until the timeout value is exceeded.</p>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="destinationName">the name of the destination to send this message to
|
||||||
|
/// (to be resolved to an actual destination by a DestinationResolver)
|
||||||
|
/// </param>
|
||||||
|
/// <returns> the message produced for the consumer or <code>null</code> if the timeout expires.
|
||||||
|
/// </returns>
|
||||||
|
/// <throws>EMSException if there is any problem</throws>
|
||||||
|
object ReceiveAndConvert(string destinationName);
|
||||||
|
|
||||||
|
/// <summary> Receive a message synchronously from the default destination, but only
|
||||||
|
/// wait up to a specified time for delivery. Convert the message into an
|
||||||
|
/// object with a configured IMessageConverter.
|
||||||
|
/// <p>This method should be used carefully, since it will block the thread
|
||||||
|
/// until the message becomes available or until the timeout value is exceeded.</p>
|
||||||
|
/// <p>This will only work with a default destination specified!</p>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="messageSelector">the EMS message selector expression (or <code>null</code> if none).
|
||||||
|
/// See the EMS specification for a detailed definition of selector expressions.
|
||||||
|
/// </param>
|
||||||
|
/// <returns> the message produced for the consumer or <code>null</code> if the timeout expires.
|
||||||
|
/// </returns>
|
||||||
|
/// <throws>EMSException if there is any problem</throws>
|
||||||
|
object ReceiveSelectedAndConvert(string messageSelector);
|
||||||
|
|
||||||
|
/// <summary> Receive a message synchronously from the specified destination, but only
|
||||||
|
/// wait up to a specified time for delivery. Convert the message into an
|
||||||
|
/// object with a configured IMessageConverter.
|
||||||
|
/// <p>This method should be used carefully, since it will block the thread
|
||||||
|
/// until the message becomes available or until the timeout value is exceeded.</p>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="destination">the destination to receive a message from
|
||||||
|
/// </param>
|
||||||
|
/// <param name="messageSelector">the EMS message selector expression (or <code>null</code> if none).
|
||||||
|
/// See the EMS specification for a detailed definition of selector expressions.
|
||||||
|
/// </param>
|
||||||
|
/// <returns> the message produced for the consumer or <code>null</code> if the timeout expires.
|
||||||
|
/// </returns>
|
||||||
|
/// <throws>EMSException if there is any problem</throws>
|
||||||
|
object ReceiveSelectedAndConvert(Destination destination, string messageSelector);
|
||||||
|
|
||||||
|
/// <summary> Receive a message synchronously from the specified destination, but only
|
||||||
|
/// wait up to a specified time for delivery. Convert the message into an
|
||||||
|
/// object with a configured IMessageConverter.
|
||||||
|
/// <p>This method should be used carefully, since it will block the thread
|
||||||
|
/// until the message becomes available or until the timeout value is exceeded.</p>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="destinationName">the name of the destination to send this message to
|
||||||
|
/// (to be resolved to an actual destination by a DestinationResolver)
|
||||||
|
/// </param>
|
||||||
|
/// <param name="messageSelector">the EMS message selector expression (or <code>null</code> if none).
|
||||||
|
/// See the EMS specification for a detailed definition of selector expressions.
|
||||||
|
/// </param>
|
||||||
|
/// <returns> the message produced for the consumer or <code>null</code> if the timeout expires.
|
||||||
|
/// </returns>
|
||||||
|
/// <throws>EMSException if there is any problem</throws>
|
||||||
|
object ReceiveSelectedAndConvert(string destinationName, string messageSelector);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
#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 TIBCO.EMS;
|
||||||
|
|
||||||
|
namespace Spring.Messaging.Ems.Core
|
||||||
|
{
|
||||||
|
/// <summary> Creates a EMS message given a Session</summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <p>The Session typically is provided by an instance
|
||||||
|
/// of the EmsTemplate class.</p>
|
||||||
|
/// </remarks>
|
||||||
|
/// <author>Mark Pollack</author>
|
||||||
|
public interface IMessageCreator
|
||||||
|
{
|
||||||
|
/// <summary> Create a Message to be sent.</summary>
|
||||||
|
/// <param name="session">the EMS Session to be used to create the
|
||||||
|
/// <code>Message</code> (never <code>null</code>)
|
||||||
|
/// </param>
|
||||||
|
/// <returns> the <code>Message</code> to be sent
|
||||||
|
/// </returns>
|
||||||
|
/// <throws>EMSException if thrown by EMS API methods </throws>
|
||||||
|
Message CreateMessage(Session session);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
#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 TIBCO.EMS;
|
||||||
|
|
||||||
|
namespace Spring.Messaging.Ems.Core
|
||||||
|
{
|
||||||
|
/// <summary> To be used with EmsTemplate's send method that
|
||||||
|
/// convert an object to a message.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// It allows for further modification of the message after it has been processed
|
||||||
|
/// by the converter. This is useful for setting of EMS Header and Properties.
|
||||||
|
/// </remarks>
|
||||||
|
/// <author>Mark Pollack</author>
|
||||||
|
public interface IMessagePostProcessor
|
||||||
|
{
|
||||||
|
/// <summary> Apply a IMessagePostProcessor to the message. The returned message is
|
||||||
|
/// typically a modified version of the original.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">the EMS message from the IMessageConverter
|
||||||
|
/// </param>
|
||||||
|
/// <returns> the modified version of the Message
|
||||||
|
/// </returns>
|
||||||
|
/// <throws>EMSException if thrown by EMS API methods </throws>
|
||||||
|
Message PostProcessMessage(Message message);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
#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 TIBCO.EMS;
|
||||||
|
|
||||||
|
namespace Spring.Messaging.Ems.Core
|
||||||
|
{
|
||||||
|
/// <summary> Callback for sending a message to a EMS destination.</summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <p>To be used with the EmsTemplate.Execute(IProducerCallback)
|
||||||
|
/// method, often implemented as an anonymous inner class.</p>
|
||||||
|
///
|
||||||
|
/// <p>The typical implementation will perform multiple operations on the
|
||||||
|
/// supplied EMS Session and MessageProducer. </p>
|
||||||
|
/// </remarks>
|
||||||
|
/// <author>Mark Pollack</author>
|
||||||
|
public interface IProducerCallback
|
||||||
|
{
|
||||||
|
/// <summary> Perform operations on the given Session and MessageProducer.
|
||||||
|
/// The message producer is not associated with any destination.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="session">the EMS <code>Session</code> object to use
|
||||||
|
/// </param>
|
||||||
|
/// <param name="producer">the EMS <code>MessageProducer</code> object to use
|
||||||
|
/// </param>
|
||||||
|
/// <returns> a result object from working with the <code>Session</code>, if any (can be <code>null</code>)
|
||||||
|
/// </returns>
|
||||||
|
object DoInEms(Session session, MessageProducer producer);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
#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 TIBCO.EMS;
|
||||||
|
|
||||||
|
namespace Spring.Messaging.Ems.Core
|
||||||
|
{
|
||||||
|
/// <summary> Callback for executing any number of operations on a provided
|
||||||
|
/// Session
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <p>To be used with the EmsTemplate.Execute(ISessionCallback)}
|
||||||
|
/// method, often implemented as an anonymous inner class.</p>
|
||||||
|
/// </remarks>
|
||||||
|
/// <author>Mark Pollack</author>
|
||||||
|
/// <seealso cref="EmsTemplate.Execute(ISessionCallback,bool)">
|
||||||
|
/// </seealso>
|
||||||
|
public interface ISessionCallback
|
||||||
|
{
|
||||||
|
/// <summary> Execute any number of operations against the supplied EMS
|
||||||
|
/// Session, possibly returning a result.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="session">the EMS <code>Session</code>
|
||||||
|
/// </param>
|
||||||
|
/// <returns> a result object from working with the <code>Session</code>, if any (so can be <code>null</code>)
|
||||||
|
/// </returns>
|
||||||
|
/// <throws>EMSException if there is any problem </throws>
|
||||||
|
object DoInEms(Session session);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
#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 TIBCO.EMS;
|
||||||
|
|
||||||
|
namespace Spring.Messaging.Ems.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Delegate that creates a EMS message given a Session
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="session">the EMS Session to be used to create the
|
||||||
|
/// <code>Message</code> (never <code>null</code>)
|
||||||
|
/// </param>
|
||||||
|
/// <returns> the <code>Message</code> to be sent
|
||||||
|
/// </returns>
|
||||||
|
/// <throws>EMSException if thrown by EMS API methods </throws>
|
||||||
|
public delegate Message MessageCreatorDelegate(Session session);
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#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 TIBCO.EMS;
|
||||||
|
|
||||||
|
namespace Spring.Messaging.Ems.Core
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Delegate that is used with EmsTemplate's ConvertAndSend method that converts
|
||||||
|
/// an object.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// It allows for further modification of the message after it has been processed
|
||||||
|
/// by the converter. This is useful for setting of EMS Header and Properties.
|
||||||
|
/// </remarks>
|
||||||
|
/// <author>Mark Pollack</author>
|
||||||
|
public delegate Message MessagePostProcessorDelegate(Message message);
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#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 TIBCO.EMS;
|
||||||
|
|
||||||
|
namespace Spring.Messaging.Ems.Core
|
||||||
|
{
|
||||||
|
/// <summary> Perform operations on the given Session and MessageProducer.
|
||||||
|
/// The message producer is not associated with any destination.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="session">the EMS <code>Session</code> object to use
|
||||||
|
/// </param>
|
||||||
|
/// <param name="producer">the EMS <code>MessageProducer</code> object to use
|
||||||
|
/// </param>
|
||||||
|
/// <returns> a result object from working with the <code>Session</code>, if any (can be <code>null</code>)
|
||||||
|
/// </returns>
|
||||||
|
public delegate object ProducerDelegate(Session session, MessageProducer producer);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
#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 TIBCO.EMS;
|
||||||
|
|
||||||
|
namespace Spring.Messaging.Ems.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Callback delegate for code that operates on a Session.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="session">The EMS Session object.</param>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>Allows you to execute any number of operations
|
||||||
|
/// on a single ISession, possibly returning a result a result.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
/// <returns>A result object from working with the <code>Session</code>, if any (so can be <code>null</code>)
|
||||||
|
/// </returns>
|
||||||
|
/// <throws>EMSException if there is any problem </throws>
|
||||||
|
/// <author>Mark Pollack</author>
|
||||||
|
public delegate object SessionDelegate(Session session);
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
using Spring.Messaging.Ems.Listener.Adapter;
|
||||||
|
using TIBCO.EMS;
|
||||||
|
|
||||||
|
namespace Spring.Messaging.Ems.Listener
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Exception thrown when the maximum connection recovery time has been exceeded.
|
||||||
|
/// </summary>
|
||||||
|
/// <author>Mark Pollack</author>
|
||||||
|
public class RecoveryTimeExceededException : EMSException
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="RecoveryTimeExceededException"/> class, with the specified message
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message.</param>
|
||||||
|
public RecoveryTimeExceededException(string message) : base(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ListenerExecutionFailedException"/> class, with the specified message
|
||||||
|
/// and root cause exception
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message.</param>
|
||||||
|
/// <param name="innerException">The inner exception.</param>
|
||||||
|
public RecoveryTimeExceededException(string message, Exception innerException)
|
||||||
|
: base(message)
|
||||||
|
{
|
||||||
|
LinkedException = innerException;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
#region License
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright <20> 2002-2007 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
|
||||||
|
|
||||||
|
#region Imports
|
||||||
|
|
||||||
|
using System.Collections;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using Rhino.Mocks;
|
||||||
|
using Spring.Context;
|
||||||
|
using Spring.Context.Support;
|
||||||
|
using Spring.Messaging.Ems.Listener;
|
||||||
|
using Spring.Objects.Factory.Xml;
|
||||||
|
using TIBCO.EMS;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
namespace Spring.Messaging.Ems.Config
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This class contains tests for
|
||||||
|
/// </summary>
|
||||||
|
/// <author>Mark Pollack</author>
|
||||||
|
/// <version>$Id:$</version>
|
||||||
|
[TestFixture]
|
||||||
|
public class EmsNamespaceHandlerTests
|
||||||
|
{
|
||||||
|
|
||||||
|
private static string DEFAULT_CONNECTION_FACTORY = "ConnectionFactory";
|
||||||
|
|
||||||
|
private static string EXPLICIT_CONNECTION_FACTORY = "testConnectionFactory";
|
||||||
|
|
||||||
|
|
||||||
|
private IApplicationContext ctx;
|
||||||
|
|
||||||
|
private MockRepository mocks;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
NamespaceParserRegistry.RegisterParser(typeof(EmsNamespaceParser));
|
||||||
|
ctx = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("EmsNamespaceHandlerTests.xml", GetType()));
|
||||||
|
mocks = new MockRepository();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Registered()
|
||||||
|
{
|
||||||
|
Assert.IsNotNull(NamespaceParserRegistry.GetParser("http://www.springframework.net/ems"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ObjectsCreated()
|
||||||
|
{
|
||||||
|
IDictionary containers = ctx.GetObjectsOfType(typeof(SimpleMessageListenerContainer));
|
||||||
|
Assert.AreEqual(3, containers.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ContainerConfiguration()
|
||||||
|
{
|
||||||
|
IDictionary containers = ctx.GetObjectsOfType(typeof (SimpleMessageListenerContainer));
|
||||||
|
ConnectionFactory defaultConnectionFactory = (ConnectionFactory) ctx.GetObject(DEFAULT_CONNECTION_FACTORY);
|
||||||
|
ConnectionFactory explicitConnectionFactory = (ConnectionFactory) ctx.GetObject(EXPLICIT_CONNECTION_FACTORY);
|
||||||
|
|
||||||
|
|
||||||
|
int defaultConnectionFactoryCount = 0;
|
||||||
|
int explicitConnectionFactoryCount = 0;
|
||||||
|
foreach (DictionaryEntry dictionaryEntry in containers)
|
||||||
|
{
|
||||||
|
SimpleMessageListenerContainer container = (SimpleMessageListenerContainer) dictionaryEntry.Value;
|
||||||
|
if (container.ConnectionFactory.Equals(defaultConnectionFactory))
|
||||||
|
{
|
||||||
|
defaultConnectionFactoryCount++;
|
||||||
|
}
|
||||||
|
else if (container.ConnectionFactory.Equals(explicitConnectionFactory))
|
||||||
|
{
|
||||||
|
explicitConnectionFactoryCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.AreEqual(1, defaultConnectionFactoryCount, "1 container should have the default connectionFactory");
|
||||||
|
Assert.AreEqual(2, explicitConnectionFactoryCount, "2 containers should have the explicit connectionFactory");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<objects xmlns="http://www.springframework.net"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:nms="http://www.springframework.net/ems">
|
||||||
|
|
||||||
|
<nms:listener-container connection-factory="testConnectionFactory"
|
||||||
|
destination-resolver="testDestinationResolver" message-converter="testMessageConverter">
|
||||||
|
<nms:listener id="listener1" destination="testDestination" ref="testObject1" method="SetName"/>
|
||||||
|
<nms:listener id="listener2" destination="testDestination" ref="testObject2" method="SetName"
|
||||||
|
response-destination="responseDestination"/>
|
||||||
|
</nms:listener-container>
|
||||||
|
|
||||||
|
<nms:listener-container>
|
||||||
|
<nms:listener destination="testDestination" ref="testObject3"/>
|
||||||
|
</nms:listener-container>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- the default ConnectionFactory -->
|
||||||
|
<object id="ConnectionFactory" type="TIBCO.EMS.ConnectionFactory, TIBCO.EMS"/>
|
||||||
|
|
||||||
|
<object id="testConnectionFactory" type="TIBCO.EMS.ConnectionFactory, TIBCO.EMS"/>
|
||||||
|
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<bean id="testActivationSpecFactory" class="org.springframework.jms.listener.endpoint.StubJmsActivationSpecFactory"/>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<object id="testDestinationResolver" type="Spring.Messaging.Ems.Support.Destinations.DynamicDestinationResolver, Spring.Messaging.Ems"/>
|
||||||
|
|
||||||
|
<object id="testMessageConverter" type="Spring.Messaging.Ems.Support.Converter.SimpleMessageConverter, Spring.Messaging.Ems"/>
|
||||||
|
|
||||||
|
|
||||||
|
<object id="testObject1" type="Spring.Objects.TestObject, Spring.Core.Tests"/>
|
||||||
|
|
||||||
|
<object id="testObject2" type="Spring.Objects.TestObject, Spring.Core.Tests"/>
|
||||||
|
|
||||||
|
<object id="testObject3" type="Spring.Messaging.Ems.Connections.TestMessageListener, Spring.Messaging.Ems.Tests"/>
|
||||||
|
|
||||||
|
</objects>
|
||||||
|
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
#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 TIBCO.EMS;
|
||||||
|
|
||||||
|
namespace Spring.Messaging.Ems.Connections
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
///
|
||||||
|
/// </remarks>
|
||||||
|
/// <author>Mark Pollack</author>
|
||||||
|
public class TestMessageListener : IMessageListener
|
||||||
|
{
|
||||||
|
private string message;
|
||||||
|
|
||||||
|
|
||||||
|
public string Message
|
||||||
|
{
|
||||||
|
get { return message; }
|
||||||
|
set { message = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IMessageListener Members
|
||||||
|
|
||||||
|
public void OnMessage(Message message)
|
||||||
|
{
|
||||||
|
this.message = "Test1";
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
using Common.Logging;
|
||||||
|
using TIBCO.EMS;
|
||||||
|
|
||||||
|
namespace Spring.Messaging.Ems.Integration
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public class LoggingExceptionHandler : IExceptionListener
|
||||||
|
{
|
||||||
|
#region Logging Definition
|
||||||
|
|
||||||
|
private static readonly ILog LOG = LogManager.GetLogger(typeof (LoggingExceptionHandler));
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region IExceptionListener Members
|
||||||
|
|
||||||
|
public void OnException(EMSException e)
|
||||||
|
{
|
||||||
|
LOG.Error("Exception processing message", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
using Common.Logging;
|
||||||
|
using TIBCO.EMS;
|
||||||
|
|
||||||
|
namespace Spring.Messaging.Ems.Integration
|
||||||
|
{
|
||||||
|
public class SimpleMessageListener : IMessageListener
|
||||||
|
{
|
||||||
|
#region Logging Definition
|
||||||
|
|
||||||
|
private static readonly ILog LOG = LogManager.GetLogger(typeof(SimpleMessageListener));
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private Message lastReceivedMessage;
|
||||||
|
private int messageCount;
|
||||||
|
|
||||||
|
public Message LastReceivedMessage
|
||||||
|
{
|
||||||
|
get { return lastReceivedMessage; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int MessageCount
|
||||||
|
{
|
||||||
|
get { return messageCount; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IMessageListener Members
|
||||||
|
|
||||||
|
public void OnMessage(Message message)
|
||||||
|
{
|
||||||
|
lastReceivedMessage = message;
|
||||||
|
messageCount++;
|
||||||
|
LOG.Debug("Message listener count = " + messageCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
#region License
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright <20> 2002-2007 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
|
||||||
|
|
||||||
|
#region Imports
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using Spring.Messaging.Ems.Core;
|
||||||
|
using Spring.Messaging.Ems.Listener;
|
||||||
|
using Spring.Testing.NUnit;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
namespace Spring.Messaging.Ems.Integration
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This class contains integration tests for the SimpleMessageListenerContainer
|
||||||
|
/// </summary>
|
||||||
|
/// <author>Mark Pollack</author>
|
||||||
|
/// <version>$Id:$</version>
|
||||||
|
[TestFixture]
|
||||||
|
public class SimpleMessageListenerContainerTests : AbstractDependencyInjectionSpringContextTests
|
||||||
|
{
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
[Explicit]
|
||||||
|
public void SendAndAsyncReceive()
|
||||||
|
{
|
||||||
|
SimpleMessageListenerContainer container =
|
||||||
|
(SimpleMessageListenerContainer) applicationContext["SimpleMessageListenerContainer"];
|
||||||
|
SimpleMessageListener listener = applicationContext["SimpleMessageListener"] as SimpleMessageListener;
|
||||||
|
Assert.IsNotNull(container);
|
||||||
|
Assert.IsNotNull(listener);
|
||||||
|
|
||||||
|
|
||||||
|
EmsTemplate emsTemplate = (EmsTemplate) applicationContext["MessageTemplate"] as EmsTemplate;
|
||||||
|
Assert.IsNotNull(emsTemplate);
|
||||||
|
|
||||||
|
Assert.AreEqual(0, listener.MessageCount);
|
||||||
|
emsTemplate.ConvertAndSend("Hello World 1");
|
||||||
|
|
||||||
|
int waitInMillis = 2000;
|
||||||
|
Thread.Sleep(waitInMillis);
|
||||||
|
Assert.AreEqual(1,listener.MessageCount);
|
||||||
|
|
||||||
|
container.Stop();
|
||||||
|
Console.WriteLine("container stopped.");
|
||||||
|
emsTemplate.ConvertAndSend("Hello World 2");
|
||||||
|
Thread.Sleep(waitInMillis);
|
||||||
|
Assert.AreEqual(1, listener.MessageCount);
|
||||||
|
|
||||||
|
container.Start();
|
||||||
|
Console.WriteLine("container started.");
|
||||||
|
Thread.Sleep(waitInMillis);
|
||||||
|
Assert.AreEqual(2, listener.MessageCount);
|
||||||
|
|
||||||
|
container.Shutdown();
|
||||||
|
|
||||||
|
Thread.Sleep(waitInMillis);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected override string[] ConfigLocations
|
||||||
|
{
|
||||||
|
get { return new string[] { "assembly://Spring.Messaging.Ems.Tests/Spring.Messaging.Ems.Integration/SimpleMessageListenerContainerTests.xml" }; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<objects xmlns="http://www.springframework.net">
|
||||||
|
|
||||||
|
|
||||||
|
<object id="ConnectionFactory" type="TIBCO.EMS.ConnectionFactory, TIBCO.EMS">
|
||||||
|
<constructor-arg index="0" value="tcp://localhost:7222"/>
|
||||||
|
</object>
|
||||||
|
|
||||||
|
|
||||||
|
<object name="SimpleMessageListenerContainer" type="Spring.Messaging.Ems.Listener.SimpleMessageListenerContainer, Spring.Messaging.Ems">
|
||||||
|
<property name="ConnectionFactory" ref="ConnectionFactory"/>
|
||||||
|
<property name="DestinationName" value="test.queue"/>
|
||||||
|
<property name="MessageListener" ref="SimpleMessageListener"/>
|
||||||
|
<property name="ExceptionListener">
|
||||||
|
<object type="Spring.Messaging.ems.Integration.LoggingExceptionHandler, Spring.Messaging.Ems.Tests"/>
|
||||||
|
</property>
|
||||||
|
</object>
|
||||||
|
|
||||||
|
<object id="SimpleMessageListener" type="Spring.Messaging.Ems.Integration.SimpleMessageListener, Spring.Messaging.Ems.Tests"/>
|
||||||
|
|
||||||
|
|
||||||
|
<object name="MessageTemplate" type="Spring.Messaging.Ems.Core.EmsTemplate, Spring.Messaging.Ems">
|
||||||
|
<property name="ConnectionFactory" ref="ConnectionFactory"/>
|
||||||
|
<property name="DefaultDestinationName" value="test.queue"/>
|
||||||
|
</object>
|
||||||
|
</objects>
|
||||||
Reference in New Issue
Block a user