Tuesday, January 29, 2013

Service Bus Notification Hubs–Part 3 My Solution Overview

In my previous post I introduced the concept of Customer Power Outages and, at a high level, introduced  how Outage Management Systems work.  The key take away from that blog post is that important, event driven data is passing through BizTalk and there is an opportunity use this information to provide better Customer and Employee engagement through Service Bus Notification Hubs.  Think about, conceptually how different is it from BAM Alerts?  The idea behind BAM Alerts is data is moving through BizTalk, Tracking Profiles pick it up and send it to subscribers who are interested in it via email (oversimplified…I know).  The process of collecting this information for Notification Hubs is different but now we can reach an audience that we may never had access to before.

In this post we will take a closer look into how we could actually implement a Power Outage system and include notifications to both customers and employees by using Service Bus Notification Hubs. 

Note: In some areas I have over-simplified the process in order to focus on some of the key technical aspects of Notification Hubs.

In the diagram below I have laid out the series of events that make up the architecture:

  1. Customer determines their power is out and launches the Windows 8 application on their SurfaceRT tablet in order to report their Power Outage.  The mobile client registers itself for Toast Notifications.  In this case the Customer is only interested in events pertaining to its SiteID (Customer ID) so a Tag of 0090123456789 is included as part of the Toast Notification registration. Next, the customer clicks the submit button to notify the power company of their outage. The message is sent to a Customer Outage Service Bus Queue.
  2. BizTalk is using the new SB-Messaging Adapter to connect to this Service Bus Queue and pulls down the Customer message.
  3. BizTalk will perform a transformation and send the message to the Work Order Create Queue.  Once again, the new SB-Messaging Adapter will be used when communicating with the Service Bus.
  4. Once the Work Order message has been sent to the Service Bus Work Order Create Queue, BizTalk will send a message using the Service Bus .Net Preview SDK to the Service Bus Notification Hub.  Included in this message is the tag “Airdrie” which happens to be the City were the customer, who submitted the trouble ticket, lives.  It also happens to be the area that the Power Line Technician (PLT)  is responsible for.  Only he will receive this toast notification because he is the only employee that is registered for this tag. 
  5. The PLT will now receive a Toast Notification indicating that he has a new Work Order that he needs to complete.
  6. When the PLT clicks on the Toast Notification, the PLT App is launched and he can click the Retrieve Next Order button to download the order. 
  7. Once the PLT has had a chance to assess the situation he can provide an Estimated Time of Restore (ETR) and send this information to a Work Order Update Queue that exists in the Service Bus.
  8. BizTalk will pickup this message from the Work Order Update Queue.
  9. The updated Work Order information will now be sent to the Outage Management System using the FILE Adapter.
  10. BizTalk will use the information contained in the Work Order Update message to push a Notification message up to the Service Bus Notification Hub.  As part of this message, a tag for the customer’s Site ID is populated.  In this case it is 0090123456789 which happens to be the same Site ID as the customer who initially logged the Power Outage ticket.
  11. The customer will now receive a Toast Notification indicating their Estimated Time of Restore (ETR).
  12. Steps 7 – 11 will be repeated once the PLT has restored power and a notification can be sent to the customer, when the work order has been closed in the Outage Management System, indicating that their power has been restored and give them a duration of the outage.

image

Conclusion
Hopefully this post has described in more detail how Service Bus Notifications can improve customer and employee engagement.  I promise that the next post in the series will have some code.  I just felt that if I could build a story, it would provide some worthwhile context that truly demonstrates why this Notification Hub technology is important.

Sunday, January 27, 2013

Service Bus Notification Hubs–Part 2 Improving Customer Engagement

 

In my previous post I introduced Service Bus Notifications and explained why you may want to use it when sending Notifications to mobile devices.  In this post I want to explore its use in a corporate environment and how introducing this technology can improve customer engagement as well as employee engagement.

Use Case

Back in the Summer of 2012, I wrote a couple blog posts on BizTalk and SignalR.  The idea was that BizTalk could provide real time notifications to on premise users.  The notifications provided the current  state of particular events that were flowing through BizTalk. In this post there is a similar theme but this time we will extend the experience onto customers and mobile field workers.

The scenario that we are going dive into is a typical Customer Power Outage scenario.  We have all been there, we get home from work (or wherever) and discover that our power is out.  If you have never worked in the utility sector, you probably have no idea what goes on behind the scenes.  I have worked in the sector for close to 7 years and I can assure you that these scenarios are taken seriously.  At least the places that I have worked have treated them that way.

Each utility will vary greatly when it comes to dealing with Power Outage scenarios.  Some utilities will have very sophisticated SCADA and Outage Management Systems (OMS) others may simply rely upon customers calling their utility to notify them that their power is out.  Sometimes the power outage may be widespread other times it may be only you.  Much like any other company, or industry, the utility companies are looking for ways to provide Self Service capabilities to customers.  Just like you can check your bank account online, why can’t you see your power consumption or inform your power company that your power is off via a mobile application?

