This topic has not yet been rated Rate this topic

Service Bus Message Buffer Overview

Service Bus Message Buffer Overview

ImportantImportant
The current Message Buffers feature, including their management protocol, will remain supported for backwards compatibility. However, the general recommendation is that you explicitly change client code to use the new Queue feature. For more information, see Queues, Topics, and Subscriptions.

Message buffers are small, temporary cache locations in which messages can be held for a short time until they are retrieved. Message buffers are especially useful in Web programming model scenarios when Windows Azure Service Bus bindings are not available; for example, when the message consumer is running on a computer that is not running Windows, or is implemented in Java. Message buffers can be accessed by applications that use HTTP and do not require the Windows Azure SDK. Hence, message buffers enable Web developers, mobile device programmers, and others to integrate their applications together with the Service Bus by creating message consumers that use HTTP requests to poll for messages.

Message buffers use the HTTP REST protocol to expose various operations on the message buffer such as creating a message buffer, sending a message to the message buffer, and retrieving a message from the message buffer. These operations are described in the following Message Buffer Protocol section.

The following code example shows how to use the REST protocol to create a message buffer, send and retrieve a message from the message buffer, and finally delete the message buffer. This example uses System.Net.WebClient to send and receive HTTP requests. For a complete working sample, see the PlainHttp sample in the Windows Azure SDK samples folder under ServiceBus\ExploringFeatures\MessageBuffer.

// Prompt the user for the service namespace and issuer key.
Console.Write("Please enter your Service Namespace: ");
string serviceNamespace = Console.ReadLine();
Console.Write("Please enter the key for the 'owner' issuer: ");
string ownerKey = Console.ReadLine();
// Create a GUID for the buffer name.
string bufferName = Guid.NewGuid().ToString("N");

// Construct the message buffer URI.
string messageBufferLocation = string.Format("http://{0}.servicebus.windows.net/{1}", serviceNamespace, bufferName);

// Get the AC token
WebClient client = new WebClient();
client.BaseAddress = string.Format("https://{0}-sb.accesscontrol.windows.net/", serviceNamespace);
NameValueCollection values = new NameValueCollection();
values.Add("wrap_name", "owner");
values.Add("wrap_password", ownerKey);
values.Add("wrap_scope", messageBufferLocation);
byte[] responseBytes = client.UploadValues("WRAPv0.9", "POST", values);
string response = Encoding.UTF8.GetString(responseBytes);

string token = Uri.UnescapeDataString(response.Split('&').Single(value => value.StartsWith("wrap_access_token=", StringComparison.OrdinalIgnoreCase)).Split('=')[1]);

// Create the auth header from the token 
string authHeaderValue = string.Format("WRAP access_token=\"{0}\"", token);

// Create the message buffer policy.
string policy =
    "<entry xmlns=\"http://www.w3.org/2005/Atom\">" +
    "<content type=\"text/xml\">" +
    "<MessageBufferPolicy xmlns=\"http://schemas.microsoft.com/netservices/2009/05/servicebus/connect\"/>" +
    "</content>" +
    "</entry>";

// Create a message buffer.
client.BaseAddress = string.Format("https://{0}.servicebus.windows.net/{1}/", serviceNamespace, bufferName);
client.Headers[HttpRequestHeader.ContentType] = "application/atom+xml;type=entry;charset=utf-8";
client.Headers[HttpRequestHeader.Authorization] = authHeaderValue;
client.UploadData(String.Empty, "PUT", Encoding.UTF8.GetBytes(policy));
Console.WriteLine("Message buffer was created at '{0}'.", messageBufferLocation);

// Send a message to the message buffer.
client.Headers[HttpRequestHeader.ContentType] = "text/xml";
client.Headers[HttpRequestHeader.Authorization] = authHeaderValue;
client.UploadData("messages?timeout=20", "POST", Encoding.UTF8.GetBytes("<msg1>This is message #1</msg1>"));
Console.WriteLine("Message sent.");

// Retrieve message.
client.Headers[HttpRequestHeader.Authorization] = authHeaderValue;
string payload = Encoding.UTF8.GetString(client.UploadData("messages/head?timeout=20", "DELETE", new byte[0]));
Console.WriteLine("Retrieved the message '{0}'.", payload);

// Delete the message buffer.
client.Headers[HttpRequestHeader.Authorization] = authHeaderValue;
client.UploadData(String.Empty, "DELETE", new byte[0]);  
Console.WriteLine("Message buffer at '{0}' was deleted.", messageBufferLocation);

