Publishing a WCF Service via Service Bus Relay in BizTalk Server 2013 (Part 2)

By Nick Hauenstein

This post is the eighth in a weekly series intended to briefly spotlight those things that you need to know about new features in BizTalk Server 2013. It is also the second part of a two-part series on the Service Bus Relay features in BizTalk Server 2013 (Click here for part 1).

Last week, we examined how BizTalk Server 2013 (and even 2010 in that case) can use the Windows Azure Service Bus Relay to make a service endpoint available in the cloud without otherwise directly exposing the machine, and while being able to take advantage of the claims-based authentication and authorization framework provided by the Access Control Service. This was done in such a way that the service was hosted in IIS rather than within an In Process BizTalk Host Instance. This week, we are going to look at the other side – a service endpoint that is ultimately hosted in IIS.

In this case, we have been provided with a few new adapters to help us along the way (although, if we were really adventurous, WCF-Custom could have still done the trick for us in the past). These two adapters are the WCF-BasicHttpRelay adapter and the WCF-NetTcpRelay adapter:

ServiceBusRelayInProc

Last week, we published a NetTcpRelay endpoint that required some additional work on the client to authenticate with the service. This week, we’re going to go to the other extreme, and publish a WCF-BasicHttpRelay endpoint that will be more or less transparent to the client.

Starting the Game of Telephone

We’re going to start out with the BizTalk version of Hello World, a simple (technically unnecessary, but convenient for illustrative purposes) orchestration. This orchestration receives a simple single node XML message (the single node containing the text “Hello”), and returns a simple single node XML message (containing the word “World”) as the response:

HelloOrch

The Setup

With this, we’re going to go through the typical process of creating an in-process receive location, and then walk through the BizTalk WCF Service Publishing wizard to publish the service. Then we’re going to consume the service as it sits. Once that is complete, we will change up the end point so that it is listening over a Service Bus Relay, and see that the client can still call the service.

We’ll start with the Receive Location. In order to keep this in-process, we’re actually using the WCF-Custom adapter (since WCF-BasicHttp will force us to an Isolated Host):

BasicHttpEP

Now that we have an endpoint to receive messages, we need to create an endpoint that informs clients what messages we’re even interested in – our MEX endpoint. For that, we will go back to the BizTalk WCF Service Publishing wizard, and select the second option – the path less traveled:

MEXPublish_Step1

We will walk through this wizard, ignoring everything that mentions Service Bus publishing for now. Ultimately, what we will end up with is a local endpoint that is exposing the WSDL necessary to consume the service. We can use the svcutil.exe utility to download and share this metadata offline, or even generate proxy classes for re-use later if we’d like. In this case, we will be consuming it in place, and generating a client that can be used to call the service no matter where it lives.

Since we started with an orchestration, and that will define the shape of the incoming/outgoing data, we will select the Publish BizTalk orchestrations as WCF service option. Do note the plural orchestrations in that sentence, I see way too many single operation services out there. Winking smile

MEXPublish_Step3

After browsing for and selecting an orchestration, you should be presented with a list of all public port types within the assembly containing the orchestration. If they Type Modifier property on the Port Type is not set to public, it will not be listed, and you will be sad:

selectport

After you click through a few more screens, you will be prompted for the location where you would like this metadata hosted. In this case, it will be hosted within IIS on the local machine:

MEXPublish_Location

A few more clicks through the wizard, and the MEX endpoint is created and hosted in IIS – though the service endpoint itself is still hosted in-process.

A visit to IIS manage demonstrates that the MEX endpoint is now:

http://localhost/IOServiceMEX/WcfService_QuickLearn_BizTalk_Process.svc?wsdl

Consuming the Service

So far, we haven’t really done anything earth shattering, so consuming the service is equally simple. In this case, I just fired up Visual Studio, used the Add Service Reference context menu option in Solution Explorer, and then provided the MEX endpoint to the wizard. With the (local, not relayed) Service Reference in place, I added the following code to my console app:

[sourcecode language=”csharp”]using System;

