May 22, 2012 at 4:05 PM

Lately, I had the task to create a generic WCF netTcp endpoint within BizTalk. The purpose was to create a single BizTalk ESB endpoint for each front-end application. BizTalk has the task to route and transform the SOAP requests to the corresponding back-end services.

 

I already had experience with hosting such an endpoint in-process (with the Custom adapter), but now it was required to host the endpoint in IIS (with the Custom-Isolated adapter). The reason for this decision is the fact that IIS, in combination with Windows Server AppFabric, adds extra tooling and manageability.

 

 

Enable Windows Activation Services

 

  • Add WAS as a Windows feature:

        clip_image002

 

  • Turn on WCF Non-HTTP Activation

        clip_image004

 

  • Start all WAS Windows Services. Change their startup type to Automatic. You can do this via Properties.

        clip_image006

 

Create IIS endpoint

  • Create a web service directory: C:\inetpub\wwwroot\BlogService

 

  • Open IIS Manager and convert the folder to an application

         clip_image008

 

  • Choose an application pool which is configured with the BizTalk isolated host user for .NET Framework 4.0

          clip_image010

 

  • Enable netTcp for the Default Web Site, via the Advanced Settings:

          clip_image012

 

  • Enable netTcp for the BlogService application, via the Advanced Settings:

        clip_image014

 

  • Add GenericEsbEndpoint.svc to the web service directory

        clip_image015

 

  • GenericEsbEndpoint.svc tells IIS to use the ServiceHostFactory of the BizTalk WCF adapter:

           <%@ ServiceHost Language="c#" Factory="Microsoft.BizTalk.Adapter.Wcf.Runtime.CustomWebServiceHostFactory, Microsoft.BizTalk.Adapter.Wcf.Runtime, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>

 

  • A web.config can be added, but all service behaviors (e.g. serviceDebug) can be configured on your BizTalk receive location too.

 

Create BizTalk receive location

  • Create a two-way receive port

        clip_image017

 

  • Create a two-way receive location and configure with the Custom-Isolated Adapter

        clip_image019

 

  • Configure the adapter URI with the format /<IIS Application Name>/<Service.svc>. Don’t use the scheme “net.tcp://” here!

        clip_image021

 

  • Configure the netTcp binding. Disable transport security (for performance reasons).

        clip_image023

 

  • Enable the BizTalk receive location

        clip_image025

 

  • Now you can additionally set up send ports and filters, to route the submitted SOAP request to the correct back-end services. Routing can be based on multiple properties, but the SOAP Action (WCF.Action) seems most suitable. Also transformations must be added in some cases.

 

Update the client binding

  • The client needs to be updated to send to the generic BizTalk endpoint, instead of directly to the back-end service. Update the client with the following address format: net.tcp://<machinename>:<tcpPortNumber>//<IIS Application Name>/<Service.svc>
<client>

<endpoint address="net.tcp://machineName:8888/BlogService/GenericEsbEndpoint.svc"

binding="netTcpBinding" bindingConfiguration="NetTcpBinding_ICoditService"

contract="PersonSvc.ICoditService" name="NetTcpBinding_ICoditService" />

</client>

 

  • The tcpPortNumber can be configured in the Site Bindings of the Default Web Site

        clip_image027

Posted in: BizTalk | IIS | SOA

Tags:


January 13, 2012 at 11:24 AM

This blog post contains some guidelines for consuming web services, with a focus on exception handling.  We will both handle pure messaging scenario and web service calls from within an orchestration.  I also make a distinguishment between asynchronous and synchronous flows.  Synchronous means that the flow needs to return a message to the original caller.  So in case of troubles, a SoapFault needs to be returned to the calling application.  In an asynchronous flow, you just need to make sure that your web service call is resumable. 

 

Messaging Scenario – Asynchronous

When an error occurs during the web service call, the default behavior of BizTalk retry 3 times and will suspend the request message on the BizTalk Send Port and this instance will be resumable.  This is the perfect behavior for this asynchronous process.

 

Messaging Scenario - Synchronous

If you are in a synchronous process, a suspended Send Port will lead to a timeout on your Receive Port.  In this scenario you need to enable "Propagate Fault Message" on the Send Port and a SoapFault will be returned to the original caller.  Also think about the Retry Count and Retry Interval settings, because a bad configuration can also lead to timeouts.

image

 

Orchestration - Asynchronous

When you consume a web service from within an orchestration, it's getting more complex.  If the consumed web service throws an exception, BizTalk creates by default 2 suspended service instances.  Resuming them does not always have the expected behavior.

 

-  The Orchestration is suspended.  A resume will not change anything to the state of the Orchestration.
-  The Send Port is suspended.  A resume will resume the web service call as expected, but the Orchestration will not be able to continue processing afterwards.

 

image

How can we now achieve a resumable web service call?

 

First of all enable "Propagate Fault Message" on the Send Port.


Also modify the calling orchestration:

-  You need to create a loop.  This loop continues as long as the Boolean bSuccess equals false.

-  Modify the logical Orchestration Send Port and add a Fault Message.  To keep it general, you can choose the SoapFault (which is part of the Microsoft.BizTalk.GlobalPropertySchemas).

clip_image002        clip_image003

-  Add an exception handler to the web service call. Catch the Fault Message that was returned.  Add a suspend shape for human intervention. Note that it’s a good practice to also add an extra exception handler which catches a System.Exception.

-  If the web service call fails: set bSuccess == false in the exception handler.  If the call succeeds, set bSuccess == true, so the orchestration will exit the loop.

 

The result should look like this:

image

 

Now we've created a resumable web service call from within an orchestration.  When testing the orchestration in a failure scenario, you will see that there are still two suspended service instances:

-  The Orchestration is suspended.  This is the one that we've made resumable.

-  The Send Port is suspended.  To avoid this second service instance to be suspended, you can enable "Routing for Failed Messages".  This will generate an ErrorReport, instead of suspending the Send Port.  Subscribe on the ErrorReport with the filter ErrorReport.ErrorType == “FailedMessage”.

 

clip_image006

 

Orchestration - Synchronous

In this scenario, you will also need to catch the SoapFault (or other exception) and make sure that you don’t end up with suspended send port instances. See “Orchestration – Asynchronous”


The extra functionality that you’ll need to add is returning a SoapFault to the original caller.

- Add a Fault Message to the Request/Response receive port of your orchestration.

- You can choose to return a typed Fault or, to keep it general, a SoapFault (which is part of the Microsoft.BizTalk.GlobalPropertySchemas).

- Make sure you return the catched SoapFault (or the created SoapFault in case of other exception) in case of errors.

- Remark that you’ll need to add a decide shape to determine you’re in a success/failure scenario. Otherwise, the compiler will fail (complaining about unconstructed messages).

 

clip_image002[4]

 

Again, think about the Retry Count and Retry Interval settings on the send port.

 

Toon Vanhoutte

Posted in: BizTalk | SOA | WCF

Tags: , ,