BizTalk 2004 has some very useful behavior around parallel execution and
scope-level timeouts that it is helpful to have a good understanding of.
What follows is a series of experiments & associated findings that should
shed some light on this area.
Experiment One:
One restriction when using the parallel shape is that if multiple branches make
use of a given orchestration variable, you can get a compiler error:
error X2226: 'someVar': if shared data is updated in a parallel then all
references in every task must be in a synchronized or atomic scope
In the experiment below, we are accesing ‘someVar’ in both parallel
branches - each within an expression shape that also calls Thread.Sleep (the
left hand for 10 seconds, the right hand for 30.) To address the compiler
error just noted, we have a scope around each usage with the
‘Synchronized’ flag on the scopes set to ‘true’.
The trace messages shown to the right of the diagram tell us that, indeed, the
execution of Scope 2 and Scope 3 is completely serialized (in this case, Scope
2 completes before Scope 3 begins.)
This experiment also tells us something unrelated (but useful): that an
exception will not interrupt “user code”. By
“user code” we refer to code in an expression shape, i.e. not
using an orchestration “intrinsic” such as a standard Delay shape
or a Receive shape, etc. Notice via the timings that the exception thrown
in the left-hand branch doesn’t abort the Thread.Sleep in the right-hand
branch. The exception is caught only after the Thread.Sleep in the
right-hand branch completes (though the final trace message in the right hand
branch – ‘after 30 sec’ – does not execute.) This
is important to understand if you have expression shapes in orchestrations
which are making blocking calls to .NET components, DCOM servers, etc.


Experiment Two:
If we eliminate the ‘someVar’ reference in the expression shapes
above, we find that the scopes do not execute serially – whether
the scope synchronization flag is set to true OR false. Notice
below (via the timings) that the sleep operations are executed at the same time
- so it is the presence of the common variable in the expression that forces
the synchronization!
We now have a 20 second gap after sleeping for 10 seconds (because the
exception we throw still doesn’t interrupt us).

Experiment Three:
We would like to use a given instance of a .NET object without imposing
the use of synchronized scopes. As it happens, if we have a .NET object
that is pointed at by two references (i.e. someVar and someVar2 - where
someVar2 was set equal to someVar with a simple assignment), the requirement
that the orchestration compiler normally imposes regarding the use of a
synchronized scope goes away.
In the orchestration below, the left branch is using someVar, and the right
branch uses someVar2. The trace indicates that the sleep operations
happen at same time (though once again the exception doesn’t interrupt
the right-hand side and is caught only when the right-hand completes.)
Lesson: If you have a .NET component (that you know to be thread-safe) you wish
to use in an orchestration - and you wish to use a single instance of it - you
will need to have multiple references to that same instance to use in each
branch of a parallel shape. (The synchronized-scope alternative is likely
unacceptable!) The first variable declaration of your component might use
the default constructor, while the others will have “Use Default
Constructor” set to false and will be assigned to the first.
 
Experiment Four:
Now, there is more to be said regarding exceptions and what they will interrupt
in parallel branches. If instead of using a Thread.Sleep we use a Delay
shape (or a Receive shape, etc.) we find that throwing an exception in one
branch of the parallel shape will indeed interrupt the other branch(es).
Notice in the timings below that the Delay 30sec shape does not complete
once the exception in the left-hand branch in thrown. Particularly when
you are structuring real-world business flows, this is an important and quite
useful behavior.


Experiment Five:
The behavior of exceptions in parallel flows is closely related to another
behavior in BizTalk 2004 - that of what BizTalk is prepared to "interrupt" when
a long-running scope has exceeded the timeout value that has been configured
for the scope. A Delay shape (or Receive, etc.) will indeed be
interrupted when the timeout expires (and a TimeoutException will be
thrown). (Note that for an atomic scope, the timeout governs the maximum
time to allow prior to aborting the transaction.) See the timings below
and note that the Delay 30sec shape does not complete.
 
On the other hand, as you might expect at this point, a blocking call in an
expression shape (like a Thread.Sleep or a DCOM call, etc.) will not be
interrupted. However, the exception will be raised when the blocking call
eventually returns:
 
