Yossi Dahan [BizTalk]

Google
 

Monday, March 16, 2009

Ok, got your message, now let us have xsl re-use!

From the Microsoft Knowledgebase  -

The <xsl:import> element is used to import an external XSLT file. The <xsl:include> element is used to include an external XSLT file. You cannot use these elements in custom XSLT files that are defined in the Custom XSL Path Grid Properties in a BizTalk project. You cannot do this because a Uniform Resource Identifier (URI) that is defined in an external XSLT file may be from a nonsecure source such as the Internet.

Am I (well, and Ben Gimblett here)  the only one who thinks this is a lame excuse? since when MS tries to protect developers from stupidity? and in any case, if they really wanted to do that – wouldn’t they have to prevent us from writing ANY code?

Labels: , ,

Monday, December 29, 2008

Wish list: optional parameters when using call/start orchestration

I wasn’t sure how bit problem this was, and in any case thought that optional parameters are a VB thing, but I’ve been proven wrong, and not only because optional parameters are soon to become a c# thing :-)

When using call/start orchestration we increasingly, as our solution “matures”, find that we need to add optional parameters to our processes..

In c# I was trained that function overloading is the correct way to implement this, and although I can see the benefit of the slim optional parameters approach I do think that it is much clearer; we’re talking BizTalk though, and you can’t really overload a function, can you? :-)

So we [can] do several things -

When dealing with .net types we can simply break the interface, add the parameter, change all the calling processes to supply one, and – if they don’t actually need to supply a value for this new parameter make them pass one anyway (an empty string, or a 0, or even –1); not elegant to say the least, and quite time consuming which means upsetting both the architect and the project manager.

Same approach works quite well when dealing with optional messages as well, only that now constructing that unnecessary extra parameter, in the same of a content-less message, is even harder (see my post on creating messages from scratch).

Another option, valid for .net types only, is to have a <something>Parameters class which would include all the parameters a process takes as properties; this would allow you to add as many properties as you need, without forcing callers to specify them; there are downsides of course – it is less readable and intuitive in my view, there’s a bit more hassle for the caller (create instance of parameters class, assign members) and now it’s harder to force those non-optional parameters (can be done via the parameter class’ constructor)

But there’s not equivalent option for optional message parameters.

Last, but not least, there’s the closest thing to overloading – you could always create a second process, with the extended set of parameters and have the original process forward the original call while providing this empty parameter, effectively saving the hassle from the original caller.

This is really how a function overloading solution would look like only that a process is not a function; it has a lot more impact in term of compile time, configuration required, deployment so the overall maintenance cost of such an approach is quite enormous for any decent sized project.

So – I can no longer ignore this problem and have to agree – allowing optional parameters with default values, for orchestration is quite important.

 

2011? :-)

Labels: ,

Sunday, October 05, 2008

Wish list: Transforming unknown message

The other day I ended up developing a process that would take one of two message types (using XmlDocument as the underlying message type), something I don't usually advocate, but I agree of course that occasionally it is the right way to go.

Naturally the first thing I wanted to do is to convert the message from either format to a single message type.

I normally write my own xsl (as opposed to using the mapper) and so I knew that the template-based xsl scripts are geared towards this type of work through the use of apply templates matching logic;

In theory I should be able to create a map that takes a message of type XmlDocument and spit out a single format; the xsl script under the covers would use apply templates to match the possible root nodes and execute the correct template to map to the target format correctly.

This is only theoretical though as the compiler does not let you build a project with a btm file that has System.Xml.XmlDocument as the input type; a schema (type) must be selected.

