CreateXmlInstance() with Multi-Root Schemas

Link. July 16, 2008. Comments [1]. Posted in: BizTalk

The DocumentSpec class in the Microsoft.BizTalk.Component.Interop namespace of the Microsoft.BizTalk.Pipelines assembly is commonly used in custom pipeline components (particularly assemblers in disassemblers) to represent a compiled BizTalk schema (a document specification).

This class has one interesting method: CreateXmlInstance(), which can generate an sample instance XML based on the associated schema [1]. Recently I saw a question in the BizTalkGurus forum about how to use this functionality if you had a schema definition with multiple potential root elements.

Turns out its pretty easy, once you understand how DocumentSpec works and how Schemas are compiled into BizTalk assemblies.

The constructor for the DocumentSpec class takes two arguments: The docSpecName (schema name) and the name of the assembly it is defined in.

The clue to support multi-root schemas is that the docSpecName is, in reality, the namespace + type name of the class generated by the compiler when you compile the Schema into the BizTalk assembly. Each schema becomes one class in the generated code.

If the schema has a single root, that's the end of it; All you need to know is that docSpecName == Namespace.ClassName. If the schema has multiple roots, however, each root becomes a nested class within the schema class.

The way to select which root element to use for the sample instance generation, then, is to provide the type name of the root element nested class as to the DocumentSpec constructor instead of the name of the schema class. In other words, in this case docSpecName == Namespace.SchemaClass+RootClass.

[1] One annoyance of this method is that it takes a TextWriter argument but doesn't actually write the generated XML into it; instead it returns a Stream you need to read!

PipelineTesting code now on GitHub

Link. July 13, 2008. Comments [0]. Posted in: BizTalk

I just pushed all the source code for my BizTalk 2006 PipelineTesting library to GitHub. I'll keep this public repository updated whenever I make any changes to the library, so if you're interested in keeping track of the code or forking it, this should make it a lot easier.

You can find the clone URL for the new repository is: git://github.com/tomasr/pipelinetesting.git

Enjoy!

Controlling BizTalk Orchestrations with PowerShell

Link. June 26, 2008. Comments [1]. Posted in: BizTalk | PowerShell

Here's a sample PowerShell script/functions to start/stop BizTalk orchestrations. This is an extended version of the Stop-Orchestration VBScript included in the BizTalk 2006 SDK, which I hope someone finds useful :-).

The script can be used to start or stop either a specific orchestration or a group of orchestrations defined in a BizTalk assembly. For example, to stop and unenlist all orchestrations in a given assembly, you could use this:

stop-orch -assembly 'MyProject.BizTalk, Version=1.0.0.0, Culture=neutral, PublicKeyToken=50b7b2906e3f8aa5' -unenlist

Here's the code for the script:

$script:bound = 2
$script:started = 4
$script:controlRecvLoc = 2
$script:controlInst = 2

function script:get-assemblyfilter([string]$assembly) {
   # The BizTalk WMI provider uses separate properties for each
   # part of the assembly name, so break it up to make it easier to handle
   $parts = $assembly.Split((',', '='))
   $filter = "AssemblyName='$($parts[0])'"
   if ( $parts.Count -gt 1 ) {
      for ( $i=1; $i -lt $parts.Count; $i += 2 ) {
         $filter = "$filter and Assembly$($parts[$i].trim())='$($parts[$i+1])'"
      }
   }
   return $filter
}
function script:find-orch([string]$name, [string]$assembly) {
   # We want to be able to find orchestrations by
   # name and/or assembly. That way we can control
   # all orchestrations in a single assembly in one call
   $filter = ""
   if ( ![String]::IsNullOrEmpty($name) ) {
      $filter = "Name='$name'"
      if ( ![String]::IsNullOrEmpty($assembly) ) {
         $filter = "$filter and $(get-assemblyfilter $assembly)"
      }
   } else {
      $filter = $(get-assemblyfilter $assembly)
   }
   get-wmiobject MSBTS_Orchestration `
      -namespace 'root\MicrosoftBizTalkServer' `
      -filter $filter
}