Summary:
-
The Synchronized flag on a scope will only cause synchronized (serialized)
behavior among “peers in parallel branches” when shared variable or
message state is involved. (This is ignoring any transactional semantics
you might layer on top – which is beyond the scope of this article!)
-
If you have a thread-safe .NET component that you wish to use in an
orchestration from multiple parallel branches, strongly consider having
multiple variables point to a common instance. The first instance might
have “Use Default Constructor = true”, while the remaining
variables will have that flag set equal to false and be assigned to the first
instance in an expression shape:
someVar2 = someVar1;
someVar3 = someVar1;
someVar4 = someVar1, etc.
An alternative is to use scope-local variables that are assigned to a global
instance.
-
A line of code in an Expression shape will not be interrupted by either
an exception in a parallel branch or a TimeOutException arising from a
timed-out scope.
-
A Delay shape or Receive shape, etc. will be interrupted by either an
exception in a parallel branch or a TimeOutException arising from a
timed-out scope.
(Update: See the latest on the Deployment Framework
here.)
It has been about three months since my initial submission to the BizTalk 2004
developer competition that I discussed
here. The contents of that contest entry took a prize (woohoo!)
but still left a lot to be desired…
Since then, I’ve had a chance to make what I believe are major
improvements to the deployment story I’ve been discussing since last
May. In addition, I’ve had a chance to see the practice being used
across several large BizTalk projects, and have done a lot of learning as a
result. (No guarantees or warranty implied, but derivatives of the
scripts/tools I discuss here have been in use for some time by a very large
BizTalk customer I work with.)
The most important changes you will see in this release are as follows:
-
The “core” NAnt functionality has now been separated from the piece
that an individual BizTalk project must “own” and maintain.
This is a huge simplification, and allows for more rapid adoption -- as
well as the ability to deploy bug fixes & feature enhancements in a way
that just wasn’t possible when stuff was intermingled. (Peter
Provost was right
about that aspect of my first attempts.) The NAnt script that a
particular project must own can now be reduced to the following for a simple
case (notice the ‘include’ reference for the core):
<project name="BizTalkSample" default="debugDeploy">
<sysinfo/>
<include buildfile="BizTalkDeploymentInclude.nant"/>
<-- Set following properties to true or false to include various pieces of a BizTalk deployment. -->
<property name="includeSchemas" value="true" />
<property name="includeOrchestrations" value="true" />
<property name="includeTransforms" value="true" />
<property name="includePipelines" value="true" />
<property name="includeComponents" value="true" />
<property name="includePipelineComponents" value="false" />
<property name="includeCustomFunctoids" value="false" />
<property name="includeVocabAndRules" value="false" />
<property name="includeVirtualDirectories" value="true" />
<property name="includeMessagingBindings" value="true" />
<property name="includeDeploymentTest" value="true" />
<property name="includeCustomTarget" value="true" />
<project/>
-
You now have the ability to supply a simple xml-driven Wizard-based UI when you
are deploying after an MSI install. You can use this UI to
gather Windows identity information for virtual directories (for SOAP/HTTP
receive ports), to indicate whether the scripts should deploy to the BizTalk
management database (for working in BizTalk groups), and for many other
purposes. I call this “Install-Time Configuration” in the
documentation below. Here are some example Wizard screens:

-
You now have the ability to have an Operations-managed
“spreadsheet-driven” mechanism for environment-relative
configuration. What do I mean? I mean those aspects of your
deployment that are particular to your development, QA, or production BizTalk
environments. Aspects that wind up appearing in your BizTalk binding
files! Queue names, database names, file shares, FTP locations,
etc. This is information that you don’t want to manage with the
Wizard UI above (there is too much of it) and you want to maintain “as a
set” for each environment. The spreadsheet (pictured below) can
start life with your developers, and ownership can gradually migrate to
Operations. This spreadsheet generates environment-specific
“settings” files, and at the point you deploy, the values for the
environment you are deploying to are automatically substituted into your
binding file…Slick!

