Service Bus Message Buffer Overview
Service Bus Message Buffer Overview
Important |
|---|
| 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} |
|
Response Body |
{policy-xml} |
|
Expected HTTP Status Code |
201 Created: The message buffer was successfully created. |
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. |
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. |
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} |
|
Response Body |
{message-payload} |
|
Expected HTTP Status Code |
200 OK: The message was successfully read and locked. |
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. |
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. |
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...
Important |
|---|
| 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. |
