Exposing a simple BizTalk orchestration as WCF service

One of the requests I recently got (from an existing customer in the recruitment space) was to demo how to expose an orchestration as a WCF service.

Let me wrap this up in a wider context of the SOA (as it will make much more sense) and I'll then reconstruct the series of steps that I actually did to build a simple project from scratch.

A classic case of service orientation is when a business division in an enterprise owns a service (which in reality could well be an entire business process designed & developed as an orchestration that integrates with multiple backend disparate systems) and then we simply expose this as a WCF service so that other areas within the enterprise (or outside depending upon the nature of the service) can consume it for their benefit. For simplicity, lets take a simple business process e.g. 'Credit Check' and go through the process of constructing it and then exposing it as a WCF service. All it takes is an input document (with details of the company, the amount for which its credit-worthiness is being checked and the current date) and after processing this service sends a reply for that company which is a simple boolean - success or failure. As evident, once this business service is built, thoroughly tested & deployed into production, it could easily be consumed by other areas of the enterprise and there should not be any need to rebuild this. So let me go through the walkthrough assuming you just have an elementary knowledge of BizTalk.

Create a new Biztalk project and call it 'SimpleCreditCheck' and setup the strong name in the assembly and call the Application name 'SimpleCreditCheck' as well (in the Deployment Configuration)

Create a new schema and call it Input.xsd (Right click the project -> Add -> Add New Item -> Schema Files). Click on the Root Node and rename it as CompanyDetails

Right click the CompanyDetails node -> Insert Schema Node -> Child Field Element and call it CompID with the default type (xs:string). Repeat this to create CompName with the default type (xs:string), CreditCheckDate with the default type (xs:string) and Amount with type as (xs:int)

So now your CompanyDetails root node has four elements under it: CompID, CompName, CreditCheckDate, Amount

Create a new schema and call it Output.xsd (Right click the project -> Add -> Add New Item -> Schema Files). Click on the Root Node and rename it as CreditCheckResult

Right click the CreditCheckResult node -> Insert Schema Node -> Child Field Element and call it CompID with the default type (xs:string). Repeat this to create CreditCheckDate with the default type (xs:string) and ApprovedStatus with type as (xs:boolean)

So now your CreditCheckResult root node has three elements under it: CompID, CreditCheckDate, ApprovedStatus

Create a new Orchestration and call it CreditCheck.odx (Right click the project -> Add -> Add New Item -> Orchestration Files).

Drop a Port from the toolbox and call it RP_CreditCheck click Next and type RPT_CreditCheck for the port type name (make sure you choose Communication pattern as request-response and Access Restriction as public). Click Next and choose the defaults and click Finish

Drop a Receive, Transform, Call Rules, Send shapes from the tool box.

In the Orchestration View, Right click on the Message -> New Message -> Call it MsgIn and choose the type as CreditCheck.Input

Again In the Orchestration View, Right click on the Message -> New Message -> Call it MsgOut and choose the type as CreditCheck.Output

Click on the Receive shape and select the Message as MsgIn Activate as True and Operation as RP_CreditCheck.Operation_1.Request in the Properties View

Click on the Construct Message part of the Transformer and in Properties window select Message Constructed as MsgOut.

Double click the transformer and select the MsgIn as Source and MsgOut as Destination and click OK.Join up the CompID and CreditCheckDate fields on the input & output schemas and select the Value = True (property in the transformer for ApprovedStatus)

Click on Save All and close the transformer pane.

Click on the Send shape and select Message as MsgOut and operation as RP_CreditCheck.Operation_1.Response in the properties.

Fire up the Business Rules Composer -> Right click Policy -> Add New Policy -> call it CreditCheckPolicy. Right click on version 1.0 -> New Rules -> Call it ApproveCredit. Right click on the IF (right pane) -> Conditions -> Predicates -> Less than equal

On the Fact Explorer click on the XML schema -> Schema -> Browse -> choose both Input.xsd & Output.xsd using the shift keys and click open

Drag the Amount field from the Input.xsd and drop it on the IF argument1. Place a value e.g. 1000 as argument2. Drag the ApprovedStatus from the Output schema into the THEN pane under the Actions. Select True from the drop down. The entire logic would then read if the Input amount is <= 1000, ApprovedStatus = True

Do the same steps for disapproval. Under the CreditCheckPolicy. Right click on version 1.0 -> New Rules -> Call it DenyCredit. Right click on the IF (right pane) -> Conditions -> Predicates -> Greater than. Drag the Amount field from the Input.xsd and drop it on the IF argument1. Place a value e.g. 1000 as argument2. Drag the ApprovedStatus from the Output schema into the THEN pane under the Actions. Select False from the drop down. The entire logic would then read if the Input amount is > 1000, ApprovedStatus = False

