Showing posts with label BizTalk Server 2010 R2. Show all posts
Showing posts with label BizTalk Server 2010 R2. Show all posts

Saturday, October 20, 2012

BizTalk 2010 R2 CTP: Azure Service Bus Integration–Part 5 Sending messages to Service Bus Queues using Sessions

 

What are Service Bus Sessions?

Service Bus Sessions are actually a rather broad subject as there are a few different scenarios in which they can be used.  At its simplest description I consider Service Bus Sessions to be a way to relate messages together.  More specifically here are a few ways in which they can be used:

  • To address the Maximum message size constraint.  Service Bus Queues can support messages that have a size of 256 KB or smaller.  Using Sessions allow us to break a larger message down into smaller messages and then send them over the wire.  A consumer, or receiver, can then receive all of these message “chunks” and aggregate them together.
  • To support receiving a related set of messages in First In First Out (FIFO) fashion
  • Allows for affinity between a consumer and a Service Bus Queue in competing consumer scenarios.  Imagine having 3 consuming clients all trying to receive messages from the same Service Bus Queue.  Under normal circumstances you cannot be assured that one receiver will receive all messages within a message set.  One can expect the messages to be distributed amongst the clients as each consumer “competes” for the right to process a particular message.  In this scenario, once a receiver has started to process a message within a session, that consumer will process all messages within that session barring some sort of application crash.
  • In some scenarios, using a Service Bus Session allows for routing of messages.  Within a receiver, you can specify an explicit Session that you are interested in.  So in some ways a Session can be used almost like a filter.  I am not suggesting that this approach be used instead of Service Bus Topics/Subscriptions, but there may be a specific business requirement to do this.

Why are Service Bus Sessions important in BizTalk processing?

BizTalk deals with a variety of different messaging scenarios in many different industry verticals.  Supporting Service Bus Sessions is just another tool in the the BizTalk toolbox for supporting new requirements.  A scenario that I came up with is dispatching messages.  For instance if we wanted to load up a field worker with all of his orders, wouldn’t it be nice to have all of his orders sent to him as a batch?  As opposed to him receiving some of his orders only to receive more orders later on.  For instance he may have driven by one of his customers already because the messages that he receive were out of order and other field workers were also receiving their orders which delayed him in receiving all of his.

image

Putting it together – Modifying Service Bus Queue

A pre-requisite for this type of messaging scenario to work is configuring our Service Bus Queue to support Sessions.  This can be enabled in a couple different ways:

  • When creating a queue from within the Azure Portal, we can check the Enable sessions checkbox.

image

  • When using the QueueDescription class we can set the RequiresSession property to true.

NamespaceManager namespaceClient = new NamespaceManager(serviceUri, credentials);

if (!namespaceClient.QueueExists(Sender.QueueName))
        {

            QueueDescription queueDescription = new QueueDescription(Sender.QueueName)
            {
                RequiresSession = true
            };
            namespaceClient.CreateQueue(queueDescription);
          
        }

BizTalk Configuration

In order to keep the solution very simple, we will create:

  • Two Receive Ports
  • A Receive Location for each Receive Port.  The purpose of these Receive Locations is to simply inject messages into BizTalk so that we can set the SessionID property on the Send Ports.
  • 2 Send Ports
    • One for Mike
    • One for Joe
  • Each Send Port will have a filter for the corresponding Receive Port.  Within each Send Port we will configure a SessionID .

image

The other Send Port will use the same URI, however it will have a different SessionID value which will be Joe.

image

 

Service Bus Queue Client

The code below will make a connection to our session-ful Service Bus Queue and retrieve all messages that have a SessionId of Mike.

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 BrokeredMessageToBizTalk;

namespace RetrieveServiceBusSession
{
    class Receiver
    {

