Back in June 2012, I had the opportunity to attend TechEd North America. At this event the BizTalk team gave us a glimpse into the next version of BizTalk and went over the Product Road map. You can read more about this Roadmap session here.
One of the areas that Microsoft wanted to address was better/seamless integration with Azure and more specifically with Service Bus Queues and Topics. The BizTalk team released a feature pack back in October 2010 that better enabled BizTalk to leverage the Service Bus Relay capabilities. This feature pack does work well but did not allow for connectivity to Service Bus Queues and Topics since they weren’t even available back then.
In the fall of 2011, the talented Paolo Salvatori wrote a very detailed article on how you can integrate BizTalk 2010 with Service Bus Queues and Topics. While Paolo’s solution does work it does require some additional effort and some people may be a little overwhelmed by the solution. But I do give credit to Microsoft and Paolo for coming up with a solution considering BizTalk 2010 was released much before Service Bus Queues and Topics were commercially available. Their solution just validates why BizTalk leveraging WCF is a good idea. When investments are made to WCF, BizTalk usually benefits. All in all, it was a good stop-gap for anyone desperate to integration BizTalk 2010 with Azure.
Fast forward to July 2012 when Microsoft released this BizTalk 2010 R2 CTP. Microsoft has delivered on making integration with Service Bus Queues and Topics very simple. The BizTalk team recently released a blog post which provides an overview of some of these new features. I thought it would be beneficial to provide a walk through for anyone interested in more details than what Microsoft included in that post.
Scenario
The scenario that we are about to explore includes a client application that will publish a typed Brokered message from a Console application to a Service Bus Queue. BizTalk will then use the new SB-Messaging adapter to retrieve the message and simply write it to the file system. As an experienced BizTalk guy, I like strongly typed messages and I am not afraid to admit it. So as part of this solution I am going to include a strongly typed BizTalk schema that I am going to deploy. For this walkthrough I am not going to transform this message but for anyone familiar with BizTalk they will be able to take this solution adapt it for their needs.
Client Application
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;
namespace BrokeredMessageToBizTalk{ public class PowerOut { public string CustomerName; public string PhoneNumber; public string Address; }}
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using Microsoft.ServiceBus;using Microsoft.ServiceBus.Messaging;using System.Runtime.Serialization;using System.IO;
namespace BrokeredMessageToBizTalk{ class Sender { const string QueueName = "PowerOutageQueue"; static string ServiceNamespace = "YOUR_NAMESPACE"; static string IssuerName ="owner"; static string IssuerKey = "YOUR_KEY”;
static void Main(string[] args) { //***************************************************************************************************** // Get Credentials //***************************************************************************************************** TokenProvider credentials = TokenProvider.CreateSharedSecretTokenProvider(Sender.IssuerName, Sender.IssuerKey); Uri serviceUri = ServiceBusEnvironment.CreateServiceUri("sb", Sender.ServiceNamespace, string.Empty);
MessagingFactory factory = null;
try { //*************************************************************************************************** // Management Operations //*************************************************************************************************** NamespaceManager namespaceClient = new NamespaceManager(serviceUri, credentials); if (namespaceClient == null) { Console.WriteLine("\nUnexpected Error: NamespaceManager is NULL"); return; }
Console.WriteLine("\nCreating Queue '{0}'...", Sender.QueueName);
// Delete if exists if (namespaceClient.QueueExists(Sender.QueueName)) { namespaceClient.DeleteQueue(Sender.QueueName); }
namespaceClient.CreateQueue(Sender.QueueName);
//*************************************************************************************************** // Runtime Operations //*************************************************************************************************** factory = MessagingFactory.Create(serviceUri, credentials);
QueueClient myQueueClient = factory.CreateQueueClient(Sender.QueueName);
//*************************************************************************************************** // Sending messages to a Queue //***************************************************************************************************
Console.WriteLine("\nSending messages to Queue...");
//Create new instance of PowerOut object PowerOut po = new PowerOut(); po.CustomerName = "Stephen Harper"; po.PhoneNumber = "613-123-4567"; po.Address = "24 Sussex Drive";
BrokeredMessage message = new BrokeredMessage(po, new DataContractSerializer(typeof(PowerOut))); myQueueClient.Send(message);
//Uncomment this code if you want to write a sample file to disk
//using (FileStream writer = new FileStream("c:/temp/file.xml",FileMode.Create, FileAccess.Write)) //{ // DataContractSerializer ser = new DataContractSerializer(typeof(PowerOut)); // ser.WriteObject(writer, po); //}
Console.WriteLine("\nAfter running the entire sample, press ENTER to exit."); Console.ReadLine(); } catch (Exception e) { Console.WriteLine("Unexpected exception {0}", e.ToString()); throw; } finally { // Closing factory close all entities created from the factory. if(factory != null) factory.Close(); } }
}}
Of the code above I want to highlight a couple different lines:
BrokeredMessage message = new BrokeredMessage(po, new DataContractSerializer(typeof(PowerOut)));
If you do not use a DataContractSerializer you can expect undesirable results when BizTalk retrieves the message from the queue. As mentioned in the recent BizTalk team blog post: “Brokered Message .NET API uses Binary encoding. To avoid this issue, you will need to use Text by explicitly provide your own serializer, instead of the default serializer.”
*As a side note – wouldn’t it be nice if BizTalk supported native .Net Classes (from a messaging perspective) - hint, hint *
BizTalk Application
We can now create a BizTalk application. Since we are using the new BizTalk 2010 R2 CTP we can also use the latest version of Visual Studio 2012. As I mentioned earlier I want to process typed messages so our BizTalk solution will be very simple. It will only include a Schema. We will deploy this message to BizTalk so that when an instance of this message is published to the MessageBox that we will have a known schema deployed that will match this message type.
Testing our scenario
Conclusion
Now that wasn’t so bad was it? For experienced BizTalk people this process should be a breeze. The only area that initially hung me up was the DataContractSerialzer that is specified in our console application. The other good news is that we are just scratching the surface in this blog post. Look for more posts related to BizTalk and Service Bus integration using the new BizTalk 2010 R2 CTP.