You can also use message buffers through the APIs provided by the Windows Azure SDK. This requires the Windows Azure SDK to be installed. For more information about using message buffers with the Windows Azure SDK, see the Using the Message Buffer with the Windows Azure SDK section later in this topic.

Message Buffer Protocol

The message buffer protocol is an HTTP REST protocol that is designed to follow REST principles and to be simple and easy to understand. The goal is to make sure that developers can easily use the protocol from any client without requiring a library or SDK.

The protocol relies on the Access Control service HTTP authorization model to help it enforce access control on the message buffer. This means that it uses the Simple Web Token (SWT) mechanism that you can use to retrieve a token using HTTP, and then embed it in an HTTP request as a header. This token includes claims that are used to determine whether an operation should be allowed.

The protocol expects each message buffer to be located at a unique URI in the Service Bus namespace. This URI then becomes the root for a set of resources that represents the message buffer instance. Each resource type has a unique URI and an associated set of HTTP verbs for interacting with it. The URIs are organized in a way that helps communicate the logical relationships between the different types of resources.

The verbs used to interact with message buffers are modeled on standard HTTP commands. The following is a list of these verbs:

  • POST/PUT: Use to create new resources. POST is used to create a new instance of the message resource. PUT is used to either create or update a message buffer resource. When using POST, the address of the new resource is returned in the response.

  • PUT: Use to update an existing resource.

  • DELETE: Use to delete an existing resource.

  • GET: Use to retrieve a representation of a resource. In this case the GET is expected to represent a snapshot of the resource and it can be cached when appropriate.

The following is a summary of the different message buffer resources and the associated verbs for each resource.

 

URI Resource Operations

http://{serviceNamespace}.servicebus.windows.net/{path}/{buffer}

Message buffer

PUT

Creates or updates message buffer.

GET

Gets message buffer policy.

DELETE

Deletes message buffer along with its policy and all associated state.

http://{serviceNamespace}.servicebus.windows.net/{path}/{buffer}/messages

Message buffer store

POST

Creates message.

(Returns message URI.)

http://{serviceNamespace}.servicebus.windows.net/{path}/{buffer}/messages/head

First unlocked message

POST

Gets the first unlocked message and locks it.

(Returns message content, message URI, lock duration, lock URI, and lock ID.)

DELETE

Retrieves the first unlocked message and deletes it from the buffer.

(Returns message content.)

http://{serviceNamespace}.servicebus.windows.net/{path}/{buffer}/messages/{messageid}

Message

DELETE

Deletes message. Supports delete with lock ID.

http://{serviceNamespace}.servicebus.windows.net/{path}/{buffer}/messages/{messageid}/{lockid}

Message lock

DELETE

Unlocks message.

Request/Response Details of the Message Buffer Protocol

The following tables list the contents of the requests and their corresponding responses for each message buffer operation.

Create or update a message buffer

Resource URI

https://{serviceNamespace}.servicebus.windows.net/{path}/{buffer}

HTTP Verb

PUT

Request Headers

Authorization: WRAPv0.8 {token}

Content-Type: application/atom+xml;type=entry;charset=utf-8

Request Body

{policy-xml}

For example:
<entry xmlns="http://www.w3.org/2005/Atom">
<content type="text/xml">
<MessageBufferPolicy xmlns="http://schemas.microsoft.com/netservices/2009/05/servicebus/connect">
<Authorization>[AuthorizationPolicy enum value]</Authorization>
<Discoverability>[DiscoverabilityPolicy enum value]</Discoverability>
<TransportProtection>[TransportProtectionPolicy enum value]</TransportProtection>
<ExpiresAfter>PTnHnMnS</ExpiresAfter>
<MaxMessageCount>nnn</MaxMessageCount>
<OverflowPolicy>[OverflowPolicy enum value]</OverflowPolicy>
</MessageBufferPolicy>
</content>
</entry>

Notes:
The ExpiresAfter time interval is broken up into hours (H), minutes (M), and seconds (S). Replace n by the corresponding amount of time for each unit of time.
The enumeration values for the policy properties are part of the Microsoft.ServiceBus namespace.

Response Body

{policy-xml}

The message buffer policy is returned because some policy property might be defaulted if their value supplied in the request is invalid.

Expected HTTP Status Code

201 Created: The message buffer was successfully created.
403 Forbidden: Quota exceeded on the number of message buffers. Please increase the per solution connection quota.