        const string QueueName = "<your_sessionful_queue>";
        static string ServiceNamespace = "<your_namespace>";
        static string IssuerName = "<your_issuerName>";
        static string IssuerKey = "<your_IssuerKey>";
        static void Main(string[] args)
        {
            TokenProvider credentials = TokenProvider.CreateSharedSecretTokenProvider(Receiver.IssuerName, Receiver.IssuerKey);
            Uri serviceUri = ServiceBusEnvironment.CreateServiceUri("sb", Receiver.ServiceNamespace, string.Empty);

            MessagingFactory factory = null;

            factory = MessagingFactory.Create(serviceUri, credentials);

            QueueClient sessionQueueClient = factory.CreateQueueClient(Receiver.QueueName);

            //Create sessionQueueClient and subscribe to SessionIDs that have a value of "Mike"
            MessageSession sessionReceiver = sessionQueueClient.AcceptMessageSession("Mike", TimeSpan.FromSeconds(60));
            BrokeredMessage receivedMessage;

                while ((receivedMessage = sessionReceiver.Receive(TimeSpan.FromSeconds(60))) != null)
                {
                    var data = receivedMessage.GetBody<PowerOut>(new DataContractSerializer(typeof(PowerOut)));
                    Console.WriteLine(String.Format("Customer Name: {0}", data.CustomerName));
                    Console.WriteLine("SessionID: {0}", receivedMessage.SessionId);
                    //remove message from Topic
                    receivedMessage.Complete();
                }
          
            Console.WriteLine("All received on this session...press enter to exit");
            Console.Read();
        }
    }
}

 

The code itself is very similar to that of some of my previous blog posts on ServiceBus integration.  The main difference is instantiating a MessionSession object.

MessageSession sessionReceiver = sessionQueueClient.AcceptMessageSession("Mike", TimeSpan.FromSeconds(60));

Within this line of we are indicating that we want to receive messages that belong to the Mike Session.  We can also provide a TimeSpan as an argument to specify the duration in which we want to receive from this Session.  Setting this value is more useful when we are looking for any available Session as it allows all messages within a Session to be processed before moving onto the next Session.

Testing

I have two sets of messages here.  Two of the messages will be routed through the Joe Send Port and subsequently the SessionID for these two messages will be set to Joe. The other two messages will be routed through the Mike Send Port and subsequently will have its SessionID property set to  Mike.

image

As mentioned previously, both Send Ports are configured to send to the same Service Bus Queue.  When we do run our client application, the expectation is that messages belonging to the Mike Session will be retrieved.  The Joe Messages will remain in the Queue until another receiver pulls them down or the the Time To Live (TTL) threshold has been exceeded.

When we start our Consumer application we do discover that the “Mike” messages are processed.

image

So what happened to the other messages?

The “Joe” messages are still in our Queue.  If we navigate to our Windows Azure Portal, we will discover that our Queue Length is set to 2.

image

So how do we get these messages out?

We have a couple options, we can create another MessageSession instance and retrieve all Messages belonging to the Mike Session or we can not specify a Session and our client will look for the next available Session which in this case will be the Mike Session.

Let’s go with the second option and retrieve the next available session.  In order to do so we need to change the following line of code from

  MessageSession sessionReceiver = sessionQueueClient.AcceptMessageSession("Mike", TimeSpan.FromSeconds(60));

to

  MessageSession sessionReceiver = sessionQueueClient.AcceptMessageSession(TimeSpan.FromSeconds(60));

We essentially are no longer specifying a specific Session that we are interested in and are now interested in any Session.

I will now process another 4 files; 2 will belong to the Joe Session and 2 will belong to the Mike Session.  What we expect to happen is that all 4 Joe messages will be processed since it is the next available Session.

image

So this proves that we have In Order Delivery occurring at the Session level.  Initially our Mike Session was processed which left our Joe messages outstanding.  We then loaded 4 more messages to the Queue and since the Joe messages were first in, they were processed first.  Our remaining 2 messages that now belong to Mike can be retrieved by starting up our Client Application once again.

image

Note:

Within my BizTalk Send Ports I statically configured my SessionID.  This isn’t very practical in the “Real World” but it was easy to demonstrate for the purpose of this blog post.  Much like other BizTalk context properties the SessionID property is available and can be set dynamically within an Orchestration Message Assignment shape or a Pipeline Component.

image

Conclusion

Overall I found this functionality pretty neat. I do think that it is another capability that we can leverage to support more granular control over message processing.  I do like the opportunity to group messages together and treat them as a batch.  This also works when dealing with message size limitations as we can stich a bunch of smaller messages together that collective make up a large message.

Tuesday, October 2, 2012

BizTalk 2010 R2 CTP: Azure Service Bus Integration–Part 4 Sending Messages to Service Bus Topics

 

Back again with Part 4 in this series.  This time around we are going use BizTalk to send a message to an Azure Service Bus Topic using the new SB-Messaging Adapter.

What is the difference between a Service Bus Queue and Topic?

Conceptually they are very similar in the sense that they both provide a durable message store within Azure where Publishers can publish messages and Consumers can consume messages.  Queues store messages in a First In First Out (FIFO) manner and provide a competing consumer experience.  What this means is that if we have two queue clients that are polling the same queue then only one client will receive a copy of any given message.

Topics provide some additional features that really support a Publish/Subscribe (Pub/Sub) architecture.  Topics allow for multiple clients to subscribe to the same Topic through subscriptions.  Subscriptions also support SQL92 expressions and allow a consumer to filter messages out based upon BrokeredMessage Properties.

Scenario

In Part 3 I  discussed how our Work Order Management system can notify our Major Account System when an Estimated Time of Restore is available.  This allows Major Account Representatives the ability to reach out to customers to share the good/bad news about when their power will be restored.

We are going to build upon this scenario but instead of sending all messages to a Queue we are going to send it to a Azure Service Bus Topic instead.  Due to the , fictional, growth of our company there are now two distinct groups responsible for Major accounts.  One for the city of Edmonton and another for the city of Calgary. (Both of these cities exist within Alberta, Canada)  Each queue Subscription client will now subscribe to events for their city.  BizTalk will however just send messages to one Topic and let the Service Bus work out which message needs to be delivered to each client.

Modifying Client Application(s)

Calgary Application

  • Once again we are going to leverage the work that we have done in previous posts(In this case Part 3).  The first thing we will do is rename our previous C# Console project from BrokeredMessageFromBizTalk to BrokeredMessageFromBizTalkCalgary.

image

  • Next we will modify the namespace for the Program.cs file so that it reflects the name of the project (BrokeredMessageFromBizTalkCalgary).  Note we will leave the namespace of our EstimatedTimeToRestore.cs as is.
  • Below is the entire code listing for our Calgary Client.  Within this code we will use our connectivity parameters to establish a connection.  Once we have a connection we will see if the Calgary subscription currently exists.  If it does not, we will create it.  We will also create it and add a SQLFilter.  This particular filter is interested in messages where the Address Brokered Message Property equals “Calgary”.

using System.IO;
using System.Runtime.Serialization;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;
using BrokeredMessageFromBizTalk;

 

namespace BrokeredMessageFromBizTalkCalgary
{
    class Receiver
    {
        const string TopicName = "<your_topic>";
        static string ServiceNamespace = "<your_namespace>";
        static string IssuerName = "<your_owner>";
        static string IssuerKey = "<your_key>";
        static string connectionString = String.Format("Endpoint=sb://{0}.servicebus.windows.net/;SharedSecretIssuer={1};SharedSecretValue={2}",
             ServiceNamespace, IssuerName, IssuerKey); 

