From the phone through the cloud and into BizTalk on my laptop
Last week I sat down to prepare a demo for an ‘application infrastructure’ workshop I’m running next week in which I wanted to demonstrate exposing a BizTalk WCF receive location accessed through the Windows Azure AppFabric Service Bus.
Granted - with the BizTalk Server 2010 Feature Pack released last October – this is merely a case of running the Publish WCF Service Wizard, but I thought it would be a cool demo to run none-the-less.
However – as I was thinking about the scenario for my demo I realised there would have to be a great deal of ‘trust me – I’m not calling the service directly on my computer, I’m really using the cloud’, which is ok, but I wanted to do better.
And then I realised – Microsoft have kindly kitted me with a cool little phone which runs .net – what if I threw this into the mix?! so I’ve decided to build a scenario where I’d use an app, on my phone, to call a BizTalk instance, on my laptop, through the Windows Azure AppFabric Service Bus. how cool is that?! – well, here’s what I needed to do -
It starts off very simple – I created my BizTalk scenario - in my case that consisted of schema, a FF schema, a map between the two, and a send pipeline with a Flat File Disassembler.
Setting up a simple receive port and send port configured with the map and pipeline I could drop an xml file in one folder and get a flat file in the other. I configured the file send adapter to append records, so as I was dropping more xml files my flat file grew bigger. nice start.
, put together it looks like this -
The next step was to publish my xml schema as a WCF service so that a client could call it directly, and I did this, as you’d expect, by running the BizTalk WCF Service Publishing Wizard. However – as I had the BizTalk Server 2010 Feature Pack installed - it was an updated wizard, with added support for exposing BizTalk in the Windows Azure AppFabric Service Bus.
I ran through the wizard normally, but made sure to tick the box indicating I wish to use the AppFabric Service Bus -
That meant that later on in the wizard, two additional steps were added to capture the service bus details, in the first I set the relay binding I wish to use and the URL scheme. normally I would use the netTcpRelayBinding and the sb:// Url scheme, but as I plan to consume this from Silverlight, which sadly does not currently support either, I had to stick with basic http.
I am also asked whether I wish to enable discovery and metadata and in this case I do, so I ticked both boxes, but these are of course optional, and in many cases I would not want to have them enabled (especially if I have security turned off)
The next step captures the security configuration for the endpoint, namely the issuer name and key; again – because I’m planning to use a Silverlight client I can’t use client authentication so I disabled it for both the endpoint and the metadata endpoint; this does mean that in its current state this would not be fit for production use, but it’s ok for my demo; for production I will have to ensure other security mechanisms are added to protect my service, which is now effectively enabled for anonymous use.
With these two extra steps done the wizard completes and the web service is published to the location specified on my local IIS.
It is worth noting though, that at this point nothing really happened in Azure, but on the flip side- the BizTalk team have done something really nice here – if you look at the receive location you will see that it uses the and if you look at the config file generated for the local service you will see that it uses the standard WCF-BasicHttp adpater, no mention of the relay binding I’ve selected at all -
That meant that there were not special configuration in the binding either -
However, if you looked a bit deeper, and opened the web.config if the generated wcf service you will find that the wizard added two additional endpoints – one for the relay binding and one for the cloud mex endpoint -
<endpoint name="RelayEndpoint" address=[cloud url here]
binding="basicHttpRelayBinding" bindingNamespace=[namespace here]
<endpoint name="MexEndpoint" address=[mex url here]
binding="ws2007HttpRelayBinding" bindingNamespace=[namespace here]
bindingConfiguration="RelayEndpointConfigMex" behaviorConfiguration="sharedSecretClientCredentialsMex" contract="IMetadataExchange" />
These are on top of the usual behaviour of such published services to expose and endpoint derived from the configured receive location, so effectively the wizard had created an on-premise endpoint which I can call directly as well as a cloud facing endpoint and the equivalent mex endpoints. Of course these are controlled through the choices in the Wizard, but if you’ve looked at the receive location generated and wondered where’s the relay binding – now you know!
Another point worth mentioning at this point is that for some reason, in my first attempt I kept getting an error when browsing to the local service suggesting the receive location was not enabled despite the fact that it was. I checked permissions carefully and various other things and eventually concluded something went wrong, so I tried again, and got the same result.
In the end I used a different name for the service in the wizard and that did the trick, but I could not consistently re-create the problem so I can’t comment on what exactly that was – all I would say is – if you’re publishing a service, and keep getting the receive location disabled error, consider using a different name!
Ok – back to the main story – so as I’ve said – with the service published, I thought I could call the cloud endpoint and reach my BizTalk, but browsing to my cloud service revealed no endpoints (despite me asking to include them in the atom feed) -
The reason is that, for security reasons amongst other things, the onerous is on the on-premise endpoint to let the cloud know it’s available, open the bi-directional connection between itself and the service bus, and as publishing a service does not actually execute anything it is not enough.
To get things going I’ve simply browsed to my on-premise service, got the usual test instructions page and then refreshed my cloud atom feed page, this time my service got listed correctly -
and in it were my two cloud facing endpoints -
For production, a way to avoid having to manually browse to the service is to have AppFabric installed and use the AutoStart feature
One last gotcha I stumbled across that’s worth noting – if you followed all the steps above, but when browsing to the local service received an error along the lines of - "The socket transfer timed out after 00:00:00. You have exceeded the timeout set on your binding. The time allotted to this operation may have been a portion of a longer timeout. " – the most likely reason is that your app pool user (which in my case is a dedicated user I usually create to run BizTalk hosts) is unable to access the internet and so was unable to contact the Windows Azure Service Bus to create the bi-directional connection, set the right permissions and that problem will go away.