In the diagram below, you will see many different key data flows:

  • Notifying the OMS system of devices that have failed via SCADA interfaces
  • Customers calling and talking to a Contact Centre agent.  The Contact Centre agent in turn will leverage a Customer Information System (CIS) to log a ticket.
  • Customers who use an Integrated Voice Recognition (IVR) service when live agents are currently servicing other customers
  • Self Service inputs such as mobile applications and  Websites

If an organization is using a Middleware product, such as BizTalk to bridge all of these different inputs with the Outage Management System then BizTalk has access to a lot of relevant, event driven information.

Another interesting fact is when orders are created and dispatched to Field workers aka Power Line Technicians (PLTS) information is often passed back to an ERP system.  This information is often used for Financial or Reporting purposes.  For instance if there is a power outage, then resources will be used to address the power outage.  This will include Employee time and materials such as replacement parts and equipment used such as vehicles to fix the problem. This information is usually passed back once the outage has been completed or maybe as the outage is being resolved in the form of updates. Since ERP systems are usually not part of Outage Management Systems, this information needs to be moved via  Middleware platform such as BizTalk.

image

Hopefully it has become apparent that BizTalk has access to a lot of important event driven information that is passing through it that may be of interest to other parties such as customers.  For instance if your power was out, would you like to know when the Estimated Time to Restore (ETR) is?  Or if you were the owner of a small business, who relied upon power to run its business, would you like to be notified the minute the outage is over? I am pretty sure you would.  The interesting part is that any decent Outage Management System will have this information.  The problem is that utilities just do not have the people resources to start calling people to let them know. Here is where the opportunity lies to use Service Bus Notification Hubs.

The Solution

Enter Service Bus Notification Hubs.  I think this is a great complimentary technology to BizTalk.  In this case BizTalk is performing traditional On-Premise integration and can easily hook into a progressive service like Service Bus Notification Hubs to deliver better customer engagement with very little effort.

I have built out a fairly comprehensive solution that dives deeper into this problem.  I will be breaking down this problem into a series of different posts.  But, as a bit of a teaser you can see part of the solution in the screen shot below.

 

Toast

Service Bus Notification Hubs – Part 1

 

This past week the Service Bus team at Microsoft rolled out a preview of their latest offering called Service Bus Notification Hubs.  For those of those of you who keep an eye open for all things Middleware from Microsoft, you may recognize the code name of the project: Iguazu.  You may  have even seen Iguazu presented by Clemens Vasters at one of the recent Microsoft conferences/summits.

What are Service Bus Notification Hubs?

So what are Service Bus Notification Hubs?  Probably the simplest way to explain it is an internet-scale Push Notification Service.  Push Notifications are nothing new.  The major mobile platforms all have them and you have inevitably used them if you use social media apps like Facebook, Twitter or even games.  These notifications are often called “Toast Notifications” in the sense that they pop up and inform you of some relevant event such as someone commenting on a post of yours or informing you that you have been mentioned on Twitter.

If they have been around for a while, why do I care about them now?

Just because Notification Services from Apple, Google and Microsoft have been around for a long time, doesn’t mean that it has been easy to use them.  Often times developers need to manage all of the subscriptions and channels within their own data stores. Developers were also required to deal with the nuances of the  different platforms and managing which subscriptions were running on a particular platform.  This results in a lot of fragmentation.  Finally, dealing with large scale has also been challenging for some organizations.  Imagine if you were a large media outlet with hundreds of thousands or millions of users.  Providing timely notifications to users of this magnitude becomes extremely important.  For example receiving a notification for a touchdown that happened in the 2nd Quarter when the game is already over is not a good user experience. Service Bus Notification Hubs can take care of this by delivering to a wide audience immediately.

Benefits of using Service Bus Notification Hubs

While I am relatively new to this technical domain(mobile notifications), I found building solutions off of Service Bus Notification Hubs was pretty straight forward.  I find it very compelling that I can choose to use Native Notifications that are specific to a respective platform or I can just use one of the many generic templates that ship and can address devices on multiple platforms.  Since the service is currently in “preview mode”, only Windows 8 and IOS notifications are supported but Microsoft is targeting Android and Windows Phone when the service becomes Generally Available.  Another key benefit, and perhaps this is why it is in the Service Bus family, is the service is true Pub-Sub.  I don’t have to worry about specific subscriptions.  I just have to throw the message at the Service Bus and let it figure out who is interested in it.  It could be 1 person/device or it could be 100 000.  It doesn’t matter to my Server code.  This features alone makes the service worth it.

What’s next?

There is quite a bit of content that is already available for this topic and I recommend checking out the following links:

Also stay tuned to this blog where I will be walking through a corporate scenario from the Energy sector where I will combine Service Bus Notification Hubs, BizTalk and Windows 8 Store Apps.

Saturday, January 5, 2013

MSDTC Adventures: 'System.EnterpriseServices.TransactionProxyException'

I was configuring a new Development environment that consisted of a BizTalk Application Server and a Remote SQL Server.  The BizTalk Installation went smoothly but the Configuration did not.  I tend to configure SSO service on its own as it can be problematic. There is no point in configuring the remaining databases until a person knows that the SSO database is created successfully.  Otherwise, there will be a lot of wasted key strokes.

In this particular case I was able to configure the SSODB but as soon as I would try to configure the Group and Runtime, the System.EnterpriseServices.Transaction Proxy exception started to surface.