        static void Main(string[] args)
        {
           
            TokenProvider tokenProvider = TokenProvider.CreateSharedSecretTokenProvider(
                Receiver.IssuerName, Receiver.IssuerKey);
            Uri uri = ServiceBusEnvironment.CreateServiceUri("sb", Receiver.ServiceNamespace, string.Empty);
            MessagingFactory messagingFactory = MessagingFactory.Create(uri, tokenProvider);

 

            // Create a "Calgary" SQLFilter
           SqlFilter calgaryFilter = new SqlFilter("Address = 'Calgary'");

            //Check to see if Calgary Subscription exists, if it does not then create it
            NamespaceManager namespaceManager = NamespaceManager.CreateFromConnectionString(Receiver.connectionString);
            if (!namespaceManager.SubscriptionExists(Receiver.TopicName, "Calgary"))
            {

                //Create Calgary Subscription with our calgaryFilter
                namespaceManager.CreateSubscription(Receiver.TopicName, "Calgary", calgaryFilter);

            }
            //Create Subscription Client using Peek/Lock Mode
            SubscriptionClient sc = messagingFactory.CreateSubscriptionClient(Receiver.TopicName , "Calgary", ReceiveMode.PeekLock);
            BrokeredMessage bm;
            while ((bm = sc.Receive(new TimeSpan(hours: 0, minutes: 0, seconds: 20))) != null)
            {
                var data = bm.GetBody<EstimatedTimeToRestore>(new DataContractSerializer(typeof(EstimatedTimeToRestore)));
                Console.WriteLine(String.Format("An estimated time of restore {0} has been received for {1}", data.RestoreTime, data.CustomerName));
                Console.WriteLine("Brokered Message Property Address has a value of {0}", bm.Properties["Address"]);
                //Remove message from Topic
                bm.Complete();
            }

        }
    }
}

Edmonton Application

  • Within our existing Visual Studio solution we are going to add another C# Console Application called BrokeredMessageFromBizTalkEdmonton.

image

  • Within this application we will create a reference to our “Calgary” project.  We need to do this so that we have access to the EstimatedTimeToRestore class. This is accomplished by including the following statement:
    • using BrokeredMessageFromBizTalk;
  • Otherwise we can simply copy and past the “Calgary” Program.cs code and adapt it for our Edmonton scenario.The main areas that we need to focus on are creating a unique Edmonton Subscription and ensuring that our Edmonton filter matches Edmonton messages and not Calgary messages.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Runtime.Serialization;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;
using BrokeredMessageFromBizTalk;

 

namespace BrokeredMessageFromBizTalkEdmonton
{
    class Receiver
    {
        const string TopicName = "<your_topic>";
        static string ServiceNamespace = "<your_namespace>";
        static string IssuerName = "<your_owner>";
        static string IssuerKey = "<your_key>";
        static string connectionString = String.Format("Endpoint=sb://{0}.servicebus.windows.net/;SharedSecretIssuer={1};SharedSecretValue={2}",
             ServiceNamespace, IssuerName, IssuerKey);

        static void Main(string[] args)
        {

            TokenProvider tokenProvider = TokenProvider.CreateSharedSecretTokenProvider(
                Receiver.IssuerName, Receiver.IssuerKey);
            Uri uri = ServiceBusEnvironment.CreateServiceUri("sb", Receiver.ServiceNamespace, string.Empty);
            MessagingFactory messagingFactory = MessagingFactory.Create(uri, tokenProvider);

 

            // Create a "Edmonton" filtered subscription
            SqlFilter edmontonFilter = new SqlFilter("Address = 'Edmonton'");

            //Create NamespaceManager object and see if Edmonton Subscription exists for our Topic
            NamespaceManager namespaceManager = NamespaceManager.CreateFromConnectionString(Receiver.connectionString);
            if (!namespaceManager.SubscriptionExists(Receiver.TopicName, "Edmonton"))
            {
                //If the Subscription does not exist, create it
                namespaceManager.CreateSubscription(Receiver.TopicName, "Edmonton", edmontonFilter);

            }

            //Create Subscription client and use Peek/Lock mechanism for delivery
            SubscriptionClient sc = messagingFactory.CreateSubscriptionClient(Receiver.TopicName, "Edmonton", ReceiveMode.PeekLock);
            BrokeredMessage bm;
            while ((bm = sc.Receive(new TimeSpan(hours: 0, minutes: 0, seconds: 20))) != null)
            {
                var data = bm.GetBody<EstimatedTimeToRestore>(new DataContractSerializer(typeof(EstimatedTimeToRestore)));
                Console.WriteLine(String.Format("An estimated time of restore {0} has been received for {1}", data.RestoreTime, data.CustomerName));
                Console.WriteLine("Brokered Message Property Address has a value of {0}", bm.Properties["Address"]);
                //remove message from Topic
                bm.Complete();
            }

        }
    }
}

