Introduction

With the advent of the cloud and enterprises building cloud-based applications, enterprises will still want to use their existing on-premise applications. Thus, one of the key requirements in building hybrid cloud-based applications across on-premise and on-cloud environments is the ability to use pre-existing on-premise applications. The BizTalk Server 2010 AppFabric Connect for Services feature now allows BizTalk users to expose their on-premise BizTalk Applications as WCF Services on the cloud, by adding Windows Azure AppFabric Service Bus endpoints. These Service Bus endpoints can subsequently be consumed by clients residing outside the enterprise’s organizational firewall.

Before we go deeper into details of exposing BizTalk Applications to the cloud, let us clarify how cloud related technologies have impacted application and service deployment. We can divide the application and service deployment scenarios into two broad categories:

  • On-premises deployment: An application or service that runs within an organization’s firewall and is typically accessed by clients that are within the firewall.
  • On-cloud deployment: An application or service that runs within an organizational firewall and can be accessed by clients inside or outside the firewall through a Service Bus endpoint exposed in the cloud. The services still run locally in IIS. Only the endpoints are exposed in the cloud.
Windows Azure AppFabric Service Bus provides the capability to take on-premise web services and extend their reach to external clients. Windows Azure AppFabric Service Bus supports this on-cloud scenario with a relay service that can listen to external clients on behalf of the on-premise web service at a given public address and relay messages between both parties.
Windows Azure AppFabric Service Bus provides the platform where developers expose the Service Bus endpoints for their on-premises services. AppFabric Connect for Services enhances the capabilities of the BizTalk WCF Service Publishing Wizard to enable developers to expose on-premise BizTalk application operations to external clients as WCF services via the Windows Azure AppFabric Service Bus relay service.

What does the BizTalk WCF Service Publishing Wizard do?

The BizTalk WCF Service Publishing Wizard essentially exposes the operations in BizTalk Applications as WCF services. AppFabric Connect for Services enhances the wizard to support the relay service provided by Azure AppFabric Service Bus. The wizard enables you to select the operations that you want to expose as services and then creates the following:

  • A local endpoint for the WCF service.
  • A Service Bus endpoint for the WCF service.
  • A Service Bus endpoint for metadata exchange with the WCF service (if configured).
  • Receive ports in the BizTalk Application, which are used to bind to the desired operations.

Security Considerations when Exposing Services on Cloud

Security becomes a paramount concern when organizations expose mission critical data and operations to services outside an organization’s protected environment. To address these concerns, organizations can follow certain security best-practices to ensure that only authenticated clients get access to the service.

  • Client authentication by the Service Bus Relay Service. All the Service Bus relay bindings expose a binding property, ‘RelayClientAuthenticationType’, that controls whether the client consuming the service is required to present an authentication token to the relay service. This property can be set to either ‘None’ or ‘RelayAccessToken’. If the property is set to ‘RelayAccessToken’, the client must provide an authentication token to the Service Bus. The authentication token must be communicated separately to the client, for example, as an e-mail message by the organization hosting the service. In addition to implementing security, setting ‘RelayClientAuthenticationType’ is also a cost-effective solution for the organization hosting the service. If there is no authentication from the Service Bus, any client would be able to hit the service endpoint even if it is eventually denied by the service. As a result, the organization would incur a chargeback even though there was no business operation that resulted.
  • Message-level and transport-level security. WCF inherently provides message-level and transport-level security for services. For more information on message- and transport-level security, see http://msdn.microsoft.com/en-us/library/ms733137.aspx.
Tip: It’s not essentially a security setting, but organizations can also secure the services which are exposed on the cloud by not making the endpoints publicly discoverable. Service Bus provides an ATOM feed which lists all the publicly discoverable endpoints under a given Service Namespace. Making the endpoints discoverable is controlled through the “DiscoveryMode” attribute of an endpoint's behavior in the "ServiceRegistrySetting". This can be set using the BizTalk WCF Adapter Publishing wizard. The disadvantage of not making the endpoints publicly discoverable is that if you have a large number of clients that would be using the service you hosted, you will have to communicate the endpoint URL to each of those clients.

Who Should Read This Whitepaper?