If you perform a Google/Bing search for 'System.EnterpriseServices.TransactionProxyException' you will probably get quite a few results.  Most of the results will point you in the direction of a MSDTC not being enabled or configured correctly.

In my case MSDTC was configured correctly based upon Microsoft’s recommendations. I was a little puzzled at this point but in some of the support forums people were discussing the DTC Tester tool.  Having been through a lot of frustration and a few failed attempts at trying to configure the Group and Runtime features I figured I would give it a try.  I am glad I did.

The purpose of DTC Tester is to enlist a remote transaction against the Temp Database which is hosted in SQL Server.  If you are able to successfully enlist and commit this transaction then there is a very high probability that your BizTalk configuration (as it relates to MSDTC) will be successful.

The tool is available here.  Download it and run the self extracting executable.  At this point we will discover a ‘dtctester’ executable and an End User License Agreement.

image

The dtctester executable needs to be run from a command prompt but requires an ODBC connection is configured before we can run the tool.  The ODBC connection should be pointed at the Database Instance where we want our BizTalk Databases to be created.

ODBC connections can be created via the Control Panel and a System DSN will work.

image

From a command prompt we can now run the tool.  When I ran it for the first time I encountered errors (highlighted in red)

 

C:\Downloads>dtctester <ODBCConnectionName> <UserName> <Password>
Executed: dtctester
DSN:  <ODBCConnectionName>
User Name: <UserName>
Password: <Password>
tablename= #dtc7063
Creating Temp Table for Testing: #dtc7063
Warning: No Columns in Result Set From Executing: 'create table #dtc7063 (ival int)'
Initializing DTC
Beginning DTC Transaction
Enlisting Connection in Transaction
Error:
SQLSTATE=25S12,Native error=-2147168242,msg='[Microsoft][ODBC SQL Server Driver]
Distributed transaction error'
Error:
SQLSTATE=24000,Native error=0,msg=[Microsoft][ODBC SQL Server Driver]Invalid cur
sor state
Typical Errors in DTC Output When
a.  Firewall Has Ports Closed
-OR-
b.  Bad WINS/DNS entries
-OR-
c.  Misconfigured network
-OR-
d.  Misconfigured SQL Server machine that has multiple netcards.

Aborting DTC Transaction
Releasing DTC Interface Pointers
Successfully Released pTransaction Pointer.

In my situation the issue ended up being the Windows Firewall on the BizTalk Server was not allowing Outbound DTC connections which was blocking MSDTC from participating in Transactions with SQL Server.  You can modify the MSDTC Firewall rules in the Control Panel.

After allowing MSDTC to communicate through the firewall I re-ran the dtctester tool and had success.

C:\Downloads>dtctester <ODBCConnectionName> <UserName> <Password>
Executed: dtctester
DSN:  <ODBCConnectionName>
User Name: <UserName>
Password: <Password>
tablename= #dtc9418
Creating Temp Table for Testing: #dtc9418
Warning: No Columns in Result Set From Executing: 'create table #dtc9418 (ival int)'
Initializing DTC
Beginning DTC Transaction
Enlisting Connection in Transaction
Executing SQL Statement in DTC Transaction
Inserting into Temp...insert into #dtc9418 values (1)
Warning: No Columns in Result Set From Executing: 'insert into #dtc9418 values (
1) '
Verifying Insert into Temp...select * from #dtc9418 (should be 1): 1
Press enter to commit transaction.

Commiting DTC Transaction
Releasing DTC Interface Pointers
Successfully Released pTransaction Pointer.

Disconnecting from Database and Cleaning up Handles

After completing this successful test with the dtctester tool I could successfully configure my BizTalk Group and Runtime.

clip_image001

Friday, January 4, 2013

WCF-SAP User account not in validity date

Recently, I have been working with a new organization and have been been building some interfaces that communicate with SAP. Over the Christmas break I continued to work on some of these interfaces.  On December 31 my interfaces were working just fine.  But, on January 1st, I made a few changes and then ran my BizUnit regression tests just to make sure everything was ok.  To my surprise, my tests were failing and the issue was related to the following error.

SAPError

It just seemed like too much of a co-incidence that the errors started occurring on the first day of the new year. My gut told me that my account must have expired. At my previous organization the SAP-BizTalk system accounts never expired but they do at this one(which is probably not a bad thing).  The resolution in this case was for the SAP Basis team to update the validity date for the account.  Once this attribute was updated I could re-connect to SAP through my interfaces.  I have no idea why the SAP error message doesn’t just say “your account has expired”.

Sunday, December 23, 2012

Windows Azure 1.8 SDK– Queue to Queue Transfers

I was recently watching an episode of the Cloud Cover show where Abhishek Lal was talking about some of the recent features that are available in SDK 1.8.  One of the features that stood out for me was Queue to Queue transfers. A Queue to Queue transfer allows for a publisher to push content to a Queue.  Next, the Queue that just received the message can now push it out to another Queue automatically.

This new capability supports a couple design patterns:

  • Fan In – Where you have multiple systems publishing messages and you want to reduce the receiving endpoint surface down to a smaller number.
  • Fan Out – Where you have a single source message that you want to disseminate to more parties

