Creating BizTalk Installer Packages For Multiple Physical Environments

BizTalk Server 2006 has been out and around for a while, now. Those of you who are familiar with both BizTalk 2004 and 2006 know that some of the biggest improvements have been made in the tools used for deploying and managing applications. One of my favorite improvements is the ability to export an application as an MSI file.

I recently had a question in a class about how someone could create an MSI for a BizTalk application that has different port binding configurations available for different environments. This was a good question, and something I think a lot of developers overlook.

By default, when you export an application to an MSI file, the port configuration settings of the application are saved directly in the MSI. This means that when you import the MSI somewhere else, you end up with ports that match the original environment. This works well, provided all your development, test, and production environments are exactly the same.

To save developers from having to create and re-create the same ports over and over again, BizTalk 2006 has the ability to create binding files. Binding files are XML representation of the port configuration from the BizTalk configuration database. Binding files include the transport settings of the ports, pipeline and maps used by the ports, and the application in which the port is contained, among other things. You can use the Administration Console to export or import binding files to quickly save and recreate physical ports. So what does this have to do with MSI files?

The short version of this is, create your physical send and receive ports, with the appropriate configuration for the end points you are interested in. Once you’ve created all the bindings for one environment export the bindings. Repeat this for the various environments that you need ports for.

Once all your binding files are created, you can add them to the Resources folder of the application (be sure to fill in the Target Environment box). When you export the application as an MSI, the bindings are bundled with it. When you import the MSI, the Target Environment page of the wizard will have a drop down list from which you can choose the bindings to apply.

There are two things you need to remember:

  1. You don’t need connectivity to the system in order to configure a port if you know all the properties (server name, user name, password, URI, connection string, etc.) so you can create the binding files in any environment.
  2. Passwords are not saved in the binding file (huge security risk), so they will need to be reconfigured after the MSI has been imported.

 

Try using the above recommendations next time you are in need of creating several MSI files with disparate application bindings.

Another update to CallWorkflow

Another update to CallWorkflow

So I started this sample  out as an off-the-cuff kind of thing and it seems a
number of people are using it.  Lenny Fenster from Microsoft found another bug
– when the child workflow would terminate with an exception – the CallWorkflowService
was sending the exception to the Queue – but the custom Activity listening for the
message wasn’t re-throwing the exception.  Its been fixed – so if you are using
this sample – you should download the new code. 

Orginal
Post
.

My
samples page.



Check out my BizTalk
R2 Training.

CTP3 of ESB Guidance Released

Some very cool updates in the just-released CTP3 of ESB Guidance. The changes that caught my eye include:

Download the full Help file in CHM format. Check out what’s new in this release, sample projects, and a fair explanation of how to perform basic tasks using the package.
New endpoint “resolver” framework. Dynamically determine endpoint and […]

Ruby vs. C# Smackdown

I recently attended a meeting of the Dallas

C# SIG, a group which I hadn’t attended in quite some time, because they had Adam

Keyscome in to talk about Ruby. I don’t live under a rock, so I’ve

heard the buzz about Ruby but I hadn’t spent much timelooking into it because

it wasn’t immensely relevant to my day to day. That said,this was a great

chanceto learn soI checked out the meeting and I must admit, I was impressed.

I’m hardly a convert but I can understand Adam’s point that Ruby “feels” moreenjoyable

towrite for him.

While most things Ruby can do I think C# 3.0 has well in hand, therestill some

things C# can’t do yet. The dynamic augmentation of an instance, not a type,

is intriguing to me and certainly powerful. One featurethat I thought

was interesting, and immediately doable in C# 3.0 was the way Ruby can handle loops.

For instance take this Ruby code (syntax errors possible,this is not checked)

:

50.Times do
  Puts "We

Built This City ..."
  Puts "We

Built This City ..."
  Puts "On

Rock And Roll"
end

I like this much better than the standard C# syntax of a For loop because it focuses

on what is important. Its terse yet clear, and I wanted in C# 3.0 right now,

so here it is:


              public

              static

              class LoopingExtensions
{

              public

              static

              void Times(thisint upperBound,

Action<int> action)
    {

              for (int index

= 0; index < upperBound; index++)
            action.Invoke(index);
    }
}

This results in a very nice piece of C# code, equivalent to our Ruby example above:

50.Times(i => {
    Console.WriteLine("We

Built This City...");
    Console.WriteLine("We

Built This City...");
    Console.WriteLine("On

Rock And Roll");
}

Simply enough to implement, and a great example of using Lambda expressions and extension

methods to improve the readability of your code.

BizTalk "Get Last Message" pattern

There is acase:
One part of the solution periodically publishes the data.This part is out of this article.
There are two kind of subscribers.
One kind of subscribers want to get the messages while they are published.
Second kind of subscribers pool this messages randomly:
  • undefined quantity of the subscribers request the undefined number times the LAST message in random interval.
  • they want toget the last input message only.
The usual publish-subscribe pattern doesn’t work, because
  1. the usual subscriber MUST receive ALL published messages. It cannot omit several and receive only others. (It can but it have to implement this logic by itself, it is not the case.)
  2. After subscriber received the message, it cannot receive this message one more time. The message pops out of the query.
  3. After one subscriber received the message, the other subscriber cannot receive the same message if it is not subscribed to the message. It is not a “random” , “one time”, “randomly appeared/disappeared”subscriber.
The question is: How can I do this in “BizTalk style”?

The orchestration implements this “Get Last Message” pattern.
The orchestration has three parts.
One is for controlling this orchestration. It starts and stops the orchestration by the Control messages (Control START and Control STOP). That’s all.
The second part is a part of the pattern. It receive all input messages (Trips_Canonical) in the Unifies Sequential convoy. Usually in the samples there are two receive shapes, one before and one inside the loop. I use the receive for the control message as an activate receive, it helps me to simplify the orchestration.
The third part is a part of the pattern too. It is compounded from the receive shape which requests the last message (Get LastRequest message), and the send shape, which send this last message. The last message isthe same as the input message, the only difference is in thevalue of the”ProcessName” element.
This sample is used in the content routed scenario that’s why there are several interesting points.
  • all messages have one first level node, right under root node with name “ProcessName”. This node holds the name of the message publisher. This helps route the messages with the same message type to different routes. For example, the input Trip_Canonical messages and the output Trip_Canonical have different values of this node, and this is the only difference.
  • the messages correlated by this “ProcessName” node (the cor_ApplicationName Correlation set).
  • I use the Decide shape to avoid to send the requested last message if I have nothing to send. But to get this project built I have to create the “foo” message.
  • I gather all receives under one direct port. This is an Ordered delivery=True port.

    Maybe it worth to include the send port under this port too.


There are the Control messages:
START:
STOP:
Input message the “Trips_Canonical”:
Get LastRequest message:
Last message: