Good news :-)
I've a couple of GMail accounts to give away. Let's make this a little contest :-) Since I'm curious how deep the average XML Schema knowledge goes, I'll grant GMail access to the first two people that post a comment explaining what is wrong with the XML Schema below.
Note: XMLSpy will mark this schema as valid while it certainly is not! (Has anyone accidently noticed my aversion against this tool? :-))) )
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified" targetNamespace="myTargetNamespace" xmlns:tns="myTargetNamespace">
<xs:element name="address" type="tns:addressType"/>
<xs:element name="firstName" type="xs:string"/>
<xs:element ref="tns:address" nillable="true"/>
<xs:element name="street" type="xs:string"/>
<xs:element name="number" type="xs:string"/>
Finally submitted my entry to the BizTalk Server contest. Curious?
I created a transactional .NET adapter. This adapter allows you to submit messages to any .NET component that implements a certain interface, in a transactional manner. This means that, for example, if you access SQL Server from within your component, every operation on SQL will be in the same transaction as all message box operations. This guarantees high reliability between the message box and any transactional backend. If the transaction fails, everything will be rollbacked (including all operations on the message box) and the message transmission will be retried.
So, instead of accessing your components using an expression shape inside an orchestration, you finally might think of doing things asynchronously now! By calling .NET component asynchronously using the BizTalk Server 2004 Transactional DOTNET Adapter you can leverage the retries, backup transport, tracking and BAM features as well.
What's in the package?
- MSI installation package
- .chm documentation files
- couple of samples
- full documented source code
To show the adapter framework's inner workings, I programmed directly against the adapter framework. (Not using the SDK adapter base classes.)
Now it's up to you guys for using this: please provide me with comments, feedback. Tell me what's good and what isn't. Tell me what or how to improve... But first of all: enjoy it. It's there, it's free, it's for you!
Have fun with the pet project I've spent couple of months with:
The BizTalk Server 2004 Transactional DOTNET Adapter.
Special thanks to my girlfriend for all the patience she had!
For those of you who haven't noticed yet: Dare Obasanjo has published a refined version of the work David Orchard did about a year ago. Doing so, Dare explains best practices in designing an extensible xml schema. Writing schemas that are both forward and backward compatible is not easy, believe me. Even an experienced schema author can be tricked by some of the requirements the xml schema spec needs you to comply with.
One of the most import things to be aware of when designing xml schemas is the requirement on the xml content model to be deterministic. Some people like to refer to this as the "Unique Particle Attribution Constraint". For the normative definition of this constraint, I'd like to refer to the W3C. No one could explain this so fuzzy as they can!! MSDN does certainly a better job :-)
Even the very first xml spec itself has recommendations about this in a non normative section. For compatibility reasons with SGML. In addition section 3.2.1 in this specification says: "For compatibility, it is an error if an element in the document can match more than one occurrence of an element type in the content model."
As for the question "why"... even Tim Ewald, recently wondered why exactly xml schema had this requirement in the first place... I can only guess... but it certainly makes writing an xml parser way easier since only one single lookahead symbol is required... (While otherwise some form of backtracking is needed, which could mean an enormous perf hit!)
.NET is a good xml citizen and requires you to comply with this constraint. If you don't, you won't even be able to validate your schema. Good work guys! As close to the standards as possible!
Could someone explain to me then, why it is that "the world's leading product family of XML development tools" - laughing out loud now - doesn't even *support* detection of this constraint!!! .NET, BizTalk Server, Word and InfoPath certainly do a better job! It's not because of Xerces supporting this kind of bad schema's that they have an excuse not to implement at least a check for this critical type of content model requirements! Even worse, I came across this post in their public FAQ. They publicly state that the detection of a non-deterministic model as an error would be wrong! Pfffff... so far for the standards.
As I suppose not everyone reading my blog is reading the newsgroups on a daily basis, here's a highlight. Today, a question came up regarding the querying of the MSBTS_MessageInstance class.
Let's summarise what is possible with this WMI class:
- Retreiving all message instances that are currently available in the message box.
- Retreiving all message instances that comply with certain conditions and are currently available in the message box.
- Saving any of those messages to the file system.
What is not possible with this class?
- Saving or retreiving a message that is tracked. Tracked messages are not handled in the same way as messages that are still resided in the message box. If you want to save tracked message instances, you need to use the MSBTS_TrackedMessageInstance WMI class. Please keep in mind, when doing this, that this class does *not* support enumeration. You will need to use the MessageInstanceID in order to create an instance of it!
In addition, remember that it is not possible to use the MSBTS_MessageInstance class to make select queries based upon the content of the message context! Why? Message context is something dynamic and is not compiled into the WMI classes. The message context is accessible on the class as an XML string though... Making selects is only possible using the WMI properties on this class. Like: ServiceName, ServiceInstanceStatus, ServiceInstanceID, ServiceClassId, ServiceClass...
If you'd like to see this class in action using real life code - please check out my pet project: the BizTalk Server 2004 Tracking Playground.
A while ago, I blogged about pipeline components and what you need to pay attention to. Stephen, in reply to this, was wondering (see his comment) how tracking came into play. And... to be honest - I didn't have a clue! Only recently I managed to get the answer.
It turns out that Stephen's question actually was really valuable in helping me understand how exactly things work underneath... So, here's my - somewhat delayed - response and comments to his question.
Assume that your pipeline component screws up and that tracking before the pipeline, is enabled. What happens?
- if the message's body stream is seekable:
- if the message's body stream is *not* seekable:
In both cases, the message ends up suspended. The body might be in the suspended message if the body stream was seekable, otherwise not. (You should always have the context.)
For example: in the case of HTTP, the stream will not be seekable and the body will not be tracked nor suspended in case of a fatal pipeline component failure. (Note: the client will not get an HTTP either!)
So, the only advise I can give is: *never* screw up in your pipeline component :-)))
Tracking may tend to grow fast, depending on your how intensive your needs are. Out of the box, BizTalk Server does not offer any tools to "autoclean" the tracking database. However, there's a sample in the BizTalk Server SDK directory exactly targetting the subject.
Although it's just a sample, I've never seen this fail and it seems to me that the given SQL script is really high quality coded!! In addition, I can't imagine any really bad "worsed case scenario"...
To cleanup the tracking database:
- If you've never done this procedure before, first do this:
- Open up SQL Server SQL Query Analyzer
- Connect to the BizTalkDTADb database
- "File - Open", and go to the BizTalk Server SDK directory and look for the Database Maintenance subdirectory
- Select the "Purge_DTADB.sql" SQL script file
- Hit F5
- You should see a message "Creating stored procedure dtasp_PruneTrackingDatabase", in addition the status bar below should mark the operation as: "Query batch completed".
You have just created a new stored procedure called "dtasp_PruneTrackingDatabase". This procedure allows you to prune the tracking database. It takes only one single parameter: @PruneBeforeDate. Executing this SP causes the tracking data to be purged that was older then the given (@PruneBeforeDate) date. So, let's try this.
- To execute the procedure:
- Select: "File - New - Blank Query Window"
- Type following statements in order to cleanup *all* tracking data before today:
DECLARE @Today datetime
SET @Today = GETDATE()
EXEC dtasp_PruneTrackingDatabase @Today
Depending on how much data is to be purged, after a while the Stored Procedure will notify you with its results. Possibly you may see a message in red, commented as: "Duplicate key was ignored." This is fine and is an expected result.
To verify this:
Select: "Reporting - Find Message"
Try selecting a schema
If you've cleaned everything, you should not see any schemas anymore... (Only schemas here should correspond to messages that were tracked, áfter the @PruneBeforeDate date parameter.)
Since I felt that this is certainly not clear to everyone that uses BizTalk, some comments:
Most people are passing data to their own assemblies by passing messages, typed as an XmlDocument. This, however does not give you access to multiple parts of that message and certainly not, to the message's context.
If you ever need to have access to the context of a message, outside of the BizTalk Server orchestration environment, you may do so by passing the message as a parameter of type Microsoft.XLANGs.BaseTypes.XLANGMessage to a method in an expression shape.
When you want to create new message programmatically within an orchestration, you'd normally assign an XmlDocument object to your message. However: did you ever wonder how you could create non-XML messages within BizTalk Server orchestrations? (Assigning an XmlDocument would clearly not work here :-) )
For all of you "bitheads", here it is :
Option Explicit On
Option Strict On
Public Class MyStreamFactory
Private m_mystringdata As String = ""
Public Sub New(ByVal stringdata As String)
m_mystringdata = stringdata
Public Overridable Function CreateStream() As System.IO.Stream _
return New IO.MemoryStream( _
Public Class MyMessageCreator
Public Sub CreateMyMessage(ByVal mydestmsg As XLANGMessage)
mydestmsg(0).LoadFrom(New MyStreamFactory("this is my data to create message from"))
The trick here is in the IStreamFactory. BizTalk Server is able to create messages from such a factory class. In this example, I've just created a 'binary' message from a string, using ASCII encoding. However: you could just as well assign something like a .PDF file or image to your message if you want.
No limits! BizTalk Server rocks!
So, here it is: my very first posting as a BizTalk Server MVP :-)
TechEd was great... I don't mean "just great", but rather "REALLY REALLY GREAT"! Microsoft certainly knows how to organise things.... ("Things" include parties :-) ) Now, as I'm only just back from Amsterdam, I'll point you in some directions you might like, if you like BizTalk Server. (Like you dó! I just know for sure :-) )
First of all: the BizTalk Server team has started a new blog.
Further, I'd like to welcome Kevin Smith to the blogosphere as well. This guy surely knows what BizTalk is about as he was a dev on the BizTalk 2000, 2002 and 2004 release! Even better: he immediately released a GREAT paper on BizTalk Server 2004 adapter development!
Later this month, I'll publish a paper on pipeline components. If you plan to dive into this, make sure to check out Gilles post as well.
Further, Scott has announced that the integration PAG is now online.
Love to see such movements in this community!!!
So... What about you? Feel like sharing?
Have a nice day!
Due to TechEd 2004, there will be some radio silence next week on both this blog and the contributions to the BizTalk Server 2004 public newsgroups. So, see you all there!!
Since there has been quite some activity on several postings lately, I'll be addressing each of those comments after next week! In the mean time: have fun - let's meet in Amsterdam!