The focus of this post is the Fan In scenario.  The diagram below describes the messaging pattern that we would like to enforce.  In this case we have 4 publishers.  Let’s pretend these are retailers who are now requesting more supply of a particular product.  If we want isolation between publishers then we would create a queue for each Publisher.  However, if we are interested in order delivery we now have race conditions that exist on the Receiver side.  Since this is a BizTalk Blog, BizTalk is acting as my Receiver.  Since we have 4 queues with 4 unique URIs this translates into 4 BizTalk Receive Locations (the blue RL boxes below).  We do not have any control over when and how those messages are received.  In my opinion this problem gets worse if we are building our own .Net client that is checking each queue looking for new messages.  Even if we are trying to be “fair” about the way in which we check the queues for new messages we don’t have any assurances of in order delivery.

image

Let’s make our lives easier and let the Service Bus maintain the order of messages through Queue to Queue  transfers and have a single endpoint that we need to consume from.  It will also simplify our BizTalk configuration as we will only need 1 Receive Location.

image

 

Solution

Within Visual Studio I am going to create a Solution that has 3 C# console applications.

image

QueueToQueuePublisher Project

The core of the overall solution is the QueueToQueuePublisher project.  Within it there are two classes:

  • DataContracts.cs -  contains our class that we will use as our PurchaseOrder
  • Program.cs -  is where we will create our Queues and establish our Queue to Queue forwarding.

image

DataContracts Class

If we further examine the DataContracts class we will discover the following object:

namespace QueueToQueuePublisher
{
    public class PurchaseOrder
    {
        public string ProductID { get; set; }
        public int QuantityRequired { get; set; }
        public string CompanyID { get; set; }
    }
}

 

Program Class

In Program.cs things get a little more interesting


using System;
using System.Collections.Generic;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;

namespace QueueToQueuePublisher
{
    public class Program
    {
        const string CommonQueueName = "CommonQueue";
        const string PubAQueueName = "PubAQueue";
        const string PubBQueueName = "PubBQueue";
        const string ServiceNamespace = "<your_namespace>";
        const string IssuerName = "owner";
        const string IssuerKey ="<your_key>";

        static void Main(string[] args)
        {

            TokenProvider credentials = TokenProvider.CreateSharedSecretTokenProvider(Program.IssuerName, Program.IssuerKey);
            Uri serviceUri = ServiceBusEnvironment.CreateServiceUri("sb", Program.ServiceNamespace, string.Empty);

            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}'...", Program.CommonQueueName);

                // Create Queue if it doesn't exist.
                //This Queue must exist prior to another
                //Queue forwarding messages to it
                if (!namespaceClient.QueueExists(Program.CommonQueueName))
                {
                    namespaceClient.CreateQueue(Program.CommonQueueName);
                }

                // Create Publisher A's Queue if it doesn't exist
                if (!namespaceClient.QueueExists(Program.PubAQueueName))
                {
                    QueueDescription qd = new QueueDescription(Program.PubAQueueName);

                    //This is where we establish our forwarding
                    qd.ForwardTo = Program.CommonQueueName;
                    namespaceClient.CreateQueue(qd);
                }

                // Create Publisher B's Queue if it doesn't exist
                if (!namespaceClient.QueueExists(Program.PubBQueueName))
                {
                     QueueDescription qd = new QueueDescription(Program.PubBQueueName);
                    {
                         //This is where we establish our forwarding

                         qd.ForwardTo = Program.CommonQueueName;
                         namespaceClient.CreateQueue(qd);
                    };
                  
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
    }
}

 

Within this class, the purpose is to:

  1. Create the Common Queue, if it does not already exist.
  2. If Publisher A’s Queue does not exist, create a new Queue Description and include the ForwardTo directive that will forward messages from the Publisher A Queue to the Common Queue. We will then use this Queue Description to create the Publisher A Queue.
  3. If Publisher B’s Queue does not exist, create a new Queue Description and include the ForwardTo directive that will forward messages from the Publisher B Queue to the Common Queue. We will then use this Queue Description to create the Publisher B Queue.

The Program.cs class that is part of this project only needs to run once in order to setup and configure our queues.

 

Publisher A Project

The purpose of this Project is very simple.  We want to create an instance of a Purchase Order and publish this message to our Publisher A Queue.

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


namespace PublisherA
{
    class Program
    {

            const string SendQueueName = "pubaqueue";
            const string ServiceNamespace = "<your_namespace>";
            const string IssuerName ="owner";
            const string IssuerKey = "<your_key>";
      
               
       static void Main(string[] args)
        {

          

     
            //***************************************************************************************************
            //                                   Get Credentials
            //***************************************************************************************************          
            TokenProvider credentials = TokenProvider.CreateSharedSecretTokenProvider  (Program.IssuerName, Program.IssuerKey);
            Uri serviceUri = ServiceBusEnvironment.CreateServiceUri("sb", Program.ServiceNamespace, string.Empty);

            MessagingFactory factory = null;

            try
            {
                PurchaseOrder po = new PurchaseOrder();

                po.CompanyID = "PublisherA";
                po.ProductID = "A1234";
                po.QuantityRequired = 300;

                factory = MessagingFactory.Create(serviceUri, credentials);

                QueueClient myQueueClient = factory.CreateQueueClient(Program.SendQueueName);

                BrokeredMessage message = new BrokeredMessage(po, new DataContractSerializer(typeof(PurchaseOrder)));
                Console.WriteLine("Publisher A sending message");
                myQueueClient.Send(message);


            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }

        }
    }
}

Publisher B Project

This project is pretty much a carbon copy of the Publisher A Project with the difference being that we are going to send messages to our Publisher B Queue instead of the Publisher A Queue.  I have included this project for completeness.

 

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


namespace PublisherA
{
    class Program
    {