Get a message buffer policy

Resource URI

https://{serviceNamespace}.servicebus.windows.net/{path}/{buffer}

HTTP Verb

GET

Request Headers

Authorization: WRAPv0.8 {token}

Request Body

Empty.

Response Body

{policy-xml}

Expected HTTP Status Code

200 OK: The message buffer policy was successfully retrieved.

Delete a message buffer

Resource URI

https://{serviceNamespace}.servicebus.windows.net/{path}/{buffer}

HTTP Verb

DELETE

Request Headers

Authorization: WRAPv0.8 {token}

Request Body

Empty.

Response Body

Empty.

Expected HTTP Status Code

200 OK: The message buffer was successfully deleted.

Send a message to a message buffer

Resource URI

https://{serviceNamespace}.servicebus.windows.net/{path}/{buffer}/messages

HTTP Verb

POST

Request Headers

Authorization: WRAPv0.8 {token}

Content-Type: application/atom+xml;type=entry;charset=utf-8

Request Body

{message-payload}

Response Body

Empty.

Expected HTTP Status Code

201 Created: The message was sent successfully.
408 Request Timeout: The request timed out. Please retry.
400 Bad Request: The request exceeded the quota of pending senders to the buffer. Please retry after some time.
410 Gone: The message buffer does not exist anymore. Please recreate the message buffer and retry.

Retrieve a message from the message buffer (destructive read)

Resource URI

https://{serviceNamespace}.servicebus.windows.net/{path}/{buffer}/messages/head?timeout={timeout-in-seconds}

The timeout parameter specifies the maximum amount of time that the retrieve request will wait if a message is not readily available in the message buffer. The maximum time that can be specified is 2 minutes.

HTTP Verb

DELETE

Request Headers

Authorization: WRAPv0.8 {token}

Request Body

Empty.

Response Body

{message-payload}

Expected HTTP Status Code

200 OK: The message was successfully retrieved.
204 No Content: No messages are present in the message buffer.
400 Bad Request: This request exceeds the quota of pending receivers to the buffer. Please retry after some time.
410 Gone: The message buffer is no longer available.

Lock a message in the message buffer (non-destructive read)

Resource URI

https://{serviceNamespace}.servicebus.windows.net/{path}/{buffer}/messages/head?timeout={timeout-in-seconds}&lockduration={lockduration-in-secs}

The timeout parameter specifies the maximum amount of time that this request will wait if a message is not readily available in the message buffer. The maximum time that can be specified is 2 minutes.

The lockduration parameter specifies the time in seconds that the returned message is locked so that no other consumer can see the message. The maximum lock duration is 5 minutes and the minimum lock duration is 10 seconds.

HTTP Verb

POST

Request Headers

Authorization: WRAPv0.8 {token}

Request Body

Empty.

Response Headers

X-MS-MESSAGE-LOCATION: https://{serviceNamespace}.servicebus.windows.net/{path}/{buffer}/messages/{message-id}
This header indicates the location of the message. This URI is needed to unlock or delete the message. For more information, see the “Unlock a locked message” and “Delete a locked message from the message buffer” tables.
X-MS-LOCK-ID: {lock-id}
This header provides the lock ID of the message. This lock ID is needed to delete the locked message. For more information, see the “Delete a locked message from the message buffer” table.
X-MS-LOCK-LOCATION: https://{serviceNamespace}.servicebus.windows.net/{path}/{buffer}/messages/{message-id}/{lock-id}
This header indicates the lock location for the message. This URI is needed to unlock the message. For more information, see the “Unlock a locked message” table.

Response Body

{message-payload}

Expected HTTP Status Code

200 OK: The message was successfully read and locked.
204 No Content: No messages are present in the message buffer.
400 Bad Request: This request exceeds the quota of pending receivers to the buffer. Please retry after some time.
410 Gone: The message buffer is no longer available.

Unlock a locked message (that is, delete a lock on a message) in the message buffer

Resource URI

https://{serviceNamespace}.servicebus.windows.net/{path}/{buffer}/messages/{message-id}/{lock-id}

HTTP Verb

DELETE

Request Headers

Authorization: WRAPv0.8 {token}

Request Body

Empty.

Response Body

Empty.

Expected HTTP Status Code

200 OK: The message was successfully unlocked.
404 Not Found: No message with the specified lock ID was found. Please retry with a valid lock ID.
410 Gone: The message buffer is no longer available.

Delete a locked message from the message buffer