(click)
-
You now can use a highly templated (reusable)
WiX based setup, rather than a Visual Studio Setup Project, to generate
your MSI. WiX, in a nutshell, is a set of tools and an Xml grammar that
allow you to specify the contents of an MSI. One of the clear pieces of
feedback I got on the last rev I released is that reproducing a Visual Studio
Setup Project was far too manual.
There are a large number of other changes that I’ll just enumerate
quickly here:
-
You no longer need to have your NAnt file enumerate your orchestration names or
their deployment order – a new custom NAnt task eliminates the
need for this.
-
You no longer need to have your NAnt file enumerate how many receive ports/send
ports/etc. you have – a new custom NAnt task eliminates the need
for this.
-
Support for BizTalk groups, where machines 2-n do not require deploying to the
BizTalk management database.
-
Support for not following the naming recommendations I made in previous
releases – you can have custom project names, assembly names, directory
names – its just a little more work.
-
Support for multiple assemblies of the various types (i.e. multiple
orchestration assemblies, schema assemblies, etc.)
-
Inclusion of a utility I call SetEnvUI.exe for creating the xml-based wizards
described above.
-
Inclusion of a utility I call DeployBTRules.exe for deploying BizTalk Rule
Engine policies and vocabularies.
-
Inclusion of Loren Halvorsen’s
XmlPreProcess tool for managing the environment-relative configuration
discussed above.
-
Support for creating IIS6 application pools (with specified Windows identity)
for HTTP and SOAP-based receive locations, and for adding virtual directories
to application pools.
-
Support for registering the btshttpreceive.dll ISAPI extension with IIS6.
-
Support for selectively restarting multiple BizTalk host instances, for
deploying custom functoids, and for dealing with send port groups, and
more…
There are now two downloads. The first contains all of the core scripts
and utilities plus a sample BizTalk solution that uses them. The
second download contains just the core scripts and utilities, and is designed
to allow a BizTalk solution to accept updates/bug-fixes/etc. over time (i.e.
the zip can be expanded into your directory structure on a developer
workstation so you can test it out.)
It should be noted, though, that some manual work will be required to
“upgrade” from the previous version I released in September –
this release is quite different, but I think you will find it is well worth the
time.
Full download is here.
Core scripts and utilities only are
here.
GotDotNet Workspace is
here.
The full documentation for this release (which includes more detail than this
blog entry…) is included in the zip files, but it can be viewed directly
here (with a diagram here.)
Enjoy! And remember: if you didn’t make into a given environment
(QA, production, etc.) with a scripted deployment of some kind, you
didn’t get there at all.
(Not necessarily this stuff, but something automated, at any rate…)
Some time ago, I published a set of
proposed naming conventions for BizTalk 2004.
In the interim, I’ve had a chance to see these used in a few different
projects and to review them with several people -- and they have evolved &
grown a fair bit.
So I thought I’d publish the new version - the Word version can be found
here, and an HTML version can be found
here. (I’ve found it helpful to open the HTML version
directly in VS.NET for quick reference.)
Hopefully these will be of value to your project. I’ve certainly
found that the documentation value to be had within Orchestrations and within
the operational tools can be hugely improved by following these
conventions – especially if you are using the
UK SDC BizTalk 2004 Documenter tool (you are, aren’t you?)
My comments on the use of such documentation
in my old post still apply, I believe.
Leave comments with questions or suggestions…
I had the pleasure of presenting on BizTalk 2004 at the
Heartland Developer’s Conference 2004. The whole conference
was a lot of fun, and as
Kent Tegels has noted, Joe
Olsen did a great job in organizing the logistics for this event –
you wouldn’t have known it was the first-of-a-kind (save for Joe’s
mea culpa on caffeine…)
I had a chance to talk to Sam Gentile
about the work he has been doing at Addesso. This was enlightening, since
in my non-BizTalk-work-life I do quite a bit mobile work in the
field-force-automation space (using ruggedized Pocket PC devices – great
fun!)
As to the presentation itself – one of the topics I discussed was BizTalk
2004’s scaling model, and the power of having being able to create
multiple host instances for a single logical host definition that contains your
orchestrations. This gives you a “competing consumer” effect
– multiple processes on multiple servers, all pulling from a common work
queue. In my talk, I suggested that this idea wasn’t new and
related it back to a
1998 article in Enterprise Developer’s magazine. In that
article, an architect from Merrill Lynch was discussing the scaling
difficulties in using NT4/MTS – the load balancing options weren’t
pretty. He proposed a pattern he dubbed “Auctioning” where
clients would submit work to an MSMQ queue, and multiple servers (all running
common server-side components) would pull work from that queue. The
benefits he articulated relate quite closely to what you will find in the
parallel aspects of BizTalk 2004.
Check out this graphic from the article – it should look a little
familiar to BizTalk folks.

