Archive

Archive for the ‘BizTalk’ Category

Adding a multipart message to ESB Portal using ESBfault

September 20, 2012 Leave a comment

Assigning a failure message to an ESB fault and making it viewable in ESB Portal is a known practice nowadays.There are many posts that explains how to add a message to ESB fault and to make it displayed in the ESB portal. The sample code would be something like this.

msgESBFault=Microsoft.Practices.ESB.ExceptionHandling.ExceptionMgmt.CreateFaultMessage();
msgESBFault.FailureCategory=”RoutingFailed”;
msgESBFault.FaultSeverity=Microsoft.Practices.ESB.ExceptionHandling.FaultSeverity.Severe;
Microsoft.Practices.ESB.ExceptionHandling.ExceptionMgmt.AddMessage(msgESBFault,ActualMsg);// “ActualMessage is the message  to be sent to ESB Portal”.
 
But when the ”ActualMessage” is a multipart message, assigning the parts to the AddMessage() does not work.
 
Microsoft.Practices.ESB.ExceptionHandling.ExceptionMgmt.AddMessage(msgESBFault,ActualMsg.Part1);
Microsoft.Practices.ESB.ExceptionHandling.ExceptionMgmt.AddMessage(msgESBFault,ActualMsg.Part2);
 
The above way of assigning the part will result in the intellisense complaing that “the message cannot be assigned to an XLangMessage”. To resolve this, the following are the steps.
 
1. Create UnTyped Messages( Type : System.Xml.XmlDocument) for each of the message part to be assigned.

2. Try to assign all the message parts to xmldocument messages and add each one by one as follows.

Msg1(Of type xmldocument) = ActualMsg.Part1;
Msg2(Of type xmldocument) = ActualMsg.Part2;
Microsoft.Practices.ESB.ExceptionHandling.ExceptionMgmt.AddMessage(EsbFault, Msg1);
Microsoft.Practices.ESB.ExceptionHandling.ExceptionMgmt.AddMessage(EsbFault, Msg2);
 

This will display all the parts and the body message to be displayed in the same view in ESB Portal. This will be helpful when HL7 multipart messages are assigned to ESB Faults.

 

First Technet Wiki Article: Microsoft BizTalk Server and Transactions

April 24, 2012 2 comments

My First Technet Wiki article has been published here. It is on BizTalk and it’s transaction boundaries. Kindly have a read and would be happy to have feedbacks and comments. Have a great day!!

Identifying the version of a reference dll with which a dll was built.

May 28, 2011 2 comments

As a part of BizTalk development, we use many Common DLLs as references in our projects. One frequent issue we face is in knowing the reference DLL details(mainly the version) with which a DLL was built with.

Assume we have a map project “MapProj” which refers to a common DLL “SharedSchemas.dll” which is of version 1.0.5.0 and also there are many versions of “SharedSchemas.dll” that coexists.

After deploying the”MapProj” to a server where it executes, you identify that the maps output was not as expected and you want to ensure if the maps project was built with the expected version of the referenced dll, 1.0.5.0 of “SharedSchemas.dll” in our case. We can use ILDASM.exe, a built-in .NET framework tool which will identify the version details of a referenced assembly.

Step1 : Go to your VisualStudio Command Prompt and type “ILDASM.exe”.

c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC>ildasm.exe

Step2 : Open the “MapProj.dll” for which we have to check the references.

ILDASM.exe

Step 3: Double-click on “Manifest”.

ILDASM_Manifest

ILDASM->Manifest

The popup gives you the list of referenced assemblies and their versions.

View AssemblyDetails

View AssemblyDetails

Please provide your feedback and comments.

InBound/OutBound Maps with same MessageType- Order of Execution

February 10, 2011 Leave a comment

Few days ago, there was a question in Biztalk forum which has triggered this post of mine.It was about the sequence in which BizTalk will execute the inbound maps configured in a receive port .

As we know, when two maps “Map A”  and “Map B”  that takes different input schema types  “Schema1” and “Schema2”  respectively will behave as follows.

When “Schema 1″ is received,” Map A” executes and for “Schema 2” it will be “Map B”.All is well till this.

What happens when multiple maps with the same schema type are input configured as inbound maps. Say the maps are taking the inputs as follows.

INPUT         MAP NAME OUTPUT
Schema 1           Map A               Schema 1
Schema 1           Map B               Schema 2
Schema 1           Map C               Schema 1

In this case, BizTalk will execute only one of the maps when an XML instance of “Schema 1” is received even though all the three Maps should have.But this is not the issue on focus..Things were well until this question raised. Which of the maps will execute?

Will they execute in the order they are configured in the port – NO.

Or in the order of their names- NO.  So how it works. Here are my findings on this.

