Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

git-svn-id: file:///Users/billburke/jboss/resteasy/resteasy-git/svn-s…

…erver-sync/resteasy/trunk/jaxrs@339 2b1ed4c4-5db3-0410-90e4-80a7a6204c25
  • Loading branch information...
commit fbd4e832a9e0763eda4ccf044d6f8bb80c110a1c 1 parent 2c1e00e
patriot1burke authored
Showing with 2,440 additions and 2 deletions.
  1. +10 −2 distribution/assembly.xml
  2. +21 −0 examples/jms-facade/README.TXT
  3. +374 −0 examples/jms-facade/docs.html
  4. +20 −0 examples/jms-facade/pom.xml
  5. +105 −0 examples/jms-facade/resteasy-mom-war/pom.xml
  6. +31 −0 examples/jms-facade/resteasy-mom-war/src/main/webapp/WEB-INF/web.xml
  7. +68 −0 examples/jms-facade/resteasy-mom/pom.xml
  8. +104 −0 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/ByteArrayMessageProcessor.java
  9. +79 −0 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/DestinationResource.java
  10. +170 −0 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/Destinations.java
  11. +65 −0 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/DlqProcessor.java
  12. +70 −0 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/DurableTopicListener.java
  13. +73 −0 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/DurableTopicReceiver.java
  14. +130 −0 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/Listener.java
  15. +100 −0 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/MessageProcessor.java
  16. +112 −0 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/QueueBrowserResource.java
  17. +23 −0 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/QueueListener.java
  18. +18 −0 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/QueueReceiver.java
  19. +117 −0 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/QueueResource.java
  20. +147 −0 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/Receiver.java
  21. +141 −0 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/ResteasyMomBootstrap.java
  22. +121 −0 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/StreamMessageProcessor.java
  23. +23 −0 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/TopicListener.java
  24. +17 −0 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/TopicReceiver.java
  25. +230 −0 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/TopicResource.java
  26. +3 −0  examples/jms-facade/resteasy-mom/src/test/resources/jndi.properties
  27. +68 −0 examples/jms-facade/resteasy-mom/src/test/resources/log4j.xml
