Introduction

With Release of BizTalk 2013, a new adapter was available which helps expose BizTalk endpoints as  REST endpoints, This adapter, webhttp adapter has opened up a lot of integration possiblities as many app in todays scenario like to use the REST apis. This article aims to discuss how to configure and expose the BizTalk endpoint as a GET endpoint using BTDF framework. This article assumes that the reader has a basic understanding of BizTalk product and how the development and deployment for BizTalk  application works. This article is can be thought of as part two of BizTalk Server: Creating and Deploying BizTalk HTTP Receive Locations using BTDF framework 

↑Back To Top 


BizTalk Application

The sample BizTalk application accepts the FirstName and LastName as the input in the service url and sends back an appended name. The first name and the last name are provided as parameters in the GET request and the BizTalk orchestration appends the name and returns the response. Following is the BizTalk response xsd.

  <xs:annotation>
    <xs:appinfo>
      <b:imports xmlns:b="http://schemas.microsoft.com/BizTalk/2003">
        <b:namespace prefix="ns0" uri="https://WebHttpLocationBTDFDemo.PropertySchema" location=".\PropertySchema.xsd" />
      </b:imports>
    </xs:appinfo>
  </xs:annotation>
  <xs:element name="Response">
    <xs:annotation>
      <xs:appinfo>
        <b:properties>
          <b:property distinguished="true" xpath="/*[local-name()='Response' and namespace- uri()='http://WebHttpLocationBTDFDemo.ServiceTypes']/*[local-name()='FullName' and namespace-uri()='']" />
        </b:properties>
      </xs:appinfo>
    </xs:annotation>
    <xs:complexType>
      <xs:sequence>
        <xs:element name="FullName" type="xs:string" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>


The orchestration accepts a untyped message (XMLDocument), hence the receive shape in the orchestration requires a filter expression to create subscriptions. Following is the orchestration screenshot.

The first and the last names can be accessed like below.

varFirstName = msgIp(WebHttpLocationBTDFDemo.FirstName);
varLastName = msgIp(WebHttpLocationBTDFDemo.LastName);
varFullName = varFirstName + varLastName;
varXmlDoc = new System.Xml.XmlDocument();
varXmlDoc.LoadXml("<ns0:Response xmlns:ns0='http://WebHttpLocationBTDFDemo.ServiceTypes'><FullName></FullName></ns0:Response>");
msgOp = varXmlDoc;
msgOp.FullName = varFullName;

↑Back To Top


Using BTDF To Create WebHttp GET Endpoint

Introduction To BTDF 

BTDF is an open source deployment framework used for deploying BizTalk applications on local dev boxes as well as different environments. It provides many facilities that can be used to club together the task that require to be performed pre and post deployment of the BizTalk deployment e.g restarting of the concerned Host Instances, IIS reset etc. Another advantage of BTDF is that it is very flexible and can be configured to do a lot of tasks before, during and after the deployment of BizTalk application. All these tasks can be packaged up as a single msi file and can be installed on the target environment. It also provides facility to define the variables related to different environments in a spreadsheet which simplifies the task of manually maintaining the binding files for the BizTalk application for Multiple environment. These are some of the features of BTDF. BTDF has proven to be a very reliable tool for creating build msi for BizTalk. It is a necessary weapon in the arsenal of a professional working on BizTalk platform. 

This article uses the latest version 5.7 that is released. To learn more about the installation of the btdf and step by step guide for configuring the BTDF, refer following link. The link discusses the steps taken for BizTalk 2016 and Visual Studio 2015 , but same can be followed for other versions of BizTalk.

Step by Step Guide For Installation and Configuration of BTDF for BizTalk 2016 and Visual Studio 2015 

Creating Services Project For Deployment

Before the BTDF can be configured to deploy the services, a project which houses the service descriptions and schemas related to the BizTalk web http service, Following is a sample of the services project.


Setting Up Initial Properties

In order to create the IIS application and reset the application pool after the deployment , following properties need to be set under the <PropertyGroup> record in the btdf project file. 

<IncludeVirtualDirectories>True</IncludeVirtualDirectories>
<SkipIISReset>False</SkipIISReset>

In case if the IISReset is not required, the the <SkipIISReset> property can be set to True 

Including BizTalk Application To Deploy

