Defining a REST-Based Service Bus Contract
Enabling REST on our service requires that we use the WebGet and WebInvoke class attributes on the service contract interface, as follows:
Example 7.
[ServiceContract(Name="IOrderService", Namespace= "http://standardmold.servicebus.windows.net/Order/1.0/")] public interface IOrderService { [WebInvoke(Method = "POST" , UriTemplate = "orders" , ResponseFormat = WebMessageFormat.Xml)] [OperationContract] int CreateOrder(Order o); [WebInvoke(Method = "PUT" , UriTemplate = "order/{id}" , ResponseFormat = WebMessageFormat.Xml)] [OperationContract] void UpdateOrder(string id, Order o); [WebGet(UriTemplate = "order/{id}" , ResponseFormat = WebMessageFormat.Xml)] [OperationContract] Order GetOrderByOrderId(string id); [WebGet(UriTemplate = "orders/{custName}" , ResponseFormat = WebMessageFormat.Xml)] [OperationContract] List<Order> GetOrdersByCustomer(string custName); [WebGet(UriTemplate = "orders" , ResponseFormat = WebMessageFormat.Xml)] [OperationContract] List<Order> GetOrders(); [WebInvoke(Method = "DELETE" , UriTemplate = "order/{id}" , ResponseFormat = WebMessageFormat.Xml)] [OperationContract] void DeleteOrder(string id); }
|
Next, we need to change the binding to webHttpRelayBinding
and set the binding security mode to None. Then, we change our service
host application to host our now RESTful service endpoint by using WebServiceHost instead of ServiceHost.
Example 8.
WebServiceHost h = new WebServiceHost(typeof (OrderService.OrderService));
|
To test, we can either create a
client application or just use another tool that is capable of creating
HTTP REST requests, like Fiddler.
Creating the Service Bus Message Buffer
Message buffers are small, temporary caches
of messages that can be held for a short time before they are retrieved.
They are particularly useful in Web programming model scenarios when
AppFabric Service Bus bindings are not available.
The message buffer
protocol relies on the AppFabric Access Control authorization model to
help it enforce access control to the message buffer. Specifically, it
uses the SWT mechanism, which you receive from Access Control. The
message buffer protocol establishes a URI tree structure that helps
convey the logical relationship between different types of resources. Table 1 provides a summary of message buffer resources and the associated verbs for each resource.
Table 1. Message buffer resources and the associated verbs.
URI | Resource | Operations |
---|
/{path}/{buffer} | message buffer | PUT (creates or updates message buffer)
GET (gets message buffer policy)
DELETE (deletes the message buffer along with its policy and associated data) |
/{path}/{buffer}/messages | message buffer store | POST (creates message and returns message URI) |
/{path}/{buffer}/messages/head | first unlocked message | POST
(gets the first unlocked message and locks it and returns message
content, message URI, lock duration, lock URI, and lock ID)
DELETE (retrieves the first locked message and deletes it from the
buffer and then returns message content) |
/{path}/{buffer}/messages/{messageid} | message | DELETE (deletes message and supports delete with lock ID) |
/{path}/{buffer}/messages/{messageid}/{lockid} | message lock | DELETE (unlocks message) |
In order to create a message buffer, you will also need to create a message buffer policy, as shown here:
Example 9.
string messageBufferLocation =
string.Format("http://{0}.servicebus.windows.net/{1}",
serviceNamespace, bufferName);
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]);
string authHeaderValue = string.Format("WRAP
access_token=\"{0}\"", token);
string policy =
@"<entry xmlns=""http://www.w3.org/2005/Atom"">" +
@"<content type=""text/xml"">" +
@"<MessageBufferPolicy