This whitepaper assumes some familiarity with Microsoft BizTalk Server, Windows Azure AppFabric Service Bus, Windows Azure AppFabric Access Control Service (ACS), and Windows Communication Foundation (WCF). This whitepaper is intended for the following users:

  • Organizations that want to extend the reach of their on-premises BizTalk applications to the cloud by exposing them as WCF Services with endpoints in Windows Azure AppFabric Service Bus.
  • Users that want to consume the web service that is extended to the cloud, to perform operations implemented in BizTalk Application that are deployed inside an organization’s firewall.

Business Scenario

This whitepaper provides information on how to use the BizTalk WCF Service Publishing Wizard to expose operations supported by on-premises BizTalk applications as web services with Service Bus endpoints, making the web services accessible to external clients. This whitepaper is written around a business scenario to help demonstrate the feature. The scenario is as follows:
  • Contoso is an organization providing a credit checking service that takes an input document that contains current date, company details, and the amount for which its credit-worthiness is being checked (see Input.xsd below). After processing, this service sends a reply indicating whether credit is approved or rejected in the ApprovalStatus Boolean value (see output.xsd below).
  • Credit approval is limited in this example by a business rule that approves only credit requests that do not exceed $1000. Credit requests greater than $1000 are denied.
  • Contoso would like the credit check service to be accessible to its external partners located outside Contoso’s firewall.
  • For this scenario, Contoso developers have developed a very simple BizTalk orchestration as shown below.

  • The screenshots below provide a view of the schemas for this example's input and output messages:

This whitepaper describes the features provided by AppFabric Connect for Services for the BizTalk WCF Service Publishing Wizard that allow Contoso to expose this BizTalk application as a external web service via the Service Bus relay service. The whitepaper also provides the procedures partner companies can use when writing a client application to invoke the service exposed by Contoso.

Prerequisites