As the sample project contains only one BizTalk project which has all the artefacts clubbed together, just one item group is sufficient for the BTDF to deploy the assembly to BizTalk group.

<ItemGroup>
  <Schemas Include="WebHttpLocationBTDFDemo.dll">
    <LocationPath>..\$(ProjectName)\bin\$(Configuration)</LocationPath>
  </Schemas>
</ItemGroup>

Creating Application Pool

In order to create the application pool to process the request received at IIS, an <ItemGroup> has to be added to the  btdf project file. BTDF gives the flexibility to the developers to deploy their application from Visual Studio also and by creating a build server msi. So two different setting need to be made based upon the method of deployment. The main difference between the two settings is the way they read the user ID and password for the identity to be set up for the application pool. In case of the Visual studio deployment the user Id and password can be configured in the item group itself while in case of server deploy using msi it can be asked from the administrator installing the msi

Deploying From Visual Studio

Following are the properties that need to be set up for the BTDF to be able to create the Application pool in IIS when the developer does a deployment from Visual Studio using BTDF .

<ItemGroup>
  <IISAppPool Include="webHTTPAdapterDemoAppPool" Condition="'$(Configuration)' != 'Server'">
    <DeployAction>Create</DeployAction>
    <DotNetFrameworkVersion>v4.0</DotNetFrameworkVersion>
    <IdentityType>SpecificUser</IdentityType>
    <UserName>hostname\localUserAddedToIsolatedHostUsersGroup</UserName>
    <Password>password</Password>
    <PipelineMode>Integrated</PipelineMode>
    <UndeployAction>Delete</UndeployAction>
  </IISAppPool>
</ItemGroup>

Deploying Using MSI

Following are the properties that need to be set up so that when the deployment is being done on a server instead of a dev box, the BTDF is able to create the Application pool in IIS.

<ItemGroup>
  <IISAppPool Include="webHTTPAdapterDemoAppPool" Condition="'$(Configuration)' == 'Server'">
    <DeployAction>Create</DeployAction>
    <DotNetFrameworkVersion>v4.0</DotNetFrameworkVersion>
    <IdentityType>SpecificUser</IdentityType>
    <UserName>$(IsolatedHostUserName)</UserName>
    <Password>$(IsolatedHostUserPassword)</Password>
    <PipelineMode>Integrated</PipelineMode>
    <UndeployAction>Delete</UndeployAction>
  </IISAppPool>
</ItemGroup>

The variable $(IsolatedHostUserName) and $(IsolatedHostUserPassword) are to be set up in the InstallWizard.xml file ( gets generated while creating a BTDF project).

A sample InstallWizard.xml file is shown below.

<?xml version="1.0" encoding="utf-8" ?>
<!--
    Deployment Framework for BizTalk
    Copyright (C) 2008-14 Thomas F. Abraham, 2004-08 Scott Colestock
-->
<!-- Each SetEnvUIConfigItem element defines a single page in the wizard that appears during a server deployment. -->
<!-- The EnvironmentVarName element specifies the name of an environment variable that will contain the value of the -->
<!-- user's selection. Each environment variable automatically becomes an MSBuild property that you may reference in -->
<!-- your .btdfproj file. -->
   <DialogCaption>WebHttpLocationBTDFDemo</DialogCaption>
  <SetEnvUIConfigItem>
    <PromptText>Select the XML file that contains configuration information specific to this environment:</PromptText>
    <PromptValue></PromptValue>
    <ValueType>FileSelect</ValueType>
    <EnvironmentVarName>ENV_SETTINGS</EnvironmentVarName>
  </SetEnvUIConfigItem>
  <SetEnvUIConfigItem>
    <PromptText>Enter the domain qualified username for the IIS app pool</PromptText>
    <PromptValue></PromptValue>
    <ValueType>Text</ValueType>
    <EnvironmentVarName>IsolatedHostUserName</EnvironmentVarName>
  </SetEnvUIConfigItem>
  <SetEnvUIConfigItem>
    <PromptText>Enter the Password for the Username entered in previous step</PromptText>
    <PromptValue></PromptValue>
    <ValueType>Password</ValueType>
    <EnvironmentVarName>IsolatedHostUserPassword</EnvironmentVarName>
  </SetEnvUIConfigItem>
  <SetEnvUIConfigItem>
      <PromptText>Is this the LAST server in the BizTalk Group you are deploying to?If so, BizTalk assemblies will be deployed to the BizTalk Management Database.</PromptText>
      <Caption>This is the LAST server in the BizTalk Group</Caption>
      <PromptValue>true</PromptValue>
      <ValueType>Checkbox</ValueType>
      <EnvironmentVarName>BT_DEPLOY_MGMT_DB</EnvironmentVarName>
   </SetEnvUIConfigItem>
