Monday, 05 April 2010

Hi all

At times you may run into this error at compile time: “an atomic scope may not contain a receive with a correlation filtration initialized in the same scope”. Not very many posts exist on this topic so I thought I’d just share some thoughts on it.

First of all, the error occurs because you have a Receive shape inside an atomic scope and this Receive shape follows a correlation set that is initialized within the same scope. This is not allowed, as explained here: http://msdn.microsoft.com/en-us/library/aa560115(BTS.10).aspx.

The reason for this limitation is, that everything that happens inside the Atomic scope is not committed until the Scope shape finishes processing. If you at some point initialize a correlation set inside the Atomic scope, then the subscriptions for any Receive shapes that follow this correlation set cannot match the properties from the correlation type because the routing engine cannot know about the values until the Atomic transaction is committed.

If you actually could follow a correlation set that is initialized within the same Atomic scope you would end up in a deadlock because:

  1. The instance subscription is not created until the transaction commits
  2. The transaction does not commit until the Receive shape has its message

So as you can see, the Receive shape would never get a message and therefore the transaction would never commit.

Hope this helps someone out there.

--
eliasen

Monday, 05 April 2010 16:04:06 (Romance Daylight Time, UTC+02:00)  #    Comments [0]  | 

Hi all

When I run into some issues on web pages and report them, one of the things that almost always happens is that they won’t deal with your request until you have deleted all cookies and tried again. The support guys have some steps to guide the user through before they can send anything on to the second level support. And this usually includes getting the users to delete all cookies.

Now, this is bad! IF there is an issue with the cookie for a particular web site, then

  1. Deal with it in your server side code
  2. Don’t ask me to delete ALL cookies, but instruct me to delete the one that is the right one for your web site.

Deleting all cookies will make me start over entering usernames and passwords for lots of web sites that are really not in any way impacted by the ongoing issue the support guys are trying to solve. It may solve the problem, sure… but it sure isn’t the RIGHT way to solve the issue. The right way would be to

  1. Make sure the cookie doesn’t get corrupted
  2. Handle the corrupt cookie in the server side code
  3. Only delete the necessary cookies and not all cookies.

Asking customers to delete all cookies is just plain lazy.

I have seen this from several web sites, and lately I actually got it from the mcp support team. I emailed them that I get this screen frequently:

ErrorOnMCPSite

As you can see, the web page instructs me to click an icon to sign in, but the icon is for signing out (Clicking it actually signs me out). Now, to me, this means that the server side code is faulty. The code generates a page that at the same time instructs me to sign in and to sign out. But, the reply from the mcp support team was that I was told to delete all cookies and try again. I have emailed them that I don’t think that is the right way to go about it and they have replied that deleting all cookies won’t do my system any harm and I should do it and get back to them. Sure it won’t harm my system, but it will for sure harm my user experience on all the web sites, whose cookies have now disappeared.

This is the way it always goes – not just with the mcp support team… I tell them it is the wrong solution and they instruct me to do it anyway.

Sigh…

--
eliasen

Monday, 05 April 2010 11:33:09 (Romance Daylight Time, UTC+02:00)  #    Comments [3]  | 

Hi all

I am trying out BizTalk 2010 beta, and just discovered a small glitch, will I will describe here and then email a link to the blog post to Microsoft to let them know about it.

I have a very simple solution:

I have a C# project which is a helper class, which I will be using from my orchestration in another project.

The project structure is as you can see here:

image

The helper class only has one class with one method which looks like this:

   1: private const string XPATH = "Some XPath expression";
   2: public static void ChangeXmlDocument(XmlDocument xmldoc)
   3: {
   4:     xmldoc.SelectSingleNode(XPATH).InnerText = "New value!";
   5: }

So it just changes the value of an element in the XML that is given to it as a parameter.

The second project only contains a schema:

image

and an orchestration:

image

The orchestration just picks up a message and then calls the helper class with the message as a parameter.

So, the deployment properties are set on the BizTalk project, so I right click it and choose to deploy it. It deploys fine.

I then entered BizTalk Server Administration, and created a new receive port and a receive location for it. I enabled the receive location and I bind the receive port to the Orchestrations receive port.

When enlisting the orchestration, I get this error:

image

Error message (For the benefit of search engines):

Could not enlist orchestration ‘strong name of orchestration’. Could not load file or assembly ‘Strong name of helper class’  or one of its dependencies. The system cannot find the file specified. (Microsoft.BizTalk.ExplorerOM)

So I am thinking that the error is because I forgot to GAC the helper class and the administration console wants to alert me to this. Not sure I like that, but ok – I’ll GAC it. That didn’t help, though.