Creating Topic

Much like we did in the previous blog post where we created a Service Bus Queue, we can also create a Service Bus Topic from the http://windowsazure.com portal

  • To create a new Topic simply click on the New Topic button.

image

  • Provide a Topic Name.  For the purpose of this post I am using PowerRestoreTopic.  We can then leave the default settings as is.

image

Note: We can also create Topics via code by using the NamespaceManager class much like we did for Subscriptions.  I decided to use the portal just to demonstrate that we have a few options when creating Service Bus artifacts.

Modifying BizTalk Solution

Once again we are going to keep the BizTalk Solution changes to a minimum and will continue to use a Messaging Only scenario.

  • The first change that we are going to make is to our BrokeredMessagePropertySchema by adding our Address field.  Note if you recall from our C# projects that we created SQLFilters based upon the Address property being equal to either Calgary or Edmonton(depending upon the application).  By adding this property to our PropertySchema we can now promote this value in our XSD.image
  • Next we will modify the ETRfile.xsd and promote the Address field.  We will then map this field to the property we just created in our PropertySchema.

image

  • We can now deploy our BizTalk Application and bounce any related Host Instances.
  • While inside the BizTalk Administration Console, we need to modify our SB-Messaging Send Port called SendEstimatedTimeToRestoreToAzure.  Previously we were using this Send Port to send messages to a Service Bus Queue.  We will now be sending messages to a Topic which uses the same convention within the URI.  Instead of including our Queue Name in the URI we need to specify the Topic Name.  In our scenario I am going to specify PowerRestoreTopic.

image

  • Our Authentication tab remains unchanged. We will continue to use the same Issuer Name and Issuer Key as in our previous example.

image

  • Finally, we need to click on the Properties tab so that we can enable our custom Brokered Message Properties. To enable these properties we need to provide the namespace for our Property Schema that we previously modified.  As you may recall, we added a property called Address that we will use to route messages within our Azure Topic Subscription.

image

Testing our Solution

  • We are going to leverage the Receive Location that we created in Part 3 of this blog series.  Our solution is expecting messages that conform to the ETRfile.xsd schema.  Below, I have included two sample files.  One contains an Address that belongs in Edmonton and the other one has an Address that belongs in Calgary.  We will drop both of these files within the same receive location and they will be sent to the same PowerRestoreTopic.

image

  • Once the messages have been sent we will launch our two client applications (Calgary and Edmonton).  The expectation is that the Calgary application will retrieve the Calgary Message and the Edmonton application will retrieve the Edmonton Message.
  • As expected, our Edmonton client retrieved the Edmonton message and the Calgary client retrieved the Calgary message.

image

Conclusion

In this post we used existing BizTalk skills to send typed messages to an Azure Service Bus Topic.  We promoted a property within BizTalk that was converted to a Brokered Message Property that can be used within Subscription Filters in order to route messages between different consumers.

Once again the experience is very seamless. I really do like the .Net API for Service Bus.  I think it is intuitive and is very logical.  As simple as it is to use this API it is hard to imagine anything being much simpler. But it has been done. The BizTalk team has made interfacing with the Service Bus even easier than using the API.  From a BizTalk perspective the Service Bus is just another endpoint and requires some additional configuration.  I do find that this aligns with some of the early goals of BizTalk.

Saturday, September 15, 2012

BizTalk 2010 R2 CTP: Azure Service Bus Integration–Part 2 Brokered Message Properties