        const string SendQueueName = "pubbqueue";
        const string ServiceNamespace = "<your_namespace>";
        const string IssuerName = "owner";
        const string IssuerKey = "<your_key>";


        static void Main(string[] args)
        {

 


            //***************************************************************************************************
            //                                   Get Credentials
            //***************************************************************************************************          
            TokenProvider credentials = TokenProvider.CreateSharedSecretTokenProvider(Program.IssuerName, Program.IssuerKey);
            Uri serviceUri = ServiceBusEnvironment.CreateServiceUri("sb", Program.ServiceNamespace, string.Empty);

            MessagingFactory factory = null;

            try
            {
                PurchaseOrder po = new PurchaseOrder();

                po.CompanyID = "PublisherB";
                po.ProductID = "B1234";
                po.QuantityRequired = 300;

                factory = MessagingFactory.Create(serviceUri, credentials);

                QueueClient myQueueClient = factory.CreateQueueClient(Program.SendQueueName);


                BrokeredMessage message = new BrokeredMessage(po, new DataContractSerializer(typeof(PurchaseOrder)));
                Console.WriteLine("Publisher B sending message");
                myQueueClient.Send(message);


            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }

        }
    }
}

BizTalk

From a BizTalk perspective we are going to keep this very simple.  We will simply create a Send Port Subscription and write a copy of any message that is retrieved from the Common Service Bus Queue to disk.

In order to configure a Send Port Subscription we need to first create a Receive Port and Receive Location.  This Receive Location will connect to our ServiceBus Namespace and will be looking for messages form the CommonQueue only.  As you may recall the messages that are sent to the individual Publisher A and B Queues will be forwarded to this Common Queue. 

Also note, since I am not deploying any Schemas we want to use the PassThruReceive pipeline.  If you specify XMLReceive then BizTalk will be looking for a schema that doesn’t exist.

image

Our Send Port will consist of using the FILE Adapter to write our messages to the local file system.

image

In order for our Send Port Subscription to work we do need to create a Filter based upon our Receive Port Name.

image

At this point we can enable our BizTalk Application.

 

Testing

In order to test our application we do need to make sure that the QueueToQueuePublisher console application is run.  This will create our common queue and our two publisher queues.  After running this application we should see the following within our namespace.

image

If we want to test our Queue To Queue forwarding we can simply create a test message in our pubaqueue and then receive the test message from our commonqueue.

image

image

image

Now that our Queue configuration has been verified we can run an instance of our PublisherA console application.

image

If we check our file folder that our send port is writing to we should see a new file has been written.

image

We can now perform the same actions with PublisherB.

image

image

Conclusion

As you can see the Queue to Queue forwarding is a pretty neat feature.  We can use it for Fan In, as in our scenario, messaging scenarios that forces Service Bus to worry about in order delivery and simplifies a Receiver’s endpoint surface.  Arguably it creates more configuration in the cloud so there may be a bit of a trade off in that regard.

Currently the only way to configure the ForwardTo property is through the Management APIs.  There is currently no GUI that allows you to take care of this.  But, without having any private knowledge, I am sure that this is something that Microsoft will address in a future update.

Something else to be aware of is that BizTalk has no understanding of ForwardTo.  Nor would any other client of the Service Bus.  This “configuration” is occurring outside of client configurations which is the way it should be.  Any perceived complexities that exist should be abstracted away from systems that are communicating with Service Bus.

Saturday, November 10, 2012

BizTalk 2013 Beta: Azure Service Bus Integration–Dynamic Sent Ports

 

I started writing this blog post before the Beta was announced and it was probably a good thing that I did not publish it as I now have something else to discuss.  Microsoft has made an enhancement to the configuration that supports Dynamic Send Ports.  More on this later.

This blog post is really about 3.5 years in the making.  You are probably saying what, how is that possible?  BizTalk 2013, nor the Azure Service Bus(in its current form) did not even exist back then.  This is true but a colleague and myself were already thinking of a cloud based pattern to solve a ‘trading partner’ scenario that we were dealing with.

Business Problem

I work in the Utilities industry within a province in Canada.  We have a ‘deregulated’ market when it comes to Electricity and Natural Gas.  What this means is that the market is more open and it provides other opportunities for companies to participate within it.  This deregulation occurred over 10 years ago and the overall goal was to reduce prices to the end consumer.  (The jury is still out on that).

The market is primarily broken up into 4 segments:

  • Generation – Organizations who generate electricity via coal, gas, wind, solar etc
  • Transmission – High voltage Transmission of energy from Generation plants to Distribution Networks
  • Distribution – Organizations that take High voltage feeds and distribute low end voltage to customer’s homes and businesses.  These Distribution businesses are also responsible for capturing  Customers’ usage and providing this information to retailers.
  • Retailers – Are responsible for billing customers for their usage.  Customers can choose who their retailer is but cannot choose who their Distribution company is as it is broken up by Service territory due to the amount of capital investment required in order to provide infrastructure.

image

Note: Image is used for illustrative purposes only and does not necessarily reflect the actual number of companies involved.

As you can probably imagine, there is a need for information to be exchanged amongst these parties.  Amongst the Generation, Transmission and Distribution companies, each company must be aware of demand that their customers are requesting so that the Generation company can produce enough energy.  The Transmission and Distribution companies must also be able of supporting that load on their networks.

From a Distribution standpoint, the segment of the industry that I work in, we need to be aware of Customer management/Enrollment, Energizing and De-energizing customers,  Meter reading and providing consumption data to Retailers so they can bill the customers.

A few years ago the industry was looking to replace its Managed File Transfer solution that facilitated the exchange of this information.  Think of an FTP type application that had an Address book with some scheduling type activities.  This tool moved around flat files that were all based upon different transaction types.  The tool at the time suffered from major reliability issues

At the time, the Service Bus just wasn’t what it is today.  Also if you think there is a lot of skepticism  about the cloud today, it was much, much worse 3.5 years ago.  People were not ready for the cloud back then and as an industry we went a different direction, I thought it would be fun to revisit this problem and look at a way that we could solve this problem today using cutting edge tools like the Azure Service Bus and BizTalk Server 2013.

Within the context of this post we are going to focus on a fairly common problem and that is enrolling new customers.  As I previously mentioned, customers can choose their retailer.  Like most businesses retailers are very interested in on-boarding new customers with incentives.  When a customer does choose to move their business to a new retailer, this retailer needs to inform the Distribution provider that the customer has chosen to switch retailers.  The Distribution provider is then responsible for notifying the old retailer that this customer is now longer a customer of theirs and the Distributor is also responsible for confirming with the new retailer that this customer is now theirs.  From here on in, the Distribution company will send this customer’s consumption (Meter Reads) to the new retailer so that they can bill the customer.

This process is defined as a set of transactions known as the Enrollment transactions and is comprised of three messages:

  • SRR – Switch Retailer Request
  • SRN – Switch Retailer Confirmation for new Retailer
  • SRO – Switch Retailer Confirmation for old Retailer

Implementation

All participants within the market place have their own company identifier.  For this blog post I have created fictitious ids.  Our New Retailer will have an id of 1111, our Old Retailer will have an id of 2222 and our Distribution Company will have an id of 3333.These ids will map to Queues that have been created within the Service Bus.

  1. The New Retailer will send an SRR request to the Distribution Company’s queue called 3333.
  2. The Distribution Company will pull this message, via BizTalk,  off of its queue and communicate with its back end ERP system (not described within this blog post).
  3. BizTalk will then need to send a notification (SRN) back to the new Retailer confirming the enrollment.
  4. BizTalk will also need to send a notification (SRO) to the Old Retailer letting them know that they have lost a customer.

image

 

Service Bus Configuration

Within my Azure account I have created a new Namespace called Electricity and created 3 different queues:

  • 1111
  • 2222
  • 3333

image

.Net Retailer Clients

Similar to some of my other recent posts we are going to use the .Net Brokered Message API from client applications that will interact with BizTalk through the Service Bus.

Within our .Net Solution there are 3 projects:

  • DataContracts -  where we will find our message specifications for the SRR, SRN and SRO message types.
  • Retailer1111 – where we will find our New Retailer  functionality.  This project will Send the SRR and receive the SRN response.
  • Retailer2222 – where we will find our Old Retailer functionality.  This project will Receive the SRO confirmation.

image

DataContracts

The first class that we want to create represents the Switch Retailer Request (SRR).  Within this message we have properties for SiteID (Customer identifier), New Retailer ID, Old Retailer ID and the Enrollment Date (effective date).

Normally the New Retailer would not necessarily be aware of the Old Retailer ID but since I am leaving the ERP functionality out of the scope of this blog post we will assume that the New Retailer is aware of this information.

namespace DataContracts
{
    public class SwitchRetailerReqeust
    {
        public string SiteID {get;set;}
        public string NewRetailerID {get;set;}
        public string OldRetailerID { get; set; }
        public DateTime EnrollmentDate { get; set; }
    }
}

 

Next we will get into the Switch Retailer Notification (SRN).  This is the message that BizTalk will send to the New Retailer confirming that the customer is now theirs.

namespace DataContracts
{
    public class SwitchNewRetailerNotification
    {
        public string SiteID { get; set; }
        public string NewRetailerID { get; set; }
        public DateTime EnrollmentDate { get; set; }
     
    }
}

 

Finally, we have the Switch Retailer Notification (SRO) that needs to be sent to the Old Retailer letting them know that this customer is no longer theirs.

namespace DataContracts
{
    public class SwitchOldRetailerNotification
    {
        public string SiteID { get; set; }
        public string OldRetailerID { get; set; }
        public DateTime EnrollmentDate { get; set; }
    }
}


Retailer1111 Project

As previously stated, the purpose of this project is to send the SRR transaction to the Distribution company and then receive the corresponding SRN transaction back.

using System.Text;
using System.Threading.Tasks;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;
using DataContracts;
using System.Runtime.Serialization;
using System.IO;

namespace RetailerNew
{
    class Retailer1111
    {
   

