The rumours have been swirling. Now the truth is out.
On Sat. Jan 14, there will be a Toronto Code Camp. You can register/find more infomation/hang out at http://www.torontocodecamp.com/
If you're a developer looking for in-depth content from the people who know (that would be other developers), then the code camp is the place to be. If you're a developer that has in-depth content that other developers could use, this is you're chance to shine. Regardless, it will be a blast. Clear your schedule now to be there.
While working on a BizTalk mapping for a client, I ran across an unusual problem. When the mapping was tested, an XSL transform error was thrown. Specifically, the error message was:
XSL transform error: (0,0) : 'userCSharp:(string(*[local-name()='Times' and namespace-uri()='']/*[local-name()='WindowCloseTime' and namespace-uri()='']/text()))' is an invalid XPath expression. 'userCSharp:(string(*[local-name()='Times' and namespace-uri()='']/*[local-name()='WindowCloseTime' and namespace-uri()='']/text()))' has an invalid qualified name.
Since this came from the XSL that is generated by the mapping, the first step I took in identifying the problem (ok…the first step after scratching my head for 30 minutes or more) was to examine the XSL for the mapping. This can be created by running the Validate Map option from the Solution Explorer. My search for this particular XPath expression found it in an XSL segment that looked like the following.
<xsl:variable select="userCSharp:(string(*[local-name()='Times' and namespace-uri()='']/*[local-name()='WindowCloseTime' and namespace-uri()='']/text()))" name="var:v18"></xsl:variable>
<xsl:variable select="string($var:v18)" name="var:v19"></xsl:variable>
Now that I have a better look, it appears that the userCSharp namespace has attached itself to an XPath expression. Normally, it is attached to a function that is defined further down in the XSL file. No wonder it’s invalid.
The good thing is that I was able to see from the attribute name that the problem is in the mapping for the FIRST_PU_MINUTE attribute. When I looked, it turned out that the scripting functoid I was using hadn’t been defined. Instead of defining the external assembly function, I had left it as the default, commented-out code. Once I corrected that problem, my transform error went away.
Update: The XSL fragment didn't appear when I first posted it. My bad. Now it makes much more sense.
As part of a current project, I'm utilizing some standard .NET assemblies in the BizTalk mapping. Because these same assemblies can be used in other non-BizTalk applications, they utilize the app.config file to store potentially changing information. Naturally, because these assemblies and indeed pretty much all of BizTalk run out of the Global Assembly Cache, the location for the app.config file becomes a little challenging to determine. While there are a number of potential solutions for where the information can be stored, I found that the simplest is to place the config information in to the BizTalk server config file. This file is called BTSNTSvc.exe.config and can be found in the installation directory for BizTalk. Also, if you're going to make a change to this file, you need to stop and restart the BizTalk services to get it picked up.
See. I told you.
Actually, this was an error of my own making. The error that appeared on building the schema project was
Error in inserting document definition: Error = [Microsoft][ODBC SQL Server Driver][SQL Server]Violation of PRIMARY KEY constraint 'PK__codset__2D27B809'. Cannot insert duplicate key in object 'codset'
A similar error was displayed for the segcon and elmnts tables as well.
The problem was that I had badly defined the EDI schema. The schema I built had two N1Loops (that is a loop that contained N1, N3, N4 and G61 segments). The second loop also contained one more segment, meaning that I couldn't reuse the loop. But, in a moment of boneheadedness, I created duplicate definitions for the N1, N3, N4 and G62 segments. The result was an error such as the one shown above. The solution is to rename the duplicated segments (say N1_2) while (and this is important) keeping the tag_name attributed of the recordInfo tag at N1.
One thing I will say is that the message that appears is completely useless for identifying the duplicated elements. To see what went wrong, I modified the table definition for segcon, sgmnts, codset and elmnts to get rid of the primary key violation message. Then a build would work to success. Once the build was complete, I used the following statement to see the duplicated records.
SELECT fc, envr, code, COUNT(*) from codset GROUP BY fc, envr, code ORDER BY COUNT(*) DESC
Any row with count greater than 1 would cause the violation exception. The envr value contains the segment that is duplicated.
means that the G61 segment is being duplicated. Realize that if G61 is duplicated, then you will also seen records for G6102, G6103, etc.
Once I had solved all of my duplication issues, I needed to rebuild the database schema. For me, I only had a couple of schemas, so it was no problem for me to rebuild. I deleted all of the tables and rebuilt the table structure using the Edi.sql script found in c:\Program Files\Microsoft BizTalk Server 2004\EDI\Adapter\bin\config. If you have already compiled a number of schemas and don't want to go through it again, make a backup of the BizTalkEdiDb database before removing the primary keys and perform a restore when all of the problems have been addressed.
First off, you'll notice that the title of this blog includes Part 1. I don't have any other parts...yet. But from what I've seen so far in terms of paucity of documentation and general gotchas, I fully expect there to be.
So I'm create an EDI schema for a 204 transaction. Not a very large transaction, so it figures to be relatively easy to put together. As it turns out, there are a couple of loops within the transaction. Since the 204 transaction is a load tender, there is a header/detail relationship between some of the segments. So after create the header segments, I define an element called DetailLoop. Then, further down in the schema, I define DetailLoop as containing, among other segments, an S5 segment.
Once the schema has been built, I build the project that contains it. A build error is generated. Specifically, the error is:
Segment name [DetailLoop] does not start with value of tag [S5]
The problem is that the EDI schema validator gives more weight to the loop name than I originally thought. It is expecting that the name of the loop start with the name of the first tag in the loop. In other words, when I changed the name of the loop from DetailLoop to S5Loop, the error went away.
Once more back into the EDI/BizTalk breach.
While testing an BizTalk EDI-document orchestration that I created, I ran into a couple of problem. Specifically, an EDI document was rejected because BizTalk was unable to authorize the sender and receiver. The specific error message (as found in the Event Log) was “The recipient of the document is not recognized” or “The sender of the document is not recognized“. The documentation on exactly what is being done here is sparse, so let me describe what BizTalk is looking for. To start with, consider the following fist couple of lines in the EDI document. These lines are before the transactions contained within the document and are used by EDI subsystem authenticate and route the document.
ISA*00* *00* *ZZ*CONTOSO *12*4162164603 *050328*0852*U*00401*000004393*0*P*>
When an EDI document is received through the pipeline, the subsystem opens the document to find the send. In the above code, the sender is indicated by the 'ZZ' and 'CONTOSO' blocks in the first line. As well, the sender id is found in the third field ('9055551212') in the second like. These data are combined to form a party identifier. The party identifier looks like EDI://CONTOSO:ZZ:9055551212. Once the identifier is created, the EDI Subsystem examines the list of Parties to find the sender. If not found, then an entry is put into the event log saying that the sender could not be authenticated.
The second part of the authentication process is to authenticate the receiver. The identifier for the receiver is constructed in a similar manner. For the above example, the recipient party identifier is EDI://4162164603:12:5198581234. The information used to create this come from the first line (segments 6 and 7) and the second line (segment 4). Not only does the EDI Subsystem look for the sender party identifier in the Parties list, but also the recipient party identifier.
What this means is that in order for the EDI Subsystem to accept an EDI document, both the sender and recipient need to be defined as a Party. To do this, open up the BizTalk Explorer, expand the view to reveal the Parties node. Right click on Parties and select Add Party. In the dialog box that appears, give a reasonable name for the party. In the Properties list that appears, add a property called EDI, with a Qualifier of EDI and a Value of the sending party identifier (for our example, EDI://CONTOSO:ZZ:9055551212). Save this new party. Make sure that a second party is created using the receiving party identifier. With this combination of parties, the incoming EDI documents can be correctly authenticated and fed in to the processing pipeline.
As a result of the problems that I described in my last post, I ran into another little documented (there seem to be a number of these surrounding EDI and BizTalk) problem. When I rebooted my system after the Validate Schema process hung my system, I immediately tried to run it again (by definition, insanity is trying the same thing over and over, expecting a different result, isn't it?). This type around I got an error message saying that my respository was locked. Specifically (and for Google), the message is:
Schema validation failed: Repository was locked on host [hostname] by process [xsd2edi], processid [nnn]
Sympton: Build output:
XSD2EDI failed to convert XSD: Can't lock repository because it is already locked
It turns out that the correction for this is quite simple. In the BizTalkEDIDb, there is a table called parame. This table contains a single record (at least, that's what it has on my system). One of the first in this table is called repolock. In that field is the name of the host, process and process id that is updating (I assume) the repository. It is set by XSD2EDI and, naturally, the information survives a system crash and restart. To unlock your respository and be able to validate your schemas again, set the value of repolock to null using your favorite method.
As you might have figured out (from my recent posts), I'm working on a BizTalk project. Specifically, I've been dealing with the joys of trying to get the base EDI adapter working the way that I want/expect. Yesterday, it was trying to get the 850 Schema validated. There are two items that I want to mention that got in my way.
First, because of all the different software I try out, I'm a firm believer and user of Virtual PC. So the BizTalk I'm using is installed on a VPC running 2K3. The system on which it's running has 1GB of RAM, around 650MB are allocated to the VPC.
So back to the story. In the BizTalk project in VS.NET, you right click on a schema and select Validate Schema. This basically runs the XSL2EDI.exe process to validate the schema and convert it into the BizTalkEDIDb tables. On my system, I was finding that running this process would freeze my machine after about 10 minutes of running. And by 'freeze', I don't just mean the VPC. My entire system would seize up, requiring a hard reboot to get started again. After having this happen a couple of times, I looked at what might be the cause.
Turns out that the project in which the schema I was validating still had an orchestration running. Once I stopped the orchestration, the freezing problem seems to be solved. Or, to put it a slightly more pragmatic way, it hasn't happened since and I've validated more than one schema since then. It's only empirical evidence, but it's all that I have.
I've been spending some time on BizTalk Server 2004 these past few weeks. And for the next few, just so that you know the source of future posts. I've run into this situation a couple of times, so I'm posting as much as a reminder to me as for any other reason.
My current project has me working EDI (after a seven or eight year absense) integration with an existing application. As a result, I get the chance to work with BizTalk's EDI Adapter. From a configuration perspective, it's quite simple to get set up, but I was receiving a strange error on my build.
XSD2EDI: Failed to convert XSD: Compiling repository failed
According to a support article (http://support.microsoft.com/?kbid=883549), this is caused by an authentication issue with the BizTalk Base EDI Service. But, in my case, that wasn't the problem. Instead, what appears to be happening is that this server, even though it is marked as being Automatic, wasn't starting. The first time I saw this error, the service actually Disabled, so you need to address that particular issue. But even after that, I would still see the error the next time I rebooted the server. Nothing in the event log to indicate a problem, so at the moment I'm both puzzled and looking for clues. I'll keep you posted if I find something.