In my last post I provided a walkthrough that allows you to send a typed Brokered Message from a Console application to a Service Bus Queue,  have BizTalk retrieve this message and then write it to disk.  I am now going to expand upon that scenario and describe how we can leverage Brokered Message properties within BizTalk to route the message to different locations using BizTalk’s promoted properties.
What is a Brokered Message Property?
In many ways a Brokered Message Property is very similar to a Promoted Property within BizTalk.  These properties can be used to capture meta-data outside the body of the message.  We can then use these properties for routing within the Service Bus when delivering messages to different Service Bus Topics. It is important to note that we don’t have to use these properties for just routing.  We can also use them as part of business logic in downstream systems if we so desire.
Why is this important for BizTalk?
As I mentioned in the previous paragraph we can use Promoted Properties within BizTalk to route messages and we can also use it to capture meta data if we want (although you should look at distinguished fields instead if that is your intent).  In the BizTalk 2010 R2 CTP there is now support for transitioning Brokered Messages Properties from Service Bus Queue clients to BizTalk promoted properties.  BizTalk applications themselves do not understand a Brokered Message property, but BizTalk will convert these Brokered Message Properties into BizTalk Promoted Properties where they can be used to route messages.
Scenario Walkthrough
In my previous blog post I used a Power Outage scenario.  My client application would pass along customer information to a Service Bus Queue and then BizTalk would pick that message up and write it to disk.  In a ‘real life’ scenario I would have routed that message to a Customer Information System (CIS) or a Work Order Management (WOM) system so that a field operations team could address the power outage.  In this walkthrough I am going to build upon that scenario.  This difference this time around is that I am going to introduce a Brokered Message Property called isCriticalCustomer.  I hate to publicly admit it but not all customers are treated equally when it comes to delivering power.  An example of a Critical Customer may be a hospital.  It is more important for a Power company to get their power on before yours.  A patient’s respirator is more important that someone watching the latest American Idol episode. 
Within my Console application this isCriticalCustomer property will be set as a Brokered Message Property.  When this message is retrieved by BizTalk this property will be converted into a Promoted Property and BizTalk will then use that Promoted Property to route the message to a different destination.
Note: A person with a lot of Service Bus experience may say why don’t you just use Topics?  I could have a Topic for regular customers and a Topic for Critical Customers.  This is also a valid pattern but for the purposes of demonstrating BizTalk capabilities I will leave the routing to BizTalk.
Modifying Queue Client
I am not going to display all of the code required for this client to work.  I am going to be adopting the code I listed in my previous post.  So please refer back to that post for the starting point.  I will include any areas within this post where I have made changes.
In the code below I am going to create and send two messages.  In red you will discover that I am setting a Brokered Message Property called isCriticalCustomer. In the first message I am indicating that this is not a critical customer (aka a regular customer).  In the second message I am saying that it will be a Critical Customer.  Once we get to the BizTalk section you will see how we can use this property to route the message within BizTalk.
              //Create new instance of PowerOut object
              //This customer will not be a Critical Customer
              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)));
              message.Properties.Add("isCriticalCustomer", false);
              myQueueClient.Send(message);

              //Create new instance of PowerOut object
              //This customer will  be a Critical Customer
              po = new PowerOut();
              po.CustomerName = "Calgary General Hospital";
              po.PhoneNumber = "403-123-4567";
              po.Address = "1 Red Mile Drive";

              message = new BrokeredMessage(po, new DataContractSerializer(typeof(PowerOut)));
              message.Properties.Add("isCriticalCustomer", true);
              myQueueClient.Send(message);

BizTalk Modifications
You may recall from my previous post that my BizTalk solution was very simple as I only had a schema that represented this Customer message being sent from my client application.  So in order to support our new scenario I only need to add one more artifact to my solution and that is a Property Schema.  The reason why I need to add this schema is that I need an artifact within my BizTalk application to “hold” these values as they are being populated when BizTalk receives the message.  This is no different than when you want take a value from one of your “regular” BizTalk schemas and turn it into a Promoted Property.
Within our BizTalk solution we need to do the following:
  • Add a PropertySchema to our project.  Once it has been added there will be a default property that we will rename to isCriticalCustomer and change the data type to be a boolean.
