Martijn's blog - E-Commerce, EAI, BizTalk and .NET

2004/08/23

Writing a pipeline component in J#

Ever wondered if besides C# and VB.NET, J# could be used to create pipeline components for use in BizTalk Server 2004? It can.

I've created a simple pipeline component in J#.

However, due to the nature of J#, many interfaces cannot be implemented in this language. This has to do with J#'s inability to deal with out parameters. As IPersistPropertyBag has an interface containing:
IPersistPropertyBag.GetClassID(out System.Guid classid)
, it cannot be implemented and design-time properties have no use.

Due to this and other rather big differences between C# and VB.NET on one hand and J# on the other, I won't be implementing support for J# in my Pipeline Component Wizard.

The example can be downloaded here

2004/08/21

Update: Pipeline Component Wizard v 1.3

Sorry for the delay in posting, I've been on holiday...

Another update to the Pipeline Component Wizard, this time, the following functionality has been added/changed:

1) support for code generation in both C# and VB.NET!
2) bug fixed with the defined component version not being used
3) the designer properties is now a dropdown list, no more editing
4) the designer properties have been expanded with two new members:
4a) SchemaList, which allows multiple (referenced) schemas to be associated with your component (like the XmlDisassemblerComponent has)
4b) SchemaWithNone, a dropdown listbox which allows you to associate a single referenced schema with your component (like the FlatFileDisassembler component has)

There have been reports of a missing component with the installer in previous versions of the Wizard, resulting in incorrect functioning of the wizard. This was due to me accidentaly excluding the Microsoft.BizTalk.Wizard, which is needed by the Pipeline Component Wizard. Subsequently, the CustomAction failed to register the DLL. This should be fixed now.

Support for other .net languages could easily be added if needed, as the CodeDOM has code has been updated to be language independent.

I hope you enjoy this release, please let me know of any issues, my e-mail address can be found here

The sourcecode for the updated pipeline component wizard can be downloaded at GotDotNet

Thanks to Jim Bowyer for creating a VB pipeline component for all to have a look at!

2004/08/14

Retrieving the matching schema for an inbound message

Ever wanted to know which schema matches your inbound message from within a pipeline component? Here's how:

Reference Microsoft.BizTalk.Streaming,

Use the following code within your pipeline component:

Stream orgStream =
   inmsg.BodyPart.GetOriginalDataStream();

MarkableForwardOnlyEventingReadStream helperStream =
   new MarkableForwardOnlyEventingReadStream(orgStream);

IDocumentSpec docSpec = null;

try {
  docSpec =
     pc.GetDocumentSpecByType(
         Utils.GetDocType(helperStream));
}
catch(Exception e)
{
  Trace.WriteLine(e.ToString());
}

if(docSpec != null)
{
  XmlSchemaCollection schemaCollection =
     docSpec.GetSchemaCollection();
  
    // use the schema collection
}
else
{
  Trace.WriteLine(
     "No schemas found matching our inbound message");
}

Now you have the schema collection which matches your document (this code is minimal, real exception handling should be added ofcourse.

Notes:

Utils.GetDocType does nothing more then read the stream using a XmlTextReader and combine any found namespace with the root element name. If you have DOCTYPE declarations, you could implement this yourself to avoid having to put your DTDs in %windir%\system32.

The MarkableForwardOnlyEventingReadStream class helps in easily resetting the position back to where the stream was once the Utils.GetDocType is done.

Hope you find this useful!

Update: undeployassembly

I've updated my undeployassembly command line utility for a few reasons:

added support for /a switch, removing all assemblies from BizTalk, other than "Microsoft" namespace assemblies (be careful!)

added the ability to shoot down any existing message instances within the BizTalk queue by assembly name (killServiceInstancesByAssemblyName), otherwise assemblies would not be removed because they were in use.

cleaned up the source somewhat

What I can't figure out is how to make sure no referenced assemblies are being used, i.e. how to set up the uninstall order. the DeploymentDriver being used doesn't seem to allow me using it's methods for that. If anyone has any suggestions for this issue, please let me know!

UPDATED: The file can be found here

2004/08/13

XmlDTDValidator pipeline component

Ever tried using DOCTYPE declarations in your inbound messages? The XML Disassembler does not validate against DTDs, only schemas. If you have DOCTYPE declarations in your inbound message, BizTalk uses the standard XmlResolver for reading in the message and will log about four error messages into the EventViewer, of which one will state:

There was a failure executing the receive pipeline: "Microsoft.BizTalk.DefaultPipelines.XMLReceive" Source: "mscorlib" Receive Location: "c:\test\input\*.xml" Reason: Could not find file "C:\WINDOWS\system32\MyDTD.DTD".

I can imagine situations in which you can't alter the messages coming in on forehand and need the message to be both validated and processed by BizTalk, without having to store your DTD files in C:\WINDOWS\system32.

I've written a pipeline component which both validates the inbound message against it's DOCTYPE, having a design-time property in which you specify where your DTD files reside, and removes the DOCTYPE declaration in order for BizTalk to process the message. (by the way, the framework was built using my Pipeline Component Wizard)

Ofcourse, a design-time property setting the folder in which your DTDs reside, might not be the best option, it's for example use only. In a production environment, you want this value to come from the App.Config file or another place you can alter real-time without having the redeploy your pipeline.

I hope you have fun with this component and would love to hear any comments, flames, what not (see this page for my e-mail address)

2004/08/07

Pipeline components: checking to see if you're interested in processing a message

If you ever needed to see whether your component has to process a given message, try implementing the IProbeMessage interface. It gives you the message, you can analyze it and return a boolean value to indicate whether you're interested in processing the message. If you return false, the next component in the current stage will be executed in the normal manner. If you return true, your component will be executed by the messaging engine.

Example:

public bool Probe(IPipelineContext pc, IBaseMessage inMsg)
{
  // TODO: implement decision logic for the
  // message here
  return true;
}

Please note that the stage you will use the component in must be configured as FirstMatch, which in this version is only the Disassemble stage (see the documentation, the BizTalk 2004 documentation mus be installed for this to work and you have to copy the link and paste it in another window because of security constraints)

Update (2004/08/08): this interface has now been incorporated in my pipeline component wizard (just choose DisassemblingSerializer for the component stage), the pipeline component wizard can be retrieved here or here

Update: Pipeline Component Wizard

The Pipeline Component Wizard has been expanded and some minor bugs were fixed. It's uploaded to gotdotnet and you can also download it here from my personal webspace.

Major issues: this new version implements the IAssemblerComponent and IDisassemblerComponent interfaces (AssemblingSerializer and DisassemblingParser) as well as the IProbeMessage interface to see if you want to process the message (see this page for more information)

I've removed the older version links from the previous article about the Wizard to ensure everyone gets the latest version.

Hope you enjoy this update! Let me know of any issues, my e-mail address can be found here

2004/08/06

Decompression pipeline component (zip files)

Ever wanted to unzip a file and use it's content in BizTalk Server? I've implemented an unzip component (disassembler stage) which uncompresses the files within the zip file and allows you to process them like you would normal messages. The sourcecode can be found here. I hope you enjoy this sample. Please let me know of any trouble with using it or any suggestions you might have!