function start-orch([string]$name, [string]$assembly) {
   $orch = (find-orch $name $assembly)
   $orch | ?{ $_.OrchestrationStatus -eq $bound } | %{
      write-host "Enlisting $($_.Name)..."
      [void]$_.Enlist()
   }
   $orch | ?{ $_.OrchestrationStatus -ne $started } | %{
      write-host "Starting $($_.Name)..."
      [void]$_.Start($controlRecvLoc, $controlInst)
   }
}

function stop-orch([string]$name, [string]$assembly, [switch]$unenlist = $false) {
   $orch = (find-orch $name $assembly)
   $orch | ?{ $_.OrchestrationStatus -eq $started } | %{
      write-host "Stopping $($_.Name)..."
      [void]$_.Stop($controlRecvLoc, $controlInst)
      if ( $unenlist ) {
         [void]$_.Unenlist()
      }
   }
}

BizTalk Filters not Getting Imported

Link. June 21, 2008. Comments [1]. Posted in: BizTalk

... or how automatic formatting of XML files can make you miserable.

During the last few days I've been helping out a client get ready for deploying a BizTalk solution. One of those things this involved was taking the existing BizTalk Binding XML files and making minor edits to them so they would match the new environment.

I did the changes, and the BizTalk Administrator used the updated Binding Files to import them into the new BizTalk Servers. They imported without any errors at all. A couple hours later he noticed some test messages were getting incorrectly routed to the wrong send ports (there's a lot of messaging only stuff in this solution)., so he checked the send port configuration.

There were no filters defined at all! We checked the Binding files again, and yes they were clearly defined there. Why were they not getting imported?

The culprit turned out to be Visual Studio. I had edited the binding files in VS and, for several reasons, this involved doing copy-and-pasting the entire XML content of the binding files between machines. Normally this isn't a problem, but this time it was.

VS will reformat XML content when you paste it into VS. This is usually a welcomed feature, but not now. Turns out that VS reformatted the <Filter> elements of the Send port configurations like this:

<Filter>
   &lt;?xml version="1.0" encoding="utf-16"?&gt;
   &lt;Filter xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
...

See anything weird? I didn't see it either at first. The problem is the line break and extra white space caused by the indentation between the opening <Filter> element and the actual string-encoded XML of the filter expression.

Apparently, BizTalk can't deal with this at all and simply treats it as if the <Filter> element had been empty when it imports the binding file. No warnings, no errors, it simply ignores it silently.

I removed the space leaving it like this:

<Filter>&lt;?xml version="1.0" encoding="utf-16"?&gt;
   &lt;Filter xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
...

And now it was imported correctly and all the Filters were recreated successfully. This was maddening to say the least, and it's one of those pesky bugs that can make deploying BizTalk solutions an even more miserable experience than it already is. Definitely a very annoying bug in the Binding importer code.

PipelineTesting 1.1.3.0 Released

Link. June 8, 2008. Comments [0]. Posted in: BizTalk

I just uploaded a new update to my PipelineTesting library. This one comes courtesy of Gregory Van de Wiele, who kindly made me aware of a nasty bug: The library wasn't handling schemas with no targetNamespace correctly when adding them to the pipeline context.

Because of this, you needed to specify the documentSpec name as "#root" instead of simply "root". This has now been fixed in this version and I added a new unit test to make sure it doesn't come up again. Thanks a lot Gregory!

As usual you can download the updated code/binaries from here.

About

Tomas Restrepo is co-founder of devdeo. His interests include .NET, Connected Systems, PowerShell and, lately, dynamic programming languages. More...

email: tomas@winterdom.com
msn: tomasr@passport.com
twitter: tomas_restrepo

Technorati Profile

devdeo logo

View my profile on LinkedIn

MVP logo

Syndicate

Ads


Links

Categories

Statistics

Total Posts: 1006
This Year: 76
This Month: 7
This Week: 0
Comments: 771

Blogroll

Post Archive

Other

Copyright © 2002-2008, Tomas Restrepo.

Powered by: newtelligence dasBlog 1.9.7174.0

Sign In