Resource URI

https://{serviceNamespace}.servicebus.windows.net/{path}/{buffer}/messages/{message-id}?lockid={lock-id}

The lockid parameter should be a valid lock ID from the response header value “X-MS-LOCK-ID” that is returned in the response of a non-destructive read operation. For more information, see the “Lock a message in the message buffer” table.

HTTP Verb

DELETE

Request Headers

Authorization: WRAPv0.8 {token}

Request fBody

Empty.

Response Body

Empty.

Expected HTTP Status Code

200 OK: The message was successfully deleted.
404 Not Found: No message with the specified lock ID was found. Please retry with a valid lock ID.
410 Gone: The message buffer is no longer available.

Message Buffer Policy

The message buffer policy is an XML document that defines the desired semantics for a message buffer. You must include a message buffer policy document in the request when creating a new message buffer instance. You can later retrieve the message buffer policy document to determine the semantics for an existing message buffer. You can also update an existing message buffer policy document to renew the expiration time-out. When doing this, you must ensure that the other properties are unchanged.

the message buffer policy properties that can be configured, see the documentation for the MessageBufferPolicy class.

Message Buffer Quota

By default, the message buffer can contain up to 10 messages. You can modify this limit through the MaxMessageCount property in the MessageBufferPolicy class. The maximum number of messages that the message buffer can hold is 50 messages.

Using the Message Buffer with the Windows Azure SDK

The Windows Azure SDK provides a set of managed client APIs that make it easy for developers to use a message buffer. They are designed to closely follow the semantics of the protocol and enable the use and configuration of message buffers. These APIs are exposed through the MessageBufferClient and the MessageBufferPolicy classes.

You can use the MessageBufferClient class to create a new message buffer or to retrieve an object that you can then use to interact with an existing message buffer. It provides methods for operating directly on the message buffer such as queuing messages in the message buffer and retrieving messages from the message buffer. the documentation for the MessageBufferClient class.

You can use the MessageBufferPolicy to configure the message buffer including the security used on the message buffer, the message buffer lifespan, and the message buffer capacity. the documentation for the MessageBufferPolicy class.

The following code example shows how to configure and create a message buffer, and send and retrieve messages from the message buffer.

string serviceNamespace = "...";
MessageVersion messageVersion = MessageVersion.Soap12WSAddressing10;
string messageAction = "urn:Message";

// Configure credentials.
TransportClientEndpointBehavior behavior = new TransportClientEndpointBehavior();
behavior.CredentialType = TransportClientCredentialType.SharedSecret;
behavior.Credentials.SharedSecret.IssuerName = "...";
behavior.Credentials.SharedSecret.IssuerSecret = "...";

// Configure buffer policy.
MessageBufferPolicy policy = new MessageBufferPolicy
{
    ExpiresAfter = TimeSpan.FromMinutes(2.0d),
    MaxMessageCount = 100
};

// Create message buffer.
string bufferName = "MyBuffer";
Uri bufferLocation = new Uri("https://" + serviceNamespace + ".servicebus.windows.net/services/" + bufferName);
MessageBufferClient client = MessageBufferClient.CreateMessageBuffer(behavior, bufferLocation, policy, messageVersion);

// Send 10 messages.
for (int i = 0; i < 10; ++i)
{
    client.Send(Message.CreateMessage(messageVersion, messageAction, "Message #" + i));
}

Message message;
string content;

// Retrieve a message (destructive read).
message = client.Retrieve();
content = message.GetBody<string>();
message.Close();

Console.WriteLine("Retrieve message content: {0}", content);

// Retrieve a message (peek/lock).
message = client.PeekLock();
content = message.GetBody<string>();

Console.WriteLine("PeekLock message content: {0}", content);

// Delete previously locked message.
client.DeleteLockedMessage(message);
message.Close();

// If no more messages are retrieved within the ExpiresAfter time span,
// the buffer will automatically be deleted...

ImportantImportant
Because message buffer contents are stored in active memory, there are no strong fault tolerance or reliability guarantees. If the server hosting a message buffer crashes, you may lose messages. In the event of a server crash, you do not necessarily lose the buffer itself: knowledge of the buffer, including policy settings, is distributed across multiple servers and can be recovered. However, any messages in your buffer at the time of the crash are lost. Therefore, if you are designing an application that requires a high degree of message reliability, we recommend that you provide for message redundancy and recovery through another way.

Did you find this helpful?
(1500 characters remaining)