Make sure you have the following components installed or configured before you proceed further:

  • You must have BizTalk Server 2010 installed to use this feature. Specifically, the BizTalk Server 2010 development tools must be installed on the machine where this feature will be used.
  • You must have registered a service namespace with Windows Azure AppFabric Service Bus. Visit the Windows Azure AppFabric portal (http://go.microsoft.com/fwlink/?LinkId=204209) to register a service namespace with Service Bus.
Note: AppFabric Connect for Services only supports registering Service Bus endpoints with Windows Azure AppFabric 1.0.

Important: If you choose to install Windows Server AppFabric, you must also install hotfix 980423 (http://go.microsoft.com/fwlink/?LinkId=204211). This fixes some issues with Windows Server AppFabric.

Exposing the BizTalk Orchestration as a Service on the Cloud

In this section, we will provide step-by-step instructions on how to expose the orchestration as a service on the cloud using the BizTalk WCF Service Publishing wizard. These steps assume the credit check application is already built and deployed internally behind Contoso's firewall.  For ease of understanding, this section is divided into the following tasks:

  1. Run the BizTalk WCF Service Publishing Wizard.
  2. Bind the Receive Port created by the Wizard to the Orchestration.
  3. Set the Application Pool for the ContosoCreditCheck WCF Web Service.
  4. Configure the WCF Service to Start Automatically.
  5. Verify the Service Bus endpoints for the WCF service are published.

Run the BizTalk WCF Service Publishing Wizard

This section walks through each screen of the BizTalk WCF Service Publishing wizard

  1. Run the BizTalk WCF Service Publishing wizard by clicking Start, Microsoft BizTalk Server 2010, BizTalk WCF Service Publishing Wizard. Click Next on the Welcome screen of the wizard.
  2. The wizard prompts for the configuration of the type of service endpoints that will be created, as shown below.  Contoso will have an on-premise metadata endpoint for on-premise testing purposes. So check the Enable on-premise metadata exchange check box. The Contoso developer also checks the option to Create BizTalk receive locations in the following application. Select the ContosoCreditCheck BizTalk application and click Next.

  3. The next screen prompts the user to decide if the reach of WCF service will be extended to the cloud. In order to extend the reach of the WCF service to cloud, click the Add a Service Bus endpoint checkbox. Then click Next.

  4. The next screen prompts the user to specify which BizTalk artifacts are to be exposed as a web service. In this example, we choose to create a WCF service which will only be based on the orchestrations in a BizTalk assembly. Click Publish BizTalk orchestrations as WCF service and then click Next.

  5. The next screen, shown below, prompts the Contoso developer for the BizTalk Assembly that contains the orchestrations from which the WCF service will be based.  Browse to the correct assembly, and click Next.

  6. The next screen, shown below, shows the result of the wizard's analysis for the chosen assembly.

    In order to publish a receive port from an orchestration to the WCF service, the access restriction setting of the port type must be configured as Public.  This can be reconfigured in the orchestration view in Visual Studio by right clicking the port and clicking Configure Port to run the port configuration wizard to create a new Public port type.  You would have to rebuild and deploy the orchestration then restart the BizTalk WCF Service Publishing wizard.

    When you use the AppFabric Connect feature by clicking Add a Service Bus endpoint (Step 3 above), all selected ports will be merged into a single WCF Service.  This is the reason that the merge option is disabled.  Additionally, all the selected ports should be either one-way or two-way. Merging one-way and two-way ports into a single WCF service is not supported by the wizard.

    Select the receive ports that will be published to the WCF service and then click Next.

  7. The next screen, shown below, allows the configuration of the namespace for the WCF Service.  In this case, we accept the default and click Next.

  8. The next screen, shown below, allows the IIS configuration for the WCF service. For this example, accept the default location and allow anonymous access to the WCF Service by clicking Allow anonymous access to the WCF service. Then click Next.

  9. The next screen, shown below, allows the configuration of the Service Bus endpoint relay bindings. Make the selections shown below and click Next.

    Relay Bindings: The following relay bindings are supported with their associated URL schemes:
    • NetTcpRelayBinding
    • BasicHttpRelayBinding
    • WS2007HttpRelayBinding

    Service Namespace: This configuration is the service namespace associated with an enabled Azure AppFabric Service Bus account. Contoso purchased an Azure AppFabric Service Bus account with the service namespace of Contoso.

    Enable endpoint discovery in Service Bus Registry ATOM feed
    :  This setting allows the Service Bus endpoints to be publicly discoverable in an ATOM feed page for the Azure AppFabric Service Bus account.

    Enable metadata exchange on cloud:  This setting instructs the wizard to also create a metadata exchange Service Bus endpoint for external clients to be able to generate a proxy to the WCF service.

  10. The next screen, shown below, accepts the authentication information for the previously configured Azure AppFabric Service Bus namespace. Make the selections shown below and click Next.

    Issuer Name: Enter a valid issuer name associated with the AppFabric Account that owns the Service Namespace. This is required to authenticate the identity of the service namespace owner to the Service Bus.

    Issuer Key: Specify the secret key for authentication of the service namespace owner.

    Enable Service Bus client authentication for service endpoint:  This setting controls whether the client consuming the service is required to present an authentication token to the relay service. If enabled, the client must provide an authentication token to the Service Bus.  The Azure AppFabric Service Bus account is charged based on access. This setting can help prevent unauthorized client access and charges against the Service Namespace (ex. denial of service attacks, etc.).

    Enable Service Bus client authentication for metadata exchange: This setting controls whether the client is required to present an authentication token to the relay service before it can retrieve metadata. The Azure AppFabric Service Bus account is charged based on number of clients accessing the Service Bus endpoints. This setting can help prevent unauthorized client access and charges against the given Service Namespace (ex. denial of service attacks, etc.). In this example we do not require client authentication for the Service Bus metadata exchange endpoint.

  11. The next screen provides a summary of the configurations allowing you to verify all configurations.  Click Next.

  12. When the WCF service has been successfully created along with the Azure AppFabric Service Bus endpoint, a report similar to the following is generated. Click Finish.

Bind the Receive Port created by the Wizard to the Orchestration.

In this BizTalk Credit Check example application, there are no receive ports or receive locations configured for the application except for the receive port and receive location created by the BizTalk WCF Service Publishing wizard. So we will bind the orchestration to the new receive port and enable the receive location. For more in-depth information regarding configuring WCF Services generated by the wizard see, http://msdn.microsoft.com/en-us/library/bb259973(BTS.70).aspx.

  1. Run the BizTalk Server 2010 Administration console by clicking Start, expand All Programs, expand Microsoft BizTalk Server 2010, click BizTalk Server Administration.
  2. In the BizTalk Server Administration Console, expand BizTalk Server Administration, expand the BizTalk group, expand Applications, and then expand the ContosoCreditCheck application. Right-click the application and click Configure. If the application's host has not been configured, set the host to BizTalkServerApplication.
  3. Bind the inbound logical port to the WCF receive port (named WcfReceivePort_ContosoCreditCheck/WcfService_ContosoCreditCheck in this example). Click OK.
  4. Under the ContosoCreditCheck application, click the Receive Locations node. Right-click the WCF service receive location and click Enable
  5. Under the ContosoCreditCheck application, click the Orchestrations node.  Right-click the orchestration and click Enlist as shown below. Right-click the orchestration again (named ContosoCreditCheck.CreditCheck in this example) and click Start.

Set the Application Pool for the ContosoCreditCheck WCF Web Service.

The application pool hosting the WCF service must be configured to use .Net Framework version 4.0 and the Integrated managed pipeline mode. The following steps show how to configure the application pool.

  1. Run Internet Information Services (IIS) Manager by Clicking Start, All Programs, Windows Server AppFabric, Internet Information Services (IIS) Manager.
  2. Right click the ContosoCreditCheck service and click Manage Application then Advanced Settings as shown below.

  3. Set the Application Pool setting to an Application Pool that supports .Net Framework version 4.0 and the Integrated managed pipeline mode.  For example, the default ASP.NET v4.0 application pool supports both of these settings. Set the application pool to ASP.NET v4.0 as shown below and click OK.

Configure the WCF Service to Start Automatically

The Auto-Start feature is only available for IIS version 7.5 and later versions.  IIS 7.5 is available only for Microsoft Windows 7 and Microsoft Windows Server 2008 R2.  Since IIS 7.5 is not supported on Microsoft Windows Server 2008 or Microsoft Windows Vista, auto-start is also not supported on these platforms. You can bring up the service using the on-premise endpoints and this will establish the Service Bus endpoints as well for external client access.

Windows Server AppFabric is a management console that eases configuring auto-start and many other cumbersome management tasks. Thus, we recommend installing Windows Server AppFabric on Windows Server 2008 R2 and Windows 7 platforms. Even on Windows Server 2008 and Windows Vista, installing Windows Server AppFabric is recommended because of its rich manageability features. For more information on configuring Auto-Start see, http://msdn.microsoft.com/en-us/library/ee677285.aspx. The procedures below show how to enable Auto-Start with Windows Server AppFabric installed.

  1. If the IIS manager is not still running, run Internet Information Services (IIS) Manager by Clicking Start, All Programs, Windows Server AppFabric, Internet Information Services (IIS) Manager.
  2. Right click the ContosoCreditCheck service and click Configure under Manage WCF and WF Services.

  3. Set Auto-Start to Enabled for the service and click OK.

Verify the Service Bus Endpoints for the WCF Service are published

While configuring the service, we had set a property that would make all the endpoints publicly discoverable (see Step 9, "Run the BizTalk WCF Service Publishing Wizard").  To verify if the endpoints are published, view the publicly discoverable endpoints listed in the ATOM feed page for the specified service namespace. The URL for the Service Bus ATOM feed page has the following format:

http://<service namespace>.servicebus.windows.net

In this procedure, the service namespace we used was Contoso. Therefore, the URL will be:

http://Contoso.servicebus.windows.net

Enter this URL in a Web browser and press Enter. It should list all the endpoints available under the specified namespace. If the service you created is registered successfully with Service Bus, you will see it listed as a Public service. In this example the contosocreditcheck service is listed. Clicking contosocreditcheck navigates to list the endpoints created for the service. In this example the following two endpoints are listed for the contosocreditcheck service which verifies the endpoints were published:

  • wcfservice_contosocreditcheck.svc_mex
  • wcfservice_contosocreditcheck.svc

Create a Client to Invoke the Service

In this section, we will create a console application as a client to test the credit check operation through the WCF service.  The client will test both the on-premise endpoint and the Service Bus endpoint. The client will first generate a proxy to the WCF service using the Service Bus endpoint. Next, the client will issue a credit request for the amount of $999 to the on-premise endpoint to test the WCF service locally without involving Windows Azure AppFabric Service Bus. Since this request is not greater than $1000, the request should be approved by returning an ApprovalStatus value of True for the CreditCheckResult. The client will then proceed to test the WCF service as an external client through the Service Bus endpoint.  A credit request for the amount value of $1001 will be issued against the Service Bus endpoint. This request should be denied with an ApprovalStatus value of False since it is greater than $1000.

  1. Start Visual Studio 2010 and create a new console application. For this example, the project is named ContosoCreditCheckClient.
  2. In the Solution Explorer, right-click References, and click Add Service Reference.
  3. In the Add Service Reference dialog box, add the Address for the Service Bus metadata exchange endpoint. To do this, do the following:

    1. You can get the URL from the ATOM feed page that listed all the publicly discoverable endpoints. For this example, opening http://contoso.servicebus.windows.net/ in the web browser will open the Contoso ATOM feed.
    2. contosocreditcheck is listed as a public service. Click contosocreditcheck to navigate to the endpoints created for the service. Right-click the metadata exchange endpoint (wcfservice_contososcreditcheck.svc_mex in this example), and click Copy Shortcut.
    3. In Visual Studio, paste the copied address into the Address field of the Add Service Reference dialog box. For this example, the URL for the Service Bus metadata exchange endpoint is:
      1. https://contoso.servicebus.windows.net/ContosoCreditCheck/WcfService_ContosoCreditCheck.svc_mex/
    4. Specify the namespace. For this example, ContosoCreditService was entered for the namespace.
    5. Click OK.

  4. When Service Bus client authentication for the service endpoint is enabled, the client will need to pass an authentication token to authenticate with the Service Bus. In this example, we will use the SharedSecret credential type. Provide the client authentication token by modifying the app.config file for the client application in the following manner.

    1. Open the app.config for the client and add the following within the system.serviceModel element:

      <behaviors>
        <endpointBehaviors>
          <behavior name="sharedSecretClientCredentials">
            <transportClientEndpointBehavior credentialType="SharedSecret">
              <clientCredentials>
                <sharedSecret issuerName="owner" issuerSecret="A Valid Contoso Service Bus Access key" />
              </clientCredentials>
            </transportClientEndpointBehavior>
          </behavior>
        </endpointBehaviors>
      </behaviors>

      In this snippet, the behavior name is specified as "sharedSecretClientCredientials". You can set this to any other value. You must obtain valid values for issuerName and issuerSecret from the organization that hosted the service.

      Note: Clients can use other authentication mechanisms like SAML token or SWT token as well.  For more information on authentication types for Service Bus endpoints see, http://msdn.microsoft.com/en-us/library/dd582752.aspx.

    2. In the app.config, add the behaviorConfiguration property to the client/endpoint element for the Service Bus endpoint named RelayEndpoint. You must set the behaviorConfiguration property to the same value you specified for the behavior name. So, if you set the behavior name to "sharedSecretClientCredientials", the updated endpoint element would now be:

      <client>
              binding="netTcpRelayBinding" bindingConfiguration="RelayEndpoint"
              contract="ContosoCreditCheck.WcfService_ContosoCreditCheck"
              name="RelayEndpoint" behaviorConfiguration="sharedSecretClientCredentials"/>
       
              binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ITwoWayAsync"
              contract="ContosoCreditCheck.WcfService_ContosoCreditCheck"
              name="WSHttpBinding_ITwoWayAsync">
                  <identity>
                      <userPrincipalName value="someuser@contoso.com" />
                  </identity>
          </endpoint>
      </client>

    3. Save and close the app.config.

  5. Open the Program.cs for the application and add the following code:

    C#

    namespace ContosoCreditCheckClient    
    {   
        class Program      
        {    
            static void Main(string[] args) 
            {
                ContosoCreditService.WcfService_ContosoCreditCheckClient client = new ContosoCreditService.WcfService_ContosoCreditCheckClient("WSHttpBinding_ITwoWayAsync");
     
                ContosoCreditService.CompanyDetails CompanyInfo = new ContosoCreditService.CompanyDetails();
                CompanyInfo.CompanyID = "ContosoClientCompany_ABC123";
                CompanyInfo.CompanyName = "Contoso Client ABC123";
                CompanyInfo.CreditCheckDate = DateTime.Now.ToLongDateString();
                CompanyInfo.Amount = 999;
     
                Console.WriteLine("\n\n******************************************************");
                Console.WriteLine("*** Credit Check Request using On-Premise Endpoint ***");
                Console.WriteLine("******************************************************\n");
     
                SimpleTest(ContosoCreditService.WcfService_ContosoCreditCheckClient client, ContosoCreditService.CompanyDetails CompanyInfo);
     
                ContosoCreditService.WcfService_ContosoCreditCheckClient client = new ContosoCreditService.WcfService_ContosoCreditCheckClient("RelayEndpoint");
     
                ContosoCreditService.CompanyDetails CompanyInfo = new ContosoCreditService.CompanyDetails();
                CompanyInfo.CompanyID = "ContosoClientCompany_ABC123";
                CompanyInfo.CompanyName = "Contoso Client ABC123";
                CompanyInfo.CreditCheckDate = DateTime.Now.ToLongDateString();
                CompanyInfo.Amount = 1001;
                 
                Console.WriteLine("\n\n*******************************************************");
                Console.WriteLine("*** Credit Check Request using Service Bus Endpoint ***");
                Console.WriteLine("*******************************************************\n");
     
                SimpleTest(ContosoCreditService.WcfService_ContosoCreditCheckClient client, ContosoCreditService.CompanyDetails CompanyInfo);  
            }
                 
     
            static void SimpleTest(ContosoCreditService.WcfService_ContosoCreditCheckClient client, ContosoCreditService.CompanyDetails CompanyInfo)
            {
                try
                {
                    Console.WriteLine("Company ID :\t" + CompanyInfo.CompanyID);
                    Console.WriteLine("Company Name :\t" + CompanyInfo.CompanyName);
                    Console.WriteLine("Credit Check Date :\t" + CompanyInfo.CreditCheckDate);
                    Console.WriteLine("Amount :\t" + CompanyInfo.Amount.ToString() + "\n");
     
                    ContosoCreditService.CreditCheckResult result = client.CheckCredit(CompanyInfo);
     
                    Console.WriteLine("***************************");
                    Console.WriteLine("*** Credit Check Result ***");
                    Console.WriteLine("***************************\n");
                    Console.WriteLine("Company ID :\t" + result.CompanyID);
                    Console.WriteLine("Credit Check Date :\t" + result.CreditCheckDate);
                    Console.WriteLine("ApprovalStatus :\t" + result.ApprovalStatus.ToString() + "\n");
                }
                catch (Exception ex)
                {
                    Console.WriteLine("\nException Message : " + ex.Message + "\n");
                    Console.WriteLine("Exception Source : " + ex.Source + "\n");
     
                    if (ex.InnerException != null)
                    {
                        Console.WriteLine("\nInner Exception Message : " + ex.InnerException.Message + "\n");
                        Console.WriteLine("Inner Exception Source : " + ex.InnerException.Source + "\n");
                    }
                }
            
        }  
     
    }

  6. Save Program.cs and Press F6 to build the solution and then press F5 to run the application.
  7. The client application should get an approved credit check with the on-premise endpoint and then a denied credit check on the service bus endpoint. The following screenshot shows an example result of the test client.

Known Issues

This section lists some known issues with suggested workarounds for the BizTalk WCF Service Publishing Wizard.

BizTalk Schemas with multiple root nodes.

If a BizTalk Schema with multiple root nodes is used with the BizTalk WCF Service Publishing Wizard, a WSDL validation error will be reported when generating the client proxy but, it can be safely ignored.

Modifying the Service Path part of a Service Bus URL

Do not modify the Service Path part of the Service Bus URL in the web.config file generated by the wizard. This will lead to runtime failures.

Issues with Unicode Characters

The BizTalk WCF Service Publishing wizard may fail to work properly if it encounters Unicode characters. For example, the wizard might not give the desired results if the BizTalk artifacts being exposed as services have Unicode characters in their names. You should not use Unicode characters when working with BizTalk WCF Service Publishing wizard.

See Also

Another important place to find a huge amount of BizTalk related articles is the TechNet Wiki itself. The best entry point is BizTalk Server Resources on the TechNet Wiki