So I thought: Maybe a refresh of the administration console, so I right clicked on the application with the orchestration and chose “Refresh”. That didn’t help.

Then I thought: I’ll right click the “Applications” node in Administration console and chose “Refresh”. That didn’t help either.

Then I tried to chose “Refresh” on the BizTalk Group node in Administration Console. That didn’t help either.

So, as it turns out, there are two options to fix this error.

  1. Restart BizTalk Server Administration Console
  2. Add the helper class as a resource in Administration Console

Neither should be necessary, I think…

Hope this helps someone.

You can find my solution here:

--
eliasen

Monday, 05 April 2010 11:05:34 (Romance Daylight Time, UTC+02:00)  #    Comments [2]  | 
Sunday, 07 March 2010

Hi all

Today I discovered something, that AGAIN confirms, that BizTalk 2009 was simply shipped without any form of proper testing of the new Visual Studio .NET project system that they chose to switch to. I have already described lots of issues here: http://blog.eliasen.dk/2009/07/21/IssuesWithBizTalk2009OnVSNET2008.aspx and a hotfix has been releases which I have shortly described here: http://blog.eliasen.dk/2010/01/27/HotfixForIssuesWithDevelopingBizTalk2009SolutionsInVisualStudio.aspx.

Anyways, the issue is, that I created a property schema in my project, and in this property schema I created four properties. I then opened up the orchestration I had in the same project and created a Correlation Type, that used these four properties. That gave me this error:

identifier 'PropertyName' does not exist in 'ProjectName'; are you missing an assembly reference?

So basically, when compiling, the new property cannot be found. Turns out, though, that if I compile the project and THEN use the properties in a Correlation Type, then everything works just fine. What a lousy deal…

The hotfix mentioned above does not seem to rectify this issue, so this remains an issue, I think.

--
eliasen

Sunday, 07 March 2010 20:35:43 (Romance Standard Time, UTC+01:00)  #    Comments [0]  | 

Hi all

I have just installed VMware WorkStation 7.0.1 in order to start building 64bit guest OS’es in order to try out Windows Server 2008 R2 and SharePoint 2010. Microsoft Virtual PC does not support 64bit guest operating systems, and since I really appreciate being able to run guest operating systems in a window on my host PC I saw no other way out than getting and installing VMware WorkStation.

Now, after installing it, I tried to create my first Windows 2008 R2 virtual machine, but that failed because I hadn’t enabled Virtualization Technology (VT) in my BIOS. So I rebooted, entered BIOS and enabled it. That worked fine, and I now have a virtual machine running Windows 2008 R2 64bit.

BUT, when I then wanted to fire up one of my old Microsoft Virtual PC virtual machines that I had earlier saved, I got an error saying that the saved file was corrupt. I had the choice of deleting the saved file or doing nothing. Since I needed the VPC, I chose to delete the saved file information and hope that I could recreate what was then lost.