I tested this scenario by configuring 3 maps A, B and C and all taking  the same “Schema 1” as their input. I added a C# script in all the maps to write the map’s name in the event log when it executes. This way we would know which map got executed.

This is how my port was configured.

MapConfiguration

Map Configuration in the Port

When Schema 1 was posted to the receive location, the event viewer log confirmed that “Map C” was executed.But,Why Map C?

After a few hours of search in the management database, I found that “admsvr_GetRecvPortTransformAssemblyName” is the SP responsible for selecting the map to execute.

 

SP

Stored Procedure Code

  1. BizTalk picks the “MessageType” of the received msg(Promoted by XMLReceive pipeline ).It will be “http://MapTests.Schema1#Root” in our test scenario.
  2. Checks for this MessageType in “bt_DocSpec” table and picks the corresponding “docspec_name” column’s value.It will be “MapTests.Schema1” in our case.
  3. Picks the receive port’s GUID from “bts_receiveport” table.
  4. Inner Joins the results from points 2 and 3 and  gets the list of map IDs matching these conditions.

The result contains the GUIDs of  all maps that takes “http://MapTests.Schema1#Root” as input and configured for this receive port.

There were 3 GUIDs returned(one for each map A,B&C) when I executed the  first highlighted part of the SP with our test case inputs.

SELECT @nMapID = ms.id FROM bt_MapSpec ms

INNER JOIN bt_DocumentSpec ds ON ds.docspec_name = ms.indoc_docspec_name

INNER JOIN bts_receiveport_transform rpt ON rpt.uidTransformGUID = ms.id

INNER JOIN bts_receiveport rp ON rp.nID = rpt.nReceivePortID

WHERE ds.msgtype =http://MapTests.Schema1#Root”

AND rp.uidGUID = “4c160275-98c6-4f60-a0bf-9c9b5ccd958b”

AND rpt.bTransmit = “False”


The result was as follows.

Result

MapIDs returned

Since “SELECT @nMapID = ms.id” in the query will always hold the last value of the result returned, @nMapID will be equal to ”68bfd6c1-eb61-40e4-9dec-a183a4f189fd” in our test scenario.

I customized the second part of our SP “admsvr_GetRecvPortTransformAssemblyName a little to take in all the GUIDs returned(for our understanding and analysis) that we just obtained as result.(Remember our @nMapID is actually having only ’68bfd6c1-eb61-40e4-9dec-a183a4f189fd”) .

SELECT ba.nvcFullName, bi.FullName FROM bts_assembly AS ba

INNER JOIN bt_MapSpec AS ms ON ba.nID = ms.assemblyid

INNER JOIN bts_item AS bi ON ms.itemid = bi.id

WHERE (ms.id IN (‘6abc55b3-24b1-4c9a-9919-84e6ca81cf25’, ‘761be6b1-f7e8-4bc7-b855-8d99203df47c’, ’68bfd6c1-eb61-40e4-9dec-a183a4f189fd’))

The result of this query resolves half the mystery.

Query Results

Query Results

So, the MapName for the GUID that @nMapID holds will be “Map C” which will be the one that executes.

IMPORTANT POINTS – MUST READ:

  • This order of the result IS NOT THE SAME  and changes if anything gets deployed. I tried deploying another set of maps that are not related to our sample project and our test scenario executed “Map A” instead of “Map C” this time but our query returned “Map A” as the final row.
  • BUT the last row of the result from the following query will be the map that executes. SELECT ms.idFROM bt_MapSpec ms INNER JOIN bt_DocumentSpec ds ON ds.docspec_name = ms.indoc_docspec_name INNER JOIN bts_receiveport_transform rpt ON rpt.uidTransformGUID = ms.id                                                                                         INNER JOIN bts_receiveport rp ON rp.nID = rpt.nReceivePortID                                                                                                                WHERE ds.msgtype = <MessageType> AND rp.uidGUID = <ReceivePortGUID> AND rpt.bTransmit = <PortTransmitType>
  • Maps that have multiple Inputs cannot be configured  EXACTLY as InBound maps. Eventhough they can be configured, the first input schema that was used while developing the map will be used as input.                                                                                              REASON: BizTalk runtime’s decision of the map to execute also depends on the “MessageType” property(as we saw in the SP).Thisgets proved at “WHERE ds.msgtype =” of the SP “admsvr_GetRecvPortTransformAssemblyName” . Here it takes only one messagetype and hence thus one input.
  • MessageType MUST be promoted to have the InBound Maps work. Passthru will not help.
  • These applies to the OutBound Maps as well.( the SP names and tables are different but follows the same naming conventions as the ones related to InBound maps).

CONCLUSION:

Even though we can find how the map selection happens during execution, in an environment where multiple deployments happen, the order in which the SP returns the result will keep varying thus leaving the Map that will be executed unpredictable. So, Watch On!