Post In Microsoft tech Net
This article presents a workable solution for consuming ReSTful services using BizTalk Server 2010.
Acknowledgements
We in the BizTalk Server CCxG team gratefully acknowledge the contributions of the following individuals for providing their valuable inputs in setting up the end-to-end scenario used in this article:
- Rupert Benbrook, Senior Consultant, BizTalk Server
- Delbert Murphy, TSP, BizTalk Server
- Anand Bheemrajaiah, BizTalk Server Product Team
- Ankit Raizada, BizTalk Server Product Team
- Shailesh Agre, BizTalk Server PSS
Contents
- What is ReST?
- BizTalk Server and ReST
- Scenario for this Article
- How to Use this Article
- Set up the Design-time
- Deploy the Solution
- Configure the BizTalk Server Application
- Test the Solution
- Download the Sample
- What Next?
What is ReST?
ReST stands for Representational State Transfer and defines an architecture to create network applications, typically over the World Wide Web. In most cases, the protocol used for a ReST client-server communication is HTTP. An application that uses ReST architecture is called a ReSTful application. Such applications use HTTP requests to create, update, read, and delete data, thereby supporting all CRUD operations. These CRUD operations are performed by ReST by supporting the GET, PUT, POST, and DELETE methods.
The two fundamental aspects of a ReST design pattern are:
- Every unique entity is an identifiable resource. A resource could be an XML document, a website, etc.
- URLs identify unique resources. Every resource can be uniquely identified through a URL.
Let us understand this with an example. An organization "Contoso" has a significantly large customer base and wants to provide customers with the option to view their details as stored in Contoso's records. If Contoso decides to expose the customer details the ReSTful way, it would have to think on the lines of:
- Each customer is resource.
- Each customer can be identified by a unique URL.
Going by this theory, a URL that could probably provide details for a customer with ID = 9999 would look like:
http://www.contoso.com/Customer/Details/9999
Had there been no ReSTful way of retrieving customer details, one would have to send a SOAP request that would have probably looked like:
<?
xml
version
=
"1.0"
?>
<
soap:Envelope
xmlns:soap
=
"http://www.w3.org/2001/12/soap-envelope "
soap:encodingStyle
=
"http://www.w3.org/2001/12/soap-encoding "
>
<
GetDetails
>
<
ID
>9999</
ID
>
</
GetDetails
>
</
soap:Body
>
</
soap:Envelope
>
In the case of ReST, the URL is sent over an HTTP GET request to the server and the response is received in the form of raw data. In the traditional SOAP-way of invoking Web services, the XML request message is sent over an HTTP POST request to the server, and the response is embedded as the payload within the SOAP response envelope.
ReST URLs can also include parameters to handle more complicated requests. For example, to get customer details for John Smith, the URL might look like:
http://www.contoso.com/Customer/Details?firstName=John&lastName=Smith
To know more about ReST, you might want to go through the following links:
- A Brief Introduction to REST
- RESTful Web Services (book)
- RESTful .NET (book)
- Steps Toward the Glory or REST
One of the real-life examples of ReST is the Twitter API .
BizTalk Server and ReST
In the previous section we saw how ReST is not SOAP and that ReST supports GET, PUT, POST, and DELETE methods. So, if one has to use ReST with BizTalk Server, the adapter to be used should be able to:
- Exchange non-SOAP messages.
- Support GET, PUT, POST, and DELETE methods.
If we look at the adapters available with BizTalk Server 2010, only the HTTP adapter satisfies the first criteria but it does not support GET (it does support the POST method). Similarly, the webHttpBinding (that supports consuming and exposing ReSTful services) available with WCF-Custom adapter can send non-SOAP messages but that too has no way of specifying the HTTP verb to be used. All other adapters either do not support HTTP verbs or always exchange SOAP messages. So, there is no way to have an out-of-box BizTalk configuration to consume a ReSTful service. To use BizTalk Server with ReST, we'll have to do some customizations around HTTP adapter or the webHttpBinding of the WCF-Custom adapter. There is no prescribed way of doing customizations around the HTTP adapter. However, to the webHttpBinding, we can add some custom behaviors that when coupled with webHttpBinding enable BizTalk users to invoke and consume ReSTful services. Through these customizations, we can specify the following:
- The HTTP method to use in the request (GET, PUT, POST, DELETE).
- How to form the request URL from operation method parameters (URL path and query string template).
- How to encode the request body and decode the response.
With WCF-Custom port configuration, there's no way of specifying these customizations directly on the webHttpBinding. So, we'll have to put these values in the request message. After specifying the values as part of the request message and adding a custom behavior to the webHttpBinding, when the request message hits the WCF-Custom port with the webHttpBinding, the custom behavior extracts the values from the request message and frames the required HTTP transport.
Now let us talk a little bit about the customization that would be required on the webHttpBinding. webHttpBinding is WCF-based. WCF enables you to alter messages before they are sent or after they are received through Message Inspectors . A message inspector is an extension to the client runtime and is configured as a behavior. A behavior, in turn, is added to a behavior extension element. This behavior extension element is registered in the machine.config with an element name, which makes it available to be configured as a custom behavior on a WCF-Custom port. For more information, see Extending WCF with Custom Behaviors .
So, to sum it up, to consume a ReSTful service with BizTalk Server, this is what we need to do:
- Create a request message that has all the required attributes such as HTTP verb, any parameters required to frame the URL, etc.
- Create a message inspector to alter the request message using the attributes specified in the request message.
- Create an endpoint behavior to apply the message inspector to the client endpoint.
- Create a behavior extension element to enable configuration of the endpoint behavior.
Scenario for this Article
In this article, we will use one of the Twitter ReST APIs that give us the public timeline and user-specific timeline . In Twitter parlance, a timeline is the list of tweets. For a public timeline, the list includes the last 20 tweets from unprotected users. For a user-specific timeline, the list includes the last 20 tweets by a specific unprotected user. An unprotected user is someone who has opted to not make the tweets private while setting up the Twitter account. There are two main reasons for picking these two APIs: both support the GET method and both do not require authentication. In this article, we want to keep the focus on how to use the customizations discussed above to use BizTalk Server with ReST. Including authentication with ReST would dilute the focus of this article. Moreover, authentication with ReST could vary with the APIs being used and will have to be handled differently for different applications. For example, Twitter uses OAuth for authenticating applications.
Coming back to the scenario, the uber scenario for this article includes dropping a request message in a folder and out comes the list of tweets (for a public timeline or for a given user) in an e-mail. However, if you break this down into stages, this is what the scenario would look like:
- You drop the request message to a file folder. A FILE receive location consumes the message and drops it to the BizTalk MessageBox database.
- A WCF-Custom send port with webHttpBinding consumes the request message from the MessageBox database. The request message contains the URI template and the method that is used to configure the HTTP transport, in a manner similar to webHttpBinding.
- The custom endpoint behavior extension attached to the WCF-Custom send port invokes the message inspector that uses the ReSTful configuration from the request message, configures the HTTP transport, and sends just the REST message body.
- The receive port tied to the request-response WCF-Custom send port receives the response from Twitter. The orchestration subscribes to this response message and maps it to a generic and simplified output message that will be used to send out the tweets on an e-mail.
- The transformed message is then sent out using an SMTP port.
Now that we understand the scenario, let's look at what all we need to create to have the solution work. We have two sets of requirement here, one for design-time where we will create a Visual Studio solution and one for the deployment-time where we will configure the BizTalk Server application by creating the physical ports in the BizTalk Server Administration console that will be required to send and receive messages.
The design-time, in turn, requires:
- A BizTalk Server project that would contain all the message schemas, orchestration, etc. For the BizTalk Server project you need:
- The schemas for all the messages. We need a schema for the request message, a schema for the response message that comes from Twitter, and finally a schema of how the message will be sent out on an e-mail.
- A map that will map the response message from Twitter to the generic output message that will be sent to the SMTP port, which will eventually send out the response in an e-mail.
- An orchestration that will contain all the logic and manage the flow of message within the BizTalk Server solution.
- A C# class library for the behavior extension element and the message inspector that will alter the message before it is sent to Twitter. The class library must contain:
- A message inspector that will pull the ReSTful configuration from the request message.
- An endpoint behavior to apply the message inspector to the client endpoint.
- A behavior extension element to enable configuration of the endpoint behavior.
For the deployment-time, in the BizTalk Server Administration console, you need:
- A FILE receive location that will pick the request message.
- A solicit-response two-way WCF-Custom send port that will send the request to Twitter and receive a response. This send port will be configured with the behavior extension.
- An SMTP send port that will send the output response on an e-mail.
How to Use this Article
This article is written around a sample, Twitter_BTS, that is available at the MSDN Code Gallery . So, you could either use that sample and go through this article to understand how the sample was built or just use this article to create your own BizTalk Server application. This article is targeted towards the second approach so that you get to understand how this sample was built. Also, to be consistent with the sample, the names of artifacts (e.g. ports, schemas, classes, etc.) used in the article are same as that in the sample.
If you just want to use the sample, make sure you extract the sample files to C:\ root directory. Also, you can use the PortBindings.xml file to create the physical ports in the BizTalk Server Administration console. After you have created the physical ports using the bindings file, you'd need to update the SMTP port configuration to include the e-mail ID to which the tweets must be sent.
Let's start creating the solution.
Set up the Design-time
At design-time, we will create a Visual Studio solution containing a BizTalk Server project and a C# class library and then finally we will deploy the solution. As part of setting up the design-time, we will perform the following tasks:
- For BizTalk Server project:
- For C# class library:
Create a Schema for the Twitter Request Message
- Open Visual Studio as an administrator and create a new BizTalk Server project. Name the projectTwitter_BTS and provide the same name for the solution as well.
- Let us first create the schema of the request message. Before creating the request schema, we must take a look at the Twitter APIs that we will be invoking through the request message. We'll then be able to include the elements/attributes in the request message that will be used to frame the URL to invoke the Twitter API.
- The URL to get the public timeline ishttp://api.twitter.com/version/statuses/public_timeline.format.
- Similarly, the URL to get a user-specific timeline ishttp://api.twitter.com/version/statuses/user_timeline.format .
From the URLs and other information available on the links, we know that we need the following information to invoke the two Twitter APIs:
- The message format. For this scenario article, let us use XML.
- The supported method. For the two APIs we will be using in this scenario article, the supported method is GET.
- The URI for the two Twitter APIs.
- The content type for message exchange.
- Parameters, if any, required to frame the URL for the Twitter APIs.
As mentioned in the preceding section, all these required attributes will be passed in the request message. So, while creating the schema, we must ensure that we have attributes/elements that take these values. Let us now start creating the request message schema.
- Right-click the BizTalk Server project, point to Add, and then click New Item.
- In the Add New Item dialog box, select Schema Files, and in the right pane selectSchema. Give the schema name as TwitterRequest.xsd, and then click Add.
- Create the attributes and elements as shown in the table below:
Node name Type Property Name to be Set Property Value <Schema> - Element FormDefault Qualified Target Namespace http://microsoft.com/schemas/
samples/biztalkwebhttp/1.0bizTalkWebHttpRequest Root node Data Structure Type bizTalkWebHttpRequest RootNode TypeName bizTalkWebHttpRequest method
(The value for this attribute will specify the method to be invoked on the Twitter API)Child attribute to bizTalkWebHttpRequest Data Type xs:string uriTemplate(The value for this attribute will be used to frame the URL) Child attribute to bizTalkWebHttpRequest Data Type xs:string param Child record under bizTalkWebHttpRequest Data Structure Type keyValue Max Occurs unbounded Min Occurs 0 Mixed True name(The value for this attribute will be used as parameters appended to the URL) Child attribute to param Data Type xs:string header Child record under bizTalkWebHttpRequest Data Structure Type keyValue Max Occurs unbounded Min Occurs 0 Mixed True name(The value for this attribute will be used to specify the encoding in the message header that will be sent to invoke the Twitter API) Child attribute to header Data Type xs:string The following screen capture depicts the schema.
Create a Schema for the Twitter Response Message
We will do a little bit of reverse engineering to get the response message schema. We will first get the XML by invoking the Twitter API from a Web browser and then use Visual Studio tools to generate the XSD from the XML.
- Open a Web browser and enter the URL http://api.twitter.com/1/statuses/public_timeline.xml . Save the response in an XML file.
- In Visual Studio, click the View menu, point to Toolbars, and then click XML Editor to view the XML Editor toolbar.
- Go back to the BizTalk Server project and add the XML file to it. Open the XML file using Visual Studio.
- From the XML Editor toolbar, click the Create Schema ( ) button to generate the schema. This is typically the first button on the toolbar. Save the schema file as twitter_user_timeline.xsd.
Create a Schema for the Output Message
Why do we need another schema for output message? Why can't we just send the response from Twitter, straight out? Well, you can of course do that and send the Twitter response as-is in an XML format out in an e-mail. However, if you look at the Twitter response by clicking the URLhttp://api.twitter.com/1/statuses/public_timeline.xml , you will see that the tweet is actually within the <text> element. All other elements just present some metadata either about the user or about the tweet. So, we want to have an output schema that has an element that maps to the <text> element in the tweet response so that all you see in the e-mail output is a list of tweets.
Even after we have mapped the <text> element from the Twitter response to an element in the output schema, the output would still be an XML document , which again does not make a good reading. So, we need an output schema that will send out the tweets in a format that is just like any other e-mail, say in an HTML format. Thankfully we can do so by creating a schema that represents the structure of an HTML document. So, we will create a schema that has the names and structure of an HTML tag. An HTML document typically has a paragraph element within a body element, which in turn, lies within the HTML element. We will create a schema with a similar structure as shown below:
<
html
>
<
body
>
<
p
></
p
>
</
body
>
</
html
>
Let's start creating the schema.
- Right-click the BizTalk Server project, point to Add, and then click New Item.
- In the Add New Item dialog box, select Schema Files, and in the right pane select Schema. Give the schema name as OutputSchema.xsd, and then click Add.
- Create the attributes and elements as shown in the table below:
Node Name Type Property Name to be Set Property Value <Schema> - - HTML Root node - - Body Child record under the HTML element - - P Child field element under Body element Data Type xs:string Max Occurs unbounded Min Occurs 0
The following screen capture depicts the schema:
Map the Twitter Response Message to Output Message
We should now use BizTalk Mapper to map the <text> element in the Twitter response schema to the <P> element in the output schema.
- Right-click the BizTalk Server project, point to Add, and then click New Item.
- In the Add New Item dialog box, select Map Files, and in the right pane select Map. Give the map name as MapResponse.btm, and then click Add.
- For source schema, open twitter_user_timeline.xsd. For the destination schema, open OutputSchema.xsd.
- Map the <text> element in the source schema to the <P> element in the response schema, as shown in the figure below:
Create a BizTalk Server Orchestration
Let's now create an orchestration that will bind the entire application flow.
- Right-click the BizTalk Server project, point to Add, and then click New Item.
- In the Add New Item dialog box, select Orchestration Files, and in the right pane select BizTalk Orchestration. Give the map name as Twitter_BTS_Orch.odx, and then click Add.
- Let's start with creating the messages and message types. We will need three messages for the three schemas that we have in the project. In the Orchestration View, right-click Messages, and then clickNew Message. Create three messages with the following details:
Message Identifier Message Type Request Twitter_BTS.BizTalkWebHttp Response Twitter_BTS.twitter_user_timeline OutputResponse Twitter_BTS.OutputSchema - Add the following message shapes:
Shape Shape Type Properties ReceiveRequest Receive - Set Activate to True
- Set Message to Request
- Set Name to ReceiveRequest
SendRequest Send - Set Message to Request
- Set Name to SendRequest
ReceiveResponse Receive - Set Message to Response
- Set Name to ReceiveResponse
SendResponse Send - Set Message to OutputResponse
- Set Name to SendResponse
- We will now add a construct message shape to the orchestration for the following two reasons: (a) we need to include the map in the orchestration that will map the <text> element from the Twitter response schema to the <P> element in the output response schema. The map will be included through the construct message shape, and (b) even after the elements are mapped to have the output response only contain the tweets, the output response would still be in XML. When this XML is sent out using an SMTP port, it will be rendered in an XML format, which again does not make for a good reading.
So, in the construct message shape we will set a context property on the output response so that the content type of the message is set to text/html. After this is done, the final e-mail output response would read like any other e-mail.- Add a Construct Message shape between the ReceiveResponse and SendResponse shapes. Set the MessageConstructed property on the Construct Message shape to OutputResponse because we will be creating and modifying the output response message through this shape.
- Drag-and-drop a Transform shape within the Construct Message shape. Double-click the Transform shape to open the Transform Configuration dialog box.
- Select the Existing Map option.
- From the Fully Qualified Map Name drop-down list select the map that you created earlier,Twitter_BTS.MapResponse.
- From the left pane, click Source and from the Source Transform grid, select Response.
- Similarly, from the left pane, click Destination and from the Destination Transform grid, selectOutputResponse.
Click OK. - Drag-and-drop a Message Assignment shape within the Construct Message shape. Double-click the Message Assignment shape to open the Expression Editor. Set the ContentType context property on the OutputResponse schema by entering the following in the Expression Editor shape:
By setting this property you are converting the content type of OutputResponse message from XML to HTML so that when the message is sent out using SMTP port, it can be rendered like any other e-mail.OutputResponse(Microsoft.XLANGs.BaseTypes.ContentType) =
"text/html"
;
- Let us know add ports to the orchestration. We'll need a one-way receive port to receive the request message, a two-way send port to send the request to Twitter and receive a response, and finally another one-way send port to send out the response from Twitter. The following table lists the ports that you must create and the properties that you must set on each port. The names listed in the Portcolumn are the names of the ports as displayed in the orchestration.
Port Properties IncomingMessage - Set Identifier to IncomingMessage
- Set Communication Pattern to One-Way
- Set Communication Direction to Receive
SendToTwitter - Set Identifier to SendToTwitter
- Set Communication Pattern to Request-Response
- Set Communication Direction to Send-Receive
OutgoingMessage - Set Identifier to OutgoingMessage
- Set Communication Pattern to One-Way
- Set Communication Direction to Send
- To complete the orchestration, we must now connect the message shapes to the ports.
- Connect the ReceiveRequest shape to the Request operation of the IncomingMessage port.
- Connect the SendRequest shape to the Request operation of the SendToTwitter port.
- Connect the ReceiveResponse shape to the Response operation of the SendToTwitter port.
- Connect the SendResponse shape to the Request operation of the OutgoingMessage port.
The completed orchestration would resemble the following:
We are now done with creating all the required artifacts for a BizTalk Server project. Let us now start creating the C# class library.
Create the Message Inspector Class
The client message inspector class must implement the IClientMessageInspector interface. The two methods that must be implemented from IClientMessageInspector are AfterReceiveReply and BeforeSendRequest . In this article, we will not do anything as part of the AfterReceiverReply method because we don't want to inspect/alter the response from Twitter. However, as part of the BeforeSendRequest method, we will pull the RESTful configuration from the request message, configure the HTTP transport, and then send the ReST message body.
- Right-click the Twitter_BTS Visual Studio solution, point to Add, and then click New Project.
- From the list of installed templates, click Visual C#, and then from the right-pane, click Class Library.
- Name the class library as MessageInspector and then click OK.
- Right-click the project, and then click Properties. In the Properties window, click Build Events, and in the Post-build event command line text box, enter:
"C:\Program Files\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0
Tools\gacutil.exe" /iF “$(TargetPath)”
This ensures that the class assemblies are added to the GAC after they are built successfully. Save and close the properties window. - Make sure your project includes references to the following:
- System.configuration
- System.Runtime.Serialization
- System.ServiceModel
- System.ServiceModel.Web
- Rename Class1.cs to BizTalkWebHttpMessageInspector.cs and include the following code excerpt.
using
System;
using
System.Linq;
using
System.ServiceModel;
using
System.ServiceModel.Channels;
using
System.ServiceModel.Dispatcher;
using
System.Xml.Linq;
using
System.Xml.Schema;
namespace
MessageInspector
{
public
class
BizTalkWebHttpMessageInspector : IClientMessageInspector
{
private
static
readonly
XNamespace BizTalkWebHttpNs =
"http://microsoft.com/schemas/samples/biztalkwebhttp/1.0 "
;
private
static
readonly
XName Request = BizTalkWebHttpNs +
"bizTalkWebHttpRequest"
;
private
static
readonly
XName Header = BizTalkWebHttpNs +
"header"
;
private
static
readonly
XName Param = BizTalkWebHttpNs +
"param"
;
private
static
readonly
XName Body = BizTalkWebHttpNs +
"body"
;
public
object
BeforeSendRequest(
ref
Message request, IClientChannel channel)
{
var requestBody = XElement.Load(request.GetReaderAtBodyContents());
if
(requestBody.Name != Request)
{
throw
new
XmlSchemaValidationException(
"Invalid request message. Expected "
+
Request +
", but got "
+ requestBody.Name +
"."
);
}
var bodyElement = requestBody.Element(Body);
var requestMessageProperty =
new
HttpRequestMessageProperty
{
Method = requestBody.Attribute(
"method"
).Value,
SuppressEntityBody = bodyElement ==
null
};
foreach
(var header
in
requestBody.Elements(Header))
{
requestMessageProperty.Headers.Add(
header.Attribute(
"name"
).Value,
header.Value);
}
var uriTemplate =
new
UriTemplate(requestBody.Attribute(
"uriTemplate"
).Value);
request = bodyElement ==
null
? Message.CreateMessage(request.Version, request.Headers.Action)
: Message.CreateMessage(request.Version, request.Headers.Action, bodyElement);
request.Headers.To = uriTemplate.BindByName(channel.RemoteAddress.Uri,
requestBody.Elements(Param).ToDictionary(
e => e.Attribute(
"name"
).Value, e => e.Value));
request.Properties[HttpRequestMessageProperty.Name] = requestMessageProperty;
return
null
;
}
public
void
AfterReceiveReply(
ref
Message reply,
object
correlationState)
{
// do nothing
}
}
}
Save and close the class file.
Create the Endpoint Behavior Class
An endpoint behavior class applies the message inspector to the client endpoint, so this class must implement the IEndpointBehavior interface. For more information, see Applying Custom Extensions with Behaviors .
- Add a new class to the MessageInspector project and name it BizTalkWebHttpBehavior.cs.
- Paste the following code:
using
System.ServiceModel.Channels;
using
System.ServiceModel.Description;
using
System.ServiceModel.Dispatcher;
namespace
MessageInspector
{
public
class
BizTalkWebHttpBehavior : IEndpointBehavior
{
public
void
Validate(ServiceEndpoint endpoint)
{
// Do nothing
}
public
void
AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
// Do nothing
}
public
void
ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
// Do nothing
}
public
void
ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.MessageInspectors.Add(
new
BizTalkWebHttpMessageInspector());
}
}
}
- Save and close the class file.
Create a Behavior Extension Element
In the previous section we created a behavior class that applies the message inspector to the client endpoint. We now need to make this behavior available to the configuration experience for the WCF-Custom adapter that will send the request message to Twitter. To make this behavior available for configuration we need to do two things: create a class that derives from the BehaviorExtensionElement and then register your BehavaiorExtensionElement in the <extensions>\<behaviorExtensions> element in the machine.config using an element name.
- Add a new class to the MessageInspector project and name it BizTalkWebHttpElement.cs
- Paste the following code:
using
System;
using
System.ServiceModel.Configuration;
namespace
MessageInspector
{
public
class
BizTalkWebHttpElement : BehaviorExtensionElement
{
protected
override
object
CreateBehavior()
{
return
new
BizTalkWebHttpBehavior();
}
public
override
Type BehaviorType
{
get
{
return
typeof
(BizTalkWebHttpBehavior); }
}
}
}
Save and close the class file. - Open the machine.config from C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config and add the following under <system.serviceModel>\<extensions>\<behaviorExtensions>:
<
add
name
=
"bizTalkWebHttp"
type
=
"MessageInspector.BizTalkWebHttpElement, MessageInspector, Version=1.0.0.0, Culture=neutral, PublicKeyToken=71062dbfcab17aa3"
/>
Here, bizTalkWebHttp is the element name with which the behavior extension element is mapped. - Save and close the machine.config.
Deploy the Solution
We must now deploy the solution to the BizTalk Server Administration console. To deploy the application using Visual Studio, you must log on Windows as a member of the BizTalk Server Administrators group and run Visual Studio as administrator. Otherwise you will get the “Access is denied” error. The deployment process requires that assembly is strongly signed. You must sign your assemblies by associating the project with a strong name assembly key file. This file is provided with the sample.
- In Solution Explorer, right-click the Twitter_BTS project, and then click Properties.
- Click the Signing tab, and select Sign the assembly.
- From the drop-down list in the Choose a strong name key file box, select <Browse…>.
- In the Select File dialog box, navigate to the location where you downloaded the solution, clickKey.snk, and then click Open.
- Repeat steps 1 through 4 for the MessageInspector project.
- Right-click the Twitter_BTS solution and then click Build.
- After the solution builds successfully, right-click the Twitter_BTS solution, and then click Deploy. The Output window should display:
========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========
========== Deploy: 1 succeeded, 0 failed, 0 skipped ==========
Configure the BizTalk Server Application
Configuring a BizTalk Server application is mostly about binding. A binding creates a mapping between a logical endpoint, such as an orchestration port, and a physical endpoint, such as a send and receive port. This enables communication between different components of a BizTalk business solution. You can create bindings by using the BizTalk Server Administration console.
In the orchestration, we created three ports - one to receive the request message, one to send the request to Twitter and receive a response, and then one to send out the response from Twitter. If you look at the scenario described under Scenario for this Article:
- A file port receives the request message.
- A WCF-Custom send port with webHttpBinding sends the request to Twitter and receives a response.
- An SMTP send port sends out the response in an e-mail.
We will now create the ports accordingly.
- Click Start, point to All Programs, point to Microsoft BizTalk Server 2010, and then click BizTalk Server Administration.
- In the console tree on the left side of the BizTalk Server Administration Console, expand BizTalk Server Administration, right-click BizTalk Group, and then click Refresh.
- Expand BizTalk Group, expand Applications, and then click BizTalk Application 1 because you deployed your BizTalk Server project to this application.
- Create a one-way FILE receive port.
- From BizTalk Server Administration Console, under the BizTalk Application 1 node, right-clickReceive Ports, point to New, and then click One-way Receive Port.
- On the General tab, provide the port name as IncomingMessages.
- Click Receive Locations, and then click New.
- Provide the receive location name as IncomingMessagesLocation, select the Type as FILE, and then click Configure.
- Set the Receive folder to C:\Twitter_BTS\DropRequestMessageHere\. Set the File mask to*.xml because the request XML will be an XML file. Click OK.
- Set the Receive handler to BizTalkServerApplication and set the Receive pipeline toXMLReceive.
- Click OK.
- Create a request-response WCF-Custom send port.
- From BizTalk Server Administration Console, under the BizTalk Application 1 node, right-clickReceive Ports, point to New, and then click Static Solicit-Response Send Port.
- On the General tab, provide the port name as Twitter, set the Type to WCF-Custom, and then click Configure.
- In the WCF-Custom Transport properties dialog box, on the General tab, specify the Address (URI) as http://api.twitter.com/1.
- Click the Binding tab, and for Binding type, select webHttpBinding.
- On the Behavior tab, right-click EndpointBehavior, and select Add extension.
- In the Select Behavior Extension dialog box, select bizTalkWebHttp, and then click OK. You had registered the behavior extension element with the name in bizTalkWebHttp in the machine.config.
- Click OK on the WCF-Custom Transport Properties dialog box.
- For the Send handler, select BizTalkServerApplication.
- For the Send pipeline, select XMLTransmit and for the Receive pipeline, select XMLReceive. Click OK.
- Create a one-way SMTP send port.
- From BizTalk Server Administration Console, under the BizTalk Application 1 node, right-clickReceive Ports, point to New, and then click Static One-way Send Port.
- On the General tab, provide the port name as SMTPPort, set the Type to SMTP, and then clickConfigure.
- In the SMTP Transport properties dialog box, on the General tab, specify the e-mail ID to which you want to send the e-mail with tweets and a subject for the e-mail.
- On the Compose tab, under E-mail body, select BizTalk message body part.
- On the Handler Override tab, specify the SMTP server name, the e-mail address from which the tweets will be sent, and the authentication type. Click OK.
- Set the Send handler to BizTalkServerApplication and set the Send pipeline toPassThruTransmit.
- Click OK.
- Configure the application to bind the logical ports in the orchestration to the physical ports we just created.
- Right-click BizTalk Application 1, and then click Configure.
- From the left pane, click Twitter_BTS_Orch. From the right pane, for Host, select BizTalkServerApplication.
- Bind the logical and physical ports as shown in the following table:
Logical Port Physical Port IncomingMessage IncomingMessages SendToTwitter Twitter OutgoingMessage SMTPPort
The following figure shows a configured application
- Click OK.
- Start the application. Right-click BizTalk Application 1, and then click Start. Verify that the orchestration, send ports, receive locations, and the BizTalk Server host instance is running.
Test the Solution
To test the solution, we will drop a request message to the DropRequestMessageHere folder under the location where you extracted the Twitter_BTS sample. The request message will be consumed by the receive location and you will get a list of tweets at the e-mail address you specified while configuring the SMTP send port.
Before testing the solution, let us have a recap of the main intent of this solution. The solution intends to get a list of tweets for a public timeline or a specific user by invoking the Twitter APIs through BizTalk Server. So, the request message must have all the information, plus any optional parameters, to frame the Twitter API. Let's first take a look at the Twitter API and the corresponding request message.
For a public timeline:
For a public timeline:
- API - http://api.twitter.com/1/statuses/public_timeline.xml?trim_user=true&include_entities=true
- Request Message will be:
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
method
=
"GET"
uriTemplate
=
"/statuses/public_timeline.xml?trim_user={TrimUser}&include_entities={IncludeEntities}"
>
<
param
name
=
"TrimUser"
>true</
param
>
<
param
name
=
"IncludeEntities"
>true</
param
>
<
header
name
=
"Content-Type"
>application/xml; charset=utf-8</
header
>
</
bizTalkWebHttpRequest
>
For a user-specific timeline (for user 'nitin_msft'):
- API - http://api.twitter.com/1/statuses/user_timeline.xml?screen_name=nitin_msft
- Request message will be:
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
method
=
"GET"
uriTemplate
=
"/statuses/user_timeline.xml?screen_name={ScreenName}"
>
<
param
name
=
"ScreenName"
>nitin_msft</
param
>
<
header
name
=
"Content-Type"
>application/xml; charset=utf-8</
header
>
</
bizTalkWebHttpRequest
>
If you take a closer look at the API and the request messages, you would notice that:
- The initial part of the API URL, http://api.twitter.com/1 is already specified as the address in the WCF-Custom port configuration.
- The remaining part of the URL is specified as the value for uriTemplate in the request message.
- The value for the parameters is specified as the values for the param element in the request message.
If you now connect the dots, you would understand that the message inspector class that we created takes these values (uriTemplate, method, parameters, etc.) from the request message and frames the required URL for the API.
Both these request messages are available as part of the sample. Let's now test the solution using these two request messages.
- Navigate to C:\Twitter_BTS, and copy the request message, RequestTwitterXmlPublicTimeline.xml.
- Paste the message at C:\Twitter_BTS\DropRequestMessageHere. Wait for the message to disappear.
- Look for an e-mail to the e-mail address that you specified in the SMTP port configuration. You must receive an e-mail with a list of 20 most recent tweets for users who have their tweets unprotected.
- Go back to C:\Twitter_BTS, and copy the request message, RequestTwitterXmlUserTimeline.xml. Paste the message at C:\Twitter_BTS\DropRequestMessageHere. Wait for the message to disappear.
- Again, go back and look for an e-mail. This time, the e-mail would contain a list of 20 most recent tweets for the user, nitin_msft.
If you received the e-mail responses as expected, you successfully invoked the Twitter ReST APIs using BizTalk Server 2010.
Download the Sample
The sample, Twitter_BTS, built around the scenario discussed in this article can be downloaded from theMSDN Code Gallery .
What Next?
You can use the solution in this article to retrieve the tweets for any unprotected user. You just need to include the user's screen name as a value within the <param name = "ScreenName"> element in theRequestTwitterXmlUserTimeline.xml. You can also add more parameters as you like to the user timeline request message. You would just need to:
- Modify the uriTemplate attribute to include placeholders for all the parameters that you want.
AND - Add the <param name="....">....</param> element to the request message.
Another approach one could take with respect to BizTalk Server + ReST is to expose BizTalk Services as ReSTful services. A couple of good writeups around this scenario are available at the following links:
- A ReSTful API for BizTalk Server Business Rules (Sample )
- Business Activity Monitoring in Depth for Developers (look at the section "Building a BAM RESTful API")