This article provides information on working with the Windows Azure AppFabric Service Bus from the Ruby programming language. This article assumes that you are familiar with Ruby, and have access to the Windows Azure AppFabric labs site. For more information on Ruby, see http://www.ruby-lang.org/. For more information on accessing Windows Azure AppFabric labs, see http://portal.appfabriclabs.com/. Currently this article is based on the WAZ-AppFabric sample produced by the CAT team and discussed at http://appfabriccat.com/2011/07/using-azure-appfabric-service-bus-from-ruby-apps/. This sample primarily targets AppFabric Queues, however the same basic principals can be applied when accessing other AppFabric Service Bus REST APIs from Ruby. NOTE: AppFabric Queues are currently in Community Technical Preview, and are only available on the AppFabricLabs.com environment. AppFabric exposes REST APIs for most service bus operations, however there are some limitations which are described at http://msdn.microsoft.com/en-us/library/gg278338.aspx#BKMK_REST1.
AppFabric queues provide a reliable store for asynchronous messages, similar to MSMQ. Messages can remain in the queue for an indefinite period of time, until read and deleted by the receiving application. Queues also offer the ability to place a transient lock on messages that are being processed, so that if the receiving application fails, the message is placed back in the queue and can be processed when the application restarts or by another instance of the receiving application.
REST is a vast topic, and far beyond the scope of this article. It can be summarized as an architecture that defines a type of client/server communication where the client interacts with resources on the server that are addressable through a unique URI. Resource interaction is typically performed using standard HTTP verbs (GET, POST, PUT or DELETE). Resources are also typed as a specific MIME type (XML, PNG, Text/Plain, etc.)
For the purposes of this article, REST is a way by which Ruby applications can interact with services provided by the Windows Azure AppFabric Service Bus. An example REST message from the client to receive a message from a queue would appear as follows:
DELETE https://rubytest.servicebus.appfabriclabs.com/testqueue/messages/head?timeout=60 HTTP/1.1 Accept: */*; q=0.5, application/xml Accept-Encoding: gzip, deflate Authorization: WRAP access_token="net.windows.servicebus.action=Listen%2cManage%2cSend&http%3a%2f%2fschemas.microsoft.com%2faccesscontrolservice%2f2010%2f07%2fclaims%2fidentityprovider=https%3a%2f%2frubytest-sb.accesscontrol.appfabriclabs.com%2f&Audience=http%3a%2f%2frubytest.servicebus.appfabriclabs.com&ExpiresOn=1306783739&Issuer=https%3a%2f%2frubytest-sb.accesscontrol.appfabriclabs.com%2f&HMACSHA256=ebfBpf%2fCKEoIxEqXzFtImTv2Z8Zk9NhqHvtjB%2fKv8b0%3d" Content-Length: 0 Host: rubytest.servicebus.appfabriclabs.com
request = generate_request(:delete, “https://rubytest.servicebus.appfabriclabs.com/testqueue/messages/head?timeout=60”, accessToken, nil, nil) result = request.execute()
gem install rest-client
The following steps will guide you through the process of creating an AppFabric Service Bus on the AppFabric Labs.
Once the namespace status changes to Active (green), you can begin working with queues within this namespace.
The stand-alone sample can be downloaded from the AppFabric CAT team blog at http://appfabriccat.com/2011/07/using-azure-appfabric-service-bus-from-ruby-apps/.
When accessing an AppFabric queue, you must present a Simple Web Token that authorizes you when using any of the REST APIs. An access token can be obtained by sending a request containing the Issuer and Key values, the scope (your service bus namespace,) to the AppFabric ACS WRAP endpoint. The endpoint will return a token that can be used when calling the service bus REST APIs. An example request to the WRAP endpoint would appear as follows:
POST https://rubytest-sb.accesscontrol.appfabriclabs.com/WRAPv0.9/ HTTP/1.1 Accept: */*; q=0.5, application/xml Content-Type: application/x-www-form-urlencoded Accept-Encoding: gzip, deflate Content-Length: 140 Host: rubytest-sb.accesscontrol.appfabriclabs.com wrap_name=owner&wrap_password=xwCOTgOHT%2Fw8daI9mhCA8Vm0SlKYPKZojYfYCafsRaU%3D&wrap_scope=http%3A%2F%2Frubytest.servicebus.appfabriclabs.com
The value returned from the WRAP endpoint must be parsed and decoded (URL-encoding) before it can be used. The AccessControl.rb file included in the WAZ-AppFabric sample provides the get_access_token method, which invokes the WRAP endpoint and returns a decoded access token. This file also provides the get_scope helper method, which creates the scope URL needed when requesting an access token.
The following is an example of using the get_scope and get_access_token methods:
scopeUri = WAZ::AppFabric::AccessControl.get_scope(serviceNamespace) accessToken = WAZ::AppFabric::AccessControl.get_access_token(serviceNamespace, scopeUri, serviceIdentityName, serviceIdentityPassword)
The queue management REST APIs provide functionality to create, inspect, list, and delete queues within a service bus namespace. The WAZ-AppFabric sample encapsulates the calls to the REST APIs in the QueueManagement.rb file, which exposes queue management functionality through the methods in the WAZ::AppFabric::QueueMagagement class. The operations and matching methods are described in the following table.
Management Operation
Description
Method
Create
Creates a new queue
create_queue(serviceNamespace, queueName, accessToken)
Delete
Deletes an existing queue
delete_queue(serviceNamespace, queueName, accessToken)
Get
Returns information on an existing queue
get_queue(serviceNamespace, queueName, accessToken)
List
List all queues within the namespace
list_queues(serviceNamespace, accessToken)
The following example creates, and then deletes a queue named ‘testqueue’:
createQueueResponse = WAZ::AppFabric::QueueManagement.create_queue(serviceNamespace, “testqueue”, accessToken) deleteQueueResponse = WAZ::AppFabric::QueueManagement.delete_queue(serviceNamespace, “testqueue”, accessToken)
Once created, you can use REST to send, receive, and delete messages from a queue. The WAZ-Appfabric sample encapsulates the REST APIs to accomplish these tasks in the QueueClient.rb file, which exposes these operations through the methods in the WAZ::AppFabric::QueueClient class. The operations and matching methods are described in the following table.
Queue Operation
Send
Stores a message into a queue
send(serviceNamespace, queueName, accessToken, content)
Receive
Receives a message from a queue, and then deletes the message
receive(serviceNamespace, queueName, accessToken)
Peek-lock
Receives a message from a queue, and then places a lock on the message
peeklock(serviceNamespace, queueName, accessToken)
Delete locked message
Deletes a message locked by peek-lock
deletePeekedMessage(serviceNamespace, queueName, accessToken, messageId, lockId)
Remove lock
Removes a lock placed on a message by peek-lock
unlockPeekedMessage(serviceNamespace, queueName, accessToken, messageId, lockId)
The receive operation is straightforward, and is generally used when the receiving application receives and processes the application as one atomic unit of work. If there is a risk that the receiving application may fail and lose the message, such as an application that passes the message to a separate process for validation, peek-lock is more desirable, as it will place the message back into the queue if the receiving application does not explicitly delete the message within the timeout period. This behavior allows you to continuously retry processing of the message until you explicitly confirm processing by deleting the message; peek-lock and delete locked message can be used to provides a pseudo-transactional receive process.
The following is an example of sending, peek-locking, and then deleting a message to a queue named ‘testqueue’:
sendMessageResponse = WAZ::AppFabric::QueueClient.send(serviceNamespace, “testqueue”, accessToken, 'Hello, from Ruby!') peeklockMessageResponse = WAZ::AppFabric::QueueClient.peeklock(serviceNamespace, “testqueue”, accessToken) messageId = peeklockMessageResponse.headers[:x_ms_message_id] lockId = peeklockMessageResponse.headers[:x_ms_lock_id] deletelockedMessageResponse = WAZ::AppFabric::QueueClient.deletePeekedMessage(serviceNamespace, “testqueue”, accessToken, messageId, lockId)
As can be seen in this example, deleting a locked message requires information obtained from the request to peek-lock the message; specifically the message ID and lock ID.
Ed Price - MSFT edited Revision 8. Comment: Spacing and TOC
Larry Franks edited Revision 7. Comment: trying to fix scrolling of pre sections again.
Larry Franks edited Revision 5. Comment: <sigh> apparently not. Trying something else.
Larry Franks edited Revision 6. Comment: reverting out the last edit.
Larry Franks edited Revision 4. Comment: code sections, you will bend to my will! (scrollbars fixed) fingers crossed.
Larry Franks edited Original. Comment: fixing code section scroll bars