Resin Documentationapp server |
resin messaging
Configuration for Resin's JMS provider implementation. The JDBC Queues and Topics provide a persistent messaging store. The Memory Queues and Topics provide a low-overhead memory-based store. Resin's messaging is build around JMS, the Java
messaging service API and EJB message driven beans. A simple messaging
application can use the Because messaging is integrated with the Resin IoC container, applications can use standard WebBeans injection to obtain the queues, avoiding code dependencies and improving testing. The following example sends a "hello, world" message
from The package demo; import java.io.*; import javax.servlet.*; import java.util.BlockingQueue; import javax.webbeans.Named; public MySendingServlet extends GenericServlet { @Named("myQueue") private BlockingQueue _queue; public void service(ServletRequest req, ServletResponse res) throws IOException, ServletException { String msg = "hello, world"; _queue.offer(msg); System.out.println("Sent: " + msg); } } The EJB message bean service will receive the message and pass it
along to package demo; import javax.jms.*; public MyListener implements MessageListener { public void onMessage(Message message) { ObjectMessage oMsg = (ObjectMessage) message; System.out.println("Received: " + oMsg.getObject()); } } Now that the code's written, we just need to configure it in the
<web-app xmlns="http://caucho.com/ns/resin"> <jms-connection-factory uri="resin:"/> <jms-queue name="myQueue" uri="memory:"/> <ejb-message-bean class="demo.MyListener"> <destination>#{myQueue}</destination> </ejb-message-bean> <servlet-mapping url-pattern="/test" servlet-class="demo.MySendingServlet"/> </web-app> <web-app xmlns="http://caucho.com/ns/resin"> <jms-queue name="my-queue" uri="memory:"/> <jms-connection-factory uri="resin:"/> </web-app> Memory QueueResin's memory queue is a basic, non-persistent queue suitable
for testing and for cases where losing the queue contents at a server
crash is acceptable. Like Resin's other queues, you can use the
<web-app xmlns="http://caucho.com/ns/resin"> <jms-connection-factory uri="resin:"/> <jms-queue name="myQueue" uri="memory:"/> <ejb-message-bean class="demo.MyListener"> <destination>#{myQueue}</destination> </ejb-message-bean> </web-app> File QueueThe file queue backs messages on the local filesystem, allowing for recovery in case of system crash. The saved file is efficient, using the same backing store as Resin's proxy caching and persistent sessions. The file queue configuration requires an additional 'path' parameter to specify a directory for the backing files. <web-app xmlns="http://caucho.com/ns/resin"> <jms-queue name="myQueue" uri="file:path=WEB-INF/messaging"/> <jms-connection-factory uri="resin:"/> <ejb-message-bean class="demo.MyListener"> <destination>#{myQueue}</destination> </ejb-message-bean> </web-app> Cluster Server QueueThe cluster server queue is a file queue which can also receive messages from the local cluster. On the local machine, it acts exactly like the file queue. When used with the cluster client queue, clients can distribute messages to any server queue in the cluster, allowing for load balancing. Like the file queue, the cluster server queue requires a 'path' attribute to specify the location of the backing file. <web-app xmlns="http://caucho.com/ns/resin"> <jms-queue name="myQueue" uri="server:"> <init> <name>my-queue</name> <path>WEB-INF/jms</path> </init> </jms-queue> <jms-connection-factory uri="resin:"/> <ejb-message-bean class="demo.MyListener"> <destination>#{myQueue}</destination> </ejb-message-bean> </web-app> Cluster Client QueueThe client queue distributes messages to server queues in a cluster. Normally, only the sending methods are used for the client queue; the receiving message beans are handled by the server queues. The client queue needs to configure the cluster of the server queues. The cluster can be different from the client's own cluster. <web-app xmlns="http://caucho.com/ns/resin"> <jms-queue name="myQueue" uri="client:cluster=message-tier"/> <jms-connection-factory uri="resin:"/> </web-app> <web-app xmlns="http://caucho.com/ns/resin"> <jms-topic name="my-topic" uri="memory:"/> <jms-connection-factory uri="resin:"/> </web-app> Memory TopicResin's memory topic is a basic, non-persistent topic suitable
for testing and for cases where losing the topic contents at a server
crash is acceptable. Like Resin's other topics, you can use the
<web-app xmlns="http://caucho.com/ns/resin"> <jms-connection-factory uri="resin:"/> <jms-topic name="myTopic" uri="memory:"/> <ejb-message-bean class="demo.MyListener"> <destination>#{myTopic}</destination> </ejb-message-bean> </web-app> File TopicThe file topic backs messages on the local filesystem for persistent subscriptions. Non-persistent subscriptions use the memory topic interface. The saved file is efficient, using the same backing store as Resin's proxy caching and persistent sessions. The file topic configuration requires an additional 'path' parameter to specify a directory for the backing files. <web-app xmlns="http://caucho.com/ns/resin"> <jms-topic name="myTopic" uri="file:path=WEB-INF/messaging"/> <jms-connection-factory uri="resin:"/> <ejb-message-bean class="demo.MyListener"> <destination>#{myTopic}</destination> </ejb-message-bean> </web-app> The <web-app xmlns="http://caucho.com/ns/resin"> <jms-connection-factory name="jms/factory" uri="resin:"/> </web-app> Resin's queues implement
the package example; import java.util.concurrent.BlockingQueue; import java.io.*; import javax.servlet.*; import javax.webbeans.*; public class TestServlet extends GenericServlet { private @In BlockingQueue _queue; public void service(ServletRequest req, ServletResponse res) throws IOException, ServletException { PrintWriter out = res.getWriter(); _queue.offer("test message"); out.println("receive: " + _queue.poll()); } } The resin-web.xml configuration for the <web-app xmlns="http://caucho.com/ns/resin"> <jms-queue uri="memory:"/> </web-app> BlockingQueue for 3rd party JMSThe <web-app xmlns="http://caucho.com/ns/resin"> <resource-adapter class="org.apache.activemq.ra.ActiveMQResourceAdapter"> <init server-url="vm://localhost"/> </resource-adapter> <connection-factory uri="activemq:" name="factory"/> <jms-queue uri="activemq:" name="queue"> <init physicalName="queue.test"/> </jms-queue> <bean name="test" class="com.caucho.jms.queue.JmsBlockingQueue"> <init> <factory>${factory}</factory> <destination>${queue}</destination> </init> </bean> </web-app> At some point, the application needs to receive messages from the and process them. Message driven beans provides a reliable, pooled framework for receiving messages. Applications just need to implement a simple listener interface, and register to listen with a queue or topic. package javax.jms; public interface MessageListener { public void onMessage(Message message); } The implementation class can use any Resin IoC capability, including injection, transaction annotations or interception. For example, a simple listener might use Amber/JPA to store messages in a database. package demo; import javax.jms.*; import javax.persistence.*; import javax.webbeans.*; public class MyListener implements MessageListener { private @In EntityManagerFactory _factory; public void onMessage(Message msg) { ObjectMessage oMsg = (ObjectMessage) msg; String value = oMsg.getObject(); EntityManager em = _factory.createEntityManager(); try { em.persist(new MyEntry(value)); } finally { em.close(); } } } The configuration in the resin-web.xml file will connect the
<web-app xmlns="http://caucho.com/ns/resin"> <jms-connection-factory uri="resin:"/> <jms-queue name="my_queue" uri="memory:"/> <ejb-message-bean class="demo.MyListener"> <destination>${my_queue}</destination> </ejb-message-bean> </web-app> The Because the The Java Connector Architecture is a driver architecture which connects JMS providers like ActiveMQ with Resin's message driven beans and JMS sessions. The JCA driver will configure a resource adapter and an activation spec to select a queue. The resource adapter is the JCA driver's main service. It handles threading, socket connections, and creates any endpoints. JCA for message driven beansThe activation specification configures the JCA driver with a message-driven bean. The configuration looks like: <web-app xmlns="http://caucho.com/ns/resin"> <resource-adapter class="org.apache.activemq.ra.ActiveMQResourceAdapter"> <init server-url="vm://localhost"/> </resource> <ejb-message-bean class="qa.MyListener"> <activation-spec class="org.apache.activemq.ra.ActiveMQActivationSpec"> <init physical-name="queue.test"/> </activation-spec> </ejb-message-bean> </web-app> Resin can also provide shortcuts for the driver classes using the uri syntax: <web-app xmlns="http://caucho.com/ns/resin"> <resource-adapter uri="activemq:"> <init server-url="vm://localhost"/> </resource> <ejb-message-bean class="qa.MyListener"> <activation-spec uri="activemq:"> <init physical-name="queue.test"/> </activation-spec> </ejb-message-bean> </web-app>
|