Then, when starting up my next saved virtual machine from Microsoft Virtual PC, I got the same error. I have now played around with it, and it simply seems that if I save the state of a VPC and then turn on VT, the file gets corrupted and cannot be used :-( I even tried saving state when VT was enabled, and then I disabled it and reenabled it. Saved file was again corrupt :-(

This REALLY sucks! This means that you need to be really careful with when you save the state and when you do not…

--
eliasen

Sunday, 07 March 2010 11:03:41 (Romance Standard Time, UTC+01:00)  #    Comments [0]  | 
Tuesday, 02 March 2010

Hi all

Just to let you all know, that David GROSPELIER has written a BizTalk 2009 book in French that is about to be published.

You can find the book at Amazon and at Editions-ENI.

David has been so kind as to mention my collection of functoids from http://eebiztalkfunctoids.codeplex.com several times in the book, and since it is in French, I have not bothered to check what has been written, but trust that David knows what he is talking about :-)

So… go check it out! :-)

--
Eliasen

Tuesday, 02 March 2010 21:16:14 (Romance Standard Time, UTC+01:00)  #    Comments [0]  | 
Tuesday, 02 February 2010

Hi all

Lots of people think, that if they use a Parallel Actions shape, they get things done in parallel. Well, rethink that. An orchestration executes in just one thread, so no chance of getting anything to run in parallel. At runtime, the shapes in the parallel shape are simply serialized.

But what is the algorithm, then?

Well, I did some tests. First of all, I created this simple orchestration:

image

It’s a receive shape to fire up the orchestration and then a parallel shape with four branches and five expression shapes in each. The code in each expression shape is this:

   1: System.Diagnostics.Trace.WriteLine("X. Y");

where X is a number indicating the branch and Y is a sequence number within the branch. This means that X=2 and Y=3 is the third expression shape in the second branch and X=4 and Y=1 is the first expression shape in the fourth branch.

Running this orchestration I get this result from DebugView:

image

So as you can see, the entire first branch is executed, then the entire second branch, and so on until the fourth branch has finished. Sounds easy enough. But lets try some other scenarios like this one:

image

In essence I have thrown in a receive shape in branch 2 to see if branches three and four will still have to wait until branch 2 has finished.

The result can be seen here:

image

So as you can see, the second branch stops after the second shape because now it awaits the receive shape. Branches three and four are then executed and after I send in a message for the receive shape, the second branch completes.

So some form of parallelism is actually achieved, but only when a shape takes too long to handle. Lets see what happens with a Delay shape instead like this:

image

I have switched the Receive Shape for a Delay shape, and I have set the Delay shape to wait for 100 milliseconds. The result of this is the same as with the Receive shape:

image

Then I tried setting the Delay shape to just 1 millisecond, but this gave the same result.

With shapes that take time in two branches, like this:

image

And the Delay is still set at one millisecond. I get the following result:

image

So as you can see, the Receive shape causes branch 2 to stop executing, and the Delay shape causes branch 3 to stop executing, allowing branch 4 to execute. Branch 3 is then executed because the Delay shape has finished and finally once the message for the Receive shape has arrived, branch 2 is executed to its end.

Another thing to note is, that the Delay shape actually doesn’t make the thread sleep. If it did, we couldn’t continue in another branch once a Delay shape is run. This makes perfectly sense, since the shapes in one branch are to be seen as a mini-process within the big process, and the delay that is needed for that mini-process shouldn’t affect the other branches. This is exemplified in this process:

image 

The third expression shape in the first branch has been updated to this code:

   1: System.Diagnostics.Trace.WriteLine("1. 3");
   2: System.Threading.Thread.Sleep(2000);

 

image

So as you can see, even though the first branch must wait for 2 seconds, it still executes completely before the second branch is started.

So, takeaways:

  1. The Parallel Actions shape does NOT mean you get any multi-threading execution environment.
  2. Think of the PArallel Actions shape as a way of letting multiple Business Activities happen and you don’t know in what order they will occur.
  3. The Delay shape does not use Thread.Sleep, but instead handles things internally.

--
eliasen

Tuesday, 02 February 2010 20:27:56 (Romance Standard Time, UTC+01:00)  #    Comments [6]  | 
Wednesday, 27 January 2010

Hi all

A hot fix has been released, which is quite poorly described, but which supposedly fixes some of the issues I have described at http://blog.eliasen.dk/2009/07/21/IssuesWithBizTalk2009OnVSNET2008.aspx

The hotfix is available at http://support.microsoft.com/kb/977428/en-us

 

Good luck :-)

--
eliasen

Wednesday, 27 January 2010 08:05:16 (Romance Standard Time, UTC+01:00)  #    Comments [2]  | 
Monday, 18 January 2010

Hi all

Today I started receiving this error in the event log every time I tried to test my custom functoid in a map on the receive port.

A message received by adapter "FILE" on receive location "Receive Location3" with URI "C:\Projects\TestCumulativeFunctoid\TestCumulativeFunctoid\Instances\In\*Copy*.xml" is suspended.
Error details: The system cannot find the file specified. (Exception from HRESULT: 0x80070002)
MessageId:  {5C621C74-A873-4E68-84E0-D0621DF9471E}
InstanceID: {21D3DCEC-7C1C-4865-BB46-6D1BF6FAC7AA}

The map worked fine in Visual Studio and I was quite confused and even restarted my machine.

It turned out that I had forgotten to sign the assembly with the functoid, so the script I have to deploy a new functoid failed when adding the assembly to the GAC, which I didn’t notice, since the script runs so fast I never see the result :-)

But really.. why can’t an error like that contain the name of the file that cannot be found?

--
eliasen

Monday, 18 January 2010 00:39:50 (Romance Standard Time, UTC+01:00)  #    Comments [0]  | 
Wednesday, 13 January 2010

Hi all

I just did a post on developing a custom cumulative functoid. You can find it here: http://blog.eliasen.dk/2010/01/13/DevelopingACustomCumulativeFunctoid.aspx

At the very end of the post I write that you should NEVER develop a custom referenced cumulative functoid but instead develop a custom inline cumulative functoid. Given the title of this blog post, probably by now you know why this is :-)

When I developed my first cumulative functoid, I developed a referenced functoid, since this is what I prefer. I tested it on an input and it worked fine. Then I deployed it and threw 1023 copies of the same message through BizTalk at the same time. My test solution had two very simple schemas:

image_2 Source schema.

image_4 Destination schema.

