Search code examples
restmavenresteasyactivemq-artemis

REST interface on ActiveMQ Artemis


I'm trying to add REST interface to ActiveMQ Artemis by building .war file with Maven following Artemis REST interface documentation. After .war file is generated I move it in /opt/artemis/apache-artemis-2.13.0/web/ directory and start ActiveMQ Artemis.

I'm getting next exception when starting ActiveMQ Artemis:

WARN [org.eclipse.jetty.webapp.WebAppContext] Failed startup of context o.e.j.w.WebAppContext@4cb702ce{/artemis-rest,file:///var/lib/test-broker/tmp/jetty-0_0_0_0-8161-artemis-rest_war-_artemis-rest-any-15304647904836420970.dir/webapp/,UNAVAILABLE}{/opt/artemis/apache-artemis-2.13.0/web/artemis-rest.war}: java.lang.RuntimeException: You must install RESTEasy as a Bootstrap Listener and it must be listed before this class
    at org.apache.activemq.artemis.rest.integration.RestMessagingBootstrapListener.contextInitialized(RestMessagingBootstrapListener.java:39) [artemis-rest-2.13.0.jar:2.13.0]

Also, getting 503 on HTTP request http://192.168.0.50:8161/artemis-rest/queues/test:

HTTP ERROR 503 Service Unavailable
URI:    /artemis-rest/queues/test
STATUS: 503
MESSAGE:    Service Unavailable
SERVLET:    -

I don't have RESTeasy installed because I can't find out how to, so I've downloaded jar file for RESTeasy jaxrs version 3.13.0.Final and put it in WEB-INF/lib directory and also included dependency for it in pom.xml.

Let me show you my configuration:

pom.xml

<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">

   <modelVersion>4.0.0</modelVersion>
   <groupId>org.somebody</groupId>
   <artifactId>artemis-rest</artifactId>
   <packaging>war</packaging>
   <name>My App</name>
   <version>1.0-SNAPSHOT</version>

   <dependencies>
      <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-jaxrs</artifactId>
        <version>3.13.0.Final</version>
      </dependency>
      <dependency>
         <groupId>org.apache.activemq.rest</groupId>
         <artifactId>artemis-rest</artifactId>
         <version>2.13.0</version>
         <exclusions>
            <exclusion>
               <groupId>*</groupId>
               <artifactId>*</artifactId>
            </exclusion>
         </exclusions>
      </dependency>
   </dependencies>
</project>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- This web.xml file is not required when using Servlet 3.0 container,
     see implementation details http://jersey.java.net/nonav/documentation/latest/jax-rs.html -->
<web-app>
   <listener>
      <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
   </listener>

   <listener>
      <listener-class>org.apache.activemq.artemis.rest.integration.RestMessagingBootstrapListener</listener-class>
   </listener>

   <filter>
      <filter-name>Rest-Messaging</filter-name>
      <filter-class>org.jboss.resteasy.plugins.server.servlet.FilterDispatcher</filter-class>
   </filter>

   <filter-mapping>
      <filter-name>Rest-Messaging</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>
   <context-param>
        <param-name>rest.messaging.config.file</param-name>
        <param-value>file:///WEB-INF/rest-messaging.xml</param-value>
   </context-param>
</web-app>

rest-messaging.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- This web.xml file is not required when using Servlet 3.0 container,
     see implementation details http://jersey.java.net/nonav/documentation/latest/jax-rs.html -->
<rest-messaging>
    <server-in-vm-id>0</server-in-vm-id> <!-- deprecated, use "url" -->
    <use-link-headers>false</use-link-headers>
    <default-durable-send>false</default-durable-send>
    <dups-ok>true</dups-ok>
    <topic-push-store-dir>topic-push-store</topic-push-store-dir>
    <queue-push-store-dir>queue-push-store</queue-push-store-dir>
    <producer-time-to-live>0</producer-time-to-live>
    <producer-session-pool-size>10</producer-session-pool-size>
    <session-timeout-task-interval>1</session-timeout-task-interval>
    <consumer-session-timeout-seconds>300</consumer-session-timeout-seconds>
    <consumer-window-size>-1</consumer-window-size> <!-- deprecated, use "url" -->
    <url>vm://0</url>
</rest-messaging>

If needed I can also attach broker.xml, jolokia-access.xml and bootstrap.xml files, but they seems OK to me. I found older question about this here, but it didn't help to resolve this.

In case you know some other approaches for adding REST interface to ActiveMQ Artemis please inform me.


Solution

  • Unfortunately the REST documentation for ActiveMQ Artemis hasn't been validated or updated in awhile.

    You can get everything you need in the war file and exclude most of what you don't need using this pom.xml:

    <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">
    
       <modelVersion>4.0.0</modelVersion>
       <groupId>org.somebody</groupId>
       <artifactId>artemis-rest</artifactId>
       <packaging>war</packaging>
       <name>My App</name>
       <version>1.0-SNAPSHOT</version>
    
       <dependencies>
          <dependency>
             <groupId>org.apache.activemq.rest</groupId>
             <artifactId>artemis-rest</artifactId>
             <version>2.13.0</version>
             <exclusions>
                <exclusion>
                   <groupId>org.apache.activemq</groupId>
                   <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                   <groupId>io.netty</groupId>
                   <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                   <groupId>org.eclipse.jetty.aggregate</groupId>
                   <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                   <groupId>org.apache.httpcomponents</groupId>
                   <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                   <groupId>org.jboss.logging</groupId>
                   <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                   <groupId>org.jboss.logmanager</groupId>
                   <artifactId>*</artifactId>
                </exclusion>
             </exclusions>
          </dependency>
       </dependencies>
    </project>
    

    Be sure to add an in-vm acceptor to your broker.xml, e.g.:

          <acceptors>
             ...
             <acceptor name="invm">vm://0</acceptor>
          </acceptors>
    

    Also, you can automatically include the REST configuration XML if you structure your project like this:

    |-- pom.xml
    `-- src
       `-- main
           `-- webapp
               `-- WEB-INF
                   `-- web.xml
           `-- resources
               `-- rest.xml
    

    Then you can reference it in your web.xml like this:

       <context-param>
            <param-name>rest.messaging.config.file</param-name>
            <param-value>rest.xml</param-value>
       </context-param>
    

    In general I would recommend against using the ActiveMQ Artemis REST interface for 2 main reasons:

    1. Your code will not be portable because the ActiveMQ Artemis REST interface is a custom (i.e. not standardized) interface.
    2. The STOMP protocol is ubiquitous, simple, standarized, and can be used in almost every circumstance and environment where REST might be used.

    I recommend you use STOMP in lieu of the ActiveMQ Artemis REST interface.