Thursday, May 7, 2009

Hi all

Today I encountered something I have never seen before, when creating a map.

The issue occurs because my customer had a schema that imports two other schemas, both of which have an element called “metadata” – but naturally the two schemas have different target namespaces.

The main schema imports both, and has two records just below the root, and these two records reference each of the two metadata elements in the two imported schemas.

So the first schema could look like this:

MetadataOne

And the second schema could look like this:

MetadataTwo

So both have an element named “metadata” but one is in the namespace “http://TwoElementsDifferentNamespace.MetadataOne” and the other is in the namespace “http://TwoElementsDifferentNamespace.MetadataTwo”.

After that, I create the schema that impors both:

BigSchema

As you can see it imports the first two schemas, and has to elements that reference each of the metadata elements form the two first schemas.

Also, I crated an output schema that just has three elements and then I created this map:

map

Pretty simple. Now, the issue comes when compiling, because I get this error:

Exception Caught: The map contains a reference to a schema node that is not valid.  Perhaps the schema has changed.  Try reloading the map in the BizTalk Mapper.  The XSD XPath of the node is: /*[local-name()='<Schema>']/*[local-name()='Root']/*[local-name()='metadata']/*[local-name()='Field2']

o the first try was to reload the schema – but that didn’t help – it just broke one of my links.

In he end I found out, that the issue is that the links are stored like this in the .BTM file:

<Link LinkID="1" LinkFrom="/*[local-name()='&lt;Schema&gt;']/*[local-name()='Root']/*[local-name()='metadata']/*[local-name()='Field1']" LinkTo="/*[local-name()='&lt;Schema&gt;']/*[local-name()='OutputRoot']/*[local-name()='Field1']" Label="" />

<Link LinkID="2" LinkFrom="/*[local-name()='&lt;Schema&gt;']/*[local-name()='Root']/*[local-name()='SomeFields']/*[local-name()='Field3']" LinkTo="/*[local-name()='&lt;Schema&gt;']/*[local-name()='OutputRoot']/*[local-name()='Field2']" Label="" />

<Link LinkID="3" LinkFrom="/*[local-name()='&lt;Schema&gt;']/*[local-name()='Root']/*[local-name()='metadata']/*[local-name()='Field2']" LinkTo="/*[local-name()='&lt;Schema&gt;']/*[local-name()='OutputRoot']/*[local-name()='Field3']" Label="" />

So. basically, the .BTM file saves links as XPath expressions WITHOUT the namespaces. So naturally, this has to go wrong, when there are two “metadata” elements on the same level in the schema.

The way to solve this is to choose the properties of the map and disable the “Ignore Namespaces for Links” like this:

property

After setting this property, the links change having namespaces inside the .BTM file and everything is just fine.

One might wonder why the namespaces are not enabled as the default, since they do make the solution more robust. Well, the reason is simple; If the namespaces are in all the links, and you change for instance the namespace of the root node, then ALL links in the map gets broken. So actually, not having the namespaces in the links make the solution more robust.

So… I hope this can help someone.

You can download the solution here:

--
eliasen

Thursday, May 7, 2009 12:36:16 AM (Romance Daylight Time, UTC+02:00)  #    Comments [0]  | 
Saturday, April 25, 2009

Hi all

Just as i have started developing a functoid library (found at http://eebiztalkfunctoids.codeplex.com/) I have also started developing a pipeline component library. Right now it contains three components:

  • DevNull. This pipeline component is quite simple. It will "swallow" everything that comes as input. This enables performance testing of stuff without concerns about adapter transport time at send port for instance.
  • SearchAndReplace. This component will perform a search and replace on the incoming stream, replacing some string with some other string. Optionally, you can decide to let the input string be a regular expression and replace based on that instead of normal string search and replace.
  • Promote. This component has three parameters, the name of a property, the namespace of the property and an XPath expression. The component will read in the value that corresponds to the XPath expression at runtime and promote it to the property given by the name and name space. This enables you to promote reoccurring elements.

You can find it at http://eebiztalkpipelinecom.codeplex.com/ – the url is weird, I know. But there is a limit to the length of the urls at codeplex, unfortunately.

--
eliasen

Saturday, April 25, 2009 11:08:40 PM (Romance Daylight Time, UTC+02:00)  #    Comments [0]  | 

Hi all

So, first I had a post about promoting reoccurring elements where I discussed 4 options for promoting an element that can occur multiple times in the input. Then I had a post about how you can pseudo do it in BizTalk 2000/2002.

This post is about two things:

  1. Another way of doing it that doesn’t work
  2. Writing the custom pipeline component that was my second suggestion in my first post.

First issue

As discussed in my first post, if you change the XPath of the promoted property in the schema (either by clicking the ellipsis as I wrote about or manually editing the XSD) to add the “[1]”, you get this compilation error:

Node "ElementWhereNumber1IsPromoted" - The promoted property field or one of its parents has Max Occurs greater than 1. Only nodes that are guaranteed to be unique can be promoted as property fields.

But, since I couldn’t get the “[1]” to work in BizTalk 2000/2002 when editing my second post I used the position function instead. So i started wondering if that might work in BizTalk 2006 R2. It doesn’t, though. It compiles just fine, and I really had my hopes up, but at runtime you get this error:

There was a failure executing the receive pipeline: "Microsoft.BizTalk.DefaultPipelines.XMLReceive, Microsoft.BizTalk.DefaultPipelines, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Source: "XML disassembler" Receive Port: "ReceivePort3" URI: "C:\Projects\Blog Entries\PrommotingReoccurringElementsEditXSD\Instances\In\*.xml" Reason: Unexpected XPath format:

So i had to drop that idea again.

Second issue

I decided to write the custom pipeline component that I discussed in my first post.

The main code is easy – just three properties:

  1. Name of the property
  2. Namespace of the property
  3. XPath

You can download it at http://eebiztalkpipelinecom.codeplex.com/ where I have just made my initial release.

--
eliasen

Saturday, April 25, 2009 11:02:07 PM (Romance Daylight Time, UTC+02:00)  #    Comments [0]  | 
Thursday, April 16, 2009

Hi all

I have had posts about the context accessor functoid here and here.

Just a couple of notes about the context accessor functoids (plural - because there are two functoids at codeplex):

  • One of the functoids will only work when called from a map that is executed inside an orchestration.
  • The other functoid will only work when called from a map in a receive port AND only if the pipeline component that ships with the functoid has been used in the receive pipeline.

As you can see, creating a map based on either of these functoids makes your map impossible to use in either an orchestration or a receive port based on which functoid you chose. So you are creating a pretty hard coupling between your map and where it should be used. This can be ok, but if other developers mess around with your solution in a year or so, they wont know that and things can start breaking up.

My self: I am a user of the functoids - I would use them instead of assigning values inside an orchestration using a message assignment shape.. but this discussion is pretty much academic and about religion :-)

Anyway, beware the limitations!

--
eliasen

Thursday, April 16, 2009 12:17:30 AM (Romance Daylight Time, UTC+02:00)  #    Comments [0]  | 

Hi all

I had a post about one of the context accessor functoids which can be seen here: http://blog.eliasen.dk/2009/04/01/TheContextAccessorFunctoidPartI.aspx

This post is about the other one – the one that can only be used in a map that is used in a receive port.

Basically, the functoid takes in three inputs:

GetReceivedFilename

The first is the name of the property and the second parameter is the namespace of the property schema this property belongs to. The third parameter is an optional string that is returned in case the promoted property could not be read.

This functoid only works in a map that is called in a receive port and only if the receive location uses a pipeline that uses the ContextAccessorProvider pipeline component that is included in he same DLL as the functoids.

What the pipeline component does is, that it takes the context of the incoming message and saves it in a public static member. This way, the functoid can access this static member of the pipeline component and read the promoted properties this way.

Good luck using it.

--
eliasen

Thursday, April 16, 2009 12:11:22 AM (Romance Daylight Time, UTC+02:00)  #    Comments [2]  | 
Tuesday, April 14, 2009

Hi all

I had a post about promoting reoccurring elements in BizTalk. As we all know, this isn’t possible…. BUT… actually… well… :-)

Basically, you promote properties for three reasons:

  1. You need it to route based on the value
  2. You need it for correlation (which is basically just a specialization of routing)
  3. You need to either read or set the value inside an orchestration (Don’t do that! Use distinguished fields instead)

So, dealing with number 1, routing, I started thinking back at BizTalk 2002, which was my first BizTalk experience (I’l bet ALL BizTalk developers/architects think of BizTalk 2000/2002 every now and then… no? :-) ). I seemed to recall that you could do something fancy with routing back then, so I fired up an old BizTalk 2002 on windows 2000 Professional to test it. It turns out, that on a channel you can enter a filter which is an XPath expression. The text field is editable, so you can change the XPath expression all you want – it will complain if you try to leave it with an invalid XPath expression (syntactically – not semantically).

Given this XML:

<MyRoot>
  <myReoccuringRecord Myfield="42" /> 
  <myReoccuringRecord Myfield="2" />
  <MySecondRecord MySecondField="jan" /> 
  <MyThirdRecord>
    <MyThirdField>1</MyThirdField> 
  </MyThirdRecord>
</MyRoot>

I can have a channel with this filter:

  • /*[local-name()='MyRoot' and namespace-uri()='']/*[local-name()='myReoccuringRecord' and namespace-uri()=''][position()=1 and @Myfield = 42]

Basically, documents will only go through this channel, if the value of the “Myfield” attribute of the first “myReoccuringRecord” element has the value 42.

So, it isn’t promoting as such – BizTalk 2002 doesn’t have this concept, but it allows us to route based on the value of a specific occurrence  of a reoccurring element.

On a side note; If you leave the filter like this:

  • /*[local-name()='MyRoot' and namespace-uri()='']/*[local-name()='myReoccuringRecord' and namespace-uri()=''][@Myfield = 42]

it will accept the incoming document no matter what the position of the “myReoccuringReord” is. Can’t make up my mind if this is a good thing or not :-)

Now, as we all know (?), manually editing the XSD in BizTalk 2006 solution to make sure the XPath evaluation will only return a single XmlNode doesn’t work. You either get a compile time error:

  • The promoted property field or one of its parents has Max Occurs greater than 1. Only nodes that are guaranteed to be unique can be promoted as property fields.

or you get a runtime error:

  • There was a failure executing the receive pipeline: "Microsoft.BizTalk.DefaultPipelines.XMLReceive, Microsoft.BizTalk.DefaultPipelines, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Source: "XML disassembler" Receive Port: "ReceivePort3" URI: "C:\Projects\Blog Entries\PrommotingReoccurringElementsEditXSD\Instances\In\*.xml" Reason: Unexpected XPath format:

Anyway… not that many BizTalk 2000/2002 installations till in production, I assume, so this post is merely for informational purposes. It’s just funny discovering functionality that is doable in earlier versions of BizTalk and not in the latest versions.

--
eliasen

Tuesday, April 14, 2009 1:22:23 AM (Romance Daylight Time, UTC+02:00)  #    Comments [0]  | 
Monday, April 13, 2009

Hi all

Well, the time has once again come for a “If I had all the money in the world to pay to the BizTalk development team and I could decide what to put into the next version of BizTalk, this would be it”-list :-) There are a couple of items that I have stolen from http://blog.eliasen.dk/2007/10/06/BizTalkVNextWishlist.aspx.

  1. Orchestration debugging should be easier. I really hate that I have to deploy my orchestration, throw a message through it just to get an instance in HAT that I an set breakpoints on and then have to throw another message trough the orchestration to debug it.
  2. No more pipelines. Why no let the developer have an inline pipeline designer in a receive location and a send port? this way I don’t have to build custom pipelines – I can just chose pipeline components right on the receive locations and send ports.
  3. For development purposes, it would be really nice to be able to right click a receive location that is disabled and choose "Execute". If for instance I have a SQL adapter receive location that is supposed to poll every minute, then I don't want to have to quickly disable the receive location once it has been fired. I want to keep it disabled, so data wont go through my system when I am not ready, and then just execute it whenever I am ready.
  4. Restart Host Instances only once. Right now, if I deploy my solution from VS.NET, and this solution has 10 projects that are all set to "Restart Host Instances" on deployment, then the host instances will get restarted 10 times. Would be nice if VS.NET could figure this out and only do it once.
  5. Specify the node that is body, when using enveloping and not just the parent. It makes great sense, that I can specify a node and all child elements are then submitted as separate messages from the receive pipeline. This is how we can receive orders, invoices, etc. in the same XML. BUT, if I receive XML where I only need the Orders, then I would like to point at the Orders element so that is all I get. Right now I have to use standard enveloping, and implement logic to just delete the invoices, etc. Not really nice, I think.
  6. Better modeling tools for business processes. The last Gartners quadrant I saw on BMPS didn’t have Microsoft mentioned at all. Would be great with some formal cooperation with IDScheers Aris product or the like. Something like simulating your business process with different values in rules would be just great
  7. Promoting via XPath. Please let me specify the XPath for some element that I want promoted in the disassembler components. If I know of an XPath that guarantees that only one value is in the result set og evaluating that XPath, then let me use it instead of forcing me to not promote anything that can occur multiple times. I am aware that with the current limitation, BizTalk is helping developers to not make mistakes, but hy not give us the opportunity and then suspend the message if the developer was wrong and multiple elements are in the resulting node list after evaluating the XPath expression?
  8. It would be nice if we could expose a web service without having to require a parameter. If I want to expose an orchestration that builds an inventory XML hat customers can request, I really don’t need a parameter to do that. Some workaround would be nice.

--
eliasen

Monday, April 13, 2009 10:58:03 PM (Romance Daylight Time, UTC+02:00)  #    Comments [0]  | 
Tuesday, April 7, 2009

Hi all

Some may have noticed it – others will know it now :-)

BizTalk 2009 is available for download from MSDN.

the official BizTalk site doesn’t reflect the new version yet, though, so please have patience if you need the trial version or the likes.

--
eliasen

Tuesday, April 7, 2009 10:50:44 PM (Romance Daylight Time, UTC+02:00)  #    Comments [0]  | 
Thursday, April 2, 2009

Hi all

At http://social.msdn.microsoft.com/Forums/en-US/biztalkgeneral/thread/ecaa2059-d78e-449f-8eb0-37696847b4b0 there is a guy who is struggling to get the MessageID into a message inside a map.

I have been trying to help him and have come to a stand still, because I missed a very important point. The MessageID is “written” and not promoted to the context base. Therefore, it cannot be read using the functoid found at http://www.codeplex.com/ContextAccessor (The one used inside an orchestration).

So basically, you can use the functoid to get hold of all the properties that were promoted into the context, but the ones that were written, you need to get to some other way.

I have created a small sample that illustrates how to do this inside an orchestration.

It can be downloaded here.

Basically, I have a schema for the input:

Inputschema

It has two fields, and I have promoted the first field.

The output schema looks like this:

OutputSchema

It has four fields.

What I want in the output is this:

  • Field1: The value from Field1 in the source schema. It isn’t to be mapped directly, though. I want to demonstrate that the functoid can be used to get values that were promoted from a schema.
  • Field2: The value from Field2 in the source schema. Mapped directly
  • MessageID: The Message ID of he input message. Since this isn’t accessible by the functoid, I will use a Message Assignment shape to do that
  • ReceivedFileName: Will contain the content of the BTS.ReceivedFileName poperty – by using the functoid.

The map looks like this:

Map

I am using the ContextAccessor (for orchestations) to fill a value into Field1 and ReceivedFileName. I am mapping Field2 directly. The MessageID field I am not mapping, since I need a message assignment shape for that. The element “MessageID” must be present in the output, though. Otherwise i cannot fill in value. So, as you can see in the screenshot, I have set the “Value” property to “<empty>”. This will create an empty element. This feature is very handy for initializing elements that will later on get values from message assignment shapes but also for creating the needed empty fields for demotion.

Anyway, the parameters for the first functoid look like this:

FirstFunctoid

The parameters are:

  1. The name of the message to get the value from.
  2. The name of the property
  3. The name space of the property schema that property exists in.

The second functoid looks like this:

SecondFunctoid

Now, the final touch is the orchestration:

Orchestration

Quite simple… A receive, a construct and a send port for the output. The construct shape has two shapes inside it. The first is a transformation shape hat will execute the map. The second is a message assignment shape hat will insert the messageid into the destination schema.

The message assignment shape looks like this:

MesageAssignment

I made the MessageID field of he output a distinguished field and can therefore insert values into it. This is quite clever . the way you can do several things to a message as long as you are still inside the same Construct Message shape. After the map, where I let the MessageID field be empty, I can insert a value into this field using a distinguished field. I could also just as easily have used XPath to do that, but that is not as readable, so I didn’t do it.

So… This was the first post of two – next time I will look at the receive port version of the Context Accessor functoid.

And one last point: If the idea i just to get an Id into a message and it doesn’t have to be the message ID of a message, you can also just use the “New GUID” functoid found at http://eebiztalkfunctoids.codeplex.com/

--
eliasen

Thursday, April 2, 2009 12:54:15 AM (Romance Daylight Time, UTC+02:00)  #    Comments [0]  | 
Tuesday, March 31, 2009

Hi all

Alister Whitford has a question today on the online forums about preserving white space in a map. He thought that the functionality has changed between BizTalk 2006 and BizTalk 2006 R2. He has done a great job looking into stuff and it appears he is right. You can check out he thread here: http://social.msdn.microsoft.com/Forums/en-US/biztalkgeneral/thread/7dd28a9b-16b5-4c0e-90db-843caf4689ee where he also shows how not to preserve white space in R2 and thus have the same functionality as in 2006 (non-R2).

Hope this helps someone

--
eliasen

Tuesday, March 31, 2009 11:05:41 PM (Romance Daylight Time, UTC+02:00)  #    Comments [0]  | 

Theme design by Jelle Druyts