image
  • We now need to re-deploy our application.
  • Open up the ReceiveBMfromServiceBus Receive Location, click the Configure button.  Now click on the Properties tab.  Within this tab we are going to specify our namespace for our PropertySchema.  If you are unsure where you can get this namespace from, look in the image above and notice the value of the targetNamespace matches the value that I have put in this text box.  We also need to ensure that the Promote Brokered Message Properties checkbox is checked on.
image
  • Next we are going to remove our previous Send Port and create two new Send Ports.  One send port will be for Regular Customers and the other will be created for Critical Customers. 
  • Below is the Send Port for regular customers.  Notice that a separate sub-folder called RegularCustomers has been created for these files.
image
  • Click on the Filters label and then add a new Property.  You will notice that within the dropdown list you will find the property that we created in our PropertySchema called isCriticalCustomer.  We need to select this value and then set the value to false.
image
Note: When you pull down the Property drop down you will also discover the Out of the Box Service Bus Brokered Message properties.  These properties are out of the scope of this post but it is something that may be beneficial down the road. 
  • We now want to perform similar actions to our other send Port that will be use to send our CriticalCustomer messages.
image
  • Once again we are going to click on the Filters label.  We will use the isCriticalCustomer property again but this time we will set the Value to true.
image
  • We can now bounce any affected Host Instance(s) and start our application.
Testing our Application
As you my recall, we modified our Console application so that it will send two messages to the same PowerOutage queue.  In the first message, we set the isCriticalCustomer Brokered Message property to false.  In the second message, for the hospital, we set it to true.  The end result is that we should receive one message in our Regular Customers folder and one in our Critical Customers folder.
  • As promised when I run the application I will find one message in each corresponding folder:
image
  • If I open the files I will discover that the right message was delivered to the correct folder:
image
Conclusion
Overall it is a pretty slick, and seamless, experience.  I think the BizTalk product team has done a great job in bridging the Service Bus Brokered Messaging Property with BizTalk’s Promoted Property.  In my opinion, the Azure Service Bus and BizTalk Server really complement each other by providing robust Hybrid solutions.  It is great to see smooth interoperability between these two technology sets.
This concludes this blog post.  I am not done yet with this series as I have still just scratched the surface.  I plan on writing more about my experience with Sending messages to Service Bus Queues/Topics from BizTalk and perhaps dive into some different messaging patterns.

Friday, September 14, 2012

BizTalk 2010 R2 CTP: Azure Service Bus Integration–Part 1

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

  • Launch Visual Studio 2012 and create a C# Console application.  I called my application BrokeredMessageToBizTalk

image

  • Next I will use the Nuget Package manager and installing the Windows Azure Service Bus package.  You can access Nuget by clicking the following within Visual Studio: Tools - Library Package Manager - Manage Nuget Packages for Solution.

image

  • Since I want deal with typed messages I am going to create a class called PowerOut.  Since I work in the Power Industry I will over-simplify a use case that involves a customer whose power is out.  They will send a message from a client application (it could be a web page, mobile phone app etc) to a Service Bus Queue.

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;
       
    }
}

  • Within our Program.cs file we want to include the following code:

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:

  • The first one deals with the DataContractSerializer as seen below.        

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.”

  • The next deals with the few lines that have been commented out.  Since I want to use typed messages within BizTalk, I can generate a sample XML message using the code below.  This will allow me to generate a BizTalk schema using tools provided within Visual Studio.

    //using (FileStream writer = new FileStream("c:/temp/file.xml",FileMode.Create, FileAccess.Write))
                //{
                //    DataContractSerializer ser = new DataContractSerializer(typeof(PowerOut));
                //    ser.WriteObject(writer, po);
                //}