Below is my paraphrase of the article’s main points, recast with BizTalk
terms (and exactly relevant to BizTalk, I believe…)
-
To load balance multiple servers, servers objects [orchestrations] should pull
work from a global [per-host] work queue that clients place their requests in.
-
Auctioning works well precisely because it relies on the message queue server
[messagebox], not DCOM [or transport of choice], to route the request to the
server object [orchestration].
-
Server objects [orchestrations] compete for requests on the queue, so load
balancing happens naturally; the server with the most available processing
capability will automatically check the queue more often and service more
requests. [unlike IP load balancing]
-
If you add more server machines, the requests just get processed faster by more
instances of the object [orchestration]
-
If one server goes down, the remaining servers continue to process the
requests. There's no single point of failure.
You can find the whole presentation (which also discussed BizTalk compared with
traditional application servers) right here.
It can turn out to be useful to use Health and Activity Tracking (HAT) and the
BizTalk Server Administration Console “remotely” (that is, from a machine other
than one of the actual servers in the BizTalk group.) This can be the
case if you have multiple environments to administer, and/or using Remote
Desktop is not desirable or available.
It should be noted that to accomplish this, you technically have to have the
“administrating machine” join the BizTalk Group – though since you won’t
have any host instances defined on the machine, that isn’t as significant as it
sounds. You are essentially just configuring the machine to point at a
particular BizTalk management database, and configuring some WMI
information. The “administrating machine” does not appear in the
“Servers” node of the BizTalk Administration Console.
It should also be noted that you will need to be in the “BizTalk
Administrators” Windows group for the BizTalk environment you want to
manage.
To get started, the “administrator” should do an “Admin-only” install of
BizTalk on the machine they will be using, where the installation options for
BizTalk look like this:

Then, on the desktop, the administrator should put a shortcut to a script that
looks like the script below. This script simply reminds the user what
BizTalk Group they are currently administrating, and confirms they want to
switch:

If you select OK, you get another warning:

This is basically warning someone who has a full-blown BizTalk installation on
their machine that they really don’t want to remove their current configuration
unless they happen to have a saved configuration file from their last run of
ConfigFramework.exe.
If you select OK, the “ConfigFramework.exe” utility is run (from BizTalk’s
installation directory) with the /u switch, to remove the current
configuration. Afterwards, ConfigFramework.exe is run normally, and the
only option you will have (for an admin-only install of BizTalk) is to select
the database corresponding to the environment you wish to administer:

Once you hit “Next”, the wizard will complete, and you will be presented with a
final confirmation dialog:

The VBScript as a text file is
here.
I recently went through a really nast bout of troubleshooting with the client I
currently work with, related to MSMQT. Hopefully, my tale can save you
similar pain.
The core issues was this: The BizTalk MSMQT adapter can be configured during
installation to integrate with Active Directory. The default is that it
will not operate in this fashion, but rather in "workgroup" mode. There
are (at least) two reasons why you might want to have MSMQT integrate with
Active Directory: 1) you want to make use of an MSMQ router in your environment
or 2) you want to use certificate-based authentication at a protocol level
(where the public certificate is managed by AD.) (Note: I know this now;
I didn't know it a couple weeks ago...)
We have been installing our servers in "workgroup" mode. To install in
Active Directory mode requires a special permission granted by the domain
administrator.
Now, when you a configure a Send Port within BizTalk and select MSMQT as the
transport, the property pages in the BizTalk Explorer offer a checkbox that is
labeled "Use MSMQ Authentication". If you hit the "Help" button on this
dialog, the explanation that is provided is this: "Identify whether BizTalk
Message Queuing uses protocol authentication every time it sends a message on
this port."
As it turns out, although it isn't documented as such, a Send Port with this
option checked can only work if MSMQT has been installed in Active
Directory-integrated mode. If you have the "Use MSMQ Authentication"
option checked on a Send Port and you are not in Active Directory-integrated
mode, then messages will not flow. When we eventually discovered this
discrepency and fixed our bindings files, the problem was resolved.
(Note: there is a similar option when configuring Receive Locations.)
This checkbox had been checked at the point our initial binding files were
exported, and became a part of our scripted deployment. What was worse,
when we encountered this problem a few weeks ago in QA, we began
troubleshooting the BizTalk configuration on the server directly and wound up
"fixing" the problem by creating an additional Send Port (subscribing to the
same traffic as the original) that simply had the MSMQ Auth checkbox off.
But we didn't realize that discrepancy at the time, so we had to troubleshoot
the same problem all over again a few weeks later. We definitely got
ourselves into the wrong troubleshooting mindset by assuming that Biztalk was
flaky in some way.
Key lesson: If you don't get into a given environment (QA, production,
whatever) with your scripted deployment, then you really didn't get there at
all….
A few more notes. As I said above, if you have the "Use MSMQ
Authentication" option checked on a Send Port and you are not in Active
Directory-integrated mode, then messages will not flow. What you will see
is:
-
Messages will appear in the HAT "Queries-Messages Sent in Past Day" report, but
they will not actually have arrived in the destination queue. (Fixed in
SP1?)
-
You will see strange behavior in the HAT "Operations-Messages" view, but
nothing that indicates an error condition. Retry count will increment on
the original service instance.
-
There will be no error condition reported in the event log. (OK, Premier
Support indicates in a phone conversation you might see something after 5 days
have elapsed, when an exponential backoff algorithm has run its course.)
IMHO, Biztalk 2004 should be more serviceable in this regard, and should give
better error information. And of course, the documentation for MSMQ Send
Port configuration should have mentioned that MSMQ Authentication would only
work for Active Directory.
Microsoft Premier Support became involved, and after around 18 hours of
analysis they said "We see some certificate-related errors in the traces.
Do you use MSMQ authentication? Are you AD-integrated?"
We looked in our binding files (since the decision had long since been
forgotten) and saw this snippet:
…
<TransportType Name="MSMQT" Capabilities="16495"
ConfigurationClsid="9a7b0162-2cd5-4f61-b7eb-c40a3442a5f8"/>
<TransportTypeData><CustomProps>&
lt;Authenticated
vt="11">-1</Authenticated></CustomProps>
</TransportTypeData>
<RetryCount>3</RetryCount>
<RetryInterval>5</RetryInterval>
…
See that in the escaped XML? Yup, that is a property called
"Authenticated" that is an old-fashioned Variant of type bool, where "-1" means
"true".
Leaps out at you, right? Determining if you are AD-integrated means
looking at
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BTSSvc.3.0\MessageQueuing\MsmqtWorkgroupMode.
From all of this I (gently) conclude that the product instrumentation/tracing
should point out this condition more quickly to a support engineer. In
addition, the MSMQT adapter should warn you of a mismatch during configuration
with the Biztalk Explorer and, ideally, when you deploy/import bindings.
Hindsight being 20/20, the support engineer should have asked to see our
binding file - and should have compared it with one exported from a server that
was indeed sending messages (since we had one.) Of course, we should have
made such a comparison, too! (and much earlier...) The engineer did look
at the Biztalk Admin Console, but of course that doesn't give any of the
detailed port configuration information - only Visual Studio/BT Explorer does.
Having said that, the support engineers were great to work with and were
certainly dedicated to getting to the bottom of our issue.
Key lesson: Diffing binding files will prove to be a key troubleshooting
technique with Biztalk...
(Update: See the latest on the Deployment Framework
here.)
I see that the GotDotNet workspace I referenced in my last post is having occasional trouble, so I'm making the current version of template available for download on this site.
(Update: See the latest on the Deployment Framework
here.)
It has been several months since I initially posted on the topic of using NAnt to coordinate the deployment of BizTalk 2004 solutions, with updates here and here. Since that time, I've been heads-down in a BizTalk project and have had a chance to refine the practice quite a bit.
So, I took the opportunity to introduce quite a few improvements into the sample I had previously released - hopefully turning it into a "template" that can be used on your projects more easily. To that end, I've created a GotDotNet workspace where you can download the current version of the build template, and I invite any feedback/suggestions/participation.
The major changes I've introduced can be categorized as follows:
- Split binding files: On a BizTalk project with multiple developers, I believe it is beneficial to split your binding files into content related to orchestrations vs. content relating to "everything else" (send ports, receive ports, etc.) The new build template sample does just that.
- Improved scripts: Many of the WMI-related scripts I relied on in the past were from BizTalk SDK samples. These were modified to get better/different error handling behavior.
- More generic handling of send ports, receive ports, receive locations, etc. in the script - though it still requires some maintenance.
- Better NAnt citizen: I'm still not a NAnt expert by any stretch, but thanks to Duncan Millard I realized that I had been remiss in applying quotes to a good deal of the text names I was using (i.e. "). In addition, I started using built-in NAnt tasks for at least a few items where I had overlapped functionality, though not in cases where I needed slightly different behavior. Finally, the build file naming convention proposed by the build template is "BizTalkSample.sln.deploy.build" (rather than "BizTalkSample.sln.build") to avoid conflicting with a NAnt file that would actually be used to build the project (e.g. with Cruise Control), as opposed to deploying it.
- Use of "Deploy with NAnt" in an MSI scenario: This is the biggest (and I believe most useful) change...Let me explain further.
As you study the build script, you will notice that it now also tackles such tasks as deploying virtual directories and applying permissions to them, patching binding files to match “local conditions”, etc. The initial goal here is to ensure that in a team development scenario, the amount of “out of band” setup required for any given developer to establish their BizTalk 2004 project environment is minimal – and that the current topology for the project is communicated efficiently (i.e. through the build file, as opposed to email or word-of-mouth.)
After a development team has spent weeks or months with this build script, refining it to represent their exact situation and deployment needs, a question might arise: Why not take this well-tested script and use it for production (or just non-development-machine) deployments as well?
To do this, it is helpful to agree that a two-phase deployment of BizTalk-related projects is both acceptable and useful. The first phase is an MSI-based installation that simply installs all of the BizTalk-related assets in a specific directory, but doesn’t deploy them to the BizTalk server. The second phase occurs when the user goes to the Start-Programs-YourProjectName menu, and chooses “Deploy YourProjectName”. The user also has the option to un-deploy (leaving the assets still on the file system until the MSI is uninstalled) or redeploy (to support the case where a single file is “patched”.) See a picture of the Start menu created by the build template's MSI file.
The reason that two phases are useful is that if the deployment to BizTalk fails, we would like a complete log of the results (which in this sample occurs in the DeployResults directory) for analysis/diagnostics, and we would rather not have the MSI simply roll back. The same holds true of un-deployment.
Dual-purposing the NAnt file you have been maintaining for “real” deployments can be summarized as follows:
-
Use the build template's approach (see BizTalkSample.sln.deploy.build in the download) for the “server.deploy” and “server.undeploy” targets, which make the build file able to work with “co-located” binaries in addition to the standard developer tree.
-
Create a Visual Studio Setup project that deploys your BizTalk assemblies according to the pattern shown in the BizTalkSample.Setup project. Notice that this setup project includes the NAnt build file, the “DeployTools” directory (with our scripts), as well as a subset of NAnt in a subdirectory of our installation (so that we don’t rely on NAnt being present on the target server.) It also includes a few convenience batch files referenced by our Start menu entries for invoking NAnt with specific targets.
The BizTalkSample.Setup project in the build file can be built, installed, and deployed to try this out. (You will want to make sure you haven't already deployed in "developer" mode, because the "Deploy BizTalk Deployment Sample" passes a flag to the NAnt script that will skip the undeploy phase in order to speed up "clean" installations.) Note that as your deployment grows more sophisticated - multiple hosts, servers, etc. - you will find the NAnt script requires additional properties to govern these variations between server deployments and developer-desktop deployments.
The build template sample also discusses the use of NUnit as a post-deployment verification process. See the documentation in the sample for a full discussion -- basically all we are doing is making sure our MSI includes a subset of our unit tests, NUnit, and appropriate test files. This is then wired up to the "Verify Deployment" Start menu option. This can be an extremely effective means of ensuring your operations team has a means of testing the system interactively (not to replace standard automated heartbeat tests you might have…)
Peter Provost proposed a great generic approach to building BizTalk NAnt files a couple of weeks ago - and I shamelessly stole his approach to reverse the "orchestration ordering" property (very slick!) If you do not wish to pursue the MSI option just discussed, and you do not wish to integrate the "out of band" setup actions discussed above (i.e. virtual directory creation, etc.), you might prefer his approach or you might want to push the build template sample provided here in that direction (i.e. more property driven.) However, I believe tackling the kinds of concerns that we do here will generally mean that a real-world project will no longer have a generic-looking NAnt script.
Again, you can download the build template sample here. Enjoy, and I hope you find it useful.
A lot has been said regarding the MSMQT adapter for BizTalk 2004 already, but
below are a few recent observations that may be of help to you.
When people ask me what MSMQT is, my short answer goes something like this:
"MSMQT is the name of the BizTalk 2004 adapter that implements the MSMQ
network protocol directly within BizTalk. It allows BizTalk 2004
to send/receive MSMQ messages directly, and move messages to/from the
MessageBox very quickly - without external (DTC) transaction
coordination. Only private queues are supported for receives."
Using the MSMQT adapter you can:
-
Use Send Ports to send to public or private queues on remote machines - but the
queues must be transactional.
-
Use Send Ports to send to local queues, which will be private
since that is all MSMQT supports.
-
Use Receive Locations to receive from locally defined queues, which will be private
since that is all MSMQT supports. These queues can be either
transactional or non-transactional. You cannot monitor remote queues
(i.e. receive locations can't reference remote queues.)
You cannot using the System.Messaging MSMQ APIs/COM MSMQ APIs/MSMQ C Libraries
or the MSMQ MMC console on a BizTalk 2004 machine that is running the MSMQT
adapter! This is because these all rely on the native MSMQ Service
running.
You can use the aforementioned APIs (though not the MMC console) from remote
machines (that are not running the MSMQT adapter) to put messages in
MSMQT-defined queues.
To test MSMQT queues on the BizTalk 2004 server where they are defined, you
can:
-
Create a Receive Port and a File Receive Location that will monitor a
particular directory...
-
Create a static one-way Send Port that specifies MSMQT & the queue you want
to test as the destination. In the "Filters" portion of the Send Port
configuration, define BTS.ReceivePortName = ReceivePortNameFromStep1
Now, when we you drop a file on your directory, it will be routed to your
queue. The receive location could also use HTTP posts, in which case the
WFETCH tool from the IIS Resource Kit (or a similar tool) will let you easily
get test messages to the queue.
Note: If you have existing applications that used to send to public MSMQ
queues, but will now be sending to MSMQT queues, the most common problem is
that they are referencing those queues via the PathName property, rather than
the FormatName property (with 'DIRECT=OS:machine\private$\qname' syntax.)
This is only a problem for users of the COM/C-Library APIs - the
System.Messaging.MessageQueue class actually allows format names to be used
with the Path property.
See this
Microsoft Support discussion for lots of additional insight into
MSMQT.
|