Further more - the orchestration designer does not let you select a message as an input or output of it is not strongly typed (although that's just a designer issue, if you edit the ODX directly the compiler is happy enough, not that I suggest anyone do that)

This leaves the following alternatives -

You could write your own code to run xsl scripts, and call that from your process passing in the XmlDocument.

You could, of course, have multiple maps - each with a different input message type- all using the same xsl underneath the hood.

You could decide to hack a little bit and create your btm with any schema as the input type (selecting one of the alternatives for the input might be a good idea, or a specially created schema to indicate the scenario at hand); you could then use the transform function in an expression shape to run that map passing in the XmlDocument message as the input message;
You could do that because the transform function does not actually validate the input (or the output) against the schema at runtime, only the out-of-the-box transform shape does that, so as long as you avoid it you're ok.
Of course it has the implication of having a btm file that does not correctly represent the reality (in terms of input message), but I guess for some its easier to live with that than for others...

Labels: , , ,

Monday, August 11, 2008

Zombies

A lot has been written about Zombies in BizTalk, but somehow they never really caused me too much problem. until today.

In one of our processes we are calling a web service to perform a certain lookup.

That web service’s implementation (whether correct or not) is to return the instance of the class if found or null otherwise.

When the service returns a null BizTalk receives an empty message, which triggers an exception in the process -

Microsoft.XLANGs.Core.MissingPartException: The XLANG/s message has no part at index '0'. The total number of parts found in the message is '0'. If you expect a multipart message, check that the pipeline supports multipart messages such as MIME.

I’m quite all right with that, BizTalk is definitely correct – we have returned an empty stream as a message which means nothing.

And so - we've added an exception handler around the call to the service and our orchestration’s flow carries on correctly all the way to the end shape. as expected.

However, contrary to the expected at this point the orchestration instance gets suspended by BizTalk with the error - “The instance completed without consuming all of its messages. The instance and its unconsumed messages have been suspended.”

I believe this behaviour has been introduced in BizTalk 2006 - 2004 was quite “happy” to have the so called "zombies" in the process, and it was up to the developer to handle those (or not, as the case often was); since 2006 this had become an error and if a process ends with unconsumed messages the process gets suspended and the unconsumed messages are available for inspection.

Generally, I think that making a zombie an explicit error is a good idea, although it would have been nice to be able to set whether this behaviour is required on a per-process basis, however - in our case we found this very problematic - we were in a position where we couldn't consume the message properly (due to the exception handler) but although we have handled the exception we ended up with a suspended in stance as it appeared as a zombie. we could not win.

I have opened a support call on this one, waiting to hear if the product group agrees that this is incorrect behaviour or not (I seem to be getting conflicting thoughts). I'll try to keep this post updated when I get an answer.

Update: I've been exchanging quite a few emails with the product group on this one, but have not (yet) managed to convince them that this cannot possibly be the expected behaviour - I should be able to handle the exception and carry on without having a suspended instance; they think otherwise.

(You can read more details about this here - http://technet.microsoft.com/en-us/library/bb203853.aspx and http://blogs.msdn.com/biztalk_core_engine/archive/2004/06/30/169430.aspx

An interesting point is that this case is not listed in the list of causes for zombies in these articles, which makes me wonder – should an exception raised through a receive shape, which was properly handled by an exception handling result in a zombie?)

Labels: , , , ,

Monday, February 25, 2008

Wish list: "End" shape.

Often orchestrations have conditions that, when met, mean the orchestration should stop executing.

In .net code a developer could simply put a “return” keyword in the function to stop the execution and return to the caller; unfortunately there is no equivalent in orchestration development.

The only “clean” way to end an orchestration currently is to reach the built-in, fixed, red shape at the bottom of the orchestration designer.
This often means that decision shapes exist all over the orchestration with branches that have to drop all the way to the bottom. In large orchestrations this can be hard to follow up on.

It could have been made much nicer by allowing a developer to add as many “end” (or “return”) shapes as needed in various places in the process. Decisions, of course, will still exist, but their scope will be much smaller.

An alternative that exists currently is to use the terminate shape, but I find it to be a bit artificial – my view is that termination of processes may be relevant in exceptional scenarios, as part of error handling, etc. but not when the orchestration ends correctly (albeit before reaching the end of the schedule). The main problem with the terminate shape possibly is that the orchestration gets a “terminated” state and not “completed” which will make it difficult to report in HAT (and otherwise)

Labels: , ,