View
12 distribution/assembly.xml
@@ -9,11 +9,11 @@
<fileSets>
<fileSet>
<directory>../resteasy-jaxrs/target/apidocs</directory>
- <outputDirectory>docs/resteasy-jaxrs</outputDirectory>
+ <outputDirectory>docs/javadocs/resteasy-jaxrs</outputDirectory>
</fileSet>
<fileSet>
<directory>../jaxrs-api/target/apidocs</directory>
- <outputDirectory>docs/jaxrs-api</outputDirectory>
+ <outputDirectory>docs/javadocs/jaxrs-api</outputDirectory>
</fileSet>
<fileSet>
<directory>../examples/spring-hibernate-contacts</directory>
@@ -27,6 +27,14 @@
<directory>../examples/jaxb-json</directory>
<outputDirectory>examples/jaxb-json</outputDirectory>
</fileSet>
+ <fileSet>
+ <directory>../examples/jms-facade</directory>
+ <outputDirectory>examples/jms-facade</outputDirectory>
+ </fileSet>
+ <fileSet>
+ <directory>../../resteasy-jaxrs-docbook/build/reference/en</directory>
+ <outputDirectory>docs/userguide</outputDirectory>
+ </fileSet>
</fileSets>
<dependencySets>
<dependencySet>
View
21 examples/jms-facade/README.TXT
@@ -0,0 +1,21 @@
+Example of using RestEasy with:
+- JMS
+- Sub Resource Locators
+- custom assembly of root resources
+
+This project is a facade over JMS. See docs.html for more information on the project
+
+System Requirements:
+====================
+- Maven 2.0.9 or higher
+- Requires JBoss 4.2.x or higher (you'll have to modify the POMs to get it to work with another EE 5 compatible application server)
+
+Building the project:
+====================
+1. Edit pom.xml in the root directory. Change the <jbossHome> property to the location of your JBoss installation
+2. In root directoy
+
+mvn clean install
+
+This will build a WAR (for resteasy) and run a bunch of unit tests.
+
View
374 examples/jms-facade/docs.html
@@ -0,0 +1,374 @@
+<html><head>
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+ <title>JMS Facade</title><link rel="stylesheet" href="css/html.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.65.1"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book" lang="en"><div class="titlepage"><div><div><h1 class="title"><a name="d0e1"></a>JMS Facade</h1></div><div><h2 class="subtitle">Using JAX-RS to build a JMS Facade</h2></div><div><p class="releaseinfo">1.0</p></div></div><div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="chapter"><a href="#Configuration">1. Configuration</a></span></dt><dt><span class="chapter"><a href="#The RESTFul Interface">2. The RESTFul Interface</a></span></dt><dd><dl><dt><span class="sect1"><a href="#Queues">2.1. Queues</a></span></dt><dt><span class="sect1"><a href="#Topics">2.2. Topics</a></span></dt><dt><span class="sect1"><a href="#Durable Topics">2.3. Durable Topics</a></span></dt></dl></dd></dl></div><div class="preface" lang="en"><div class="titlepage"><div><div></div></div><div></div></div><p>
+ </p></div><div class="chapter" lang="en"><div class="titlepage"><div><div><h2 class="title"><a name="Configuration"></a>Chapter&nbsp;1.&nbsp;Configuration</h2></div></div><div></div></div><p>
+
+RESTEasy MOM has only been used/tested with JBoss MQ on JBoss 4.2.2. It should work with other JMS providers and on other application servers, but you may have to do some tweaking. RESTEasy MOM is deployed as a WAR file. To configure you will have to modify its web.xml file.
+</p><p>
+
+
+</p><p>
+
+By default, RESTEasy MOM will try to lookup and use a ConnectionFactory stored under the JNDI name "java:/ConnectionFactory". You can configure it to look into another JNDI location by setting the context param:
+</p><p>
+
+</p><pre class="programlisting">resteasy.mom.connection.factory</pre><p>
+</p><p>
+
+</p><p>
+
+
+</p><p>
+
+When RESTEasy MOM cannot deliver a message it tries to send the message to a dead letter queue. It looks for this in JNDI, by default, under "queue/DLQ". You can configure this setting via
+</p><p>
+
+</p><p>
+
+resteasy.mom.dlq.jndi
+</p><p>
+
+</p><p>
+
+
+</p><p>
+
+Every RESTEasy MOM URI path is prefaced with
+</p><p>
+
+</p><pre class="programlisting">/queues/{queue-name} </pre><p>
+</p><p>
+
+or
+</p><p>
+
+</p><pre class="programlisting">/topics/{topic-name} </pre><p>
+</p><p>
+
+</p><p>
+
+By default, RESTEasy MOM will try and lookup destinations as follows:
+</p><p>
+
+</p><pre class="programlisting">
+Destination dest = (Destination)jndi.lookup("queue/" + {queue-name});
+</pre><p>
+</p><p>
+
+or
+</p><p>
+
+</p><pre class="programlisting">
+Destination dest = (Destination)jndi.lookup("topic/" + {topic-name});
+</pre><p>
+</p><p>
+
+If you are using JBoss MQ and you have not defined a specific JNDIName for your queue or topic, then this will just work, if not, read further.
+</p><p>
+
+
+</p><p>
+
+You can use the resteasy.mom.queues.jndi or resteasy.mom.topics.jndi web.xml context-params to specify a name/jndiName mapping of the form:
+</p><p>
+
+name ':' jndi-name
+</p><p>
+
+As many as these as you want separate by a ','. For example:
+</p><p>
+
+</p><pre class="programlisting">
+&lt;context-param&gt;
+ &lt;param-name&gt;resteasy.mom.queues.jndi&lt;/param-name&gt;
+ &lt;param-value&gt;
+ queueA : java:comp/env/jms/MyQueue,
+ queueB : jboss/queues/B
+ &lt;/param-value&gt;
+&lt;/context-param&gt;
+</pre><p>
+</p><p>
+
+</p><p>
+
+
+</p><p>
+
+If you cannot obtain JMS ConnectionFactory or destinations from JNDI, then you must write your own RestasyMomBootstrap class. Download the RESTEasy MOM src and checkout the implementation of this class. Its pretty straightforward.
+ </p><p>
+
+
+</p></div><div class="chapter" lang="en"><div class="titlepage"><div><div><h2 class="title"><a name="The RESTFul Interface"></a>Chapter&nbsp;2.&nbsp;The RESTFul Interface</h2></div></div><div></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="Queues"></a>2.1.&nbsp;Queues</h2></div></div><div></div></div><p>
+
+
+</p><pre class="programlisting">
+POST /queues/{queue-name}?persistent=[true|false]&amp;priority=[0-9+]&amp;timeToLive=[0-9+]
+</pre><p>
+</p><p>
+
+Response is 204 NO-CONTENT on success. All query parameters optional
+</p><p>
+
+</p><p>
+
+
+</p><pre class="programlisting">
+POST /queues/{queue-name}/head?wait=[0-9+]
+</pre><p>
+</p><p>
+
+Wait is optional. Defaults to wait forever.
+</p><p>
+
+</p><p>
+
+</p><p>
+
+
+</p><pre class="programlisting">
+GET /queues/{queue-name}/browser
+</pre><p>
+</p><p>
+
+Returns HTML document with links to message you can view.
+</p><p>
+
+
+Dedicated queues receivers are JMS message consumers attached to a specific session.
+</p><p>
+
+
+</p><p>
+
+</p><pre class="programlisting">
+PUT /queues/{queue-name}/receivers/{receiver-id}
+</pre><p>
+If you pass an ACCEPT header this will create a JMS selector that filters message for only a specific media type. So, if you pass an ACCEPT header of 'application/xml' this receiver will only get message of CONTENT-TYPE 'application/xml'
+</p><p>
+
+</p><p>
+
+
+</p><pre class="programlisting">DELETE /queues/{queue-name}/receivers/{receiver-id} </pre><p>
+</p><p>
+
+
+</p><p>
+
+</p><pre class="programlisting">
+GET /queues/{queue-name}/receivers/{receiver-id}/head?wait=[0-9+]
+</pre><p>
+</p><p>
+
+
+</p><p>
+
+</p><pre class="programlisting">
+DELETE /queues/{queue-name}/receivers/{receiver-id}/head
+</pre><p>
+</p><p>
+
+FYI, this is idempotent still!
+</p><p>
+
+
+</p><pre class="programlisting">
+POST /queues/{queue-name}/receivers/{reciever-id}/head
+</pre><p>
+</p><p>
+
+</p><p>
+
+
+You can register a URI to post to when a message is sent to the queue. This registers a MessageListener with the queue. When the message is received, on the server, it send the message to the registered URI.
+</p><p>
+
+
+</p><p>
+
+</p><pre class="programlisting">
+PUT /queues/{queue-name}/listeners/{listener-id}
+</pre><p>
+You must send a string that is the URI you want to send the message to. The content-type can be anything, "text/plain" or whatever.
+</p><p>
+
+If you pass an ACCEPT header this will create a JMS selector that filters message for only a specific media type. So, if you pass an ACCEPT header of 'application/xml' this receiver will only get message of CONTENT-TYPE 'application/xml'
+</p><p>
+
+
+</p><pre class="programlisting">DELETE /queues/{queue-name}/receivers/{receiver-id} </pre><p>
+</p><p>
+
+</p><p>
+
+
+</p><p>
+
+</p><p>
+
+
+</p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="Topics"></a>2.2.&nbsp;Topics</h2></div></div><div></div></div><p>
+
+
+</p><pre class="programlisting">
+POST /topics/{topic-name}?persistent=[true|false]&amp;priority=[0-9+]&amp;timeToLive=[0-9+]
+</pre><p>
+</p><p>
+
+Response is 204 NO-CONTENT on success. All query parameters optional
+</p><p>
+
+
+Dedicated topic receivers are JMS message consumers attached to a specific session.
+</p><p>
+
+
+</p><p>
+
+</p><pre class="programlisting">
+PUT /topics/{topic-name}/receivers/{receiver-id}
+</pre><p>
+If you pass an ACCEPT header this will create a JMS selector that filters message for only a specific media type. So, if you pass an ACCEPT header of 'application/xml' this receiver will only get message of CONTENT-TYPE 'application/xml'
+</p><p>
+
+</p><p>
+
+
+</p><pre class="programlisting">DELETE /topics/{topic-name}/receivers/{receiver-id} </pre><p>
+</p><p>
+
+
+</p><p>
+
+</p><pre class="programlisting">
+GET /topics/{topic-name}/receivers/{receiver-id}/head?wait=[0-9+]
+</pre><p>
+</p><p>
+
+
+</p><p>
+
+</p><pre class="programlisting">
+DELETE /topics/{topic-name}/receivers/{receiver-id}/head
+</pre><p>
+</p><p>
+
+FYI, this is idempotent still!
+</p><p>
+
+
+</p><pre class="programlisting">
+POST /topics/{topic-name}/receivers/{receiver-id}/head
+</pre><p>
+</p><p>
+
+</p><p>
+
+
+You can register a URI to post to when a message is sent to this dedicated topic listener. This registers a MessageListener with the queue. When the message is received, on the server, it send the message to the registered URI.
+</p><p>
+
+
+</p><p>
+
+</p><pre class="programlisting">
+PUT /topics/{topic-name}/listeners/{listener-id}
+</pre><p>
+You must send a string that is the URI you want to send the message to. The content-type can be anything, "text/plain" or whatever.
+</p><p>
+
+If you pass an ACCEPT header this will create a JMS selector that filters message for only a specific media type. So, if you pass an ACCEPT header of 'application/xml' this receiver will only get message of CONTENT-TYPE 'application/xml'
+</p><p>
+
+
+</p><pre class="programlisting">DELETE /topics/{topic-name}/receivers/{receiver-id} </pre><p>
+</p><p>
+
+</p><p>
+
+
+</p><p>
+
+</p><p>
+
+
+</p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="Durable Topics"></a>2.3.&nbsp;Durable Topics</h2></div></div><div></div></div><p>
+
+
+</p><pre class="programlisting">
+POST /topics/{topic-name}?persistent=[true|false]&amp;priority=[0-9+]&amp;timeToLive=[0-9+]
+</pre><p>
+</p><p>
+
+Response is 204 NO-CONTENT on success. All query parameters optional
+</p><p>
+
+</p><p>
+
+
+Dedicated topic receivers are JMS message consumers attached to a specific session.
+</p><p>
+
+
+</p><p>
+
+</p><pre class="programlisting">
+PUT /topics/{topic-name}/durable/receivers/{receiver-id}
+</pre><p>
+If you pass an ACCEPT header this will create a JMS selector that filters message for only a specific media type. So, if you pass an ACCEPT header of 'application/xml' this receiver will only get message of CONTENT-TYPE 'application/xml'
+</p><p>
+
+</p><p>
+
+
+</p><pre class="programlisting">DELETE /topics/{topic-name}/durable/receivers/{receiver-id} </pre><p>
+</p><p>
+
+
+</p><p>
+
+</p><pre class="programlisting">
+GET /topics/{topic-name}/durable/receivers/{receiver-id}/head?wait=[0-9+]
+</pre><p>
+</p><p>
+
+
+</p><p>
+
+</p><pre class="programlisting">
+DELETE /topics/{topic-name}/durable/receivers/{receiver-id}/head
+</pre><p>
+</p><p>
+
+FYI, this is idempotent still!
+</p><p>
+
+
+</p><pre class="programlisting">
+POST /topics/{topic-name}/durable/receivers/{receiver-id}/head
+</pre><p>
+</p><p>
+
+</p><p>
+
+
+You can register a URI to post to when a message is sent to this dedicated topic listener. This registers a MessageListener with the queue. When the message is received, on the server, it send the message to the registered URI.
+</p><p>
+
+
+</p><p>
+
+</p><pre class="programlisting">
+PUT /topics/{topic-name}/durable/listeners/{listener-id}
+</pre><p>
+You must send a string that is the URI you want to send the message to. The content-type can be anything, "text/plain" or whatever.
+</p><p>
+
+If you pass an ACCEPT header this will create a JMS selector that filters message for only a specific media type. So, if you pass an ACCEPT header of 'application/xml' this receiver will only get message of CONTENT-TYPE 'application/xml'
+</p><p>
+
+
+</p><pre class="programlisting">DELETE /topics/{topic-name}/durable/receivers/{receiver-id} </pre><p>
+
+
+</p></div></div></div></body></html>
View
20 examples/jms-facade/pom.xml
@@ -0,0 +1,20 @@
+<!-- test -->
+<project>
+ <name>Resteasy MOM Parent POM</name>
+ <url>http://www.attainware.com/</url>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.jboss.resteasy.mom</groupId>
+ <version>1.0</version>
+ <artifactId>resteasy-mom-all</artifactId>
+ <packaging>pom</packaging>
+ <properties>
+ <resteasy-mom-version>1.0</resteasy-mom-version>
+ <jbossHome>/Users/billburke/jboss/jboss-4.2.2.GA</jbossHome>
+ </properties>
+
+ <modules>
+ <module>resteasy-mom</module>
+ <module>resteasy-mom-war</module>
+ </modules>
+</project>
View
105 examples/jms-facade/resteasy-mom-war/pom.xml
@@ -0,0 +1,105 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.jboss.resteasy.mom</groupId>
+ <artifactId>resteasy-mom-all</artifactId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.jboss.resteasy.mom</groupId>
+ <artifactId>resteasy-mom-war</artifactId>
+ <packaging>war</packaging>
+ <version>${resteasy-mom-version}</version>
+ <name>Resteasy Mom Webapp</name>
+ <url>http://maven.apache.org</url>
+ <repositories>
+ <repository>
+ <id>jboss</id>
+ <url>http://repository.jboss.org/maven2</url>
+ </repository>
+ <repository>
+ <id>maven</id>
+ <url>http://repo1.maven.org/maven2</url>
+ </repository>
+ </repositories>
+ <dependencies>
+ <dependency>
+ <groupId>org.jboss.resteasy.mom</groupId>
+ <artifactId>resteasy-mom</artifactId>
+ <version>${resteasy-mom-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.5</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <finalName>resteasy-mom</finalName>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>jboss-maven-plugin</artifactId>
+ <configuration>
+ <jbossHome>${jbossHome}</jbossHome>
+ </configuration>
+ <executions>
+ <execution>
+ <id>jboss-deploy</id>
+ <phase>pre-integration-test</phase>
+ <goals>
+ <goal>deploy</goal>
+ </goals>
+ <configuration>
+ <fileName>${basedir}/target/resteasy-mom.war</fileName>
+ </configuration>
+ </execution>
+ <execution>
+ <id>jboss-undeploy</id>
+ <phase>post-integration-test</phase>
+ <goals>
+ <goal>undeploy</goal>
+ </goals>
+ <configuration>
+ <fileName>${basedir}/target/resteasy-mom.war</fileName>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ <executions>
+ <execution>
+ <id>surefire-it</id>
+ <phase>integration-test</phase>
+ <goals>
+ <goal>test</goal>
+ </goals>
+ <configuration>
+ <skip>false</skip>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
View
31 examples/jms-facade/resteasy-mom-war/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,31 @@
+<!DOCTYPE web-app PUBLIC
+ "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+ "http://java.sun.com/dtd/web-app_2_3.dtd" >
+
+<web-app>
+ <display-name>Archetype Created Web Application</display-name>
+ <context-param>
+ <param-name>resteasy.scan</param-name>
+ <param-value>false</param-value>
+ </context-param>
+
+ <listener>
+ <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
+ </listener>
+
+ <listener>
+ <listener-class>org.jboss.resteasy.mom.ResteasyMomBootstrap</listener-class>
+ </listener>
+
+ <servlet>
+ <servlet-name>Resteasy</servlet-name>
+ <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>Resteasy</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+
+
+</web-app>
View
68 examples/jms-facade/resteasy-mom/pom.xml
@@ -0,0 +1,68 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.jboss.resteasy.mom</groupId>
+ <artifactId>resteasy-mom-all</artifactId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.jboss.resteasy.mom</groupId>
+ <artifactId>resteasy-mom</artifactId>
+ <packaging>jar</packaging>
+ <version>${resteasy-mom-version}</version>
+ <name>Resteasy MOM</name>
+ <url>http://maven.apache.org</url>
+ <repositories>
+ <repository>
+ <id>jboss</id>
+ <url>http://repository.jboss.org/maven2</url>
+ </repository>
+ <repository>
+ <id>maven</id>
+ <url>http://repo1.maven.org/maven2</url>
+ </repository>
+ </repositories>
+ <dependencies>
+ <dependency>
+ <groupId>org.jboss.resteasy</groupId>
+ <artifactId>resteasy-jaxrs</artifactId>
+ <version>1.0-beta-6</version>
+ </dependency>
+ <dependency>
+ <groupId>tjws</groupId>
+ <artifactId>webserver</artifactId>
+ <version>1.3.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.jms</groupId>
+ <artifactId>jms</artifactId>
+ <version>1.1</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.5</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
View
104 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/ByteArrayMessageProcessor.java
@@ -0,0 +1,104 @@
+package org.jboss.resteasy.mom;
+
+import javax.jms.BytesMessage;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.Session;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class ByteArrayMessageProcessor extends MessageProcessor
+{
+ private int bufferSize = 1000;
+
+ public ByteArrayMessageProcessor() throws Exception
+ {
+ }
+
+ public Message createMessage(HttpHeaders headers, InputStream entityStream, Session session)
+ throws JMSException, IOException
+ {
+ BytesMessage message = session.createBytesMessage();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] buffer = new byte[bufferSize];
+ int wasRead = 0;
+ do
+ {
+ wasRead = entityStream.read(buffer);
+ if (wasRead > 0)
+ {
+ //System.out.println("SENT " + wasRead + " bytes!");
+ baos.write(buffer, 0, wasRead);
+ }
+ } while (wasRead > -1);
+
+ for (String key : headers.getRequestHeaders().keySet())
+ {
+ message.setStringProperty(toJavaIdentifier(key.toLowerCase()), headers.getRequestHeaders().getFirst(key));
+ }
+ message.setIntProperty("httpMessageSize", buffer.length);
+ buffer = baos.toByteArray();
+ message.writeBytes(buffer);
+
+ return message;
+ }
+
+
+ public Response extractResponse(Message message)
+ throws JMSException
+ {
+ if (message instanceof BytesMessage) return extractStreamResponse((BytesMessage) message);
+
+ throw new WebApplicationException(500);
+ }
+
+
+ protected Response extractStreamResponse(BytesMessage message)
+ throws JMSException
+ {
+ byte[] body = extractBody(message);
+
+
+ //System.out.println("RECEIVED body length: " + body.length);
+ Response.ResponseBuilder builder = Response.ok(body);
+
+ Enumeration en = message.getPropertyNames();
+ while (en.hasMoreElements())
+ {
+ String key = (String) en.nextElement();
+ if (!key.startsWith("JMS"))
+ {
+ String value = message.getStringProperty(key);
+ //System.out.println("header: " + toHeaderName(key) + " value: " + value);
+ builder.header(toHeaderName(key), value);
+ }
+ }
+ return builder.build();
+ }
+
+ public byte[] extractBody(Message message)
+ throws JMSException
+ {
+ // todo need to use OutputStream when available
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ //System.out.println("Extracting body");
+
+ BytesMessage stream = (BytesMessage) message;
+ int size = message.getIntProperty("httpMessageSize");
+ byte[] buffer = new byte[size];
+ stream.readBytes(buffer);
+ stream.reset();
+ return buffer;
+ }
+
+
+}
View
79 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/DestinationResource.java
@@ -0,0 +1,79 @@
+package org.jboss.resteasy.mom;
+
+import javax.jms.Connection;
+import javax.jms.DeliveryMode;
+import javax.jms.Destination;
+import javax.jms.Message;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import java.io.InputStream;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class DestinationResource
+{
+ protected Connection connection;
+ protected Destination destination;
+ protected String name;
+ protected MessageProcessor processor;
+
+ public DestinationResource(MessageProcessor processor, String name, Connection connection, Destination destination)
+ {
+ this.processor = processor;
+ this.name = name;
+ this.connection = connection;
+ this.destination = destination;
+ }
+
+ @GET
+ @Produces("text/html")
+ public String details()
+ {
+ return "<html><body><h1>Destination: " + name + "</h1></body></html>";
+ }
+
+ @POST
+ public void send(@Context HttpHeaders headers,
+ @QueryParam("persistent") @DefaultValue("true")boolean persistent,
+ @QueryParam("priority") @DefaultValue("4")int priority,
+ @QueryParam("timeToLive") @DefaultValue("0")long timeToLive,
+ InputStream entityStream) throws Exception
+ {
+ //System.out.println("SENDING MESSAGE!");
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ try
+ {
+ MessageProducer producer = session.createProducer(destination);
+ try
+ {
+ Message message = processor.createMessage(headers, entityStream, session);
+ int deliveryMode = persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT;
+ producer.send(message, deliveryMode, priority, timeToLive);
+ }
+ finally
+ {
+ producer.close();
+ }
+ }
+ finally
+ {
+ session.close();
+ }
+ }
+
+ public void close() throws Exception
+ {
+ connection.close();
+ }
+
+}
View
170 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/Destinations.java
@@ -0,0 +1,170 @@
+package org.jboss.resteasy.mom;
+
+import org.jboss.resteasy.util.HttpResponseCodes;
+
+import javax.jms.ConnectionFactory;
+import javax.jms.Destination;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.WebApplicationException;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+@Path("/")
+public class Destinations
+{
+ private ConcurrentHashMap<String, QueueResource> queues = new ConcurrentHashMap<String, QueueResource>();
+ private ConcurrentHashMap<String, TopicResource> topics = new ConcurrentHashMap<String, TopicResource>();
+
+ private ConnectionFactory factory;
+ private MessageProcessor processor;
+ private DlqProcessor dlq;
+ private String queueJndiPrefix = "queue/";
+ private String topicJndiPrefix = "topic/";
+
+
+ public void addQueue(String name, Destination queue) throws Exception
+ {
+ QueueResource res = new QueueResource(name, factory.createConnection(), queue, processor, dlq);
+ queues.put(name, res);
+ }
+
+ public void addTopic(String name, Destination topic) throws Exception
+ {
+ TopicResource res = new TopicResource(name, factory, factory.createConnection(), topic, processor, dlq);
+ topics.put(name, res);
+ }
+
+ public void setQueueJndiPrefix(String queueJndiPrefix)
+ {
+ this.queueJndiPrefix = queueJndiPrefix;
+ }
+
+ public void setTopicJndiPrefix(String topicJndiPrefix)
+ {
+ this.topicJndiPrefix = topicJndiPrefix;
+ }
+
+ public void setFactory(ConnectionFactory factory)
+ {
+ this.factory = factory;
+ }
+
+ public void setProcessor(MessageProcessor processor)
+ {
+ this.processor = processor;
+ }
+
+ public void setDlq(DlqProcessor dlq)
+ {
+ this.dlq = dlq;
+ }
+
+ public void stop()
+ {
+ for (QueueResource queue : queues.values())
+ {
+ try
+ {
+ queue.close();
+ }
+ catch (Exception ignored)
+ {
+ ignored.printStackTrace();
+ }
+ }
+ for (TopicResource topic : topics.values())
+ {
+ try
+ {
+ topic.close();
+ }
+ catch (Exception ignored)
+ {
+ ignored.printStackTrace();
+ }
+ }
+ dlq.close();
+ }
+
+ @Path("/queues/{destination}")
+ public QueueResource getQueue(@PathParam("destination")String name) throws Exception
+ {
+ return getQueueResource(name);
+ }
+
+ @Path("/topics/{destination}")
+ public TopicResource getTopic(@PathParam("destination")String name) throws Exception
+ {
+ return getTopicResource(name);
+ }
+
+ public QueueResource getQueueResource(String name) throws Exception
+ {
+ QueueResource queue = queues.get(name);
+ if (queue != null)
+ {
+ return queue;
+ }
+
+ InitialContext ctx = new InitialContext();
+ Destination destination = null;
+ try
+ {
+ destination = (Destination) ctx.lookup(queueJndiPrefix + name);
+ }
+ catch (NamingException e)
+ {
+ throw new WebApplicationException(e, HttpResponseCodes.SC_NOT_FOUND);
+ }
+ queue = new QueueResource(name, factory.createConnection(), destination, processor, dlq);
+ QueueResource tmp = queues.putIfAbsent(name, queue);
+ if (tmp == null)
+ {
+ //System.out.println("created Queue Resource:" + name);
+ return queue;
+ }
+ else
+ {
+ queue.close();
+ return tmp;
+ }
+ }
+
+ public TopicResource getTopicResource(String name) throws Exception
+ {
+ TopicResource topic = topics.get(name);
+ if (topic != null)
+ {
+ return topic;
+ }
+
+ InitialContext ctx = new InitialContext();
+ Destination destination = null;
+ try
+ {
+ destination = (Destination) ctx.lookup(topicJndiPrefix + name);
+ }
+ catch (NamingException e)
+ {
+ throw new WebApplicationException(e, HttpResponseCodes.SC_NOT_FOUND);
+ }
+ topic = new TopicResource(name, factory, factory.createConnection(), destination, processor, dlq);
+ TopicResource tmp = topics.putIfAbsent(name, topic);
+ if (tmp == null)
+ {
+ //System.out.println("created Topic Resource:" + name);
+ return topic;
+ }
+ else
+ {
+ topic.close();
+ return tmp;
+ }
+ }
+}
View
65 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/DlqProcessor.java
@@ -0,0 +1,65 @@
+package org.jboss.resteasy.mom;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class DlqProcessor
+{
+ private Connection deadletterConnection;
+ private Destination dlq;
+
+ public DlqProcessor(Connection deadletterConnection, Destination dlq) throws Exception
+ {
+ this.deadletterConnection = deadletterConnection;
+ this.dlq = dlq;
+ }
+
+ public void close()
+ {
+ try
+ {
+ deadletterConnection.close();
+ }
+ catch (JMSException ignored)
+ {
+ ignored.printStackTrace();
+ }
+ }
+
+ public void deadletter(Message message)
+ {
+ try
+ {
+ if (deadletterConnection == null || dlq == null) return;
+ //System.out.println("DEAD LETTER!!!!");
+ Session session = deadletterConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ try
+ {
+ MessageProducer producer = session.createProducer(dlq);
+ producer.send(message);
+ //System.out.println("SENT DEAD LETTER");
+ }
+ catch (JMSException e)
+ {
+ }
+ finally
+ {
+ session.close();
+ }
+ }
+ catch (JMSException ignored)
+ {
+
+ }
+ }
+
+
+}
View
70 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/DurableTopicListener.java
@@ -0,0 +1,70 @@
+package org.jboss.resteasy.mom;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Topic;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class DurableTopicListener extends Listener
+{
+ private String name;
+
+ public DurableTopicListener(String name, Destination destination, Connection connection, String callback, MessageProcessor processor, DlqProcessor dlq, String selector)
+ throws Exception
+ {
+ super(destination, connection, callback, processor, dlq);
+ this.name = name;
+ consumer = session.createDurableSubscriber((Topic) destination, name, selector, false);
+ consumer.setMessageListener(this);
+ connection.start();
+ }
+
+ @Override
+ public void close()
+ {
+ throw new RuntimeException("Illegal to call this method, call close(boolean unsubscribe)");
+ }
+
+ public synchronized void close(boolean unsubscribe)
+ {
+ try
+ {
+ connection.stop();
+ }
+ catch (JMSException e)
+ {
+ throw new RuntimeException(e);
+ }
+ try
+ {
+ if (consumer != null) consumer.close();
+ }
+ catch (JMSException ignored) {}
+ consumer = null;
+
+ try
+ {
+ if (unsubscribe)
+ {
+ session.unsubscribe(name);
+ }
+
+ if (session != null) session.close();
+ }
+ catch (JMSException ignore) {}
+ session = null;
+ try
+ {
+ if (connection != null) connection.close();
+ connection = null;
+ }
+ catch (JMSException ignored)
+ {
+ }
+ }
+
+}
View
73 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/DurableTopicReceiver.java
@@ -0,0 +1,73 @@
+package org.jboss.resteasy.mom;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Topic;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class DurableTopicReceiver extends Receiver
+{
+ private String name;
+
+ public DurableTopicReceiver(String name, Connection connection, Destination destination, MessageProcessor processor, String selector) throws Exception
+ {
+ super(connection, selector, destination, processor);
+ this.name = name;
+ getConsumer();
+ }
+
+ protected void createConsumer()
+ throws JMSException
+ {
+ consumer = session.createDurableSubscriber((Topic) destination, name, selector, false);
+ }
+
+ @Override
+ public void close()
+ {
+ throw new RuntimeException("Illegal to call this method, call close(boolean unsubscribe)");
+ }
+
+ public synchronized void close(boolean unsubscribe)
+ {
+ try
+ {
+ connection.stop();
+ }
+ catch (JMSException e)
+ {
+ throw new RuntimeException(e);
+ }
+ try
+ {
+ if (consumer != null) consumer.close();
+ }
+ catch (JMSException ignored) {}
+ consumer = null;
+
+ try
+ {
+ if (unsubscribe)
+ {
+ session.unsubscribe(name);
+ }
+
+ if (session != null) session.close();
+ }
+ catch (JMSException ignore) {}
+ session = null;
+ try
+ {
+ if (connection != null) connection.close();
+ connection = null;
+ }
+ catch (JMSException ignored)
+ {
+ }
+ }
+
+}
View
130 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/Listener.java
@@ -0,0 +1,130 @@
+package org.jboss.resteasy.mom;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.params.HttpMethodParams;
+import org.jboss.resteasy.util.HttpResponseCodes;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageListener;
+import javax.jms.Session;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class Listener implements MessageListener
+{
+ protected Destination destination;
+ protected Connection connection;
+ protected MessageConsumer consumer;
+ protected Session session;
+ protected HttpClient httpClient = new HttpClient();
+ protected String callback;
+ protected MessageProcessor processor;
+ protected DlqProcessor dlq;
+
+ public Listener(Destination destination, Connection connection, String callback, MessageProcessor processor, DlqProcessor dlq) throws Exception
+ {
+ this.destination = destination;
+ this.connection = connection;
+ this.callback = callback;
+ this.session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+ this.processor = processor;
+ this.dlq = dlq;
+ }
+
+ protected boolean isDead(int status)
+ {
+ switch (status)
+ {
+ case HttpResponseCodes.SC_REQUEST_TIMEOUT:
+ case HttpResponseCodes.SC_CONFLICT:
+ case HttpResponseCodes.SC_REQUEST_ENTITY_TOO_LARGE:
+ case HttpResponseCodes.SC_SERVICE_UNAVAILABLE:
+ case HttpResponseCodes.SC_GATEWAY_TIMEOUT:
+ return false;
+
+ }
+ return true;
+ }
+
+ public void onMessage(Message message)
+ {
+ try
+ {
+ //System.out.println("****** ON MESSAGE");
+ byte[] body = processor.extractBody(message);
+ System.out.println("LISTENER RECEIVED body length: " + body.length);
+ Map<String, String> headers = processor.extractHeaders(message);
+
+ //System.out.println("setting up PostMethod to: " + callback);
+ PostMethod method = new PostMethod(callback);
+ for (String key : headers.keySet())
+ {
+ method.setRequestHeader(key, headers.get(key));
+ }
+ method.setRequestEntity(new ByteArrayRequestEntity(body));
+ HttpMethodParams params = new HttpMethodParams();
+ params.setSoTimeout(1000);
+ method.setParams(params);
+ try
+ {
+ int status = httpClient.executeMethod(method);
+ if (status == HttpResponseCodes.SC_OK)
+ {
+ //System.out.println("message sent to listener: " + callback);
+ return;
+ }
+ else
+ {
+ //System.out.println("failed to send message to listener: " + callback + " error code: " + status);
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ //System.out.println("Failed sending to listener: " + callback + ", deadlettering");
+ dlq.deadletter(message);
+ }
+ catch (Throwable throwable)
+ {
+ throwable.printStackTrace();
+ }
+ finally
+ {
+ try
+ {
+ //System.out.println("ACKNOWLEDGING!!!!!");
+ message.acknowledge();
+ }
+ catch (JMSException ignored)
+ {
+ }
+ }
+ }
+
+ public synchronized void close()
+ {
+ try
+ {
+ if (consumer != null) consumer.close();
+ }
+ catch (JMSException ignored) {}
+ consumer = null;
+
+ try
+ {
+ if (session != null) session.close();
+ }
+ catch (JMSException ignore) {}
+ session = null;
+ }
+}
View
100 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/MessageProcessor.java
@@ -0,0 +1,100 @@
+package org.jboss.resteasy.mom;
+
+import org.jboss.resteasy.util.HttpHeaderNames;
+
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.Session;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public abstract class MessageProcessor
+{
+ /**
+ * Replaces '-' with '$'
+ *
+ * @param str
+ * @return
+ */
+ protected String toJavaIdentifier(String str)
+ {
+ return str.replace('-', '$').toLowerCase();
+ }
+
+ protected String toHeaderName(String str)
+ {
+ return str.replace('$', '-').toLowerCase();
+ }
+
+ public String createSelector(HttpHeaders headers)
+ {
+ StringBuffer selector = new StringBuffer();
+
+ boolean first = true;
+
+ for (MediaType type : headers.getAcceptableMediaTypes())
+ {
+ if (type.isWildcardType()) return "";
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ selector.append(" OR ");
+ }
+ selector.append(toJavaIdentifier(HttpHeaderNames.CONTENT_TYPE));
+ if (type.isWildcardSubtype())
+ {
+ selector.append(" LIKE '")
+ .append(type.getType())
+ .append("/%'");
+ }
+ else
+ {
+ selector.append(" = '")
+ .append(type.toString())
+ .append("'");
+ }
+ }
+ return selector.toString();
+ }
+
+ public abstract Message createMessage(HttpHeaders headers, InputStream entityStream, Session session)
+ throws JMSException, IOException;
+
+ public abstract Response extractResponse(Message message)
+ throws JMSException;
+
+ public abstract byte[] extractBody(Message message)
+ throws JMSException;
+
+ public Map<String, String> extractHeaders(Message message) throws JMSException
+ {
+ Map<String, String> rtn = new HashMap<String, String>();
+
+ Enumeration en = message.getPropertyNames();
+ while (en.hasMoreElements())
+ {
+ String key = (String) en.nextElement();
+ if (!key.startsWith("JMS"))
+ {
+ String value = message.getStringProperty(key);
+ //System.out.println("header: " + toHeaderName(key) + " value: " + value);
+ rtn.put(toHeaderName(key), value);
+ }
+ }
+ return rtn;
+ }
+
+}
View
112 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/QueueBrowserResource.java
@@ -0,0 +1,112 @@
+package org.jboss.resteasy.mom;
+
+import org.jboss.resteasy.util.HttpResponseCodes;
+
+import javax.jms.Connection;
+import javax.jms.Message;
+import javax.jms.Queue;
+import javax.jms.QueueBrowser;
+import javax.jms.Session;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import java.net.URI;
+import java.util.Enumeration;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class QueueBrowserResource
+{
+ private Connection connection;
+ private Queue queue;
+ private MessageProcessor processor;
+
+ public QueueBrowserResource(Connection connection, Queue queue, MessageProcessor processor)
+ {
+ this.connection = connection;
+ this.queue = queue;
+ this.processor = processor;
+ }
+
+ @GET
+ @Produces("text/html")
+ public String getBrowser(@QueryParam("index") @DefaultValue("0")int index, @Context UriInfo info) throws Exception
+ {
+ StringBuffer buffer = new StringBuffer("<html><body>");
+ buffer.append("<h1>Queue Message Browser: ");
+ buffer.append(queue.getQueueName()).append("</h1>");
+ buffer.append("<ul>");
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ try
+ {
+ QueueBrowser browser = session.createBrowser(queue);
+ Enumeration en = browser.getEnumeration();
+ int count = 0;
+ int i = 0;
+ for (; en.hasMoreElements() && count < 10; i++)
+ {
+ Message message = (Message) en.nextElement();
+ if (i >= index)
+ {
+ buffer.append("<li><a href=\"");
+ URI uri = info.getAbsolutePathBuilder().path("messages").path(message.getJMSMessageID()).build();
+ buffer.append(uri.toString()).append("\">").append(message.getJMSMessageID()).append("</a></li>");
+ count++;
+ }
+ }
+
+
+ buffer.append("</ul>");
+ if (en.hasMoreElements())
+ {
+ buffer.append("<a href=\"").append(info.getAbsolutePath().toString());
+ buffer.append("?index=").append(Integer.toString(i)).append("\">More...</a>");
+ }
+ buffer.append("</body></html>");
+ return buffer.toString();
+ }
+ finally
+ {
+ session.close();
+ }
+ }
+
+ @GET
+ @Path("/messages/{id}")
+ public Response get(@PathParam("id")String id) throws Exception
+ {
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ try
+ {
+ QueueBrowser browser = session.createBrowser(queue);
+ Enumeration en = browser.getEnumeration();
+ Message target = null;
+ while (en.hasMoreElements())
+ {
+ Message message = (Message) en.nextElement();
+ if (message.getJMSMessageID().equals(id))
+ {
+ target = message;
+ break;
+ }
+ }
+ if (target == null)
+ {
+ return Response.status(HttpResponseCodes.SC_NOT_FOUND).build();
+ }
+ return processor.extractResponse(target);
+ }
+ finally
+ {
+ session.close();
+ }
+ }
+}
View
23 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/QueueListener.java
@@ -0,0 +1,23 @@
+package org.jboss.resteasy.mom;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class QueueListener extends Listener
+{
+ public QueueListener(Destination destination, Connection connection, String callback, MessageProcessor processor, DlqProcessor dlq, String selector)
+ throws Exception
+ {
+ super(destination, connection, callback, processor, dlq);
+
+ //System.out.println("Callback URI: " + callback);
+ //System.out.println("SELECTOR : " + selector);
+ consumer = session.createConsumer(destination, selector);
+ consumer.setMessageListener(this);
+ connection.start();
+ }
+}
View
18 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/QueueReceiver.java
@@ -0,0 +1,18 @@
+package org.jboss.resteasy.mom;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class QueueReceiver extends Receiver
+{
+
+ public QueueReceiver(Destination destination, Connection connection, MessageProcessor processor, String selector) throws Exception
+ {
+ super(connection, selector, destination, processor);
+ }
+
+}
View
117 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/QueueResource.java
@@ -0,0 +1,117 @@
+package org.jboss.resteasy.mom;
+
+import org.jboss.resteasy.util.HttpResponseCodes;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+import javax.jms.Queue;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class QueueResource extends DestinationResource
+{
+ protected QueueReceiver autoReceiver;
+ protected Map<String, Receiver> receivers = new ConcurrentHashMap<String, Receiver>();
+ protected Map<String, Listener> listeners = new ConcurrentHashMap<String, Listener>();
+ protected DlqProcessor dlq;
+
+ public QueueResource(String name, Connection connection, Destination destination, MessageProcessor processor, DlqProcessor dlq) throws Exception
+ {
+ super(processor, name, connection, destination);
+ this.dlq = dlq;
+ }
+
+ @Path("/browser")
+ public QueueBrowserResource getBrowser() throws Exception
+ {
+ return new QueueBrowserResource(connection, (Queue) destination, processor);
+ }
+
+
+ @POST
+ @Path("/head")
+ public synchronized Response getAndAcknowledge(@QueryParam("wait") @DefaultValue("-1")long wait) throws Exception
+ {
+ if (receivers.size() > 0) return Response.status(HttpResponseCodes.SC_CONFLICT).build();
+ if (autoReceiver == null) autoReceiver = new QueueReceiver(destination, connection, processor, "");
+ return autoReceiver.getAndAcknowledge(wait);
+ }
+
+
+ @PUT
+ @Path("/receivers/{id}")
+ public Response createReceiver(@PathParam("id")String id, @Context HttpHeaders headers) throws Exception
+ {
+ if (receivers.containsKey(id))
+ {
+ return Response.ok().build();
+ }
+ else
+ {
+ QueueReceiver receiver = new QueueReceiver(destination, connection, processor, processor.createSelector(headers));
+ receivers.put(id, receiver);
+ return Response.status(HttpResponseCodes.SC_CREATED).build();
+ }
+ }
+
+ @Path("/receivers/{id}")
+ public QueueReceiver getReceiver(@PathParam("id")String id)
+ {
+ //System.out.println("getReceiver: " + id);
+ QueueReceiver receiver = (QueueReceiver) receivers.get(id);
+ if (receiver == null) throw new WebApplicationException(HttpResponseCodes.SC_NOT_FOUND);
+ return receiver;
+ }
+
+ @PUT
+ @Path("/listeners/{id}")
+ public Response createListener(@PathParam("id")String id, String uri, @Context HttpHeaders headers) throws Exception
+ {
+ if (listeners.containsKey(id))
+ {
+ return Response.ok().build();
+ }
+ else
+ {
+ Listener listener = new QueueListener(destination, connection, uri, processor, dlq, processor.createSelector(headers));
+ listeners.put(id, listener);
+ return Response.status(HttpResponseCodes.SC_CREATED).build();
+ }
+ }
+
+ @DELETE
+ @Path("/receivers/{id}")
+ public Response closeReceiver(@PathParam("id")String id) throws Exception
+ {
+ Receiver receiver = receivers.remove(id);
+ if (receiver == null) throw new WebApplicationException(HttpResponseCodes.SC_NOT_FOUND);
+ receiver.close();
+ return Response.status(HttpResponseCodes.SC_NO_CONTENT).build();
+ }
+
+ @DELETE
+ @Path("/listeners/{id}")
+ public Response closeListener(@PathParam("id")String id) throws Exception
+ {
+ Listener listener = listeners.remove(id);
+ if (listener == null) throw new WebApplicationException(HttpResponseCodes.SC_NOT_FOUND);
+ listener.close();
+ return Response.status(HttpResponseCodes.SC_NO_CONTENT).build();
+ }
+
+}
View
147 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/Receiver.java
@@ -0,0 +1,147 @@
+package org.jboss.resteasy.mom;
+
+import org.jboss.resteasy.util.HttpResponseCodes;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.Session;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public abstract class Receiver
+{
+ protected Destination destination;
+ protected Connection connection;
+ protected MessageConsumer consumer;
+ protected Session session;
+ protected Message currentMessage;
+ protected MessageProcessor processor;
+ protected String selector;
+
+ public Receiver(Connection connection, String selector, Destination destination, MessageProcessor processor)
+ {
+ this.connection = connection;
+ this.selector = selector;
+ this.destination = destination;
+ this.processor = processor;
+ }
+
+ protected Receiver(String selector, Destination destination, MessageProcessor processor)
+ {
+ this.selector = selector;
+ this.destination = destination;
+ this.processor = processor;
+ }
+
+ public MessageConsumer getConsumer() throws Exception
+ {
+ if (consumer == null)
+ {
+ this.session = getConnection().createSession(false, Session.CLIENT_ACKNOWLEDGE);
+
+ try
+ {
+ createConsumer();
+ //System.out.println("COnnection started");
+ getConnection().start();
+ }
+ catch (Exception ex)
+ {
+ session.close();
+ throw ex;
+ }
+ }
+ return consumer;
+ }
+
+ protected void createConsumer()
+ throws JMSException
+ {
+ consumer = session.createConsumer(destination, selector);
+ }
+
+
+ public synchronized void close()
+ {
+ currentMessage = null;
+ try
+ {
+ if (consumer != null) consumer.close();
+ }
+ catch (JMSException ignored) {}
+ consumer = null;
+
+ try
+ {
+ if (session != null) session.close();
+ }
+ catch (JMSException ignore) {}
+ session = null;
+ }
+
+ protected Message getMessage(long wait) throws Exception
+ {
+ //System.out.println("wait time: " + wait);
+ Message message = null;
+ if (wait < 0) message = getConsumer().receiveNoWait();
+ else message = getConsumer().receive(wait);
+
+ if (message == null) throw new WebApplicationException(HttpResponseCodes.SC_REQUEST_TIMEOUT);
+ return message;
+ }
+
+ @GET
+ @Path("/head")
+ public synchronized Response get(@QueryParam("wait") @DefaultValue("-1")long wait) throws Exception
+ {
+ //System.out.println("getHead");
+ if (currentMessage == null)
+ {
+ currentMessage = getMessage(wait);
+ }
+
+ return processor.extractResponse(currentMessage);
+
+ }
+
+ @DELETE
+ @Path("/head")
+ public synchronized void acknowledge() throws Exception
+ {
+ if (currentMessage == null) return;
+ currentMessage.acknowledge();
+ currentMessage = null;
+ }
+
+ @POST
+ @Path("/head")
+ public synchronized Response getAndAcknowledge(@QueryParam("wait") @DefaultValue("-1")long wait) throws Exception
+ {
+ if (currentMessage != null)
+ {
+ return Response.status(HttpResponseCodes.SC_CONFLICT).build();
+ }
+ Message message = getMessage(wait);
+ Response response = processor.extractResponse(message);
+ message.acknowledge();
+ return response;
+ }
+
+ protected Connection getConnection()
+ {
+ return connection;
+ }
+}
View
141 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/ResteasyMomBootstrap.java
@@ -0,0 +1,141 @@
+package org.jboss.resteasy.mom;
+
+import org.jboss.resteasy.plugins.server.resourcefactory.SingletonResource;
+import org.jboss.resteasy.spi.Registry;
+
+import javax.jms.ConnectionFactory;
+import javax.jms.Destination;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class ResteasyMomBootstrap implements ServletContextListener
+{
+ private Destinations destinations;
+ private Registry registry;
+
+ public void contextInitialized(ServletContextEvent event)
+ {
+ registry = (Registry) event.getServletContext().getAttribute(Registry.class.getName());
+ destinations = new Destinations();
+ event.getServletContext().setAttribute(Destinations.class.getName(), destinations);
+ String queueJndiPrefix = event.getServletContext().getInitParameter("resteasy.mom.queue.jndi.prefix");
+ if (queueJndiPrefix != null && !queueJndiPrefix.trim().equals(""))
+ destinations.setQueueJndiPrefix(queueJndiPrefix.trim());
+ String topicJndiPrefix = event.getServletContext().getInitParameter("resteasy.mom.topic.jndi.prefix");
+ if (topicJndiPrefix != null && !topicJndiPrefix.trim().equals(""))
+ destinations.setTopicJndiPrefix(topicJndiPrefix.trim());
+
+ String factoryLocation = event.getServletContext().getInitParameter("resteasy.mom.connection.factory");
+ if (factoryLocation == null || factoryLocation.trim().equals("")) factoryLocation = "java:/ConnectionFactory";
+
+ try
+ {
+ InitialContext ctx = new InitialContext();
+ ConnectionFactory factory = (ConnectionFactory) ctx.lookup(factoryLocation);
+
+ String dlqLocation = event.getServletContext().getInitParameter("resteasy.mom.dlq.jndi");
+ if (dlqLocation == null || dlqLocation.trim().equals("")) dlqLocation = "queue/DLQ";
+ Destination dlq = (Destination) ctx.lookup(dlqLocation);
+
+ int bufferSize = 1024;
+ String buffer = event.getServletContext().getInitParameter("resteasy.mom.message.buffer.size");
+ if (buffer != null && !buffer.trim().equals("")) bufferSize = Integer.parseInt(buffer.trim());
+
+ StreamMessageProcessor processor = new StreamMessageProcessor(bufferSize);
+ //ByteArrayMessageProcessor processor = new ByteArrayMessageProcessor();
+ DlqProcessor dlqProcessor = new DlqProcessor(factory.createConnection(), dlq);
+
+ destinations.setFactory(factory);
+ destinations.setProcessor(processor);
+ destinations.setDlq(dlqProcessor);
+
+ String queues = event.getServletContext().getInitParameter("resteasy.mom.queues.jndi");
+ if (queues != null)
+ {
+ Map<String, String> queueMap = parseMap(queues.trim());
+ for (String name : queueMap.keySet())
+ {
+ String jndiName = queueMap.get(name).trim();
+ Destination queue = null;
+ try
+ {
+ queue = (Destination) ctx.lookup(jndiName);
+ }
+ catch (NamingException e)
+ {
+ throw new RuntimeException("Unable to find preconfigured jndi queue" + jndiName, e);
+ }
+ destinations.addQueue(name, queue);
+ }
+ }
+
+ String topics = event.getServletContext().getInitParameter("resteasy.mom.topics.jndi");
+ if (topics != null)
+ {
+ Map<String, String> topicMap = parseMap(topics.trim());
+ for (String name : topicMap.keySet())
+ {
+ String jndiName = topicMap.get(name).trim();
+ Destination topic = null;
+ try
+ {
+ topic = (Destination) ctx.lookup(jndiName);
+ }
+ catch (NamingException e)
+ {
+ throw new RuntimeException("Unable to find preconfigured jndi topic" + jndiName, e);
+ }
+ destinations.addTopic(name, topic);
+ }
+ }
+ registry.addResourceFactory(new SingletonResource(destinations));
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+
+
+ }
+
+ protected static Map<String, String> parseMap(String map)
+ {
+ Map<String, String> parsed = new HashMap<String, String>();
+ String[] entries = map.trim().split(",");
+ for (String entry : entries)
+ {
+ entry = entry.trim();
+ int firstColon = entry.indexOf(':');
+ String name = entry.substring(0, firstColon).trim();
+ String val = entry.substring(firstColon + 1).trim();
+ parsed.put(name, val);
+
+ }
+ return parsed;
+ }
+
+
+ public void contextDestroyed(ServletContextEvent event)
+ {
+ registry.removeRegistrations(destinations.getClass());
+ destinations.stop();
+ }
+
+ public static void main(String[] args)
+ {
+ String config = "stuff : java:comp/env/jms/Blah, another : java:comp/env/jms/foo";
+ Map<String, String> map = parseMap(config);
+ for (String key : map.keySet())
+ {
+ System.out.println(key + " : \"" + map.get(key));
+ }
+ }
+}
View
121 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/StreamMessageProcessor.java
@@ -0,0 +1,121 @@
+package org.jboss.resteasy.mom;
+
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.Session;
+import javax.jms.StreamMessage;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class StreamMessageProcessor extends MessageProcessor
+{
+ private int bufferSize = 100;
+
+ public StreamMessageProcessor(int bufferSize) throws Exception
+ {
+ this.bufferSize = bufferSize;
+ }
+
+ public Message createMessage(HttpHeaders headers, InputStream entityStream, Session session)
+ throws JMSException, IOException
+ {
+ StreamMessage message = session.createStreamMessage();
+ byte[] buffer = new byte[bufferSize];
+ int wasRead = 0;
+ do
+ {
+ wasRead = entityStream.read(buffer);
+ if (wasRead > 0)
+ {
+ //System.out.println("SENT " + wasRead + " bytes!");
+ message.writeBytes(buffer, 0, wasRead);
+ }
+ } while (wasRead > -1);
+
+ for (String key : headers.getRequestHeaders().keySet())
+ {
+ message.setStringProperty(toJavaIdentifier(key.toLowerCase()), headers.getRequestHeaders().getFirst(key));
+ }
+ return message;
+ }
+
+
+ public Response extractResponse(Message message)
+ throws JMSException
+ {
+ if (message instanceof StreamMessage) return extractStreamResponse((StreamMessage) message);
+
+ throw new WebApplicationException(500);
+ }
+
+
+ protected Response extractStreamResponse(StreamMessage message)
+ throws JMSException
+ {
+ byte[] body = extractBody(message);
+
+
+ //System.out.println("RECEIVED body length: " + body.length);
+ Response.ResponseBuilder builder = Response.ok(body);
+
+ Enumeration en = message.getPropertyNames();
+ while (en.hasMoreElements())
+ {
+ String key = (String) en.nextElement();
+ if (!key.startsWith("JMS"))
+ {
+ String value = message.getStringProperty(key);
+ //System.out.println("header: " + toHeaderName(key) + " value: " + value);
+ builder.header(toHeaderName(key), value);
+ }
+ }
+ return builder.build();
+ }
+
+ public byte[] extractBody(Message message)
+ throws JMSException
+ {
+ // todo need to use OutputStream when available
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ //System.out.println("Extracting body");
+
+ StreamMessage stream = (StreamMessage) message;
+ byte[] buffer = new byte[bufferSize];
+
+ try
+ {
+ int wasRead = 0;
+ do
+ {
+ //System.out.println("LOOP!");
+ wasRead = stream.readBytes(buffer);
+ if (wasRead > 0)
+ {
+ //System.out.println("EXTRACTED: " + wasRead);
+ baos.write(buffer, 0, wasRead);
+ }
+ else
+ {
+ //System.out.println("Nothing extracted, wasRead: " + wasRead);
+ }
+ } while (wasRead == bufferSize || wasRead == -1);
+ byte[] body = baos.toByteArray();
+ return body;
+ }
+ finally
+ {
+ stream.reset();
+ }
+ }
+
+
+}
View
23 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/TopicListener.java
@@ -0,0 +1,23 @@
+package org.jboss.resteasy.mom;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class TopicListener extends Listener
+{
+ public TopicListener(Destination destination, Connection connection, String callback, MessageProcessor processor, DlqProcessor dlq, String selector)
+ throws Exception
+ {
+ super(destination, connection, callback, processor, dlq);
+
+ //System.out.println("Callback URI: " + callback);
+ //System.out.println("SELECTOR : " + selector);
+ consumer = session.createConsumer(destination, selector);
+ consumer.setMessageListener(this);
+ connection.start();
+ }
+}
View
17 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/TopicReceiver.java
@@ -0,0 +1,17 @@
+package org.jboss.resteasy.mom;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class TopicReceiver extends Receiver
+{
+ public TopicReceiver(Connection connection, Destination destination, MessageProcessor processor, String selector) throws Exception
+ {
+ super(connection, selector, destination, processor);
+ getConsumer();
+ }
+}
View
230 examples/jms-facade/resteasy-mom/src/main/java/org/jboss/resteasy/mom/TopicResource.java
@@ -0,0 +1,230 @@
+package org.jboss.resteasy.mom;
+
+import org.jboss.resteasy.util.HttpResponseCodes;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.Destination;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class TopicResource extends DestinationResource
+{
+ protected ConnectionFactory factory;
+
+ protected Map<String, DurableTopicReceiver> durableReceivers = new ConcurrentHashMap<String, DurableTopicReceiver>();
+ protected Map<String, TopicReceiver> nondurableReceivers = new ConcurrentHashMap<String, TopicReceiver>();
+ protected Map<String, DurableTopicListener> durableListeners = new ConcurrentHashMap<String, DurableTopicListener>();
+ protected Map<String, TopicListener> nondurableListeners = new ConcurrentHashMap<String, TopicListener>();
+ protected DlqProcessor dlq;
+
+ public TopicResource(String name, ConnectionFactory factory, Connection connection, Destination destination, MessageProcessor processor, DlqProcessor dlq) throws Exception
+ {
+ super(processor, name, connection, destination);
+ this.factory = factory;
+ this.dlq = dlq;
+ }
+
+ public void close() throws Exception
+ {
+ for (DurableTopicReceiver receiver : durableReceivers.values())
+ {
+ try
+ {
+ receiver.close(false);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+ for (DurableTopicListener receiver : durableListeners.values())
+ {
+ try
+ {
+ receiver.close(false);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+ super.close();
+ }
+
+
+ @Path("/durable/receivers/{id}")
+ public DurableTopicReceiver getDurableReceiver(@PathParam("id")String id)
+ {
+ id = "durable/receivers/" + id;
+ //System.out.println("getDurableReceiver: " + id);
+ DurableTopicReceiver receiver = durableReceivers.get(id);
+ if (receiver == null) throw new WebApplicationException(HttpResponseCodes.SC_NOT_FOUND);
+ return receiver;
+ }
+
+ @PUT
+ @Path("/durable/receivers/{id}")
+ public Response createDurableReceiver(@PathParam("id")String id,
+ @Context HttpHeaders headers) throws Exception
+ {
+ id = "durable/receivers/" + id;
+ if (durableReceivers.containsKey(id))
+ {
+ return Response.ok().build();
+ }
+ else
+ {
+ //System.out.println("Creating durable receiver: " + id);
+ Connection connection = factory.createConnection();
+ connection.setClientID(id);
+ DurableTopicReceiver receiver = null;
+ try
+ {
+ receiver = new DurableTopicReceiver(id, connection, destination, processor, processor.createSelector(headers));
+ }
+ catch (Exception e)
+ {
+ try { connection.close(); } catch (Exception ignored) {}
+ throw e;
+ }
+ durableReceivers.put(id, receiver);
+ return Response.status(HttpResponseCodes.SC_CREATED).build();
+ }
+ }
+
+ @DELETE
+ @Path("/durable/receivers/{id}")
+ public Response closeDurableReceiver(@PathParam("id")String id,
+ @QueryParam("unsubscribe") @DefaultValue("true")boolean unsubscribe) throws Exception
+ {
+ id = "durable/receivers/" + id;
+ DurableTopicReceiver receiver = durableReceivers.remove(id);
+ if (receiver == null) throw new WebApplicationException(HttpResponseCodes.SC_NOT_FOUND);
+ receiver.close(unsubscribe);
+ return Response.status(HttpResponseCodes.SC_NO_CONTENT).build();
+ }
+
+ @PUT
+ @Path("/durable/listeners/{id}")
+ public Response createDurableListener(@PathParam("id")String id,
+ String callback,
+ @Context HttpHeaders headers) throws Exception
+ {
+ id = "durable/listeners/" + id;
+ if (durableListeners.containsKey(id))
+ {
+ return Response.ok().build();
+ }
+ else
+ {
+ //System.out.println("Creating durable listener: " + id + " callback uri: " + callback);
+
+ Connection connection = factory.createConnection();
+ connection.setClientID(id);
+ DurableTopicListener receiver = null;
+ try
+ {
+ receiver = new DurableTopicListener(id, destination, connection, callback, processor, dlq, processor.createSelector(headers));
+ }
+ catch (Exception e)
+ {
+ try { connection.close(); } catch (Exception ignored) {}
+ throw e;
+ }
+ durableListeners.put(id, receiver);
+ return Response.status(HttpResponseCodes.SC_CREATED).build();
+ }
+ }
+
+ @DELETE
+ @Path("/durable/listeners/{id}")
+ public Response closeDurableListener(@PathParam("id")String id,
+ @QueryParam("unsubscribe") @DefaultValue("true")boolean unsubscribe) throws Exception
+ {
+ id = "durable/listeners/" + id;
+ DurableTopicListener receiver = durableListeners.remove(id);
+ if (receiver == null) throw new WebApplicationException(HttpResponseCodes.SC_NOT_FOUND);
+ receiver.close(unsubscribe);
+ return Response.status(HttpResponseCodes.SC_NO_CONTENT).build();
+ }
+
+ @PUT
+ @Path("/receivers/{id}")
+ public Response createReceiver(@PathParam("id")String id,
+ @Context HttpHeaders headers) throws Exception
+ {
+ if (nondurableReceivers.containsKey(id))
+ {
+ return Response.ok().build();
+ }
+ else
+ {
+ TopicReceiver receiver = new TopicReceiver(connection, destination, processor, processor.createSelector(headers));
+ nondurableReceivers.put(id, receiver);
+ return Response.status(HttpResponseCodes.SC_CREATED).build();
+ }
+ }
+
+ @DELETE
+ @Path("/receivers/{id}")
+ public Response closeReceiver(@PathParam("id")String id) throws Exception
+ {
+ Receiver receiver = nondurableReceivers.remove(id);
+ if (receiver == null) throw new WebApplicationException(HttpResponseCodes.SC_NOT_FOUND);
+ receiver.close();
+ return Response.status(HttpResponseCodes.SC_NO_CONTENT).build();
+ }
+
+ @Path("/receivers/{id}")
+ public TopicReceiver getReceiver(@PathParam("id")String id)
+ {
+ //System.out.println("getTopicReceiver: " + id);
+ TopicReceiver receiver = (TopicReceiver) nondurableReceivers.get(id);
+ if (receiver == null) throw new WebApplicationException(HttpResponseCodes.SC_NOT_FOUND);
+ return receiver;
+ }
+
+ @PUT
+ @Path("/listeners/{id}")
+ public Response createListener(@PathParam("id")String id, String uri,
+ @Context HttpHeaders headers) throws Exception
+ {
+ if (nondurableListeners.containsKey(id))
+ {
+ return Response.ok().build();
+ }
+ else
+ {
+ TopicListener listener = new TopicListener(destination, connection, uri, processor, dlq, processor.createSelector(headers));
+ nondurableListeners.put(id, listener);
+ return Response.status(HttpResponseCodes.SC_CREATED).build();
+ }
+ }
+
+
+ @DELETE
+ @Path("/listeners/{id}")
+ public Response closeListener(@PathParam("id")String id) throws Exception
+ {
+ TopicListener receiver = nondurableListeners.remove(id);
+ if (receiver == null) throw new WebApplicationException(HttpResponseCodes.SC_NOT_FOUND);
+ receiver.close();
+ return Response.status(HttpResponseCodes.SC_NO_CONTENT).build();
+ }
+
+}
View
3  examples/jms-facade/resteasy-mom/src/test/resources/jndi.properties
@@ -0,0 +1,3 @@
+java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
+java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
+java.naming.provider.url=jnp://localhost:1099
View
68 examples/jms-facade/resteasy-mom/src/test/resources/log4j.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<!-- ===================================================================== -->
+<!-- -->
+<!-- Log4j Configuration -->
+<!-- -->
+<!-- ===================================================================== -->
+
+<!-- $Id: log4j.xml 64736 2007-08-21 15:49:48Z anil.saldhana@jboss.com $ -->
+
+<!--
+ | For more configuration infromation and examples see the Jakarta Log4j
+ | owebsite: http://jakarta.apache.org/log4j
+ -->
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
+
+ <!-- ================================= -->
+ <!-- Preserve messages in a local file -->
+ <!-- ================================= -->
+
+ <!-- A time/date based rolling appender -->
+ <appender name="FILE" class="org.jboss.logging.appender.DailyRollingFileAppender">
+ <param name="File" value="${build.testlog}/test.log"/>
+ <param name="Append" value="true"/>
+
+ <!-- Rollover at midnight each day -->
+ <param name="DatePattern" value="'.'yyyy-MM-dd"/>
+
+ <!-- Rollover at the top of each hour
+ <param name="DatePattern" value="'.'yyyy-MM-dd-HH"/>
+ -->
+
+ <layout class="org.apache.log4j.PatternLayout">
+ <!-- The default pattern: Date Priority [Category] Message\n -->
+ <param name="ConversionPattern" value="%d %-5p [%c] %m%n"/>
+
+ <!-- The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
+ <param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
+ -->
+ </layout>
+ </appender>
+
+ <!-- ============================== -->
+ <!-- Append messages to the console -->
+ <!-- ============================== -->
+
+ <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
+ <param name="Threshold" value="DEBUG"/>
+ <param name="Target" value="System.out"/>
+
+ <layout class="org.apache.log4j.PatternLayout">
+ <!-- The default pattern: Date Priority [Category] Message\n -->
+ <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n"/>
+ </layout>
+ </appender>
+
+
+ <!-- ======================= -->
+ <!-- Setup the Root category -->
+ <!-- ======================= -->
+
+ <root>
+ <appender-ref ref="CONSOLE"/>
+ </root>
+
+</log4j:configuration>
Please sign in to comment.