JBoss.orgCommunity Documentation

Chapter 4. Posting Messages

4.1. Duplicate Detection
4.2. Persistent Messages

This chapter discusses the protocol for posting messages to a queue or a topic. In Chapter 3, you saw that a queue or topic resource publishes variable custom headers that are links to other RESTful resources. The msg-create header is the URL you post messages to. Messages are published to a queue or topic by sending a simple HTTP message to the URL published by the msg-create header. The HTTP message contains whatever content you want to publish to the HornetQ destination. Here's an example scenario:

  1. Obtain the starting msg-create header from the queue or topic resource.

    HEAD /queues/jms.queue.bar HTTP/1.1
    Host: example.com
    
    --- Response ---
    HTTP/1.1 200 Ok
    msg-create: http://example.com/queues/jms.queue.bar/create
    msg-create-with-id: http://example.com/queues/jms.queue.bar/create/{id}
    
  2. Do a POST to the URL contained in the msg-create header.

    POST /queues/jms.queue.bar/create
    Host: example.xom
    Content-Type: application/xml
    
    <order>
       <name>Bill</name>
       <item>iPhone4</name>
       <cost>$199.99</cost>
    </order>
    
    --- Response ---
    HTTP/1.1 201 Created
    msg-create-next: http://example.com/queues/jms.queue.bar/create/002
    

    A successful response will return a 201 response code. Also notice that a msg-create-next response header is sent as well. You must use this URL to POST your next message.

  3. POST your next message to the queue using the URL returned in the msg-create-next header.

    POST /queues/jms.queue.bar/create/002
    Host: example.com
    Content-Type: application/xml
    
    <order>
       <name>Monica</name>
       <item>iPad</item>
       <cost>$499.99</cost>
    </order>
    
    --- Response --
    HTTP/1.1 201 Created
    msg-create-next: http://example.com/queues/jms.queue.bar/create/003
    

    Continue using the new msg-create-next header returned with each response.

It is VERY IMPORTENT that you never re-use returned msg-create-next headers to post new messages. This URL may be uniquely generated for each message and used for duplicate detection. If you lose the URL within the msg-create-next header, then just go back to the queue or topic resource to get the msg-create URL.

Sometimes you might have network problems when posting new messages to a queue or topic. You may do a POST and never receive a response. Unfortunately, you don't know whether or not the server received the message and so a re-post of the message might cause duplicates to be posted to the queue or topic. By default, the HornetQ REST interface is configured to accept and post duplicate messages. You can change this by turning on duplicate message detection by setting the dups-ok config option to false as described in Chapter 3. When you do this, the initial POST to the msg-create URL will redirect you, using the standard HTTP 307 redirection mechanism to a unique URL to POST to. All other interactions remain the same as discussed earlier. Here's an example:

  1. Obtain the starting msg-create header from the queue or topic resource.

    HEAD /queues/jms.queue.bar HTTP/1.1
    Host: example.com
    
    --- Response ---
    HTTP/1.1 200 Ok
    msg-create: http://example.com/queues/jms.queue.bar/create
    msg-create-with-id: http://example.com/queues/jms.queue.bar/create/{id}
    
  2. Do a POST to the URL contained in the msg-create header.

    POST /queues/jms.queue.bar/create
    Host: example.xom
    Content-Type: application/xml
    
    <order>
       <name>Bill</name>
       <item>iPhone4</name>
       <cost>$199.99</cost>
    </order>
    
    --- Response ---
    HTTP/1.1 307 Redirect
    Location: http://example.com/queues/jms.queue.bar/create/001
    

    A successful response will return a 307 response code. This is standard HTTP protocol. It is telling you that you must re-POST to the URL contained within the Location header.

  3. re-POST your message to the URL provided within the Location header.

    POST /queues/jms.queue.bar/create/001
    Host: example.com
    Content-Type: application/xml
    
    <order>
       <name>Bill</name>
       <item>iPhone4</name>
       <cost>$199.99</cost>
    </order>
    
    --- Response --
    HTTP/1.1 201 Created
    msg-create-next: http://example.com/queues/jms.queue.bar/create/002
    

    You should receive a 201 Created response. If there is a network failure, just re-POST to the Location header. For new messages, use the returned msg-create-next header returned with each response.

  4. POST any new message to the returned msg-create-next header.

    POST /queues/jms.queue.bar/create/002
    Host: example.com
    Content-Type: application/xml
    
    <order>
       <name>Monica</name>
       <item>iPad</name>
       <cost>$499.99</cost>
    </order>
    
    --- Response --
    HTTP/1.1 201 Created
    msg-create-next: http://example.com/queues/jms.queue.bar/create/003

    If there ever is a network problem, just repost to the URL provided in the msg-create-next header.

How can this work? As you can see, with each successful response, the HornetQ REST server returns a uniquely generated URL within the msg-create-next header. This URL is dedicated to the next new message you want to post. Behind the scenes, the code extracts an identify from the URL and uses HornetQ's duplicate detection mechanism by setting the DUPLICATE_DETECTION_ID property of the JMS message that is actually posted to the system.

An alternative to this approach is to use the msg-create-with-id header. This is not an invokable URL, but a URL template. The idea is that the client provides the DUPLICATE_DETECTION_ID and creates it's own create-next URL. The msg-create-with-id header looks like this (you've see it in previous examples, but we haven't used it):

msg-create-with-id: http://example.com/queues/jms.queue.bar/create/{id}

You see that it is a regular URL appended with a {id}. This {id} is a pattern matching substring. A client would generate its DUPLICATE_DETECTION_ID and replace {id} with that generated id, then POST to the new URL. The URL the client creates works exactly like a create-next URL described earlier. The response of this POST would also return a new msg-create-next header. The client can continue to generate its own DUPLICATE_DETECTION_ID, or use the new URL returned via the msg-create-next header.

The advantage of this approach is that the client does not have to repost the message. It also only has to come up with a unique DUPLICATE_DETECTION_ID once.

By default, posted messages are not durable and will not be persisted in HornetQ's journal. You can create durable messages by modifying the default configuration as expressed in Chapter 2 so that all messages are persisted when sent. Alternatively, you can set a URL query parameter called durable to true when you post your messages to the URLs returned in the msg-create, msg-create-with-id, or msg-create-next headers. here's an example of that.

POST /queues/jms.queue.bar/create?durable=true
Host: example.xom
Content-Type: application/xml

<order>
   <name>Bill</name>
   <item>iPhone4</item>
   <cost>$199.99</cost>
</order>