            const string SendQueueName = "3333";
            const string ReceiveQueueName = "1111";
            const string ServiceNamespace = "<your_namespace>";
            const  string IssuerName ="owner";
            const string IssuerKey = "<your_key>”;

        static void Main(string[] args)
        {
            //***************************************************************************************************
            //                                   Get Credentials
            //***************************************************************************************************          
            TokenProvider credentials = TokenProvider.CreateSharedSecretTokenProvider  (Retailer1111.IssuerName, Retailer1111.IssuerKey);
            Uri serviceUri = ServiceBusEnvironment.CreateServiceUri("sb", Retailer1111.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("\nChecking to see if Queue '{0}' exists...", Retailer1111.SendQueueName);

                // If Queue doesn't exist, then let's create it
                if (!namespaceClient.QueueExists(Retailer1111.SendQueueName))
                {
                    QueueDescription qd = new QueueDescription(Retailer1111.SendQueueName);
                   

                    namespaceClient.CreateQueue(qd);
                  
                }

                //***************************************************************************************************
                //                                   Runtime Operations
                //***************************************************************************************************
                factory = MessagingFactory.Create(serviceUri, credentials);

                QueueClient myQueueClient = factory.CreateQueueClient(Retailer1111.SendQueueName);

                //***************************************************************************************************
                //                                   Sending messages to a Queue
                //***************************************************************************************************
               

                Console.WriteLine("\nSending messages to Queue...");

                //Create a Switch Retailer Request
                SwitchRetailerRequest srr = new SwitchRetailerRequest();
                srr.SiteID = "3333123456789";
                srr.NewRetailerID = "1111";
                srr.OldRetailerID = "2222";
                srr.EnrollmentDate = DateTime.Now.AddDays(1);
          

     //Serialize the request so that BizTalk can process it correctly

                BrokeredMessage message = new BrokeredMessage(srr, new DataContractSerializer(typeof(SwitchRetailerRequest)));


                //Here we specify which URI we are expecting our response
                message.ReplyTo = serviceUri.AbsoluteUri + Retailer1111.ReceiveQueueName;
                 myQueueClient.Send(message);


                 //**************************************************************************************************
                 //                                   Receive messages from Queue
                 //**************************************************************************************************

                TokenProvider tokenProvider = TokenProvider.CreateSharedSecretTokenProvider(
                    Retailer1111.IssuerName, Retailer1111.IssuerKey);
                Uri uri = ServiceBusEnvironment.CreateServiceUri("sb", Retailer1111.ServiceNamespace, string.Empty);
                MessagingFactory messagingFactory = MessagingFactory.Create(uri, tokenProvider);
                QueueClient qc = messagingFactory.CreateQueueClient(Retailer1111.ReceiveQueueName, ReceiveMode.ReceiveAndDelete);
                BrokeredMessage bm;
                while ((bm = qc.Receive(new TimeSpan(hours: 0, minutes: 0, seconds: 30))) != null)
                {
                    var data = bm.GetBody<SwitchNewRetailerNotification>(new DataContractSerializer(typeof(SwitchNewRetailerNotification)));
                    Console.WriteLine(String.Format("Customer with SiteID {0} has now been enrolled as of {1}", data.SiteID, data.EnrollmentDate.ToString() ));
                }


                Console.WriteLine("\nAfter running the entire sample, press ENTER to clean up and 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();
            }
           
        }

    }

}

 

Probably the most interesting/significant line of code in there is where we set the Brokered Message ReplyTo property.  The reason why this code is significant is that BizTalk can use the value of this property to set our URI that our Dynamic Send port is going to use in order to send the response back out.  You will see how this is set in the BizTalk section.

//Here we specify which URI we are expecting our response
message.ReplyTo = serviceUri.AbsoluteUri + Retailer1111.ReceiveQueueName;

 

Retailer2222 Project

The purpose of this project is to retrieve the SRO notifications that occur when we lose a customer to another retailer.

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

namespace RetailerOld
{
    class Retailer2222
    {

       
        const string ReceiveQueueName = "2222";
        const string ServiceNamespace = "<your_namespace>";
        const  string IssuerName ="owner";
        const string IssuerKey = "<your_key>";