namespace QuickLearn.WCF.Client
{
class Program
{
static void Main(string[] args)
{
var client = new IOServiceReference.WcfService_QuickLearn_BizTalk_ProcessClient("BasicHttpBinding_ITwoWayAsync",
"http://localhost:81/Sample/IOService.svc");

var response = client.ProcessMessage(new IOServiceReference.InOutRequest()
{
Contents = "Hello"
});

Console.WriteLine(response.Contents);
Console.ReadLine();
}
}
}[/sourcecode]

 

In the code above, the only moderately odd thing that I did was to use an overload of the client constructor that included an endpoint address. The reason for that was so I could more easily demonstrate the only change necessary as we switch to the WCF-BasicHttpRelay adapter.

To the Cloud

Since my client code is currently working and happy, I am ready to move this to the cloud. I am actually going to maintain my local endpoint (Receive Location) as well and simply add another Receive Location that will open the relay. The configuration of this one will be a little bit different, and certainly more involved.

NOTE: Before you continue, please be sure that you have read part 1.

I’m going to re-use my Azure Service Bus namespace from last week (though I have a new key for this week). I will start by creating a new receive location, selecting the WCF-BasicHttpRelay adapter, and then opening the adapter configuration. The first thing I am prompted for is the listen URI for the endpoint. This URI must incorporate my Service Bus Namespace, and should also add some identifier for the service after:

RelayEP_Config

The only other page of the configuration that I must visit is the Security page. This is where I get to determine if the client needs to provide some sort of authentication information in order to invoke the service, if the existence of the service is going to be discoverable by hitting the root of the namespace, and this is also where I set the authentication details for the access control service – so that BizTalk can prove to Azure that it can listen at that address and receive messages.

Since we don’t want to make changes to our client (other than the endpoint address), we will set the client authentication type to None. Then we need to click Edit under Access Control Service to bring up this dialog:

acs_credentials

In this dialog, we need to re-iterate our namespace (leaving the –sb suffix in-tact), and then then we also need to provide our super secret key which we can look up through the Azure Management Portal (see the previous post for details).

Once that is all in place, we’re set to Enable our Receive Location and then update the client to point to the relay.

Updating the Client

I mentioned before that we really only want to update the endpoint in the client. While this is true, the change of endpoint does (in this case) require a single simple change in configuration. The reason has nothing to do with the Service Bus Relay itself, but instead the change of scheme from http to https. An http address does not imply any security added in by the transport, it is just clear text over the wire. An https address, on the other hand, implies transport level security, as a result we need this small tweak to the otherwise auto-generated config file:

TransportSecurity

And then an update to our endpoint in code (everything else remains):

[sourcecode language=”csharp”]using System;

namespace QuickLearn.WCF.Client
{
class Program
{
static void Main(string[] args)
{
var client = new IOServiceReference.WcfService_QuickLearn_BizTalk_ProcessClient("BasicHttpBinding_ITwoWayAsync",
"https://uniquename.servicebus.windows.net/IOService/");

var response = client.ProcessMessage(new IOServiceReference.InOutRequest()
{
Contents = "Hello"
});

Console.WriteLine(response.Contents);
Console.ReadLine();
}
}
}[/sourcecode]

This gives us the very happy result:

consoleapp_result

Clearly this is one of the most robust, secure, and complex ways to write the word “World” out to the console.

The Take-away

The take-away here for the last two posts is that BizTalk Server 2013 gives you some new options for exposing select endpoints over the internet without touching firewall configuration, without involving IIS (if you don’t want to involve it), and without exposing the whole box out to the internet. All the while giving you the ability to work with clients that are aware of the setup (in the case of the NetTcpRelay) or are blissfully ignorant of the magic behind the scenes (in the case of the BasicHttpRelay).

One thought on “Publishing a WCF Service via Service Bus Relay in BizTalk Server 2013 (Part 2)

  1. Pingback: BizTalk Server 2013 New Features Series Index | QuickLearn Training Blog

Leave a Reply

Your email address will not be published. Required fields are marked *