</SetEnvUIConfig>

Creating an IIS Application

In order to create an IIS application after the deployment, following setting needs to be added to the BTDF project. ( Here the service details that were captured earlier from the IIS , copied to the WebHttpLocationBTDFDemo.Services project will be used). 

<ItemGroup>
  <IISApp Include="WebHttpLocationDemo">
    <AppPoolName>webHTTPAdapterDemoAppPool</AppPoolName>
    <DeployAction>CreateOrUpdate</DeployAction>
    <UndeployAction>Delete</UndeployAction>
    <SiteName>Default Web Site</SiteName>
    <PhysicalPath>..\$(ProjectName).Services</PhysicalPath>
    <VirtualPath>/WebHttpLocationDemo</VirtualPath>
    <Exclusions>*.csproj;Web.Debug.config;Web.Release.config;obj;Properties;bin</Exclusions>
  </IISApp>
</ItemGroup>

The exclusion tells the BTDF to ignore the files that it should not deploy under the IIS Application.

Configuring The Receive Location in Port Bindings Master 

A typical entry for the recive location exposed a GET REST endpoint will look like following.

    <ReceivePort Name="WcfReceivePort_WebHttpLocationDemo/Service1" IsTwoWay="true" BindingOption="1" AnalyticsEnabled="false">
      <Description xsi:nil="true" />
      <ReceiveLocations>
        <ReceiveLocation Name="WcfService_WebHttpLocationDemo/Service1">
          <Description xsi:nil="true" />
          <Address>/WebHttpLocationDemo/Service1.svc</Address>
          <PublicAddress />
          <Primary>true</Primary>
          <ReceiveLocationServiceWindowEnabled>false</ReceiveLocationServiceWindowEnabled>
          <ReceiveLocationFromTime>2000-01-01T00:00:00</ReceiveLocationFromTime>
          <ReceiveLocationToTime>2000-01-01T23:59:59</ReceiveLocationToTime>
          <ReceiveLocationStartDateEnabled>false</ReceiveLocationStartDateEnabled>
          <ReceiveLocationStartDate>2000-01-01T00:00:00</ReceiveLocationStartDate>
          <ReceiveLocationEndDateEnabled>false</ReceiveLocationEndDateEnabled>
          <ReceiveLocationEndDate>2000-01-01T23:59:59</ReceiveLocationEndDate>
          <ReceiveLocationTransportType Name="WCF-WebHttp" Capabilities="387" ConfigurationClsid="e5b2de81-de67-4559-869b-20925949a1e0" />
          <ReceiveLocationTransportTypeData><CustomProps><DisableLocationOnFailure vt="11">0</DisableLocationOnFailure><HttpMethodAndUrl vt="8">&lt;BtsHttpUrlMapping&gt;
&lt;Operation Name="AppendName" Method="GET" Url="/AppendName?FirstName={FirstName}&amp;amp;LastName={LastName}" /&gt;
&lt;/BtsHttpUrlMapping&gt;</HttpMethodAndUrl><MaxReceivedMessageSize vt="3">65536</MaxReceivedMessageSize><VariablePropertyMapping vt="8">&lt;BtsVariablePropertyMapping xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
  &lt;Variable Name="FIRSTNAME" PropertyName="FirstName" PropertyNamespace="https://WebHttpLocationBTDFDemo.PropertySchema" /&gt;
  &lt;Variable Name="LASTNAME" PropertyName="LastName" PropertyNamespace="https://WebHttpLocationBTDFDemo.PropertySchema" /&gt;