*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.

  • We can now create a new BizTalk application. I have called mine PowerOutage and I have also added a Strong Name Key called PowerOutage.snk.

image

  • Next I want to create a new Schema based upon the sample file that we previously generated.  I can create this new schema by right mouse clicking on BizTalk project (PowerOutage) - Add - Add Generated Items.
  • When prompted, click on the Generate Schemas label and then click the Add button.

image

  • Select Well-Formed XML from the Document type dropdown and then we need to provide the name of our sample file.  Click OK to proceed.

image

  • We will now have a schema added to our solution that represents our PowerOutage class.

image

  • Deploy our BizTalk Application
  • When we launch the BizTalk Admin Console we will discover our PowerOutage application.
  • We now need to create a Receive Port and corresponding Receive Location.  In this situation we are going to use the SB-Messaging Adapter.

image

  • When we click the Configure button we will have a few more properties to fill out including our URL.  Our URL is going to include our Namespace (highlighted in Green) and our QueueName (highlighted in Orange)

image

  • Next we need to click on the Authentication tab.  Within this tab we will provide our Namespace as it relates to the Access Control Servers (ACS), an our Issuer Name and Key.

image

  • The Properties tab is not used in this example.  I will further examine it in a later post.
  • With our Receive Port and Receive Location created we can no move on to our Send Port.  For this example we are simply going to create a File Drop where we can write out the file that we have received from the Service Bus Queue.

image

  • Since we do not have any Orchestrations we do need to wire up a subscription for our inbound message.  In order to do this we will simply create a “Send Port Subscription” by setting filter.

image

  • We can now Start our BizTalk application and bounce our Host Instance(if applicable)

Testing our scenario

  • Next, launch our Console Application and we will discover that our message has been sent to our Queue.

image

  • If we check the File Drop that was specified in our Send Port we should see a newly created file.  When we open this file we should recognize the content that we populated in our Console application.  Since we now have typed data within BizTalk it will be easy to transform it into other message types so that we can exchange data with other systems such as Line of Business (LOB) systems.

image

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.

Thursday, December 8, 2011

BizTalk Server 2010 R2 Announced

In a previous post, I discussed Microsoft’s integration road map particularly related to Microsoft BizTalk Server.  The foundation of that post was based upon Tony Meleg’s presentation from the World Partner Conference.  The good news is that today, Microsoft has given us a glimpse into what is to come with respect to BizTalk Server.  Previously, Tony cautioned us that Microsoft will continue to support BizTalk and will introduce incremental changes to the platform.  Where as most of the innovation will occur in the Azure AppFabric space.

The next version of BizTalk Server is currently called BizTalk Server 2010 R2.  I suspect they are calling this an “R2” release since it is an evolutionary release that particularly focuses on platform alignment with Windows Server 8, SQL Server 12 and Visual Studio 11.  For those of you who do follow the BizTalk scene closely you may recall that BizTalk Server 2010 was originally called BizTalk Server 2009 R2 when it was in beta.  It was renamed to BizTalk Server 2010 prior to RTM.  So who knows if the BizTalk 2010 R2 name will stick but for now that is the name we will go with.

In addition to the platform alignment that I have already mentioned, we can look forward to some new features in the areas of:

  • Adapter connectivity to new data sources including IBM Informix V11 and IBM IMS/DB V11
  • Updates to industry schemas like HIPPA, HL7, SWIFT and SWIFTNet
  • Improved Performance and Scalability
  • Tighter integration with the Azure Service Bus
  • Adjustment to licensing geared towards cloud hosting

Of the features mentioned, I certainly will not complain about improved performance and am happy to see tighter integration with Azure AppFabric.  I really hope that they introduce a smoother way of integrating with Azure AppFabric Queues and Subscriptions.

I am a little disappointed that there was no mention of fully supported REST endpoints, but it is early so I am hoping that Microsoft will surprise us with that feature.

I have only touched on some of the new features that will be available.  You can find the complete post from Microsoft here.