The field “Field1” in the source schema has a maxOccurs = unbounded and the field “Field1” in the destination schema has maxOccurs = 1.

I then created a simple map between them:

image_6 

The map merely utilizes my “Cumulative Comma” functoid (Yes, I know the screen shot is of another functoid. Sorry about that… :-) ) to get all occurrences of “Field1” in the source schema concatenated into one value separated by commas that is output to the “Field1” node in the output.

My 1023 test instanced all have 10 instances of the “Field1” in the input, so all output XML should have these ten values in a comma separated list in the “Field1” element in the output schema.

Basically, what I found was, that it was quite unpredictable what the outcome of that was. Some of the output XML has a completely empty “Field1” element. Others had perhaps 42 values in their comma separated list. About 42% of the output files had the right number of fields in the comma separated list, but I don’t really trust they are the right values…

Anyway, I looked at my code, and looked again… couldn’t see anything wrong. So I thought I’d try with the cumulative functoids that ship with BizTalk. I replaced my functoid with the built-in “Cumulative Concatenate” functoid and did the same test. The output was just fine – nothing wrong. This baffled me a bit, but then I discovered that the cumulative functoids that ship with BizTalk are actually developed so they can be used as BOTH referenced functoids and inline functoids. Which one is used depends on the value of the “Script Type Precedence” property on the map. By default, inline C# has priority, so the built-in “Cumulative Concatenate” functoid wasn’t used as a referenced functoid as my own functoid was. I changed the property to have “External Assembly” as first priority and checked the generated XSLT to make sure that now it was using the functoid as a referenced functoid. It was. So I deployed and tested… and guess what?

I got the same totally unpredictable output as I did with my own functoid!

So the conclusion is simple; The cumulative functoids that ship with BizTalk are NOT thread safe, when used as referenced functoids. As a matter of fact, I claim that it is impossible to write a thread safe referenced cumulative functoid, for reasons I will now explain.

When using a referenced cumulative functoid, the generated XSLT looks something like this:

   1: <xsl:template match="/s0:InputRoot">
   2:   <ns0:OutputRoot>
   3:     <xsl:variable name="var:v1" select="ScriptNS0:InitCumulativeConcat(0)" /> 
   4:     <xsl:for-each select="/s0:InputRoot/Field1">
   5:       <xsl:variable name="var:v2" select="ScriptNS0:AddToCumulativeConcat(0,string(./text()),"1000")" /> 
   6:     </xsl:for-each>
   7:     <xsl:variable name="var:v3" select="ScriptNS0:GetCumulativeConcat(0)" /> 
   8:     <Field1>
   9:       <xsl:value-of select="$var:v3" /> 
  10:     </Field1>
  11:   </ns0:OutputRoot>
  12: </xsl:template>

As you can see, the “InitCumulativeConcat” is called once, then “AddToCumulativeConcat is called for each occurrence of “Field1” and finally “GetCumulativeConcat” is called and the value is inserted into the “Field1” node of the output.

In order to make sure the functoid can distinguish between instances of the functoid, there is an “index” parameter to all three methods, which the documentation states is unique for that instance. The issue here is, that this is only true for instances within the same map and not across all instances of the map. As you can see in the XSLT, a value of “0” is used for the index parameter. If the functoid was used twice in the same map, a value of “1” would be hardcoded in the map for the second usage of the functoid and so on.

But if the map runs 1000 times simultaneously, they will all send a value of “0” to the functoids methods. And since the functoid is not instantiated for each map, but rather the same object is used across all the maps, there will a whole lot of method calls with the value “0” for the index parameter without the functoid having a clue as to which instance of the map is calling it, basically mixing everything up good.

The reason it works for inline functoids is, of course, that there is no object to be shared across map instances – it’s all inline for each map… so here the index parameter is actually unique and things work.

And the reason I cannot find anyone on the internet having described this before me (This issue must have been there since BizTalk 2004) is probably that the default behavior of maps is to use the inline functionality if present, then probably no one has ever changed that property at the same time as having used a cumulative functoid under high load.

What is really funny is, that the only example of developing a custom cumulative functoid I have found online is at MSDN: http://msdn.microsoft.com/en-us/library/aa561338(BTS.10).aspx and the example is actually a custom referenced cumulative functoid… which doesn’t work, because it isn’t thread safe. Funny, eh?

So, to sum up:

Never ever develop a custom cumulative referenced functoid – use the inline versions instead. I will have o update the one at http://eebiztalkfunctoids.codeplex.com right away :)

Good night…

--
eliasen

Wednesday, 13 January 2010 22:34:55 (Romance Standard Time, UTC+01:00)  #    Comments [0]  | 

Theme design by Jelle Druyts