&lt;/BtsVariablePropertyMapping&gt;</VariablePropertyMapping><SecurityMode vt="8">None</SecurityMode><IncludeExceptionDetailInFaults vt="11">0</IncludeExceptionDetailInFaults><TransportClientCredentialType vt="8">None</TransportClientCredentialType><OpenTimeout vt="8">00:01:00</OpenTimeout><UseSSO vt="11">0</UseSSO><SuspendMessageOnFailure vt="11">0</SuspendMessageOnFailure><CloseTimeout vt="8">00:01:00</CloseTimeout><SendTimeout vt="8">00:01:00</SendTimeout><MaxConcurrentCalls vt="3">200</MaxConcurrentCalls></CustomProps></ReceiveLocationTransportTypeData>
          <ReceivePipeline Name="Microsoft.BizTalk.DefaultPipelines.XMLReceive" FullyQualifiedName="Microsoft.BizTalk.DefaultPipelines.XMLReceive, Microsoft.BizTalk.DefaultPipelines, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Type="1" TrackingOption="None" Description="" />
          <ReceivePipelineData><Root xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Stages><Stage CategoryId="9d0e4105-4cce-4536-83fa-4a5040674ad6"><Components><Component Name="Microsoft.BizTalk.Component.XmlDasmComp"><Properties><AllowUnrecognizedMessage vt="11">-1</AllowUnrecognizedMessage></Properties></Component></Components></Stage><Stage CategoryId="9d0e410e-4cce-4536-83fa-4a5040674ad6"><Components><Component Name="Microsoft.BizTalk.Component.PartyRes"><Properties /></Component></Components></Stage></Stages></Root></ReceivePipelineData>
          <SendPipeline Name="Microsoft.BizTalk.DefaultPipelines.PassThruTransmit" FullyQualifiedName="Microsoft.BizTalk.DefaultPipelines.PassThruTransmit, Microsoft.BizTalk.DefaultPipelines, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Type="2" TrackingOption="None" Description="" />
          <SendPipelineData xsi:nil="true" />
          <Enable>true</Enable>
          <ReceiveHandler Name="BizTalkServerIsolatedHost" HostTrusted="false">
            <TransportType Name="WCF-WebHttp" Capabilities="387" ConfigurationClsid="e5b2de81-de67-4559-869b-20925949a1e0" />
          </ReceiveHandler>
          <ScheduleRecurrenceType>None</ScheduleRecurrenceType>
          <ScheduleRecurenceFrom>2018-03-04T00:00:00</ScheduleRecurenceFrom>
          <ScheduleRecurrenceInterval>1</ScheduleRecurrenceInterval>
          <ScheduleDaysOfWeek>None</ScheduleDaysOfWeek>
          <ScheduleMonths>None</ScheduleMonths>
          <ScheduleMonthDays>None</ScheduleMonthDays>
          <ScheduleOrdinalDayOfWeek>None</ScheduleOrdinalDayOfWeek>
          <ScheduleOrdinalType>None</ScheduleOrdinalType>
          <ScheduleIsOrdinal>false</ScheduleIsOrdinal>
          <ScheduleLastDayOfMonth>false</ScheduleLastDayOfMonth>
          <ScheduleAutoAdjustToDaylightSaving>true</ScheduleAutoAdjustToDaylightSaving>
          <ScheduleTimeZone>UTC</ScheduleTimeZone>
        </ReceiveLocation>
      </ReceiveLocations>
      <SendPipelineData xsi:nil="true" />
      <Authentication>0</Authentication>
      <Tracking>0</Tracking>
      <Transforms />
      <OutboundTransforms />
      <RouteFailedMessage>false</RouteFailedMessage>
      <ApplicationName>WebHttpLocationBTDFDemo</ApplicationName>
    </ReceivePort>

This completes the setup of BTDF for the deployment. 

↑Back To Top 


Verifying Deployment

When Deployed using BTDF project configured above, following artifacts were created.

Application Pool

 

IIS Application


BizTalk Receive Location

The HTTP Method and URL mapping for the GET operation is as follows.

<BtsHttpUrlMapping>          
<Operation Name="AppendName" Method="GET" Url="/AppendName?FirstName={FirstName}&LastName={LastName}" />
</BtsHttpUrlMapping>

The {FirstName} and {LastName} are mapped using the promoted properties as below.


  

↑Back To Top 


Testing

A Get can be done simply using any browser available. Following are some of the samples that were tested against the BizTalk Application deployed earlier.

  

↑Back To Top 


Conclusion 

As observed from the test results, it can be concluded that it is very easy to set up the BizTalk web HTTP receive locations using BTDF. 

↑Back To Top 


See Also

An 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 Technet Wiki 

↑Back To Top 


References

Following articles were referred while writing this article
↑Back To Top