        static void Main(string[] args)
        {

               try
               {

                //Create instance of tokenProvider using our credentials
                TokenProvider tokenProvider = TokenProvider.CreateSharedSecretTokenProvider(
                    Retailer2222.IssuerName, Retailer2222.IssuerKey);
                Uri uri = ServiceBusEnvironment.CreateServiceUri("sb", Retailer2222.ServiceNamespace, string.Empty);
                MessagingFactory messagingFactory = MessagingFactory.Create(uri, tokenProvider);
                QueueClient qc = messagingFactory.CreateQueueClient(Retailer2222.ReceiveQueueName, ReceiveMode.ReceiveAndDelete);
                BrokeredMessage bm;


                //***************************************************************************************************
                //                                   Receive messages from Queue
                //***************************************************************************************************

                Console.WriteLine("About to connect to the Queue");
                while ((bm = qc.Receive(new TimeSpan(hours: 0, minutes: 0, seconds: 30))) != null)
                {
                    var data = bm.GetBody<SwitchOldRetailerNotification>(new DataContractSerializer(typeof(SwitchOldRetailerNotification)));
                    Console.WriteLine(String.Format("Customer with SiteID {0} is no longer our customr as of {1}", data.SiteID, data.EnrollmentDate.ToString() ));
                }

                Console.WriteLine("\nAfter running the entire sample, press ENTER to clean up and exit.");
                Console.ReadLine();
            }
            catch (Exception e)
            {
                Console.WriteLine("Unexpected exception {0}", e.ToString());
                throw;
            }
       
        }
}
}

 

BizTalk Project

Within this solution I am going to demonstrate what is required to send messages to Service Bus Queues using a dynamic send port.  I am going to use two slightly different approaches so keep your eyes open for that.

Schemas

I have created 3 schemas to match those classes that were included in our DataContracts project.  In order to create these schemas, I did use the Auto Generate Schemas feature that is included in Visual Studio (when you have BizTalk installed of course).  I discussed this approach in a previous post if you are interested in more details.

image

Maps

I have two very simple maps, the first one will transform an instance of our SRR message to an instance of our SRN message.

image

The second map will transform an instance of our SRR message to an instance of our SRO message.

image

Orchestration

Here is where most of the “magic” happens.  We have a receive shape where we will receive an instance of our SRR message.  We will then transform it and set some context properties, within a Message Assignment shape, so that we can use a Dynamic Send Port.  What is special about this Message Assignment shape is that we are going to use a Brokered Message property called ReplyTo as our URI.  So this is a pretty need “out of the box” feature that allows a client to dictate where we need to send a response message.

Even thought this ReplyTo property is beneficial, it only gets us part way.  We will need to provide a transport type and indicate that it is the new SB-Messaging adapter.  We also need to provide our Service Bus credentials and the URI to the Access Control Service.  It, of course, is a good idea to maintain these values in some sort of configuration store as opposed to hardcoding within our Orchestration.

image

Once we have sent out our SRN message back to the Service Bus Queue, we now need to process the SRO message.  We will once again leverage a map to instantiate this message in the absence of an ERP system were this message would ordinarily be created.  We will once again take advantage of Dynamic Send Ports but in this case we do not have the ReplyTo brokered message property because this retailer never sent us the message.  We will need to provide the base uri for the Service Bus but we can augment this by distinguishing the OldRetailerID node that is part of the SRO schema.  This will allow the solution to work for any retailer that needs to receive an SRO.

Much like the previous scenario we will need to specify a TransportType, our credentials and our Access Control Service URI.

image

When we are done putting these building blocks together we should have something that resembles the following.  We can now deploy our BizTalk application.

image

Receive Location

We will configure our Receive Location much like we did in my previous posts that discuss BizTalk integration with the Service Bus.

image

image

Send Ports 

As outlined in the Orchestration section of this post, we have two different Send Ports.  Part of the reason why I have included two is to demonstrate the following NEW features that has been included in the BizTalk 2013 Beta.  In previous BizTalk versions, if you used a Dynamic Send Port then it would automatically use the Adapter’s Default Send Handler to send out the message.  This isn’t ideal, especially in a shared environment where there can be many different groups or applications using this same Send Handler(Host).

Going forward we now have a Configure button that we can click within a Dynamic Send Port’s configuration.  When we do this a Configure Send Handler dialogue will appear that allows us to set different Send Handlers depending upon the Adapter.

image

Even within our own Application we can set a different Send Handler if you have more than 1 Dynamic Send Port.  For our second Dynamic Send Port I have specified BizTalkServerApplication as the Send Handler for this Dynamic Send Port.

There is probably not a really good reason to do this but the point I am trying to make is that we have gone from being very restricted to having a lot of flexibility.

image

Testing

We are now ready to test our application.  The steps that we need to take in order to do so are:

  • Run an instance of our Retailer1111 client.  This application will send the SRR to the Service Bus Queue where BizTalk will retrieve it.
  • BizTalk in turn will look for the ReplyTo property and send an SRN message back to the ServiceBus but this time to the the Retailer’s 1111 queue.
  • Next, BizTalk will generate an SRO message and send it to the old Retailer’s 2222 queue.

image

Conclusion

The point of this blog post was to take a real world problem and discuss how the combination of Azure Service Bus Queues and BizTalk 2013 can help us solve it.  Of course I had to over-simplify things to make this blog post some-what reasonable in length.  This also is not the only approach that we can take in order to solve this problem.  Using Azure Service Bus Topics is another option as well but I thought it was important to demonstrate how we can use the SB-Messaging context properties and Dynamic Send Ports.  I also felt it was a great opportunity to highlight the new Send Port Configuration for Dynamic Send Ports.