Using the Windows Azure Service Bus REST API to Send to Topic from Salesforce.com

In the past, I’ve written and talked about integrating the Windows Azure Service Bus with non-Microsoft platforms like Salesforce.com. I enjoy showing how easy it is to use the Service Bus Relay to connect on-premises services with Salesforce.com. On multiple occasions, I’ve been asked how to do this with Service Bus brokered messaging options (i.e. Topics and Queues) as well. It can be a little tricky as it requires the use of the Windows Azure REST API and there aren’t a ton of public examples of how to do it! So in this blog post, I’ll show you how to send a message to a Service Bus Topic from Salesforce.com. Note that this sequence resembles how you’d do this on ANY platform that can’t use a Windows Azure SDK.

Creating the Topic and Subscription

First, I needed a Topic and Subscription to work with. Recall that Topics differ from Queues in that a Topic can have multiple subscribers. Each subscription (which may filter on message properties) has its own listener and gets their own copy of the message. In this fictitious scenario, I wanted users to submit IT support tickets from a page within the Salesforce.com site.

I could create a Topic in a few ways. First, there’s the Windows Azure portal. Below you can see that I have a Topic called “TicketTopic” and a Subscription called “AllTickets”.

If you’re a Visual Studio developer, you can also use the handy Windows Azure extensions to the Server Explorer window. Notice below that this tool ALSO shows me the filtering rules attached to each Subscription.

With a Topic and Subscription set up, I was ready to create a custom VisualForce page to publish to it.

Code to Get an ACS Token

Before I could send a message to a Topic, I needed to get an authentication token from the Windows Azure Access Control Service (ACS). This token goes into the request header and lets Windows Azure determine if I’m allowed to publish to a particular Topic.

In Salesforce.com, I built a custom VisualForce page with the markup necessary to submit a support ticket. The final page looks like this:

I also created a custom Controller that extended the native Accounts Controller and added an operation to respond to the “Submit Ticket” button event. The first bit of code is responsible for calling ACS and getting back a token that can be included in the subsequent request. Salesforce.com extensions are written in a language called Apex, but it should look familiar to any C# or Java developer.

So what’s happening here? First, I set the endpoint URL. In this case, I had to follow a particular structure that includes “/messages” at the end. Next, I added the ACS token to the HTTP Authorization header.

After that, I set the brokered messaging header. This fills up a JSON-formatted BrokerProperties structure that includes any values you needed by the message consumer. Notice here that I included a GUID for the message ID and provided a “label” value that I could access later. Next, I defined a custom header called “Account”. These custom headers get added to the Brokered Message’s “Properties” collection and are used in Subscription filters. In this case, a subscriber could choose to only receive Topic messages related to a particular account.

Finally, I set the body of the message. I could send any string value here, so I chose a lightweight JSON format that would be easy to convert to a typed object on the receiving end.

With all that, I was ready to go.

Receiving From Topic

To get a message into the Topic, I submitted a support ticket from the VisualForce page.

I immediately switched to the Windows Azure portal to see that a message was now queued up for the Subscription.

How can I retrieve this message? I could use the REST API again, but let’s show how we can mix and match techniques. In this case, I used the Windows Azure SDK for .NET to retrieve and delete a message from the Topic. I also referenced the excellent JSON.NET library to deserialize the JSON object to a .NET object. The tricky part was figuring out the right way to access the message body of the Brokered Message. I wasn’t able to simply pull it out a String value, so I went with a Stream instead. Here’s the complete code block:

Pretty simple. Receive the message, extract interesting values (like the “Label” and custom properties), and convert the BrokeredMessage body to a typed object that I could work with. When I ran this bit of code, I saw the values we set in Salesforce.com.

Summary

The Windows Azure Service Bus brokered messaging services provide a great way to connect distributed systems. The store-and-forward capabilities are key when linking systems that span clouds or link the cloud to an on-premises system. While Microsoft provides a whole host of platform-specific SDKs for interacting with the Service Bus, there are platforms that have to use the REST API instead. Hopefully this post gave you some insight into how to use this API to successfully publish to Service Bus Topics from virtually ANY software platform.

13 replies

Good stuff, thanks. But I keep getting a 401 – Invalid authorization token signature – when I send a message. The SWT token looks fine as far as I can tell, so I think it’s a problem with the way I’ve set up ACS. Any tips on that?

Is there also a way of doing this the other way round? So my Azure app adds a message to a Topic and a third-party customer who subscribes to that Topic using an HTTP endpoint (using a non-.NET system) receives this message?

Hi Richard
Thanks for your article. It was really helpful. I’m using the REST API to receive a message according to the above document in MSDN. However I’m getting “The specified HTTP verb (POST) is not valid”, HTTP 400 error when try to retrieve the message. Any idea why? I’m using SAS for authentication. The send message works fine.
Cheers
Manoj

You are using Azure service bus in the cloud. If I were to use on premise Service Bus for windows server and I have the port 9355 open and ssl enabled, how can I send a message to the queue from salesforce and also pick up from the queue? Do I use Shared Access Signature Authentication? Is that similar to adding ACS token to the HTTP Authorization header?

Nothing comes to mind. If the ports are open, I don’t see any obvious reason it wouldn’t work. That said, you’ll want to be careful about security and opening up a service like that to public internet traffic.