Something you REALLY should know about dates ! (beeing Kind to DateTime.Kind)

Here we go, some important stuff about dates.....(it's not only BizTalk related)

I had a very simple scenario.

  1. Webservice Receives a request (with several datetime fields in it)
  2. Send the received message to SQL via the WCF adapter

For some obscure reason some datetime values  originating from the same WebRequest got modified once in the database and some did not. 
After some tracing we found that the dates were serialized in a different way once inside the webservice.
some of the formats we saw :

  • 2011-08-29T18:00:00.826;
  • 2011-08-29T18:00:00
  • 2011-08-29T18:00:00.3983714
  • 2011-08-29T18:00:00Z

All these got to the database unchanged, but we also saw datetime like below

And these datetime fields got calculated back to their UTC time and were then stored in the database.

After some experimenting we found the following interesting stuff.....

Datetime.Kind (but for sure, everybody already knew that).... So what is this KIND ?

Public property Supported by the XNA Framework Supported by Portable Class Library Kind Gets a value that indicates whether the time represented by this instance is based on local time, Coordinated Universal Time (UTC), or neither.

So what happens is the following, 

  • Create a DateTime in code (like DateTime current = DateTime.Now) and Kind is Local
  • Create a DateTime in code and Assign a database field (like DateTime fromdb = datetimefield from database) and Kind = Unspecified

And what's the difference ?

Well the difference is that when the WCF Adapter stores the date to the database field.

  • when != to unspecified it calculates it back to UTC
  • when == unspecified it is stored as is....

 

Since I really wanted unified DateTimes in the complete solution I created a pipeline that did the following trick:

        static string CreateUnspecifiedDate(string someXsDateTimeString)
        {
           DateTimeOffset dto = DateTimeOffset.Parse(someXsDateTimeString);
           DateTime res = dto.LocalDateTime;
           return System.Xml.XmlConvert.ToString(res,System.Xml.XmlDateTimeSerializationMode.Unspecified);
        }

And the problem was solved. But I did learn something about datetimes

Posted by Patrick Wellink with no comments
Filed under: ,

I think this is a bug in the orchestration engine but I am not really sure.

Today I had a very weird problem.
I submitted a message via a WCF webservice and had an orchestration listening on the messagebox for that particular messagetype.

The orchestration does some serious data-massage and needs to store the converted message a couple of times. For this I created some helper components that store the changed message in a database (all the logic is in a callable orchestration).
Below is a sample of the orchestration that went wrong.


So it's nothing too fancy and I have used this pattern a lot and never had any problems. Until today.......
If the message is sent to the messagebox, there could be a failure (no subscribers) this will kick in the errorhandeling and the message is send to the Faultportal where you can resubmit the message.
But today things went a little different than I was used to......

Because there was  was no subscribtion I would expect ONE routing failure, but I got TWO routing failures....... So I did some investigation on those routing failures..... Below is a screenshot of this :

The Field marked with the red square is the ID that I get back from the Database insert (Callable orchestration)..... It is a distinguished field so it sits on the contex of a message.
Thats why I can see these are two different routing failures, and there were two calls made to the Database to store the message. (So the callable orchestration was called twice !)
And both routing failures are from one orchestration. See the instance ID in the header of the window.

For sure I have been looking half a day in the message box for that hidden subscription somewhere but finally I gave up there was nothing, everything seems to be all right...

After a day looking, I think i have found it. First let's describe what should happen.

  1. Message is received
  2. Some transformations are done
  3. New message is stored in the DB and we get the ID back
  4. Message is Send off to the Messagebox
  5. Subscription fails
  6. Errorhandler kicks in and writes the message to the FaultPortal.

Now let's rewrite this with the things that happen :

  1. Message is received
  2. Some transformations are done
  3. New message is stored in the DB and we get the ID back
  4. Message is Send off to the Messagebox (First Routing Failure)
  5. Subscription fails
  6. (For some reason we start at two again but  this time with the knowledge that publishing will fail)
  7. Some transformations are done (step 2 again !)
  8. New message is stored in the DB and we get the ID back (step 3 so we get a new ID)
  9. Message is Send off to the Messagebox (Second Routing Failure)
  10. Errorhandler kicks in and writes the message to the FaultPortal.

This is definitely not what I was expecting.
So I had a close look at my other orchestrations that do work with almost the same construct and I did find a very small difference that made all the difference.
Below is a screenshot of this.

 Now the Expected flow and the flow that actually happens are again in sync :

  1. Message is received
  2. Some transformations are done
  3. New message is stored in the DB and we get the ID back
  4. Message is Send off to the Messagebox
  5. Subscription fails
  6. Errorhandler kicks in and writes the message to the Faultportal.

I think this is a bug in BizTalk, but I am not really sure about it so if you think you know why this happens please leave a message on my blog.

It ran on a machine with BizTalk 2006 R2 SP 1, but since the XLANG engine did not change that much this could happen in all BizTalk versions.

Posted by Patrick Wellink with no comments

Ntrace is available for Visual studio 2010

Ntrace is a great tool for logging. It has virtually no impact and is blazing fast. Finally it's been migrated to Visual studio 2010.
So now I can start building my BizTalk Bestpractice toolbox with it. The author of Ntrace can probably explain best what it is...

What is this ETW thing?

Event Tracing for Windows is a kernel-level tracing service that has been around since Windows 2000. Since it’s baked right into the kernel, it is extremely fast. Most of the developers that use ETW are writing drivers, but why should they have all the fun?

Why should I use ETW?

ETW Tracing has several benefits over the tracing classes provided with the .NET Framework. Most importantly, ETW tracing can be turned on and off without having to restart the application, but it also has features like built-in high performance circular logging (a circular log is one that never grows above a specified size by flushing out older trace messages), and the ability for you to capture the logs from multiple sources into a single trace session.

What is this preprocessor and why do we need it?

Put simply, to maximize application performance when tracing is not enabled. In a perfect world, an application’s performance when tracing is disabled would be identical to one where tracing wasn’t included at all. The problem is that your code is only compiled once; if those trace calls are in there, they’re GOING to get called, and while the ETW functions return quickly when tracing is disabled, the runtime still has to evaluate trace arguments, allocate memory, construct method call stacks, and so on. The application performance would be even faster if the functions were never called in the first place. How much faster is it? Here’s an example: Let’s write a simple application that has a function named DoSomething.
static int DoSomething(String arg0, int arg1, long arg2, DateTime arg3)

As you can see, DoSomething in this case simply returns a value and does no other calculations. It should be blazingly fast, right? Well, it is, but there’s still the overhead of the method call. To demonstrate this, let’s run two loops: one that ends up in a call to DoSomething one million times, and another that will shortcut the call. To do this, we’ll create a method named DoRun that will call DoSomething unless the caller has specified that it should bypass the call entirely. If the value passed to shortcut is true, we’ll skip the DoSomething call altogether.
static void DoRun(bool shortcut)
{
  DateTime start, stop;

  start = DateTime.Now;
  for (int index = 0; index < 1000000; index++)
  {
    if (!shortcut)
    {
      Program.DoSomething("Hi there!", 42, 42L, DateTime.Now);
    }
  }
  stop = DateTime.Now;

  Console.WriteLine(
    "Shortcut {0}: {1} milliseconds", 
    shortcut, 
    (stop - start).TotalMilliseconds);
}

To get our results, we will now call DoRun twice; once with shortcut set to False, and again with shortcut set to True. On my machine (a 2GHz Core2Duo running Windows Vista x86), the results are:

Shortcut False: 546 milliseconds
Shortcut True: 15.6 milliseconds

In other words, it was 35 times faster to completely bypass the function call. That’s nearly two orders of magnitude! Now, imagine if you were doing something even more complicated there such as calling ToString() on an exception or dumping a string containing the values of all of the properties of the object you are working on and you should be able to see that you get a rather large performance boost by skipping those calls completely. NTrace's preprocessor provides your code with this boost by automatically injecting conditional statements around your trace calls for you, allowing you to focus on writing your code instead of remembering which conditions to check.

 

I have been waiting for this tool to upgrade to 2010 for a long time. So see what it is and grab your copy of Ntrace >>here<<

Really nice BizTalk Admin tool, BizTalk 360

Today I stumbled upon a really nice BizTalk admin tool. (thanks google reader)

Have a look at it >>here<<

It's a kind of Silverlight BizTalk Administration console with quite a few extra's.
Really good work !

Posted by Patrick Wellink with 1 comment(s)
Filed under:

Removing unwanted namespaces from a BizTalk Map

BizTalk is a great tool but sometimes the output is a little unreadable because of the number of namespaces in a document.
This post is related to a previous post where I had to import a zillion schemas. Once I had those schema's imported I could map them but the ouput looked as the picture below.

So about 120 namespace declarations and then some data. (the namespace declaration was about 10K and the message itself only 5K) This was not what the customer desired and they wanted to get rid of some (most) of those namespaces.
So I created a nice little CSLT that would get rid of those namespaces. I started a discussion on MSDN <clickto see> and Greg Forsythe came with the following solution.
Create a custom XSLT like this :

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:template match="*">
      <xsl:element name="{local-name()}" namespace="{namespace-uri()}">
         <xsl:apply-templates select="@* | node()"/>
     </xsl:element>
  </xsl:template>
<xsl:template match="@* | text() | comment() | processing-instruction()">
   <xsl:copy/> 
</xsl:template>
</xsl:stylesheet>


And surely that did the trick.
But there was a problem. I now had to execute two maps. One to map to the desired output and one to get rid of all those namespaces.
Furthermore this script had the problem that instead of declaring all the namespaces once at the top of the document, it repeated the namespaces in every node, resulting in a much less readable message.

Leg xmlns="urn:fec:florecom:xml:data:draft:ReusableAggregateBusinessInformationEntity:3">
      <TransportMeans>
        <TypeCode xmlns="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:3" listID="Recommendation 28" listAgencyID="6" listVersionID="2007"/>
      </TransportMeans>
      <SpecifiedLoadingLocation>
        <CountryID schemeVersionID="second edition 2006"/>
      </SpecifiedLoadingLocation>

After googling around I came to a solution where I had the following problems solved.

  • No extra map required
  • Namespaces declared only once per message
  • High level of control of what namespace to declare and what namespace to omit.

Here is how I did it :

  • First Create the map as you normally do.
  • Then after the map is finished, select validate map.
  • You will be presented with something like this :

 D:\Lokale Bestanden\Ontwikkeling\CE\FH.CE\FH.CCE.CCX.Plugins.XMLLB_v0006\FH.CCE.CCX.Plugins.XMLLB_v0006\Maps\GeleverdePartij_v0006_To_Delivery_0p2.btm: warning btm1004: The destination node "TypeCode" has multiple inputs but none of its ancestors is connected to a looping functoid.
D:\Lokale Bestanden\Ontwikkeling\CE\FH.CE\FH.CCE.CCX.Plugins.XMLLB_v0006\FH.CCE.CCX.Plugins.XMLLB_v0006\Maps\GeleverdePartij_v0006_To_Delivery_0p2.btm: The output XSLT is stored in the following file:
file:///C:\Documents and Settings\pkwk\Local Settings\Temp\1\_MapData\GeleverdePartij_v0006_To_Delivery_0p2.xsl
D:\Lokale Bestanden\Ontwikkeling\CE\FH.CE\FH.CCE.CCX.Plugins.XMLLB_v0006\FH.CCE.CCX.Plugins.XMLLB_v0006\Maps\GeleverdePartij_v0006_To_Delivery_0p2.btm: The Extension Object XML is stored in the following file: <file:///C:\Documents and Settings\pkwk\Local Settings\Temp\1\_MapData\GeleverdePartij_v0006_To_Delivery_0p2_extxml.xml>

  •  Now test the map and see if it still gives the same result (it should)
  • Then open the Custom.xsl and look  for "exclude-result-prefixes"
  • Then I added all the namespaces I wanted to exclude to this so it looked like this :

exclude-result-prefixes

="msxsl var s2 s0 s1 userCSharp udt qdt ns1 ns2 ns3 ns4 ns5 ns6 ns7 ns8 ns9 ns10 ns11 ns12 ns13 ns14 ns15 ns16 ns17 ns18 ns19 ns20 ns21 ns22 ns23 ns24 ns25 ns26 ns27 ns28 ns29 ns30 ns31 ns32 ns33 ns34 ns35 ns36 ns37 ns38 ns39 ns40 ns41 ns42 ns43 ns44 ns45 ns46 ns47 ns48 ns49 ns50 ns51 ns52 ns53 ns54 ns55 ns56 ns57 ns58 ns59 ns60 ns61 ns62 ns63 ns64 ns65 ns66 ns67 ns68 ns69 ns70 ns71 ns72 ns73 ns74 ns75 ns76 ns77 ns78 ns79 ns80 ns81 ns82 ns83 ns84 ns85 ns86 ns87 ns88 ns89 ns90 ns91 ns92 ns93 ns94 ns95 ns96 ns97 ns98 ns99 ns100 ns101 ns102 ns103 ns104 ns105 ns106 ns107 ns108 ns109 ns110 ns111 ns112"

  • That's guite a list. And now if I test the map the result looks like the picture below :

 

  • And that's exactly what the customer wanted.

I hope this Blog post will help other people wha are struggeling with the same problem. If it does, please leave a comment below.

Posted by Patrick Wellink with 2 comment(s)
Filed under: , ,

XSLT Distinct another way to determine distinct in XSLT 1.0

I had a requirement to map a buyer only if it was the same buyer throughout the entire document.
The reason for this was that in the source document the buyer was defined in a sub sub sub node of a document and in the destination it occurred only once.
So I ended up with several choices.

  • Only map the first buyer
  • Don't map
  • Only map if they were the same throughout the entire document

For sure the first option would be a bad thing.
The second option would work for all parties involved (it's an optional element in the output of the map) but the parties really want their buyer information if it's there.
The third option seemed the best solution. I quickly googled on XSLT and distinct and there were some results. So I told the customer implementing a distinct wouldn't be too hard. (it already existed in XSLT).
(I wish I looked a bit harder, cause then I would have seen that the distinct function of XSLT comes with XSLT 2.0 and sadly BizTalk is still using XSLT1.0)

After some thinking I got the following solution for this problem.

  1. Perform a count of the number of buyers in a document
  2. Get the first buyer (buyer is mandatory in the input document)
  3. Perform a count of the numbers of buyers where buyer != buyer found in step2

If the number in step 3 is 0 then we know all the buyers are the same. Below is the XSLT I used to perform this different distinct approach.

<xsl:template name="Buyerparty_DocTemplate">
  <xsl:param name="var1" />
  <xsl:param name="var2" />
  <xsl:param name="dbg" />
  <xsl:variable name="buyers" select="count(/s0:Request/GeleverdePartij/LeveringsBericht/Levering[*]/Ladingdrager[*]/Goederen[*]/Koper/kop_gln)" />
  <xsl:variable name="firstBuyer" select="/s0:Request/GeleverdePartij/LeveringsBericht/Levering[1]/Ladingdrager[1]/Goederen[1]/Koper/kop_gln" />
  <xsl:variable name="otherBuyers" select="count(/s0:Request/GeleverdePartij/LeveringsBericht/Levering[*]/Ladingdrager[*]/Goederen[*]/Koper[not(kop_gln=$firstBuyer)])" />
  <xsl:if test="$dbg=1">
    <xsl:element name="BuyerInfo">
      <xsl:element name="TotalBuyers">
        <xsl:value-of select="$buyers" />
      </xsl:element>
      <xsl:element name="FirstBuyer">
        <xsl:value-of select="$firstBuyer" />
      </xsl:element>
      <xsl:element name="OtherBuyers">
        <xsl:value-of select="$otherBuyers" />
      </xsl:element>
    </xsl:element>
  </xsl:if>
  <xsl:if test="$otherBuyers=0">
    <xsl:if test="string-length($firstBuyer) > 0">
      <xsl:element name="BuyerParty">
        <xsl:element name="PrimaryID">
          <xsl:value-of select="$firstBuyer" />
        </xsl:element>
        <xsl:element name="schemeID">
          <xsl:value-of select="$var1" />
        </xsl:element>
        <xsl:element name="schemeAgencyName">
          <xsl:value-of select="$var2" />
        </xsl:element>
      </xsl:element>
    </xsl:if>
  </xsl:if>
</xsl:template>

Posted by Patrick Wellink with no comments
Filed under: , ,

xs:int and xs:integer, what's the difference....

I am busy creating schema's and exposing them as a web service.
I always generate a client and try to post some messages and this time I was again surprised by BizTalk. (or should I say XML).
When creating a schema you can chose several types for an element. Some of these are xs:int and xs:integer.
I noticed these two before but didn't bother too much.
But now for the first time I see there is a clear difference in the way stuff is treated by .Net. Below is a screenshot of a node with the type xs:integer.

I also have some regular elements of type xs:int. Below is a screenshot of that.

Now after I generated the WCF service for this schema, I imported the WSDL into VS 2005 and I was quite surprised to see what intellisense did to these elements in visual studio :

 So intellisense showed me it was actually a string !... And the other node of type xs:int was the .Net type I expected to see.

So what did I learn today, to stay away from xs:integer and use xs:int instead.
Hope this will help someone in the future, if it does, leave a comment

 

Posted by Patrick Wellink with 6 comment(s)
Filed under: , ,

Millions of records in the BAMAlertsApplication and how to get rid of them (NSVacuum to the rescue)

As a BizTalk consultant I always implement BAM to do basic auditing. This is besides the BAM a business analist would want to see. The basic functionality of this audit trial is:

  • When was the message received
  • Where did it came from
  • Where did it go
  • What happend to the message
  • Any important business decision made in an orchestration

I write this audit data into a BAM view, and it has proven to be valuable information. From time to time you will get questions regarding messages and it's always nice to have this information. Besides that you can set nice alerts ( if you use them) on specific events and have people mailed in case things go wrong. So this is nice and i wouldn't want to do an implementation without it.

But there is a downside to it. All these audit records also write some data in a not very well documented database BAMAlertsApplication. And over time there could be millions of rows in them. Below is a sample of the BAMAlertsApplication

The records are just piling up and are consuming more and more resources from your SQL server. I had noticed this behaviour before and posted a question about it on the MDSN forums see "How to clean up the BAMAlertsApplication database." And the answer of a MS Employee was to open a case by Microsoft. Yesterday the BizTalk Administrator of the customer that I work for, asked me if there was anything I could do about the size of this database that just kept on growing and growing. The administrator even pointing me to my own discussion on MSDN and stated that he wanted to indeed start a case with MS.

This triggered me to have a look at the database and by looking at the stored procedures ( I was looking for remove/archive/delete stored procedures) I noticed the NSVacuum stored procedure. This triggered me to see what it did. So I turned to the almighty google to see what it knew  about NSVacuum. I got only 2 results !.The first post wasn't really encouraging, since it increased the databases

.

 

But looking at the code of the stored procedure I was convinced that it did some cleaning. So I dropped the "BizTalk" keyword from the search to have another look.....

This was not too encouraging either, only three real results this time. But fortunately the first one pointed me to a Microsoft document with usefull information. It turned out that NSVaccum was exactly what we needed. And after some runs the databas has now shrunk to a more reasonable size. See the picture below.

 So, the takaway is....., do NOT forget to schedule NSVacuum if you are using BAM !....

I really hope this is usefull for other people in the future, if it is, please leave reaction on my blog, it will keep me motivated to share my BizTalk experiences with the community !

Getting rid of : WCF-Custom" raised an error message. Details "System.Data.SqlClient.SqlException: Timeout expired

I had a nice setup in my BizTalk environment. I had 4 receive locations polling for data (in the same table) and it all boiled down to execute a stored procedure with different parameters. I used the WCF adapter with SQL bindings for that.
For some obscure reason, I would get timeouts in the eventlog. Below is a screenshot of the receive port setup I had. Only one is shown but I had four of them.

Some important things to notice:

  • PolledDataAvailablestatement, is not used cause Pollwhiledatatfound = false. But you still have to put stuff in there to make things work.
  • Execute a specific sproc, with the number of records you want to receive as a parameter.
  • UseAmbientTransaction, no, no,no, had too many problems in the past when using msdtc and receive locations (locks and stuff) so this is a NO.
  • ReceiveTimeout is set to 10 minutes. This is a bit long but i never touched that value, it's the default.

To make things a little bit more clear, The stored procedure I used looks looked like this :

 CREATE PROCEDURE [dbo].[Get_TeVertalen_Berichten]
(
 @MaximumAantal INT = NULL
)
AS
BEGIN
 EXEC [dbo].[Get_Berichten_Internal]
  @MaximumAantalInternal = @MaximumAantal,
  @OudeBerichtStatus = 'TeVertalen',
  @NieuweBerichtStatus = 'VertalenGestart',
  @Richting  = 'Ingaand'  
END

And here is the code of Get_Berichten_Internal:

CREATE PROCEDURE [dbo].[Get_Berichten_Internal]
(
 @MaximumAantalInternal INT = 15,
 @OudeBerichtStatus  VARCHAR(200),
 @NieuweBerichtStatus VARCHAR(200),
 @Richting    VARCHAR(20) 
)
AS
BEGIN
 BEGIN TRY
  -- Declare variables
  DECLARE @AFFECTED_KEYS TABLE
  (
   BerichtID NUMERIC(18, 0)
  )
  DECLARE @AFFECTED_ROWS INT
   -- Some sets needed
  SET NOCOUNT ON
  -- Perform the update statement and capture all the keys
  UPDATE
   TOP (@MaximumAantalInternal) dbo.tb_Bericht
  SET  
   BerichtStatus = @NieuweBerichtStatus
  OUTPUT
   INSERTED.BerichtID
  INTO
   @AFFECTED_KEYS
  WHERE
   BerichtStatus = @OudeBerichtStatus
  AND
   ExternBerichtTypeID IS NOT NULL
  AND
   InternBerichtTypeID IS NOT NULL
  AND
   Richting = @Richting
  -- DO STUFF WITH THE AFFECTED KEYS
  <-- SNIP-->
 END TRY
END

Now everything looks good and in the query analyzer everything was working blazingly fast. But I started to see the following message in the eventlog every 10 minutes (hmm that's the receive timeout).  And sometimes several (four to be exactly) of them within a very short period of time.

Event Type: Warning
Event Source: BizTalk Server 2006
Event Category: BizTalk Server 2006
Event ID: 5740
Date:  14-12-2010
Time:  10:47:07
User:  N/A
Computer: BA34T
Description:
The adapter "WCF-Custom" raised an error message. Details "System.Data.SqlClient.SqlException: Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.
   at Microsoft.ServiceModel.Channels.Common.Design.AdapterAsyncResult.End()
   at Microsoft.ServiceModel.Channels.Common.Channels.AdapterInputChannel.EndTryReceive(IAsyncResult result, Message& message)
   at System.ServiceModel.Dispatcher.InputChannelBinder.EndTryReceive(IAsyncResult result, RequestContext& requestContext)
   at System.ServiceModel.Dispatcher.ErrorHandlingReceiver.EndTryReceive(IAsyncResult result, RequestContext& requestContext)".

For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.

And once this message started to appear, stuff went downhill from there on. I could see in the profiler that stored procedures were taking ages, and even simple updates of a single record would take thirty seconds or so. Lock-Time-outs and deadlocks were occuring on a very regular basis. Even though the receive locations werent receiving any data. So nothing was received and I still got may daily portion of errors/warnings/suspended stuff in BizTalk because of this.
So basically it looked like I was having some kind of locking problem even if no work was done by the second stored procedure. But the second procedure did an update (even when there was nothing to update) and maybe that triggered the nasty behaviour.

I started a discusiion on MSDN to see if anybody could help : <<See here>>

 But eventually i cghanged something to make this behaviour go away. The idea was only to perform the update when there was stuff to update. So i changed the first procedure to :

CREATE PROCEDURE [dbo].[Get_TeVertalen_Berichten]
(
   @MaximumAantal INT = NULL
)
AS
BEGIN
 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
 DECLARE @Aantal int
 SELECT
  @Aantal=count(*)
 FROM
  dbo.tb_Bericht WITH (NOLOCK)
 WHERE
  BerichtStatus = 'TeVertalen'
 AND
  ExternBerichtTypeID IS NOT NULL
 AND
  InternBerichtTypeID IS NOT NULL
 AND
  Richting = 'Ingaand'
 IF @Aantal > 0
 BEGIN
  EXEC [dbo].[Get_Berichten_Internal]
    @MaximumAantalInternal = @MaximumAantal,
    @OudeBerichtStatus  = 'TeVertalen',
    @NieuweBerichtStatus = 'VertalenGestart',
    @Richting    = 'Ingaand'  
 END 
END

 And by first checking if there was any work to do and only then do an update, I got rid of the deadlocks and the errors in the eventlog.
I really don't know why this solved it, but my guess is there is some bug in the WCF adapters, that go wrong if you start a transaction but return no data.

Everything is running smooth now and I hope this post will help somebody experiencing the same problems.

Download all files referenced in an xsd locally (+ Possible fix for BizTalk CS0013 compilation error)

Well if you ever end up like me with a XSD that has about a zillion includes (schemaLocation), maybe this tool is something for you.

It is a pretty simple tool. You give it an XSD, and it will download all files that are referenced to your local system. It will parse the file names a bit and set them all to the local download folder.
This way you can simply include the folders and downloaded schema's in your BizTalk Project.

For example take the schema's from UNECE like http://www.unece.org/uncefact/data/standard/Acknowledgement_4p0.xsd

It can be pretty frustrating to download all the schema's manually and link them together again with a correct import. IncludeSchemaDownloader.exe comes to the rescue.. Below is a screenshot of this tool.

The workings are quite simple. Follow these steps to get the all the schema's on yoyr local machine.

  1. Download the Toplevel XSD to a work folder.
  2. Point the Toplevel XSD to that working folder.
  3. Point the StoreFolder to the desired location where the xsd's will be stored (typically schema's folder of a BizTalk Project
  4. Hit the process button !
  5. Done
  6. Now include this folder in your BizTalk project
  7. Hit the Validate button... (should work)

Now these XSD schemas that you get from UNECE are full with usefull comments and annotations. And if your schema's get too large you cannot compile them anymore. (there seems to be a limit in the size of the dll the BizTalk compile can handle). You would get an error message like this:

error CS0013: Unexpected error writing metadata to file '<somedrive><somefolders><yourproject>.dll'

 

To solve this you would have to break up your huge XSD project into smaller projects. This would solve the problem but in my case VisualStudio was soo busy reflectoring all the DLL's it hardly had time for me. (You know opening a map would take ages....).

When I looked into the XSD's they were all beautifully documented with lots and lots of annotations and comments. But wait a minute..... I only had to send these documents. So i only have to validate the documents. So I don't need all those comments and annotations. That's why the tool has the option to strip comments and annotations.

When I tried to compile the XSD's with comments and annotations (size on disk roughly 12 megabytes) I got the dreaded  CS0013 compilation error.

I ran the tool again (size on dis now about 1.5 megabytes) I ended up with a DLL only 4 MB in size. And if reference this DLL in a map or whatever it's way faster than the other solution(you know several projects / dll's)

You can download the tool >>HERE <<

If I import the schema http://www.unece.org/uncefact/data/standard/Acknowledgement_4p0.xsd

The output of the tool will be  :

Starting with D:\Temp\Demo\Acknowledgement_4p0.xsd
getting all imports
Loading file :http://www.unece.org/uncefact/data/standard/UnqualifiedDataType_7p0.xsd
getting all imports
Loading file :http://www.unece.org/uncefact/codelist/standard/IANA_CharacterSetCode_20070514.xsd
getting all imports
Loading file :http://www.unece.org/uncefact/codelist/standard/IANA_MIMEMediaType_20090304.xsd
getting all imports
Loading file :http://www.unece.org/uncefact/identifierlist/standard/ISO_ISOTwoletterCountryCode_SecondEdition2006VI-4.xsd
getting all imports
Loading file :http://www.unece.org/uncefact/codelist/standard/ISO_ISO3AlphaCurrencyCode_20090305.xsd
getting all imports
Loading file :http://www.unece.org/uncefact/codelist/standard/UNECE_CharacterSetEncodingCode_40106.xsd
getting all imports
Loading file :http://www.unece.org/uncefact/codelist/standard/UNECE_MeasurementUnitCommonCode_5.xsd
getting all imports
Loading file :http://www.unece.org/uncefact/codelist/standard/UNECE_AgencyIdentificationCode_D08B.xsd
getting all imports
Loading file :http://www.unece.org/uncefact/data/standard/QualifiedDataType_6p0.xsd
getting all imports
Loading file :http://www.unece.org/uncefact/data/standard/UnqualifiedDataType_7p0.xsd
getting all imports
Loading file :http://www.unece.org/uncefact/codelist/standard/IANA_CharacterSetCode_20070514.xsd
getting all imports
Loading file :http://www.unece.org/uncefact/codelist/standard/IANA_MIMEMediaType_20090304.xsd
getting all imports
Loading file :http://www.unece.org/uncefact/identifierlist/standard/ISO_ISOTwoletterCountryCode_SecondEdition2006VI-4.xsd
getting all imports
Loading file :http://www.unece.org/uncefact/codelist/standard/ISO_ISO3AlphaCurrencyCode_20090305.xsd
getting all imports
Loading file :http://www.unece.org/uncefact/codelist/standard/UNECE_CharacterSetEncodingCode_40106.xsd
getting all imports
Loading file :http://www.unece.org/uncefact/codelist/standard/UNECE_MeasurementUnitCommonCode_5.xsd
getting all imports
Loading file :http://www.unece.org/uncefact/codelist/standard/UNECE_AgencyIdentificationCode_D08B.xsd
getting all imports
Loading file :http://www.unece.org/uncefact/codelist/standard/EDIFICASEU_AccountingAccountType_D08B.xsd
getting all imports
Loading file :http://www.unece.org/uncefact/codelist/standard/EDIFICASEU_AccountingAmountType_D08B.xsd
getting all imports
Loading file :http://www.unece.org/uncefact/codelist/standard/EDIFICASEU_AccountingEntryCategory_D08B.xsd
getting all imports
Loading file :http://www.unece.org/uncefact/codelist/standard/EDIFICASEU_AccountingEntryLineCategory_D08B.xsd
getting all imports
Loading file :http://www.unece.org/uncefact/codelist/standard/EDIFICASEU_AccountingEntryLineSource_D08B.xsd
getting all imports
Loading file :http://www.unece.org/uncefact/codelist/standard/EDIFICASEU_AccountingEntryProcessing_D08B.xsd
getting all imports
Loading file :http://www.unece.org/uncefact/codelist/standard/EDIFICASEU_AccountingVoucherMedium_D08B.xsd
getting all imports
Loading file :http://www.unece.org/uncefact/codelist/standard/EDIFICASEU_AlternateCurrencyAmount_D08B.xsd
getting all imports
Loading file :http://www.unece.org/uncefact/codelist/standard/EDIFICASEU_TaxExemptionReason_D08B.xsd
This list goes on and on and on

 Below are some results:

 

 

 

 

Posted by Patrick Wellink with no comments
Filed under: ,

My BizTalk infrastructure design baseline

Today I found a great post about a nice BizTalk infrastructure baseline. It's always hard to specify what you need and why you need it.
In an excellent blogposting Johan Hedberg explains what he needs and (more important why).

Follow >>this link<< to have a read of his excellent post by Johan.

 

 

 

Posted by Patrick Wellink with no comments
Filed under:

Strange COM exception in BizTalk

A while ago I had serious problems with BizTalk. For some obscure reason the BizTalk engine would throw some XLANG errors and stop processing all messages. A restart of the hosts would fix the problem for a while but after some time the same problem would occur and BizTalk would effectively stop processing. (orchestrations would be marked as  active but nothing happens)

The funny thing is, these orchestrations were deployed on the BizTalk Server a long time ago and they never gave any problem. All of a sudden these problems started to appear. So I think the blame is probably in some kb^*&^(& hotfix somewhere.

I had a case with MS-Support (and for sure they had never seen this error) and even google will not tell you that much about it.
However, until now I have had two people contact me with exactly the same problem.
So I know I was not alone ! Since googling on this gives me very poor results I will put some details about what happened in this post.

Unable to cast COM object of type 'System.__ComObject'   followed by No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

When this happens you will find a lot of references to the guid 6C90EC05-4918-11D3-A242-00C04F60A533 (see bottom)

I have mentioned both MSDN threads that have this problem. The things we have in common are:

  • Usage of the classic SQL adapter 
  • Typically, this problem occurs when the orchestration engine reaches a Call Orchestration shape or a Start Orchestration shape.

To isolate this problem we added a specific SQL Host that does all the work for the SQL Adapter. We hoped the next time we saw the error, we could see if it was caused by orchestrations or really by the SQL adapter. Cause then onlu the SQL Host would have a problem. We had everything set up to debug the BizTalk environment with the tools provided by MS and we were waiting for the event to happen. But unfortunately after we added a dedicated SQL host the problem never re-occurred. So the supportcase is closed now (without a definitive answer).

If you have had a similar experience please give a response to this post.

Using XSLT Templates in a map (reminder@self)

We all know that using XSLT inside a map can be very usefull to do stuff that's very hard to do with the mapper itself.
Sometimes using XSLT it is the only way things can be done. I find myself struggeling each time to figure out how specific tasks work with XSLT.

That's why I write this post. So I wont have to figure it all out again the next time i need this functionality....
Below is some code used in an 'Inline XSLT Call Template' to calculate the number of segments in a message (UNT) and the message Message Reference number.

The input CurrentIndex is retrieved from an Iteration functoid that returns the current index of the transaction. This index is used to retrieve the correct values for the UNT segment of that transaction
( I am using the batched EDI schema's).

<xsl:template name="UNTTemplate">

  <xsl:param name="currentIndex" />

  <xsl:variable name="sum01" select="count(/s2:Request/INTERCHANGE/UNB)" />

  <xsl:variable name="sum02" select="count(/s2:Request/INTERCHANGE/TRANSACTION[position()=$currentIndex]/UNH)" />

  <xsl:variable name="sum03" select="count(/s2:Request/INTERCHANGE/TRANSACTION[position()=$currentIndex]/BGM)" />

  <xsl:variable name="sum04" select="count(/s2:Request/INTERCHANGE/TRANSACTION[position()=$currentIndex]/DTM)" />

  <xsl:variable name="sum05" select="count(/s2:Request/INTERCHANGE/TRANSACTION[position()=$currentIndex]/NAD)" />

  <xsl:variable name="sum06" select="count(/s2:Request/INTERCHANGE/TRANSACTION[position()=$currentIndex]/LIN)" />

  <xsl:variable name="sum07" select="count(/s2:Request/INTERCHANGE/TRANSACTION[position()=$currentIndex]/LIN/DTM)" />

  <xsl:variable name="sum08" select="count(/s2:Request/INTERCHANGE/TRANSACTION[position()=$currentIndex]/LIN/NAD)" />

  <xsl:variable name="sum09" select="count(/s2:Request/INTERCHANGE/TRANSACTION[position()=$currentIndex]/LIN/RFF)" />

  <xsl:variable name="sum10" select="count(/s2:Request/INTERCHANGE/TRANSACTION[position()=$currentIndex]/LIN/QTY)" />

  <xsl:variable name="sum11" select="count(/s2:Request/INTERCHANGE/TRANSACTION[position()=$currentIndex]/LIN/PRI)" />

  <xsl:variable name="sum12" select="count(/s2:Request/INTERCHANGE/TRANSACTION[position()=$currentIndex]/LIN/IMD)" />

  <xsl:variable name="sum13" select="count(/s2:Request/INTERCHANGE/TRANSACTION[position()=$currentIndex]/LIN/IMD/PRICE_INFORMATION)" />

  <xsl:variable name="sum14" select="count(/s2:Request/INTERCHANGE/TRANSACTION[position()=$currentIndex]/LIN/PAC)" />

  <xsl:variable name="sum15" select="count(/s2:Request/INTERCHANGE/TRANSACTION[position()=$currentIndex]/LIN/PAC/PRI)" />

  <xsl:variable name="sum16" select="count(/s2:Request/INTERCHANGE/TRANSACTION[position()=$currentIndex]/LIN/EQD)" />

  <xsl:variable name="sum17" select="count(/s2:Request/INTERCHANGE/TRANSACTION[position()=$currentIndex]/LIN/EQD/EQN)" />

  <xsl:variable name="unt18"  select="/s2:Request/INTERCHANGE/TRANSACTION[position()=$currentIndex]/UNH/MESSAGE_REFERENCE_NUMBER" />

  <xsl:variable name="totalCount" select="$sum01 + $sum02 + $sum03 + $sum04 + $sum05+ $sum06 + $sum07 + $sum08 + $sum09 + $sum10 + $sum11 + $sum12 + $sum13 + $sum14 + $sum15+ $sum16 + $sum17" />

  <xsl:element name="UNT">

    <xsl:element name="UNT1">

      <xsl:value-of select="$totalCount" />

    </xsl:element>

    <xsl:element name="UNT2">

      <xsl:value-of  select="$unt18" />

    </xsl:element>

  </xsl:element>

</xsl:template>

 

Posted by Patrick Wellink with no comments
Filed under: , ,

Again a BizTalk Hotrod issue you should not miss

Last week I stumbled upon the Tenth issue op BizTalk HotRod. I have looked into it a couple of times cause there are so much goodies in there.
The items covered in this issue are: 

  • Creating Business Documents 
  • Automating deployments of BizTalk change requests
  • Request and Response Message Pattern
  • Instrumentation Best Practices for High Performance BizTalk Solutions
  • Financial Messaging Service Bus
  • How To Boost Message Transformations Using the XslCompiledTransform class

 Go and get this issue, you can download it >>HERE<<

Posted by Patrick Wellink with 1 comment(s)
Filed under:

Interessante Blog Postings

Gedurende een bepaalde periode kom je op het internet interessante zaken tegen of zijn er interesante blogpostings gedaan. Soms google je wat en kom je een oude maar zeer interessante blogposting tegen. In dit artikel wil ik een aantal van deze blogpostings/blogposters/artikelen aanstippen.

 

Maxime Labelle

 

Heeft een interessant blog waar hij af en toe diep ingaat op de werking van BizTalk. Er zitten veel code voorbeelden bij. Enkele noemenswaardige zaken zijn onder andere:

A Base Class for Building Custom Pipeline Components

Een handige base class welke het leven van een BizTalk ontwikkelaar behoorlijk kan versimpelen. In plaats van iedere keer weer alles van de grond af aan op te bouwen zorgt deze base class standaard voor een aantal zaken. Je hoeft eigenlijk alleen nog maar de Execute van de pipeline te programmeren. Erg handig.

Streaming Data in and out of an SQLServer 2005 Database

Interessant artikel over het opslaan van BizTalk Berichten in een database. Absoluut de moeite van het lezen waard.

 

Als je nog wat verder snuffelt op zijn blog zul je zien dat er echt interessante en nuttige zaken tussen staan.

 

Validatie functie BizTalk

 

Gebruikers van de “BizTalk Best Practice” zullen wel weten dat ik een groot voorstander ben van het valideren van xml nadat er gemapped is. Een map biedt immers geen enkele garantie met betrekking tot het valide zijn van het resultaat. Voorheen gebruikte ik daarvoor altijd de ‘Cool XSD Validation Function for Orchestration van de ‘Arch Hacker’ . Deze validatie functie is inmiddels stokoud en compileert niet zonder warnings meer in .Net 2.0 en hoger. Met een aantal ‘Pragma Directives’ kon het nog net compileren zonder warnings maar dat de code ondertussen sterk verouderd is blijft een feit. Onlangs kwam ik een nieuwe versie tegen die wel voldoet aan 2.0. Daarnaast biedt deze wat meer functionaliteit.

 

BizTalk Service Pack 1, Fix Pack1, Fix Pack 2 !

 

Begin dit jaar is voor BizTalk Service Pack 1 uitgerold en zodra deze geïnstalleerd was op de ontwikkel server van de klant waar ik op dit moment zit werkte zaken niet meer zoals ze zouden moeten werken. Omdat dit bij Microsoft Support liep was ik op de hoogte van een BizTalk 2006 R2 SP1 Cumulative Update 1. Hierin waren een aantal zaken opgelost, maar het belangrijkste issue stond nog steeds open. Zeer onlangs kreeg ik te horen dar er nu ook een BizTalk 2006 R2 SP1 Cumulative Update 2 beschikbaar is. Blijkbaar was Service Pack 1 niet de meest geslaagde update uit de BizTalk geschiedenis.

 

 

More Posts Next page »