This is an old-beaten-to-death issue, but I've got a couple of queries about this already. That, and a lack of anything else substantial to post, and I'm ready for my latest blog entry.
Once in a while when you are using the SOAP adapter to consume a Secure Web Service (more often than not, a J2EE Web Service), you might get the following error:
The adapter "SOAP" raised an error message. Details "The underlying connection was closed: Could not establish trust relationship with remote server."
Now you've made sure that you've installed the certificate in all the right roots and you're specifying the thumbprint wherever you are required to, and still, this error keeps hounding you.
The following could be one reason why this is happening. By default, with the .NET Framework 1.1, the name that is used on the HTTP request must match the name of the server that is issued with the SSL certificate. Meaning, the "Issued To" property in the certificate (marked in red) that the Web Server sends to identify itself, needs to match the qualified server name on which the Web Service that you need to access resides.

For e.g.: When trying to call a Web Method on a Service found at:
https://myyada.youryada.com/ouryada
the certificate that the Web Server sends to you, should be Issued To, "myyada.youryada.com".
More often than not when we're interacting with older Web Services and those that are developed on different platforms, this won't necessarily be the case. This policy can be overridden through code, but since the SOAP Adapter is a black box to us, we could do the following. This policy is also defined by the following Config entry in machine.config.
One workaround this problem is to override this entry in BTSNtSvc.exe.config as:
But like all workarounds, this one comes with its own caveats - security implications in this case. Use it only if the Web Service is a live system and reconfiguring certificates on it is going to be a pain. If you have a resident MS consultant, take his blessings before proceeding.
Enough of this spasmodically intermittent blogging! My new year resolution is to post at least once a week. So now that we've got that out of the way, lets discuss some interesting findings about the MQ Series Adapter 2.0 for BizTalk.
During performance testing, our team discovered that if the “TransactionSupported” property of a MQ Series receive location is set to “Yes”, and the “Maximum Messages in Batch” property is set to a number > 1, the adapter will rollback transactions even in case of Subscription Failures. Obviously in a lot of workflows, Subscription Failures are acceptable, even expected sometimes. Interestingly enough, the adapter doesn't rollback (put messages back on the queue), if “Maximum Messages in Batch” = 1, or if we put just one messages on to the queue and wait for the adapter to complete a poll cycle. Moreover the above behaviour is contradictory with what is written in this MS technical article on Transactions Across BizTalk Server 2004.
It was discovered that this is a known issue and there exists a hotfix (albeit not on the public internet) for this problem. So if you are facing this problem, just pick up the phone.
My company is currently looking for 4 BizTalk 2004 resources for a project in Atlanta, GA. If anyone's interested in this opportunity, they can get in touch with:
Sunil Phatak
sphatak@igate.com
412-490-9621
In one of my previous posts, I had mentioned Stephen Thomas's BizTalk Server 2004 Convoy Deep Dive article on MSDN. That article mentions a .NET console app that he'd written that “detects zombie orchestrations and writes the zombie message to a file location”.
A couple of months back our Ops guys wanted something like that to use with MOM. So I used Stephen's model in a VBScript file. This script can be configured so that MOM can run it whenever it gets a message suspension event from BizTalk. It might need some proofing, but here it is:
On Error Resume Next
Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20
'Replace "DEVWS108" with comma sep list of Prod Machines eg: "Aaron1","Aaron2"
arrComputers = Array("DEVWS108")
For Each strComputer In arrComputers
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\MicrosoftBizTalkServer")
'Messages that are Resumable should be Resumed
Set colItems = objWMIService.ExecQuery("SELECT * FROM MSBTS_ServiceInstance where ServiceStatus = '4' ", "WQL", _
wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each objItem In colItems
objItem.Resume()
Next
'Messages that are Not-Resumable or Completed with Discarded(zombies)
Set colItems = objWMIService.ExecQuery("SELECT * FROM MSBTS_ServiceInstance where ServiceStatus = '16' or ServiceStatus = '32'", "WQL", _
wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each objItem In colItems
Set objWMITrackedMsg = GetObject("winmgmts:\\" & strComputer & "\root\MicrosoftBizTalkServer")
Set colResumableMsgs = objWMITrackedMsg.ExecQuery("SELECT * FROM MSBTS_MessageInstance WHERE ServiceInstanceID = '" & objItem.InstanceID & "'", "WQL", _
wbemFlagReturnImmediately + wbemFlagForwardOnly)
'change "c:\" to any directory that you want problematic messages to be saved to
colResumbleMsgs.SaveToFile("c:\")
Next
Next
Okay, so that was a little over the top. Basically I wanted to find out whether I could do much with the appearance of my blog, given the fact that I am not hosting it. So my choice of skins is limited to what Geeks With Blogs provides. I have been putting it off for a while now, but today was an unusually slow day and I decided to take a peek under the hood.
The appearance of my blog now, is what used to be the LuxLight display skin. So what did I do? Well I shifted the sidebar to the left. I made my content area wider (at the expense of poor layout if you reduce the size of your browser window too much). I changed some colors here and there, and I added a category to the sidebar, which isn't “News”. :)
A few tricks that might help others like me, who just love mutiliating a perfectly good skin. This might be old old information to some people.
- I set my Display Skin to LuxLight, and then used http://jigsaw.w3.org/css-validator/ to extract the CSS part out. I know I know, this is a round about way, but I was too impatient to dig out the LuxLight CSS from the web.
- With this CSS in hand, I proceeded to override a whole lot of CSS Elements and Classes. These overrides, I put in the Custom CSS Selectors section.
- For the new category, Map Stats in this case, I wrote an Un-Numbered List and some List Items in HTML, into the Static News/Announcement section in the configuration page. This section takes JavaScript too, so use it wisely. Or better still, exploit it!
Here is a snippet of the Custom CSS that I wrote for this page. Ctrl+C and Ctrl+V were used generously, so the CSS purists will find a lot of redundant code. You can take the idea further and run with it.
#container
{
width
: auto;
width
: auto;
width
: auto;
margin
: 1em 10px auto 10px;
background-color
: #ffffff;
text-align
: left;
}
#content
{
padding
: 0.5em 1em;
margin
: 6px 0 0 0;
float
: right;
width
: 750px;
}
#sidebar-a
{
background-color
: #efefef;
width
: 200px;
float
: left;
padding
: 0.5em;
font-size
: 0.9em;
border-style
: solid;
border-width
: 1px;
border-color
: #0040FF;
margin : 6px 0 0 0;
}
Here's the HTML I used in the Static News configuration.
<H3>Map Stats</H3>
<UL>
<LI>
<script src="http://mapstats.blogflux.com/button.js.php?id=3312" language="JavaScript" type="text/javascript"></script>
<noscript>
<a href="http://mapstats.blogflux.com/3312.html"><img src="http://mapstats.blogflux.com/button.php?id=3312" alt="Blog Flux MapStats: Stats and Counter for Devdutt's Blog"
border="0" />
</a>
</noscript>
</LI>
</UL>
See...that was relatively painless, right? So go cutomize your .TEXT blog.
Apparently, I seem to be the last one to see these BMW Advertisement-Shorts. These short films have been directed by some top notch directors and star Clive Owen. All in all, they serve as some nice adrenalin shots for those 3:00 PM bouts of drowsiness.
Not to mention, a gentle reminder that I can't afford a beamer yet. :)
So we developed a custom Socket Adapter for BizTalk Server 2004, and hooked up with a 3rd party demographics and charges vendor. As is often the case in such scenarios, their application took an intense dislike to our adapter. It wouldn't send Acks for some messages, then the next message would get back 42 Acks and so on and so forth. All in all not very savoury. So I went looking for a tool that would monitor my network interface, show me packets real-time, allow me to set up fancy filters, not require me to install it, minimize work for my lazy butt, and of course it had to be freeware (so basically my butt's a cheapskate too).
I found a lot of tools out there including the network monitor that ships with Server 2003. I tried all of them, and settled on this light-weight packet monitor from NetworkActiv Software (the freeware version of course). It served all of my needs and was light-weight enough to not contain ones that I didn't. It is downloadable as an install, but works even if you just copy over the exe to the target machine.
Turns out the problems were in the Vendor's app or that's the official party line at least. So do take a look.
I was going through my emails and I found one from July of 2004 that prompted me to this trip down memory lane. During that fateful month, I was under some serious pressure to get our Electronic Claims solution up and running. We were using BTS 2004 and the HIPAA Accelerator 3.0 which was in its relative infancy. After mucho dll trading with engineers from MS, I finally got our solution up and running. Needless to say, the powers that be, weren't impressed. After all, BTS isn't as sophisticated as Excel or Project.
I was then asked to get the solution up and running from a bare-bones Server 2003 machine. Okay, I said, just watch and learn. I proceeded to install the BTS pre-requisites while at the same time, making paper airplanes out of my copy of our internal BTS installation guide. Me? Follow an installation document? The document that I wrote? Hell, no!!
I was at the home stretch now - configuring BTS - and generally playing to the audience, when I was knocked out of my chair by the following error message. I swear I haven't altered this image in any way:

Later I found out that it was something as simple as an incorrect logon which prevented the installation from adding users to COM+ Application roles, but at that particular moment, all I could do was to shake my head and listen to the guys laughing their asses off at me.
Need to take a better look at this, but at first glance it looked good. Hopefully my days of creating Windows Applications to test my interfaces are over.
Take a look at the BizTalk Server 2004 Load Generation Tool here.
Yet another very old post from my previous blog.
The BizTalk Accelerator for HIPAA 3.0 throws up a mighty detailed error in the event log when it fails during Xml to EDI translation and/or validation. These errors tend to look a little scary (they scared me at the very least). An example would be :
Status report details: SRH DevBT03 200411122204111 DEFAULT 2 DEFAULT
SRM 00000000 00010168 101 0 837 004010HC09translate failed 0000010000010000000000010 10168
SRE 001030ProcessSegment 00053 000TS837Q1_2420A_NM103__RenderingProviderLastOrOrganizationName source format: [101 0 ,XML 1.0]\r\nsource document: [837 004010DEFAULT X X098A1,Health Care Claim: Professional]\r\nsource segment: [data#53,def#232,name=TS837Q1_2420A_NM1_RenderingProviderName]\r\nsource element: [def#4,elm#0,comp#0,name=TS837Q1_2420A_NM103__
RenderingProviderLastOrOrganizationName], (msgnr:1 segnr:53)(line:2 pos:11671 filepos:11953)
Look for the last numeric code following the SRE element. In this case its 001030. Ignore the 0010 part and you are left with 30. Open [document's home]\HIPAA_EDI\Subsystem\EIF\live.eif with notepad. Please be careful not to edit this file!! Preferrably create and open a copy. The first section of the file contains code to message mapping entries like :
ET1000001The path does not exist. Check the folder location.
Look for the entry matching our code i.e. 30. We have :
ET1000030The document does not contain a required element. Contact the sender.
So, the actual interpretation of the event log message is :
"The required element/attribute TS837Q1_2420A_NM103__RenderingProviderLastOrOrganizationName in the segment TS837Q1_2420A_NM1_RenderingProviderName is missing."
Now that's a LOT less frightening I think. :)
Yet another very old post from my previous blog.
People using In-Line XSLT Templates in their scripting functoids often run into the need for looping, WITHOUT using an <xsl:for-each>. An example in the BizTalk context would be, if you had a comma separated string in the source schema and wanted to tokenize it into multiple destination schema elements. The following XSLT template does that for you.
1 <xsl:template name="TokenizeCommaSepString">
2 <xsl:param name="stringToTokenize" />
3 <xsl:param name="destinationElementName" />
4 <xsl:if test="$stringToTokenize != ''">
5 <xsl:choose>
6 <xsl:when test="contains($stringToTokenize, ',')=0">
7 <xsl:element name="{$destinationElementName}">
8 <xsl:value-of select="$stringToTokenize" />
9 </xsl:element>
10 </xsl:when>
11 <xsl:otherwise>
12 <xsl:element name="{$destinationElementName}">
13 <xsl:value-of select="substring-before($stringToTokenize, ',')" />
14 </xsl:element>
15 </xsl:otherwise>
16 </xsl:choose>
17 <xsl:call-template name="TokenizeCommaSepString">
18 <xsl:with-param name="stringToTokenize" select="substring-after($stringToTokenize,',')" />
19 <xsl:with-param name="destinationElementName" select="$destinationElementName" />
20 </xsl:call-template>
21 </xsl:if>
22 </xsl:template>
Drag a Scripting functoid onto the BizTalk Mapper. Go to properties and choose Configure functoid script. Choose Inline XSLT Call Template as the Script Type. Paste the above code in the Script Buffer text area. This functoid will take the comma separated string in as the first parameter and the destination element name as the second parameter. It will split the string into parts and create a sequence of elements in the destination message.
Observe the use of recursion (marked in bold), to solve similar problems. Have any questions, post a comment.
Another very old post from my previous blog.
A long, long break between posts. Actually was working on some custom adapters, which kinda left me with little to post. Anyways, today morning a colleague of mine was facing a problem with Sequential Convoys. He didn’t know how many messages he was going to receive in a particular convoy. Consequently, he didn’t know how many times to loop the Receives that follow the co-relation set (Hence, the "Non-Deterministic" in the title). A simple solution exists to solve this problem. Use a Listen shape! A Listen shape with the Following Receive(s) in one branch and a Delay shape in the other, provides us with a graceful 'Timeout' kind of mechanism. Here’s a screen shot of how to plug in the Listen logic in your sequential convoys.

Most information in my previous post about Uniform Sequential Convoys holds true in this case too. Post a comment if you need any clarifications.