<document>
  <header>
    <product>resin-ee</product>
    <title>JMS Listener IoC</title>
        <description>
          <p>Introduces the JMS message listener configured with IoC.</p>
        </description>
    <type>tutorial</type>
    <tutorial-startpage>send</tutorial-startpage>
  </header>

<body>
<summary/>

<section title="Files in this tutorial">
<deftable>
<tr><td><viewfile-link file="WEB-INF/web.xml"/>
    <td>Configures the Queue, MessageSender, MessageListener.
<tr><td><viewfile-link file="WEB-INF/classes/example/MyListener.java"/>
    <td>The message listener.
<tr><td><viewfile-link file="WEB-INF/classes/example/MessageServlet.java"/>
    <td>The message servlet
</deftable>
</section>

<section title="Overview">

<p>Messaging lets a servlet delegate processing to a batch process either
on the same machine or on a separate machine.  The servlet creates a message
and sends it to a queue.  The servlet immediately completes and when the
batch process is ready, it processes the message.</p>

<p>Messaging is therefore comprised of three main components:
<ul>
<li>A <var>Producer</var> creates messages and sends them to
a <var>Queue</var>.  The Producer could be something like a Servlet.
<li>A <var>Queue</var> stores the messages from the Produces and provides
them to a Consumer when ready.  The Queue is implemented by the
messaging provider.
<li>A <var>Consumer</var> processes messages as they become
available in the Queue.  The <var>Consumer</var> is typically a bean
implementing the <code>MessageListener</code> interface.
</ul>

</section>

<section title="Producer (MessageServlet)">

<p>In this example, the Producer is a Servlet which sends a simple message.
The Producer uses a <code>MessageSender</code> configured in the web.xml
to send the message.</p>

<example title="MessageServlet">
String message = "sample message";

MessageSender sender = ...; // JNDI lookup

sender.send(null, message);
</example>

<p>In this configuration, the <code>MessageSender</code> is a
<code>com.caucho.services.message.MessageSender</code>.  It's also possible
to use the full JMS <code>MessageProducer</code> which is more verbose.
The <code>MessageSender</code> is an interface available in the open
source <a href="http://www.caucho.com/hessian">Hessian distribution</a>,
so it can be used in other application servers as a convenient facade.</p>

<p>The <code>send</code> method completes as soon as
the message is stored in the queue.  Laster, when a thread is available, the
Queue will send the message to the Consumer.</p>

</section>

<section title="Consumer (MyListener)">

<p>The Queue delivers message to the Consumer one by one.  When the
Consumer finishes processing a message the Queue will deliver the next
available message.</p>

<p>The Consumer implements <code>javax.jms.MessageListener</code>, and
will therefore be identical code in any application server.  The
Consumer might even be on a different server or use a different
application server.</p>

<p>In this example, the Consumer just logs the message.</p>

<example title="MyListener">
package example;

import java.util.logging.Logger;
import java.util.logging.Level;

import javax.jms.Message;
import javax.jms.TextMessage;
import javax.jms.MessageListener;

public class MyListener implements MessageListener {
  private static final Logger log =
    Logger.getLogger(MyListener.class.getName());

  public void onMessage(Message message)
  {
    try {
      TextMessage textMessage = (TextMessage) message;

      log.info("received: " + textMessage.getText());

      _lastMessage = textMessage.getText();
    } catch (Throwable e) {
      log.log(Level.WARNING, e.toString(), e);
    }
  }
}
</example>

</section>

<section title="Configuration">

<p>Since Resin is an inversion of control container (IoC), it can
 configure the JMS resources in the standard Resin configuration file.</p>

<p>The configuration is responsible for three things:</p>
<ul>
<li>Configuring the Queue
<li>Configuring the MessageSender
<li>Configuring the MessageListener
</ul>

<p>The <code>Queue</code> is configured directly in a &lt;resource>
tag, together with any configuration setters.  This example uses a
local JDBC store.</p>

<p>Because the listener and sender need a reference to the queue,
the resource stores it in the "queue" variable.  (It could also have
used jndi-name to store the queue in JNDI.)</p>

<example title="Queue resin-web.xml fragment">
&lt;resource var="queue" type="com.caucho.jms.jdbc.JdbcQueue">
  &lt;init>
     &lt;queue-name>resin&lt;/queue-name>
     &lt;data-source>jdbc/resin&lt;/data-source>
  &lt;/init>
&lt;/resource>
</example>

<p>JMS also needs a configured ConnectionFactory, so the sender
and listener can create JMS connections.</p>

<example title="ConnectionFactory resin-web.xml fragment">
&lt;resource var="jmsFactory" type="com.caucho.jms.ConnectionFactoryImpl">
&lt;/resource>
</example>

<p>The MessageListener is configured and registered with Resin's
MessageListenerResource.  That resource instantiates the listeners
and receives messages from the queue.</p>

<example title="MyListener configuration resin-web.xml">
&lt;resource type="com.caucho.jms.resource.ListenerResource">
  &lt;init>
     &lt;connection-factory>\${jmsFactory}&lt;/connection-factory>

     &lt;destination>\${queue}&lt;/destination>

     &lt;listener type="example.MyListener"/>
  &lt;/init>
&lt;/resource>
</example>

<p>Finally, we configure a MessageSender.  This step is optional,
since the application could use the JMS ConnectionFactory with
the Queue directly, if it wanted.</p>

<example title="MessageSender configuration resin-web.xml">
&lt;resource jndi-name="jms/sender"
        type="com.caucho.jms.resource.MessageSenderResource">
 &lt;init>
    &lt;connection-factory>\${jmsFactory}&lt;/connection-factory>

    &lt;destination>\${queue}&lt;/destination>
  &lt;/init>
&lt;/resource>
</example>

<deftable>
<tr><th>tag<th>meaning
<tr><td>resource<td>Configures a bean using Resin's IoC configuration
<tr><td>type<td>The type of a resource to be configured
</deftable>

</section>

</body>
</document>