Now that you have the Policy & Rules in Place -> Right Click version 1.0 and select Save then Publish & finally Deploy. Close the Business Rules Composer.

Go back to the Orchestration and double click on the call Rules shape - select the CreditCheckPolicy and Input & Output schemas as parameters.

Right click the project and click on Deploy. Once the project has deployed successfully, you can now choose to publish it as a WCF service.

Go to the Tools in the Visual Studio (alternatively from Start -> All Programs -> BizTalk Server 2006 as well) and select the BizTalk WCF Service Publishing Wizard -> Next -> Select the Service endpoint option, (this means that you will publish a WCF service from an orchestration in an assembly) and Select WCF-BasicHttpfrom the Adapter name (Transport type) drop-down list.

Select the Enable metadata endpoint check box to make the WCF receive location hosted by IIS publish its WCF service metadata. (this sets the httpGetEnabled attribute of the to true in Web.Config. This metadata can thus be retrieved when an HTTP/GET request calls it - useful for generating proxy to build a client to test this service)

Select the Create BizTalk receive locations in the following application option to create the receive ports and locations corresponding to each generated .svc file for the WCF-BasicHttp adapter. Choose SimpleCreditCheck Application. Click Next

On the Create WCF Service page, select Publish BizTalk orchestrations as WCF service, and then click Next.

In the BizTalk assembly file (*.dll) choose the default SimpleCreditCheck.dll and click Next

Choose the defaults for the BizTalk assembly descriptions and click Next

Select the default URI, "https://tempuri.org/" in the Target namespace of the WCF service (unless you want your published WCF service to use a different URI in which case you can specify it here) and click Next

Leave the default location https://localhost/SimpleCreditCheck in the Location.
and Select the Allow anonymous access to WCF service option, and then click Next.

On the WCF Service Summary page, click Create to create the service and on the Completing BizTalk WCF Service Publishing Wizard page, click Finish

Click on the Start -> Administrative tools -> IIS and right click the SimpleCreditCheck on the Deafult Web Site and make sure an appropriate Application Pool is selected or create a new Application Pool. Also, make sure that on the ASP.NET pane, ASP.NET framework version 2.0.* (and not 1.1.*) is selected. Also copy over (on a Notepad) the full WSDL address from the .svc file that the wizard generated for building the proxy classes for Client.

Go back to the BizTalk admin console and check - the wizard would have created the Receive Port & Receive Location for you - configure them so that they are bound to the Logical Receive Port and start the application

To create a client for this WCF serivce, go to the Visual Studio and create a new project (Visual C# -> Windows -> Windows Application) lets call it SimpleCreditCheckClient

Go to the Start -> All Programs -> Microsoft Windows SDK -> CMD Shell and change the directory to point towards your SimpleCreditCheckClient project directory created above. Use the svcutil.exe command saved in the steps above and paste it on the command window

Click Enter to create the proxy class & config file

Right Click SimpleCreditCheckClient project -> Add -> Add Existing Item -> click on BizTalkServiceInstance.cs and output.config files, and then click Add (rename output.config  to App.config). Also make sure System.ServiceModel.dll is referenced (Right Click References -> Add Reference -> Choose System.ServiceModel from the .NET component)

On the Form, drag & drop 5 textboxes for CompID, CompName, CurrentDate, Amount & Status fields. Label them by dragging & dropping 5 labels of the same name. Disable the Status textBox. Drag & Drop a button and call it Check. Double click the button 'Check' and have the following code:

SimpleCreditCheck_CreditCheck_RP_CreditCheckClient proxy = new SimpleCreditCheck_CreditCheck_RP_CreditCheckClient();

CompanyDetails comp = new CompanyDetails(); CreditCheckResult result = new CreditCheckResult ();

comp.CompID = tbCompID.Text; comp.CompName = tbCompName.Text; comp.CreditCheckDate= tbCreditCheckDate.Text; comp.Amount= Convert.ToInt32(tbAmount.Text);

result = proxy.Operation_1(comp);

if (result.ApprovedStatus) tbStatus = "Passed"; else tbStatus = "Failed";

Run the CreditCheckClient - Enter the Amount and check - change the Rules to a new version - deploy & test. Happy to help out if you have any issues. Let me know if you've had to do similar demos/PoCs and would like to share your thoughts.