SPRNET-1229 - Documentation for TIBCO EMS integration
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
<!ENTITY psa-intro SYSTEM "psa-intro.xml">
|
||||
<!ENTITY remoting SYSTEM "remoting.xml">
|
||||
<!ENTITY messaging SYSTEM "messaging.xml">
|
||||
<!ENTITY messaging-ems SYSTEM "messaging-ems.xml">
|
||||
<!ENTITY msmq SYSTEM "msmq.xml">
|
||||
<!ENTITY scheduling SYSTEM "scheduling.xml">
|
||||
<!ENTITY templating SYSTEM "templating.xml">
|
||||
@@ -324,6 +325,11 @@
|
||||
<xref linkend="messaging"/>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<xref linkend="messaging-ems"/>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<xref linkend="msmq"/>
|
||||
|
||||
584
doc/reference/src/messaging-ems.xml
Normal file
584
doc/reference/src/messaging-ems.xml
Normal file
@@ -0,0 +1,584 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
-->
|
||||
<chapter version="5" xml:id="messaging-ems" xml:lang=""
|
||||
xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:ns6="http://www.w3.org/1999/xlink"
|
||||
xmlns:ns5="http://www.w3.org/1998/Math/MathML"
|
||||
xmlns:ns4="http://www.w3.org/1999/xhtml"
|
||||
xmlns:ns3="http://www.w3.org/2000/svg"
|
||||
xmlns:ns="http://docbook.org/ns/docbook">
|
||||
<title>Message Oriented Middleware - TIBCO EMS</title>
|
||||
|
||||
<section>
|
||||
<title>Introduction</title>
|
||||
|
||||
<para>The bulk of the documentation for Spring's JMS support , independent
|
||||
of vendor, is described in the chapter <xref linkend="messaging" />. While
|
||||
that chapter refers to classes that are part of Spring's ActiveMQ
|
||||
integration, those classes have counter parts as part of Spring's TIBCO
|
||||
EMS integration. For example,
|
||||
<literal>Spring.Messaging.Nms.Core.NmsTemplate</literal> and
|
||||
<literal>Spring.Messaging.Ems.Core.EmsTemplate</literal>. This chapter
|
||||
fills in some of the gaps in taking that approach by describing Spring.NET
|
||||
features that are specific to its integration with TIBCO EMS and showing
|
||||
some examples using the TIBCO EMS integration.</para>
|
||||
|
||||
<note>
|
||||
<para>A complete sample application using Spring's EMS integration
|
||||
classes is in the distribution under the directory
|
||||
<literal>examples\Spring\Spring.EmsQuickStart</literal>. Documentation
|
||||
for the Quickstart is available <link
|
||||
linkend="ems-quickstart">here</link>.</para>
|
||||
</note>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Interface based APIs</title>
|
||||
|
||||
<para>The TIBCO EMS APIs are not interface based. What this means is that
|
||||
the class <classname>TIBCO.EMS.Session</classname> does not inherit from
|
||||
an <classname>ISession</classname> interface. The lack of interfaces makes
|
||||
it impossible to apply traditional approahces to support caching of
|
||||
Connections, Sessions, MessageProducers, and MessageProducers. Also, in
|
||||
some cases Java like setter methods were used instead of standard .NET
|
||||
properties making it difficult to configure those classes using dependency
|
||||
injection. (For example, see
|
||||
<classname>EmssslSystemStoreInfo.SetCertificateStoreLocation()</classname>).
|
||||
For these reasons it was decided to create a 'mirror' API of the TIBCO EMS
|
||||
API that is interface based. In the namespace
|
||||
<literal>Spring.Messaging.Ems.Common</literal> are interfaces such as
|
||||
<interfacename>IConnectionFactory</interfacename>,
|
||||
<interfacename>IConnection</interfacename>,
|
||||
<interfacename>ISession</interfacename>,
|
||||
<interfacename>IMessageProducer</interfacename>, etc as well as their
|
||||
implementation classes <classname>EmsConnectionFactory</classname>,
|
||||
<classname>EmsConnection</classname>, <classname>EmsSession</classname>,
|
||||
etc. The interfaces mirror all the operations that are on the standard
|
||||
TIBCO EMS classes so you should feel right as home when programming
|
||||
against these classes.</para>
|
||||
|
||||
<para>Typically users of Spring.NET do not need to programmatically
|
||||
interact with these classes, instead using methods of
|
||||
<classname>EmsTemplate</classname> to syncrhonously send and consume
|
||||
messages and a <classname>SimpleMessageListenerContainer</classname> to
|
||||
asynchronously consume messages. It will be common to configure an
|
||||
<classname>Spring.Messaging.Ems.Common.ConnectionFactory</classname> using
|
||||
dependency injection. The following sections show some example usage. You
|
||||
can also set or get the underlying 'native' TIBCO EMS object, such as the
|
||||
TIBCO.EMS.ConnectionFactory using a property 'NativeConnectionFactory'
|
||||
Each class in the Spring.Messaging.Ems.Common namespace has a similar
|
||||
'Native' property, for example NativeSession, NativeMessageProducer if you
|
||||
need access the raw TIBCO EMS class.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Using Spring's EMS based Messaging</title>
|
||||
|
||||
<section>
|
||||
<title>Overivew</title>
|
||||
|
||||
<para>In the namespace Spring.Messaging.Ems.Core is the class
|
||||
EmsTemplate. This is the main class you will use to send messages and to
|
||||
receive messages synchronously. In the namespace
|
||||
Spring.Messaging.Ems.Listener is the class
|
||||
SimpleMessageListenerContainer. This is the main class you will use to
|
||||
recieve messages asynchronously.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Connections</title>
|
||||
|
||||
<para>To create a
|
||||
<classname>Spring.Messaging.Ems.Common.ConnectionFactory</classname> use
|
||||
the following object definition</para>
|
||||
|
||||
<programlisting language="myxml"> <object id="emsConnectionFactory" type="Spring.Messaging.Ems.Common.EmsConnectionFactory, Spring.Messaging.Ems">
|
||||
<constructor-arg name="serverUrl" value="tcp://localhost:7222"/>
|
||||
<constructor-arg name="clientId" value="SpringEMSClient"/>
|
||||
<property name="ConnAttemptCount" value="10" />
|
||||
<property name="ConnAttemptDelay" value="100" />
|
||||
<property name="ConnAttemptTimeout" value="1000" />
|
||||
</object></programlisting>
|
||||
|
||||
<para>Please refer to the API documentation for other properties you way
|
||||
want to set, in particular for those relating to SSL.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Caching Messaging Resources</title>
|
||||
|
||||
<para>While TIBCO EMS provides thread safe access to EMS Sessions (above
|
||||
and beyond what is specified in the JMS specification), Spring provides
|
||||
two implementations of the IConnectionFactory infrastructure to manage
|
||||
the use of intermediate objects when following the 'standard' API walk
|
||||
of</para>
|
||||
|
||||
<programlisting>IConnectionFactory->IConnection->ISession->IMessageProducer->Send</programlisting>
|
||||
|
||||
<section>
|
||||
<title>SingleConnectionFactory</title>
|
||||
|
||||
<para><literal>Spring.Messaging.Ems.Connections.SingleConnectionFactory
|
||||
</literal>will return the same connection on all calls to
|
||||
<methodname>CreateConnection</methodname> and ignore calls to
|
||||
Close.</para>
|
||||
|
||||
<para>You can configure a SingleConnectionFactory as you would an
|
||||
<classname>EmsConnectionFactory</classname>.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>CachingConnectionFactory</title>
|
||||
|
||||
<para><literal>Spring.Messaging.Ems.Connections.CachingConnectionFactory</literal>
|
||||
extends the functionality of SingleConnectionFactory and adds the
|
||||
caching of Sessions, MessageProducers, and MessageConsumers. See the
|
||||
documentation for ActiveMQ CachingConnectionFactory for some
|
||||
additional information <link
|
||||
linkend="activemq-using-caching-cachingconnectionfactory"
|
||||
os="">here</link>.</para>
|
||||
|
||||
<para>An example configuration is shown below</para>
|
||||
|
||||
<programlisting language="myxml"> <object id="connectionFactory" type="Spring.Messaging.Ems.Connections.CachingConnectionFactory, Spring.Messaging.Ems">
|
||||
<property name="SessionCacheSize" value="10" />
|
||||
<property name="TargetConnectionFactory" ref="emsConnectionFactory" />
|
||||
</object></programlisting>
|
||||
|
||||
<para>Notice that the property TargetConnectionFactory refers to
|
||||
'emsConnectionFactory' defined in the previous section. This
|
||||
connection factory implementation also set the ReconnectOnException
|
||||
property to true by default allowing for automatic recovery of the
|
||||
underlying Connection.</para>
|
||||
|
||||
<note>
|
||||
<para>The CachingConnectionFactory requires explicit closing of all
|
||||
Sessions obtained from its shared Connection. This is the usual
|
||||
recommendation for native EMS access code anyway and Spring EMS code
|
||||
follows this recommendation. However, with the
|
||||
CachingConnectionFactory, its use is mandatory in order to actually
|
||||
allow for Session reuse.</para>
|
||||
</note>
|
||||
|
||||
<note>
|
||||
<para>MessageConsumers obtained from a cached Session won't get
|
||||
closed until the Session will eventually be removed from the pool.
|
||||
This may lead to semantic side effects in some cases. For a durable
|
||||
subscriber, the logical Session.Close() call will also close the
|
||||
subscription. Re-registering a durable consumer for the same
|
||||
subscription on the same Session handle is not supported; close and
|
||||
reobtain a cached Session first.</para>
|
||||
</note>
|
||||
|
||||
<para>To avoid accidentally referring to the ConnectionFactory that
|
||||
does not support caching, (emsConnectionFactory), you should use an
|
||||
inner object definition as shown below.</para>
|
||||
|
||||
<programlisting language="myxml"> <object id="connectionFactory" type="Spring.Messaging.Ems.Connections.CachingConnectionFactory, Spring.Messaging.Ems">
|
||||
<property name="SessionCacheSize" value="10" />
|
||||
<property name="TargetConnectionFactory">
|
||||
<object type="Spring.Messaging.Ems.Common.EmsConnectionFactory, Spring.Messaging.Ems">
|
||||
<constructor-arg name="serverUrl" value="tcp://localhost:7222"/>
|
||||
<constructor-arg name="clientId" value="SpringEMSClient"/>
|
||||
<property name="ConnAttemptCount" value="10" />
|
||||
<property name="ConnAttemptDelay" value="100" />
|
||||
<property name="ConnAttemptTimeout" value="1000" />
|
||||
</object>
|
||||
</property>
|
||||
</object></programlisting>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Dynamic Destination Management</title>
|
||||
|
||||
<para>The <link linkend="activemq-using-destination-mgmt">section</link>
|
||||
in the ActiveMQ documentation covers the use of Dynamic Destination
|
||||
mangement for TIBCO as well.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Accessing Admistrated objects via JNDI</title>
|
||||
|
||||
<para>TIBCO provides an implementation of JNDI to retrieve admistrive
|
||||
objects in .NET. You can retrieve TIBCO
|
||||
<classname>Destinations</classname> and
|
||||
<literal>ConnectionFactories</literal> from the JNDI registry. To
|
||||
provide ease of access to these JNDI managed objects in a Spring
|
||||
application context the class <classname>JndiFactoryObject</classname>
|
||||
is used. This allows you look configure the location of the JNDI
|
||||
registry and to retrieve objects by name. The objects are retrieved from
|
||||
JNDI at application startup. </para>
|
||||
|
||||
<para>These retrieved objetcts from JNDI in turn can be dependency
|
||||
injected into other collaborating objects such as Spring's
|
||||
<classname>CachingConnectionFactory</classname> (for connections) or
|
||||
EmsTemplate (for destinations). Here is an example to retrieve a TIBCO
|
||||
ConnectionFactory object from the JNDI registry.</para>
|
||||
|
||||
<programlisting language="myxml"> <object id="jndiEmsConnectionFactory" type="Spring.Messaging.Ems.Jndi.JndiLookupFactoryObject, Spring.Messaging.Ems">
|
||||
<property name="JndiName" value="TopicConnectionFactory"/>
|
||||
<property name="JndiProperties[LookupContext.PROVIDER_URL]" value="tibjmsnaming://localhost:7222"/>
|
||||
</object></programlisting>
|
||||
|
||||
<para>JndiLookupFactory object implements the IFactoryObject interface,
|
||||
so the type that is associated with the name 'jndiConnectionFactory' is
|
||||
not JndiLookupFactoryObject, but the type returned from this factory's
|
||||
'GetType' method, in this case the type of what was retrieved from
|
||||
JNDI.</para>
|
||||
|
||||
<note>
|
||||
<para>The dictionary JndiProperties is set using Spring Expression
|
||||
language syntax for the property name. This provides a shortcut to the
|
||||
more verbose <dictionary/> element. To enable this functionality
|
||||
a the TIBCO.EMS.LookupContext was registered under the name
|
||||
'LookupContext' in Spring's TypeRegistry.</para>
|
||||
</note>
|
||||
|
||||
<para>The use of this object retrieved from JNDI to configure Spring's
|
||||
CachingConnectionFactory set the property TargetConnectionFactory as
|
||||
shown below </para>
|
||||
|
||||
<programlisting language="myxml"> <object id="cachingJndiConnectionFactory" type="Spring.Messaging.Ems.Connections.CachingConnectionFactory, Spring.Messaging.Ems">
|
||||
<property name="SessionCacheSize" value="10" />
|
||||
<property name="TargetConnectionFactory">
|
||||
<object type="Spring.Messaging.Ems.Common.EmsConnectionFactory, Spring.Messaging.Ems">
|
||||
<constructor-arg ref="jndiEmsConnectionFactory"/>
|
||||
</object>
|
||||
</property>
|
||||
</object></programlisting>
|
||||
|
||||
<para>Other useful properties and features of JndiLookupFactoryObject
|
||||
are</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><literal>JndiContextType</literal> : This is an enumeration
|
||||
that can have either the value JMS or LDAP. These translate to
|
||||
configuring JNDI context with the constants
|
||||
LookupContextFactory.TIBJMS_NAMING_CONT or
|
||||
LookupContextFactory.LDAP_CONTEXT for use with EMS's own JNDI
|
||||
registry or an LDAP directory respectively. The default is set use
|
||||
LookupContextFactory.TIBJMS_NAMING_CONT. The type JndiContextType is
|
||||
also registered in Spring's TypeRegistry so that you can use a SpEL
|
||||
expression to set the value as shown below.</para>
|
||||
|
||||
<programlisting language="myxml"> <object id="jndiEmsConnectionFactory" type="Spring.Messaging.Ems.Jndi.JndiLookupFactoryObject, Spring.Messaging.Ems">
|
||||
<property name="JndiName" value="TopicConnectionFactory"/>
|
||||
<property name="JndiProperties[LookupContext.PROVIDER_URL]" value="tibjmsnaming://localhost:7222"/>
|
||||
<property name="JndiContextType" expression="JndiContextType.JMS"/>
|
||||
<property name="ExpectedType" value="TIBCO.EMS.ConnectionFactory"/>
|
||||
</object></programlisting>
|
||||
|
||||
<note>
|
||||
<para>The <literal>TargetConnectionFactory</literal> is of the
|
||||
Spring wrapper type
|
||||
<interfacename>Spring.Messaging.Ems.Common.IConnectionFactory</interfacename>.
|
||||
You can pass into Spring's implementation of that interface,
|
||||
<classname>Spring.Messaging.Ems.Common.EmsConnectionFactory</classname>,
|
||||
the 'raw' TIBCO EMS type,
|
||||
<classname>TIBCO.EMS.ConnectionFactory</classname>.</para>
|
||||
</note>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>ExpectedType</literal>: This is a property of the
|
||||
type System.Type. You can set the type that the located JNDI object
|
||||
is supposed to be assignable to, if any. It's use is shown in the
|
||||
previous XML configuraiton listing.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>JndiLookupContext</literal>: This is a property of
|
||||
the type <classname>TIBCO.EMS.ILookupContext</classname>. If you
|
||||
create a custom implementation of
|
||||
<interfacename>ILookupContext</interfacename> (for example one that
|
||||
performs lazy caching), assign this property instead of configuring
|
||||
the property <literal>JndiContextType.</literal></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>DefaultObject</literal>: Sets a reference to an
|
||||
instance of an object to fall back to if the JNDI lookup fails. The
|
||||
default is not to have a fallback object.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para></para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>MessageListenerContainers</title>
|
||||
|
||||
<para>Spring's MessageListenerContainer's are used to process messages
|
||||
asynchronously and concurrently. MessageListenerContainers are described
|
||||
more in <link linkend="activemq-listener-containers">this</link>
|
||||
section. </para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Transaction Management</title>
|
||||
|
||||
<para>Spring provides an implementation of the
|
||||
IPlatformTransactionManager interface for managing TiBCO messaging
|
||||
transactions. The class is <literal>EmsTransactionManager</literal> and
|
||||
it manages transactions for a single ConnectionFactory. Please refer to
|
||||
<link linkend="activemq-using-txmgmt">this</link> section for addtional
|
||||
information on messaging based transaction managers.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Sending a Message</title>
|
||||
|
||||
<para>The class Spring.Messaging.Ems.Core.EmsTemplate contains several
|
||||
convenience methods to send a message. These methods are identical to
|
||||
those described in the ActiveMQ documentation <link
|
||||
linkend="activemq-sending-messages">section</link> aside from the use of
|
||||
type destination type TIBCO.EMS.Destination instead of
|
||||
Apache.NMS.IDestination and switching of the namespace from Apache.NMS
|
||||
to Spring.Messaging.Ems.Common. </para>
|
||||
|
||||
<para>Shown below is the code example for a SimplePublisher using
|
||||
Spring's TIBCO EMS classes. This does now show the 'one-liner' send
|
||||
methods but one that gives you direct access to the ISession to create
|
||||
the message however you wish.</para>
|
||||
|
||||
<programlisting language="csharp">using Spring.Messaging.Ems.Common;
|
||||
using TIBCO.EMS;
|
||||
|
||||
namespace Spring.Messaging.Ems.Core
|
||||
{
|
||||
public class SimplePublisher
|
||||
{
|
||||
private EmsTemplate emsTemplate;
|
||||
|
||||
public SimplePublisher()
|
||||
{
|
||||
emsTemplate = new EmsTemplate(new EmsConnectionFactory("tcp://localhost:7222"));
|
||||
}
|
||||
|
||||
public void Publish(string ticker, double price)
|
||||
{
|
||||
emsTemplate.SendWithDelegate("APP.STOCK.MARKETDATA",
|
||||
delegate(ISession session)
|
||||
{
|
||||
MapMessage message = session.CreateMapMessage();
|
||||
message.SetString("TICKER", ticker);
|
||||
message.SetDouble("PRICE", price);
|
||||
message.Priority = 5;
|
||||
return message;
|
||||
});
|
||||
}
|
||||
}
|
||||
}</programlisting>
|
||||
|
||||
<para>A more DI friendly implementation would be to expose a EmsTemplate
|
||||
property or to inherit from Spring's EmsGatewaySupport base class which
|
||||
provides a IConnectionFactory property that will instantiate a
|
||||
EmsTemplate instance that is made available via the property
|
||||
EmsTemplate.</para>
|
||||
|
||||
<programlisting language="csharp">using Spring.Messaging.Ems.Common;
|
||||
using TIBCO.EMS;
|
||||
|
||||
namespace Spring.Messaging.Ems.Core
|
||||
{
|
||||
public class SimpleGateway : EmsGatewaySupport
|
||||
{
|
||||
public void Publish(string ticker, double price)
|
||||
{
|
||||
EmsTemplate.SendWithDelegate("APP.STOCK.MARKETDATA",
|
||||
delegate(ISession session)
|
||||
{
|
||||
MapMessage message = session.CreateMapMessage();
|
||||
message.SetString("TICKER", ticker);
|
||||
message.SetDouble("PRICE", price);
|
||||
message.Priority = 5;
|
||||
return message;
|
||||
});
|
||||
}
|
||||
}
|
||||
}</programlisting>
|
||||
|
||||
<para>Where the ConnectionFactory is injected using the
|
||||
configuration.</para>
|
||||
|
||||
<programlisting language="myxml"> <object id="simpleGateway" type="Spring.Messaging.Ems.Core.SimpleGateway, Spring.Messaging.Ems.Integration.Tests">
|
||||
<property name="ConnectionFactory" ref="connectionFactory" />
|
||||
</object></programlisting>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section xml:id="ems-messageconverters">
|
||||
<title>Using MessageConverters</title>
|
||||
|
||||
<para>In order to facilitate the sending of domain model objects, the
|
||||
<literal>EmsTemplate</literal> has various send methods that take a .NET
|
||||
object as an argument for a message's data content. The overloaded methods
|
||||
<literal>ConvertAndSend</literal> and <literal>ReceiveAndConvert</literal>
|
||||
in <literal>NmsTemplate</literal> delegate the conversion process to an
|
||||
instance of the <literal>IMessageConverter</literal> interface. Please
|
||||
refer to <link linkend="activemq-messageconverter">this</link> section for
|
||||
more information on MessageConverters.</para>
|
||||
|
||||
<para>Example code that uses the <literal>EmsTemplate's</literal>
|
||||
<literal>ConvertAndSendWithDelegate</literal>, which allows access to the
|
||||
message after it has been converted but before it has been sent is shown
|
||||
below. For examples of using other <literal>ConvertAndSend</literal>
|
||||
methods see the section referred to in the previous paragraph.</para>
|
||||
|
||||
<programlisting language="csharp">public void PublishUsingDict(string ticker, double price)
|
||||
{
|
||||
IDictionary marketData = new Hashtable();
|
||||
marketData.Add("TICKER", ticker);
|
||||
marketData.Add("PRICE", price);
|
||||
EmsTemplate.ConvertAndSendWithDelegate("APP.STOCK.MARKETDATA", marketData,
|
||||
delegate(Message message)
|
||||
{
|
||||
message.Priority = 5;
|
||||
message.CorrelationID = new Guid().ToString();
|
||||
return message;
|
||||
});
|
||||
} </programlisting>
|
||||
</section>
|
||||
|
||||
<section xml:id="ems-session-producer">
|
||||
<title>Session and Producer Callback</title>
|
||||
|
||||
<para>Please refer to <link
|
||||
linkend="messaging-session-callback">this</link> section for more
|
||||
information on Session and Producer Callbacks.</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="ems-receive">
|
||||
<title>Receiving a messages</title>
|
||||
|
||||
<para>There are two ways to receive messages, synchronously and
|
||||
asynchronously. To recieve messages synchronously use EmsTemplate, to
|
||||
recieve asynchronously use a MessageListenerContainer.</para>
|
||||
|
||||
<section xml:id="ems-sync">
|
||||
<title>Synchronous Reception</title>
|
||||
|
||||
<para>Please refer to <link linkend="???"
|
||||
xml:id="activemq-sync-receive">this</link> section for using
|
||||
EmsTemplate's overloaded Recieve methods.</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="ems-async">
|
||||
<title>Asynchronous Reception </title>
|
||||
|
||||
<para>Please refer to <link linkend="???"
|
||||
xml:id="activemq-async-reception">this</link> section for an
|
||||
introduction to Spring's MessageListenerContainers. The TIBCO EMS
|
||||
namespace to create an instance of a message listener container is shown
|
||||
below.</para>
|
||||
|
||||
<para><programlisting language="csharp">using Common.Logging;
|
||||
using TIBCO.EMS;
|
||||
|
||||
namespace Spring.Messaging.Ems.Core
|
||||
{
|
||||
public class SimpleMessageListener : IMessageListener
|
||||
{
|
||||
private static readonly ILog LOG = LogManager.GetLogger(typeof(SimpleMessageListener));
|
||||
|
||||
private int messageCount;
|
||||
|
||||
public int MessageCount
|
||||
{
|
||||
get { return messageCount; }
|
||||
}
|
||||
|
||||
public void OnMessage(Message message)
|
||||
{
|
||||
messageCount++;
|
||||
LOG.Debug("Message listener count = " + messageCount);
|
||||
TextMessage textMessage = message as TextMessage;
|
||||
if (textMessage != null)
|
||||
{
|
||||
LOG.Info("Message Text = " + textMessage.Text);
|
||||
} else
|
||||
{
|
||||
LOG.Warn("Can not process message of type " message.GetType());
|
||||
}
|
||||
}
|
||||
}
|
||||
}</programlisting>And the configuration to create 10 threads that process
|
||||
message off the queue named "APP.STOCK.REQUEST". See this section for
|
||||
more details about the message listener container.</para>
|
||||
|
||||
<para><programlisting language="myxml"><objects xmlns="http://www.springframework.net"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:ems="http://www.springframework.net/ems">
|
||||
|
||||
<object id="connectionFactory" type="Spring.Messaging.Ems.Connections.CachingConnectionFactory, Spring.Messaging.Ems">
|
||||
<property name="SessionCacheSize" value="10" />
|
||||
<property name="TargetConnectionFactory">
|
||||
<object type="Spring.Messaging.Ems.Common.EmsConnectionFactory, Spring.Messaging.Ems">
|
||||
<constructor-arg name="serverUrl" value="tcp://localhost:7222"/>
|
||||
<constructor-arg name="clientId" value="SpringEMSClient"/>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
|
||||
<object name="simpleMessageListener"
|
||||
type="Spring.Messaging.Ems.Core.SimpleMessageListener, Spring.Messaging.Ems.Integration.Tests"/>
|
||||
|
||||
|
||||
<ems:listener-container connection-factory="connectionFactory" concurrency="10">
|
||||
<ems:listener ref="simpleMessageListener" destination="APP.STOCK.REQUEST" />
|
||||
</ems:listener-container>
|
||||
|
||||
</objects></programlisting></para>
|
||||
</section>
|
||||
|
||||
<section xml:id="ems-session-aware">
|
||||
<title>The ISessionAwareMessageListener interface</title>
|
||||
|
||||
<para xml:id="ems-sessionaware">Refer to <link
|
||||
linkend="activemq-sessionaware">this</link> section for more information
|
||||
on the use of this interface.</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="ems-message-adapter">
|
||||
<title>MessageListenerAdapter</title>
|
||||
|
||||
<para>Refer to <link linkend="message-listener-adapter">this</link>
|
||||
section for more information on this feature and change code/XML
|
||||
references of 'Nms' to 'Ems'.</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="ems-msg-tx">
|
||||
<title>Processing messages within a messaging transaction</title>
|
||||
|
||||
<para>Refer to <link linkend="activemq-msg-tx">this</link> section for
|
||||
more information about this type of message processing.</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="ems-namespace">
|
||||
<title>Messaging Namespace support</title>
|
||||
|
||||
<para>To use the EMS namespace you will need to reference the Ems
|
||||
schema. Please refer to <link linkend="activemq-namespace">this</link>
|
||||
section for more information on configuring message listener containers.
|
||||
Change references of 'Nms' to 'Ems' in that section.</para>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
||||
@@ -40,108 +40,118 @@
|
||||
|
||||
<para>This chapter discusses Spring's messaging support for providers
|
||||
whose API was modeled after the Java Message Service (JMS) API. Vendors
|
||||
who provide a JMS inspired API include Apache, TIBCO, IBM, and Progress
|
||||
Software. If you are using Microsoft's Message Queue, please refer to the
|
||||
specific <link linkend="msmq">MSMQ section</link>.</para>
|
||||
who provide a JMS inspired API include Apache ActiveMQ, TIBCO, IBM, and
|
||||
Progress Software. If you are using Microsoft's Message Queue, please
|
||||
refer to the specific <link linkend="msmq">MSMQ section</link>. The
|
||||
description of Spring messages features in this chapter apply to all of
|
||||
these JMS vendors. However, the documentation focuses on showing code
|
||||
examples that use Apache ActiveMQ. For code examples and some features
|
||||
specific to TIBCO EMS please refer to <link
|
||||
linkend="messaging-ems">this</link> chapter.</para>
|
||||
|
||||
<para>As there is no de facto-standard common API across messaging
|
||||
vendors, Spring provides an implementation of its helper classes for each
|
||||
of the major messaging middleware vendors. The naming of the classes you
|
||||
will interact with most frequently will either be identical for each
|
||||
provider, but located in a different namespace, or have their prefix
|
||||
change to be the three-letter-acronym commonly associated with the message
|
||||
provider. The list of providers supported by Spring is show below along
|
||||
with their namespace and prefix.</para>
|
||||
<section xml:id="activemq-multi-vendor">
|
||||
<title>Multiple Vendor Support</title>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>Apache ActiveMQ (NMS) in namespace
|
||||
<literal>Spring.Messaging.Nms</literal>. 'Nms' is sometimes used as
|
||||
the class prefix</para>
|
||||
</listitem>
|
||||
<para>As there is no de facto-standard common API across messaging
|
||||
vendors, Spring provides an implementation of its helper classes for
|
||||
each of the major messaging middleware vendors. The naming of the
|
||||
classes you will interact with most frequently will either be identical
|
||||
for each provider, but located in a different namespace, or have their
|
||||
prefix change to be the three-letter-acronym commonly associated with
|
||||
the message provider. The list of providers supported by Spring is show
|
||||
below along with their namespace and prefix.</para>
|
||||
|
||||
<listitem>
|
||||
<para>TIBCO EMS in namespace <literal>Spring.Messaging.Ems</literal>.
|
||||
'Ems' is sometimes used as the class prefix (available as of
|
||||
Spring.NET 1.3 )</para>
|
||||
</listitem>
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>Apache ActiveMQ (NMS) in namespace
|
||||
<literal>Spring.Messaging.Nms</literal>. 'Nms' is used as the class
|
||||
prefix</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>SonicMQ in namespace <literal>Spring.Messaging.Sonic</literal>,
|
||||
'Jms' is sometimes used as the class prefix. (in a future
|
||||
release)</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>TIBCO EMS in namespace
|
||||
<literal>Spring.Messaging.Ems</literal>. 'Ems' is used as the class
|
||||
prefix.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Websphere MQ in namespace
|
||||
<literal>Spring.Messaging.Xms</literal>, 'Xms' is sometimes used as
|
||||
the class prefix (in a future release)</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
<listitem>
|
||||
<para>Websphere MQ in namespace
|
||||
<literal>Spring.Messaging.Xms</literal>, 'Xms' is used as the class
|
||||
prefix (in a future release)</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
<para>JMS can be roughly divided into two areas of functionality, namely
|
||||
the production and consumption of messages. For message production and the
|
||||
synchronous consumption of messages the a template class, named
|
||||
<literal>NmsTemplate</literal>, <literal> EmsTemplate</literal> (etc.) is
|
||||
used. Asynchronous message consumption is performed though a
|
||||
multi-threaded message listener container,
|
||||
<literal>SimpleMessageListenerContainer</literal>. This message listener
|
||||
container is used to create Message-Driven PONOs (MDPs) which refer to a
|
||||
messaging callback class that consists of just 'plain .NET object's and is
|
||||
devoid of any specific messaging types or other artifacts. The
|
||||
<literal>IMessageConverter</literal> interface is used by both the
|
||||
template class and the message listener container to convert between
|
||||
provider message types and PONOs.</para>
|
||||
<para>JMS can be roughly divided into two areas of functionality, namely
|
||||
the production and consumption of messages. For message production and
|
||||
the synchronous consumption of messages the a template class, named
|
||||
<literal>NmsTemplate</literal>, <literal> EmsTemplate</literal> (etc.)
|
||||
is used. Asynchronous message consumption is performed though a
|
||||
multi-threaded message listener container,
|
||||
<literal>SimpleMessageListenerContainer</literal>. This message listener
|
||||
container is used to create Message-Driven PONOs (MDPs) which refer to a
|
||||
messaging callback class that consists of just 'plain .NET object's and
|
||||
is devoid of any specific messaging types or other artifacts. The
|
||||
<literal>IMessageConverter</literal> interface is used by both the
|
||||
template class and the message listener container to convert between
|
||||
provider message types and PONOs.</para>
|
||||
|
||||
<para>The namespace
|
||||
<literal>Spring.Messaging.<Vendor>.Core</literal> contains the
|
||||
messing template class (e.g. <literal>NmsTemplate</literal>). The template
|
||||
class simplifies the use of the messaging APIs by handling the creation
|
||||
and release of resources, much like the <literal>AdoTemplate</literal>
|
||||
does for ADO.NET. The JMS inspired APIs are low-level API, much like
|
||||
ADO.NET. As such, even the simplest of operations requires 10s of lines of
|
||||
code with the bulk of that code related to resource management of
|
||||
intermediate API objects Spring's messaging support, both in Java and
|
||||
.NET, addresses the error-prone boiler plate coding style one needs when
|
||||
using these APIs.</para>
|
||||
<para>The namespace
|
||||
<literal>Spring.Messaging.<Vendor>.Core</literal> contains the
|
||||
messing template class (e.g. <literal>NmsTemplate</literal>). The
|
||||
template class simplifies the use of the messaging APIs by handling the
|
||||
creation and release of resources, much like the
|
||||
<literal>AdoTemplate</literal> does for ADO.NET. The JMS inspired APIs
|
||||
are low-level API, much like ADO.NET. As such, even the simplest of
|
||||
operations requires 10s of lines of code with the bulk of that code
|
||||
related to resource management of intermediate API objects Spring's
|
||||
messaging support, both in Java and .NET, addresses the error-prone
|
||||
boiler plate coding style one needs when using these APIs.</para>
|
||||
|
||||
<para>The design principle common to Spring template classes is to provide
|
||||
helper methods to perform common operations and for more sophisticated
|
||||
usage, delegate the essence of the processing task to user implemented
|
||||
callback interfaces. The messaging template follows the same design. The
|
||||
message template class offer various convenience methods for the sending
|
||||
of messages, consuming a message synchronously, and exposing the message
|
||||
Session and MessageProducer to the user.</para>
|
||||
<para>The design principle common to Spring template classes is to
|
||||
provide helper methods to perform common operations and for more
|
||||
sophisticated usage, delegate the essence of the processing task to user
|
||||
implemented callback interfaces. The messaging template follows the same
|
||||
design. The message template class offer various convenience methods for
|
||||
the sending of messages, consuming a message synchronously, and exposing
|
||||
the message Session and MessageProducer to the user.</para>
|
||||
|
||||
<para>The namespace
|
||||
<literal>Spring.Messaging.<VendorAcronym>.Support.Converter</literal>
|
||||
provides a <literal>IMessageConverter</literal> abstraction to convert
|
||||
between .NET objects and messages. The namespace
|
||||
<literal>Spring.Messaging.<VendorAcronym>.Support.Destinations</literal>
|
||||
provides various strategies for managing destinations, such as providing a
|
||||
service locater for destinations stored in a directory service.</para>
|
||||
<para>The namespace
|
||||
<literal>Spring.Messaging.<VendorAcronym>.Support.Converter</literal>
|
||||
provides a <literal>IMessageConverter</literal> abstraction to convert
|
||||
between .NET objects and messages. The namespace
|
||||
<literal>Spring.Messaging.<VendorAcronym>.Support.Destinations</literal>
|
||||
provides various strategies for managing destinations, such as providing
|
||||
a service locater for destinations stored in a directory service.</para>
|
||||
|
||||
<para>Finally, the namespace
|
||||
<literal>Spring.Messaging.<VendorAcronym>.Connections</literal>
|
||||
provides an implementations of the ConnectionFactory suitable for use in
|
||||
standalone applications.</para>
|
||||
<para>Finally, the namespace
|
||||
<literal>Spring.Messaging.<VendorAcronym>.Connections</literal>
|
||||
provides an implementations of the ConnectionFactory suitable for use in
|
||||
standalone applications.</para>
|
||||
|
||||
<para>The rest of the sections in this chapter discusses each of the major
|
||||
helper classes in detail. Please refer to the sample application that
|
||||
ships with Spring for additional hands-on usage.</para>
|
||||
<para>The rest of the sections in this chapter discusses each of the
|
||||
major helper classes in detail. Please refer to the sample application
|
||||
that ships with Spring for additional hands-on usage.</para>
|
||||
|
||||
<note>
|
||||
<para>To simplify documenting features that are common across all
|
||||
provider implementations of Spring's helper classes a specific provider,
|
||||
Apache ActiveMQ, was selected. As such when you see 'NmsTemplate' in the
|
||||
documentation, it also refers to EmsTemplate, XmsTemplate, etc. unless
|
||||
specifically documented otherwise. The provider specific API classes are
|
||||
typically named after their JMS counterparts with the possible exception
|
||||
of a leading 'I' in front of interfaces in order to follow .NET naming
|
||||
conventions. In the documentation these API artifacts are referred to as
|
||||
'ConnectionFactory', 'Session', 'Message', etc. without the leading
|
||||
'I'.</para>
|
||||
</note>
|
||||
<note>
|
||||
<para>To simplify documenting features that are common across all
|
||||
provider implementations of Spring's helper classes a specific
|
||||
provider, Apache ActiveMQ, was selected. As such when you see
|
||||
'NmsTemplate' in the documentation, it also refers to EmsTemplate,
|
||||
XmsTemplate, etc. unless specifically documented otherwise. The
|
||||
provider specific API classes are typically named after their JMS
|
||||
counterparts with the possible exception of a leading 'I' in front of
|
||||
interfaces in order to follow .NET naming conventions. In the
|
||||
documentation these API artifacts are referred to as
|
||||
'ConnectionFactory', 'Session', 'Message', etc. without the leading
|
||||
'I'.</para>
|
||||
</note>
|
||||
|
||||
<note>
|
||||
<para>To view some of this chapters contents that are based on TIBCO
|
||||
EMS please refer to the <link linkend="messaging-ems">TIBCO EMS
|
||||
chapter</link>.</para>
|
||||
</note>
|
||||
</section>
|
||||
|
||||
<section xml:id="activemq-intro-soc">
|
||||
<title>Separation of Concerns</title>
|
||||
@@ -243,7 +253,8 @@
|
||||
<literal>ISessionCallback</literal> provides the user with the provider
|
||||
specific messaging Session and the callback
|
||||
<literal>IProducerCallback</literal> exposes a provider specific Session
|
||||
and MessageProducer pair.</para>
|
||||
and MessageProducer pair. See <xref
|
||||
linkend="messaging-session-callback" />.</para>
|
||||
|
||||
<para>Provider messaging APIs typically expose two types of send
|
||||
methods, one that takes delivery mode, priority, and time-to-live as
|
||||
@@ -277,29 +288,20 @@
|
||||
and encapsulates various configuration parameters, many of which are
|
||||
vendor specific such as SSL configuration options.</para>
|
||||
|
||||
<para>To create a ActivfeMQ ConnectionFactory define can create an
|
||||
object definition as shown</para>
|
||||
|
||||
<programlisting> <object id="nmsConnectionFactory" type="Apache.NMS.ActiveMQ.ConnectionFactory, Apache.NMS.ActiveMQ">
|
||||
<constructor-arg index="0" value="tcp://localhost:61616"/>
|
||||
</object></programlisting>
|
||||
|
||||
<para><classname>EmsTemplate</classname> also requres a reference to a
|
||||
ConnectionFactory, however, it is not the 'native'
|
||||
<classname>TIBCO.EMS.ConnectionFactory</classname>. Instead the
|
||||
connection factory type is
|
||||
Spring.Messaging.Ems.Common.IConnectionFactory. A set of interfaces has
|
||||
created that mirror the standard TIBCO API for ConnectionFactory,
|
||||
Connection, Session, MessageProducer, MessageConsumer, and
|
||||
ITopicSubscriber. This was done in order to provide caching of these
|
||||
resources internally in a transparent manager and to a lesser extent,
|
||||
provide a convenient API that makes them easy to configure using
|
||||
dependency injection. Typically users of Spring.NET do not need to
|
||||
programmatically interact with these classes, instead using methods of
|
||||
EmsTemplate to syncrhonously send and consume messages and a
|
||||
SimpleMessageListenerContainer to asynchronously consume messages. It
|
||||
will be common to configure an
|
||||
Spring.Messaging.Ems.Common.ConnectionFactory using depdency injection.
|
||||
Please refer to the Spring APi documentation for the properties that are
|
||||
available - they mirror all the properties you find on the standard
|
||||
TIBCO ConnectionFactory. You can also set or get the underlying 'native'
|
||||
TIBCO EMS object, such as the TIBCO.EMS.ConnectionFactory using a
|
||||
property 'NativeConnectionFactory' There is a similar 'Native' property
|
||||
that is available on all of the classes that are in the
|
||||
Spring.Messaging.Ems.Common.namespace.</para>
|
||||
Spring.Messaging.Ems.Common.IConnectionFactory. See the documentation
|
||||
for TIBCO EMS supper for more information <link
|
||||
linkend="messaging-ems">here</link>.</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="activemq-using-caching-resources">
|
||||
@@ -347,11 +349,23 @@
|
||||
destination. <literal>MessageConsumers</literal> are cached based on a
|
||||
key composed of the destination, selector, noLocal delivery flag, and
|
||||
the durable subscription name (if creating durable consumers).</para>
|
||||
|
||||
<para>Here is an example configuration</para>
|
||||
|
||||
<programlisting> <object id="connectionFactory" type="Spring.Messaging.Nms.Connections.CachingConnectionFactory, Spring.Messaging.Nms">
|
||||
<property name="SessionCacheSize" value="10" />
|
||||
<property name="TargetConnectionFactory">
|
||||
<object type="Apache.NMS.ActiveMQ.ConnectionFactory, Apache.NMS.ActiveMQ">
|
||||
<constructor-arg index="0" value="tcp://localhost:61616"/>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</programlisting>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section xml:id="activemq-using-destination-mgmt">
|
||||
<title>Destination Management</title>
|
||||
<title>Dynamic Destination Management</title>
|
||||
|
||||
<para>In Java implementations of JMS, Connections and Destinations are
|
||||
'administered objects' accessible though JNDI - a directory service much
|
||||
@@ -409,13 +423,14 @@
|
||||
resolution via implementations of the
|
||||
<literal>IDestinationResolver</literal> interface.</para>
|
||||
|
||||
<para>You can also configure the NmsTemplate with a default destination
|
||||
via the property <literal>DefaultDestination</literal>. The default
|
||||
destination will be used with send and receive operations that do not
|
||||
refer to a specific destination.</para>
|
||||
<para>You can also configure the <classname>NmsTemplate</classname> with
|
||||
a default destination via the property
|
||||
<literal>DefaultDestination</literal>. The default destination will be
|
||||
used with send and receive operations that do not refer to a specific
|
||||
destination.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<section xml:id="activemq-listener-containers" xml:lang="">
|
||||
<title>Message Listener Containers</title>
|
||||
|
||||
<para>One of the most common uses of JMS is to concurrently process
|
||||
@@ -441,13 +456,19 @@
|
||||
the provider supports it), will be provided in future releases.
|
||||
SimpleMessageListenerContainer creates a fixed number of JMS sessions at
|
||||
startup and uses them throughout the lifespan of the container.</para>
|
||||
|
||||
<para>Creating and configuring a ActiveMQ MessageListener container is
|
||||
described in <link linkend="activemq-async-reception">this</link>
|
||||
section.</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="activemq-using-txmgmt">
|
||||
<title>Transaction Management</title>
|
||||
|
||||
<para>Spring provides a <literal>NmsTransactionManager</literal> that
|
||||
manages transactions for a single ConnectionFactory. This allows
|
||||
<para>Spring provides an implementation of the
|
||||
IPlatformTransactionManager interface for managing ActiveMQ messaging
|
||||
transactions. The class is <literal>NmsTransactionManager</literal> and
|
||||
it manages transactions for a single ConnectionFactory. This allows
|
||||
messaging applications to leverage the managed transaction features of
|
||||
Spring as described in <xref linkend="transaction" />. The
|
||||
<literal>NmsTransactionManager</literal> performs local resource
|
||||
@@ -568,7 +589,7 @@
|
||||
a ConnectionFactory property that will instantiate a NmsTemplate instance
|
||||
that is made available via the property NmsTemplate.</para>
|
||||
|
||||
<section>
|
||||
<section xml:id="activemq-messageconverter">
|
||||
<title>Using MessageConverters</title>
|
||||
|
||||
<para>In order to facilitate the sending of domain model objects, the
|
||||
@@ -580,19 +601,23 @@
|
||||
<literal>IMessageConverter</literal> interface. This interface defines a
|
||||
simple contract to convert between .NET objects and JMS messages. The
|
||||
default implementation <literal>SimpleMessageConverter</literal>
|
||||
supports conversion between String and TextMessage, byte[] and
|
||||
BytesMesssage, and System.Collections.IDictionary and MapMessage. By
|
||||
using the converter, you and your application code can focus on the
|
||||
business object that is being sent or received via messaging and not be
|
||||
concerned with the details of how it is represented as a JMS message.
|
||||
There is also an <literal>XmlMessageConverter</literal> that converts
|
||||
objects to an XML string and vice-versa for sending via a TextMessage.
|
||||
Please refer to the API documentation and example application for more
|
||||
information on configuring an XmlMessageConverter.</para>
|
||||
supports conversion between <classname>String</classname> and
|
||||
<classname>TextMessage</classname>, <classname>byte[]</classname> and
|
||||
<classname>BytesMesssage</classname>, and
|
||||
<classname>System.Collections.IDictionary</classname> and
|
||||
<classname>MapMessage</classname>. By using the converter, you and your
|
||||
application code can focus on the business object that is being sent or
|
||||
received via messaging and not be concerned with the details of how it
|
||||
is represented as a JMS message. There is also an
|
||||
<literal>XmlMessageConverter</literal> that converts objects to an XML
|
||||
string and vice-versa for sending via a TextMessage. Please refer to the
|
||||
API documentation and example application for more information on
|
||||
configuring an <classname>XmlMessageConverter</classname>.</para>
|
||||
|
||||
<para>The family of <literal>ConvertAndSend</literal> messages are
|
||||
similar to that of the Send method with the additional argument of type
|
||||
IMessagePostProcessor. These methods are listed below.</para>
|
||||
<interfacename>IMessagePostProcessor</interfacename>. These methods are
|
||||
listed below.</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
@@ -686,7 +711,7 @@
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<section label="" xml:id="messaging-session-callback" xml:lang="">
|
||||
<title>Session and Producer Callback</title>
|
||||
|
||||
<para>While the send operations cover many common usage scenarios, there
|
||||
@@ -721,12 +746,12 @@
|
||||
|
||||
<para><programlisting language="csharp">public interface IProducerCallback
|
||||
{
|
||||
object DoInJms(Session session, MessageProducer producer);
|
||||
object DoInNms(ISession session, IMessageProducer producer);
|
||||
}</programlisting>and</para>
|
||||
|
||||
<programlisting language="csharp">public interface ISessionCallback
|
||||
{
|
||||
object DoInJms(Session session);
|
||||
object DoInNms(ISession session);
|
||||
}</programlisting>
|
||||
|
||||
<para>The delegate signatures are listed below and mirror the interface
|
||||
@@ -740,7 +765,7 @@ public delegate object ProducerDelegate(ISession session, IMessageProducer produ
|
||||
<section>
|
||||
<title>Receiving a message</title>
|
||||
|
||||
<section>
|
||||
<section xml:id="activemq-sync-receive">
|
||||
<title>Synchronous Reception</title>
|
||||
|
||||
<para>While messaging middleware is typically associated with
|
||||
@@ -833,13 +858,13 @@ public delegate object ProducerDelegate(ISession session, IMessageProducer produ
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<section xml:id="activemq-async-reception">
|
||||
<title>Asynchronous Reception</title>
|
||||
|
||||
<para>Asynchronous reception of messages occurs by the messaging
|
||||
provider invoking a callback function. This is commonly an interface
|
||||
such as the IMessageListener interface shown below, taken from the TIBCO
|
||||
EMS provider.</para>
|
||||
such as the <interfacename>IMessageListener</interfacename> interface
|
||||
shown below, taken from the TIBCO EMS provider.</para>
|
||||
|
||||
<programlisting language="csharp">public interface IMessageListener
|
||||
{
|
||||
@@ -901,9 +926,13 @@ namespace MyApp
|
||||
<literal>SimpleMessageListenerContainer</literal> creates a fixed number
|
||||
of JMS Sessions/MessageConsumer pairs as set by the property
|
||||
<property>ConcurrentConsumers</property>. The default value of
|
||||
ConcurrentConsumers is one. Here is a sample configuration</para>
|
||||
ConcurrentConsumers is one. Here is a sample configuration that uses the
|
||||
the custom schema provided in Spring.NET to more reasily configure
|
||||
MessageListenerContainers.</para>
|
||||
|
||||
<programlisting language="myxml"><objects xmlns="http://www.springframework.net"
|
||||
xmlns:nms="http://www.springframework.net/nms">
|
||||
|
||||
<programlisting language="myxml">
|
||||
<object id="ActiveMqConnectionFactory" type="Apache.NMS.ActiveMQ.ConnectionFactory, Apache.NMS.ActiveMQ">
|
||||
<constructor-arg index="0" value="tcp://localhost:61616"/>
|
||||
</object>
|
||||
@@ -915,17 +944,15 @@ namespace MyApp
|
||||
|
||||
<object id="MyMessageListener" type="MyApp.SimpleMessageListener, MyApp"/>
|
||||
|
||||
<object id="MessageListenerContainer" type="Spring.Messaging.Nms.Listener.SimpleMessageListenerContainer, Spring.Messaging.Nms">
|
||||
<property name="ConnectionFactory" ref="ConnectionFactory"/>
|
||||
<property name="DestinationName" value="APP.REQUEST"/>
|
||||
<property name="ConcurrentConsumers" value="10"/>
|
||||
<property name="MessageListener" ref="MyMessageListener"/>
|
||||
</object>
|
||||
</programlisting>
|
||||
<nms:listener-container connection-factory="ConnectionFactory" concurrency="10">
|
||||
<nms:listener ref="MyMessageListener" destination="APP.STOCK.REQUEST" />
|
||||
</nms:listener-container>
|
||||
|
||||
</objects></programlisting>
|
||||
|
||||
<para>The above configuration will create 10 threads that process
|
||||
messages off of the queue named "APP.REQUEST". The threads are those
|
||||
owned by the messaging provider as a result of creating a
|
||||
messages off of the queue named "APP.STOCK.REQUEST". The threads are
|
||||
those owned by the messaging provider as a result of creating a
|
||||
MessageConsumer. Other important properties are
|
||||
<property>ClientID</property>, used to set the ClientID of the
|
||||
Connection and <property>MessageSelector</property> to specify the
|
||||
@@ -935,21 +962,6 @@ namespace MyApp
|
||||
exception listener using the property
|
||||
<literal>ExceptionListener</literal>.</para>
|
||||
|
||||
<para>A custom schema to create the
|
||||
<literal>SimpleMessageListener</literal> container is also provided.
|
||||
Using this schema the configuration above looks like the
|
||||
following</para>
|
||||
|
||||
<programlisting language="myxml"><objects xmlns="http://www.springframework.net"
|
||||
xmlns:nms="http://www.springframework.net/nms">
|
||||
|
||||
<!-- other object definitions -->
|
||||
<nms:listener-container connection-factory="ConnectionFactory" concurrency="10">
|
||||
<nms:listener ref="MyMessageListener" destination="APP.STOCK.REQUEST" />
|
||||
</nms:listener-container>
|
||||
|
||||
</objects></programlisting>
|
||||
|
||||
<para>Exceptions that are thrown during message processing can be passed
|
||||
to an implementation of <literal>IExceptionHandler</literal> and
|
||||
registered with the container via the property
|
||||
@@ -968,7 +980,7 @@ namespace MyApp
|
||||
<literal>SimpleMessageListenerContainer</literal>.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<section xml:id="activemq-sessionaware">
|
||||
<title>The ISessionAwareMessageListener interface</title>
|
||||
|
||||
<para>The <literal>ISessionAwareMessageListener</literal> interface is a
|
||||
@@ -1120,7 +1132,7 @@ namespace MyApp
|
||||
<para></para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<section xml:id="activemq-msg-tx">
|
||||
<title>Processing messages within a messaging transaction</title>
|
||||
|
||||
<para>Invoking a message listener within a transaction only requires
|
||||
@@ -1143,7 +1155,7 @@ namespace MyApp
|
||||
transactions.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<section xml:id="activemq-namespace">
|
||||
<title>Messaging Namespace support</title>
|
||||
|
||||
<para>To use the NMS namespace elements you will need to reference the
|
||||
|
||||
@@ -34,6 +34,12 @@
|
||||
<literal>Trigger</literal> instances, respectively. Furthermore, a
|
||||
convenience class for the Quartz Scheduler is available that allows you to
|
||||
invoke a method of an existing target object.</para>
|
||||
|
||||
<note>
|
||||
<para>There is a Quartz Quickstart application that is shipped with
|
||||
Spring.NET. It is documented <link
|
||||
linkend="quartz-quickstart">here</link>.</para>
|
||||
</note>
|
||||
</section>
|
||||
|
||||
<section xml:id="scheduling-quartz">
|
||||
@@ -77,7 +83,7 @@
|
||||
|
||||
<programlisting language="csharp">namespace Example.Quartz;
|
||||
|
||||
public class ExampleJob extends QuartzJobObject {
|
||||
public class ExampleJob : QuartzJobObject {
|
||||
|
||||
private int timeout;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user