Tuesday 19 February 2008

Dynamic Send Ports

Part of the project I'm currently working on involves sending XML messages to a variety of trading partners. Each partner has several products each of which could require different port settings (URL, credentials, timeout, retry strategy). Another variable is the transport type. Currently all support plain XML over HTTP but in the future SOAP may be a requirement. As we have up to 1000 different partner/product combinations to support dynamic ports seem like a logical choice.

So how do you implement dynamic HTTP and SOAP send ports? Let's start with HTTP first as it's a little more straightforward.

Assuming that the orchestration is in place, add a request/response send port to the port surface and mark its type as Dynamic. The only other configuration required on the port is to specify the pipelines to be used and to connect up the request and response operations to the relevant send and receive shapes in the orchestration.

dynamicsend1

Prior to the send shape (I have used the message assignment shape that builds the request message) add the following code.

// Assign message
msgSendRequest = msgReceiveRequest;

// Set base properties
MySendPort(Microsoft.XLANGs.BaseTypes.Address) = "
http://localhost/testpartner/test.aspx";
MySendPort(Microsoft.XLANGs.BaseTypes.TransportType) = "HTTP";

// Set HTTP adapter specific properties

msgSendRequest(HTTP.AuthenticationScheme) = "Basic";
msgSendRequest(HTTP.Username) = "mark";
msgSendRequest(HTTP.Password) = "pwd";

This code sets up the address URI and the transport type to be used. The TransportType is a means of informing BizTalk which adapter you want to use. If it is omitted the prefix of the Address (in this case http://) will be used to query an alias table to lookup the adapter to use. For some prefixes there are multiple adapters that could handle the request. For http:// it could be the HTTP, WCF-Basic or WCF-WSHttp so the TransportType property can be used to explictly choose the correct adapter. In this instance I could have omitted the TransportType since the HTTP is the default for http:// addresses.

Next I have set some properties that are specific to the HTTP adapter. In this instance I have just configured the authentication details but there are lots of other that can be used. Typically these settings could be looked up from a database or other configuration store and set dynamically based on the request.

And that's it! The request should then be routed to the URI configured in code above using the HTTP adapter. This is a very powerful technique to add flexibility to your application. I'll continue by demonstrating how to use the same technique for the SOAP adapter in a future post.

6 comments:

venkat said...

Sir,
Can you please provide the code for this article - http-request/response dynamic port?

my mail id is venkats@tesl.com


I am not sure of how the response from the http service could be handled?

should i have a xml pipeline in receive operation,and how the message could further be handled?

Thanks,
Venkat

Mark said...

Hi Venkat,

You can use a dynamic port in exactly the same way as any other port. If you are receiving an XML response you can specify an XMLReceive pipeline component.
The response is returned to your orchestration from the two way send port just as it would be for a static port. The receive shape will receive the response message and populate the associated message object.

Regards
Mark

Unknown said...

Thanks... I was stuck at some problem and while reading this post i got it resolved.

Good one.

Kaleem Khan said...

I have to call a google map service like this one for example.

http://maps.googleapis.com/maps/api/distancematrix/xml?origins=k2g7a6&destinations=k1t2t5&mode=driving&sensor=true&units=metric

what kind of msg I should construct for send port. k2g7a6 and k1t2t5 are hypothetical postal codes, the service returns distance between 2 postal codes. thanks !

Mark said...

Seems as though you need an HTTP GET since all of the parameters are passed as querystrings and there is no message to post.
Unfortunately the HTTP adapter does not do GET's (or at least not the last time I looked). You could either
a) Look at using a WCF adapter
b) Perhaps try looking at the LOB Adapters
c) Write a custom adapter
d) Write a .NET library to do the GET via the HttpWebRequest object.

Hope this helps.
Mark

Unknown said...

Hi Richard,

Question: I use a dynamic send port to do a HTTP Post to a URL, and configure the proxy settings on it, but get the message back "Unable to connect to the remote server"

If I set up a static HTTP port, and configure the proxy settings in there, it works fine(with the same URL_, no problem and get the response back.

Any ideas? What user will it use to authenticate agains the proxy? The user set up in the context by using the HTTP properties right?

I checked that the username , password , etc, are all exactly the same as what I use for the static HTTP port configuration.

Nico