BizTalk 2006 Documenter Available

I hadn’t realized we released this publicly yet, but noticed this morning that the BizTalk Server 2006 Documenter is now
available for you to download. See Paul’s blog
for the link.

I love this tool. To be able to generate a CHM file containing summaries of all your BizTalk artifacts (and relationships), plus business
rules, plus port configurations, plus orchestration image snapshots is freakin’ great. Essential way to quickly document your
entire BizTalk application without writing a single line in a boring Word doc!

Technorati Tags: BizTalk

Web service parameters by reference

My customer’s web service has two (string) parameters passed by reference so that they can return multiple pieces of information from a single call.  (Let’s leave design issues to the side for now.)  In some cases, one of these strings is empty (“”).


What I’m observing, in these cases, is that my orchestration hangs waiting for the response from the web service.


For now, I’ve put up a fascade web service that passes the call through to my customer, and on return, checks for the empty string.  The fascade replaces the empty string with a single space.  This seems to work.


My guess is that the SOAP response doesn’t contain the node for the blank string, and the port doesn’t recognize the “abbreviated” response, so it keeps waiting for the full one (which never comes).  By putting in the single space, the SOAP response contains the node, the port recognizes the response, and the port passes the response back to the orchestration.


If someone has more information on this, I’d love to hear it.  At some point, I’d like to sniff out the SOAP response and check my theory, but that’s not going to happen anytime soon.

Use SOAP

First lesson: you don’t need WSE to consume a web service.  Just add the web reference.


Second lesson: if you have a web service that only exposes simple types (e.g., strings), you don’t get a Reference.xsd created when you add the web reference.  Therefore, you can’t use a map to set the values of your web service’s parameters.  You need to use a Message Assignment shape inside a Construct Message shape to set your parameters.  This also means that you have to promote or distinguish any value in your incoming message that you need to pass to the web service.  See my previous post about promoting strings >256 characters.


Third lesson: the Request-Response port that you need should use the SOAP protocol and the PassThru pipelines.


I also found that, if you have the same service on different URLs, the URL that you use to add the web reference to your project can be different from the URL that you use to configure your port.

Question in mail: Do you need assembly language?

From: sandusergiu1984@…
Sent: Friday, August 18, 2006 2:12 AM
To: Eldar Musayev
Subject: (Random Thoughts and Hints on Software Development) : Hello
Importance: High


Hello Eldar, I’ve read somewhere that every developer who want to write great efficient code need to learn assembly language? Is it true? If have time, please, write the answer in the blog. Thank you.


Well, do you? One thing for sure, you will almost never use it at work. In most cases, you will never use it. Period.


Even if you develop hard real-time OS, like I did in the past, you never normally go below straight C.


So, do you need to know assembly language? Normally, I would say “no”, but a few encounters convinced me otherwise. Let me tell you about it.


It was many years ago, I worked for a huge well-recognizable MidWestern manufacturing company. We did software for their dealers, sort of a custom mix of CRM and SCM with a fat Java client (yes, fat, it was supposed to be thin, but over the time it become really, really fat without any sort of rich functionality of thick clients) and C++/C backend on AS/400 (now this midrange machine from IBM is called somewhat differently, but still around). We used DCE (IBM variety and granddaddy of CORBA) and a middleware server to deliver calls from the client to the server. It was a royal pain. Seriously. If something did not work, you started from checking if IDLs on the middleware server are the same as the current build. In 90% of cases, it was not.


So we decided to replace the communication architecture. Me and two other guys were charged with the task. One of them was our lead and – beyond writing the code – took care of selling the idea and pacifying the management. Both were great to work with as well as to have a beer or two after work in a pub across the street which proudly called itself “An Irish Embassy in Peoria”. But enough with memoirs, let’s get back to business.


To send data over network we had to serialize them. Fortunately, the only thing we dealt with were simple structures of primitive types. How do you serialize a simple structure in C/C++, if you are allowed binary serialization? Right, the pointer to the structure is also a pointer to a byte array. That’s it.


On the Java side it was a little more tricky. We had to get them byte by byte from the byte[] array, and push into the individual data fields. Even with IBM library doing a lot of work for us, the picture was complicated with the fact that AS/400 uses Big Endian and alignment (the old concept of always putting a four-byte integer at the address ending with two binary zeros and similar practice for 2- and 8-bytes words to improve the performance). On top of it I used a hack or two of a reliable sort to smooth the things.


And then I had to explain it all to Brandon, because he had to write such code too. He was a bright smart guy, but his first language, unfortunately, was Java, that carefully hides such meagerly details from the developer. Each time I tried to explain it to him, his face went blank. I think that until the first call went through, he firmly believed that I am feeding him with tons of crap to boost my personal ego. And when the first call really came through, it was a shock for him. The world shuttered, turned inside out and showed it’s alien reverse side. It was both exciting and frightening experience for him, like if a person experienced first-hand with his own eyes the bizarre wild dance of elementary particles in a quantum mechanics of everyday things.


Well, he was a bright smart guy, so today he does not have any of such problems anymore, but the experience was painful to both of us. Did I managed to answer the question?


Don’t learn it as a professional language, you are not likely to need it, and even if it does exists somewhere (compiler writers have to deal with it), it’s a niche market. But learn it as a curious puzzle, a toy, figuratively speaking – a way to tinker individual electrons and atoms in your morning cup of hot tea. Not very useful practically, but a completely new level of understanding why you should not spill it on yourself. Makes sense? 😉


 

Delete Byte Order Mark from outgoing messages in Biztalk 2004/2006

A byte order mark is appended to a message when the assembler component or the disassembler component is used to process a message in BizTalk Server. If you use a PassThruReceive pipeline or a PassThruTransmit pipeline, a byte order mark is not appended to a message.

In UTF-16 encoding, a byte order mark is the FE FF byte sequence or the FF FE byte sequence at the start of the encoded string. The FE FF byte sequence indicates that the encoded characters that follow use the big-endian byte order. The FF FE byte sequence indicates that the encoded characters that follow use the little-endian byte order. In UTF-8 encoding, a byte order mark is the EF BB BF byte sequence at the start of the encoded string.

To delete a byte order mark from an outgoing message in BizTalk Server 2006, use a custom pipeline. In the assembler component in the custom pipeline, set the Preserve Byte Order Mark property to False.

To delete a byte order mark from an outgoing message in BizTalk Server 2004, use a custom pipeline. In the custom pipeline, create a custom component that deletes the byte order mark.

Handling incoming data streams in pipeline components in BizTalk Server 2004/2006

When you write custom disassembler code for pipeline components, you must make sure that you do not close the incoming data stream in the custom disassembler code. The incoming stream from the input message is a shared resource. The incoming stream is also used by the message body tracking component in the BizTalk Server message engine.

If you either implicitly or explicitly close the incoming stream, tracking data may be lost. Therefore, you cannot examine the data in the Health and Activity Tracking (HAT) tool in BizTalk Server.

Additionally, you must make sure that you read from the incoming data stream until the end of the stream is reached. For example, if the custom code makes a read request for 300 KB of data and the code only receives 34 KB of data, do not assume that the end of the stream has been reached. The custom code must always read from the incoming stream until 0 bytes is returned.

At the end of a custom pipeline component, make sure that you “rewind” the data stream pointer back to the start of the stream. Typically, you do this just before returning the data stream near the end of the custom component logic. For example, use the following code.

msgDataStream.Seek(0, SeekOrigin.Begin);
return msgDataStream;

If you do not do this and the stream is read to the end in the current component, the next component receives what appears to be an empty stream because the data stream pointer was not rewound. This can cause unexpected parsing and validation errors in follow-on pipeline components.

Summary:
1. Don’t close the stream Implicitly or Explicitly
2. Read till the end of the stream, until 0 bytes is returned.

Persistence Points in Orchestration

The orchestration engine persists the entire state of a running orchestration instance at various points, so that the instance can later be completely restored in memory.

The state includes
1. The internal state of the engine, including its current progress.
2. The state of any .NET components that maintain state information and are being used by the orchestration.
3. Message and variable values.

Persistence Points
The orchestration engine saves the state of a running orchestration instance at various points. If it needs to rehydrate the orchestration instance, start up from a controlled shutdown, or recover from an unexpected shutdown, it will run the orchestration instance from the last persistence point, as though nothing else had occurred. For example, if a message is received but there is an unexpected shutdown before state can be saved, the engine will not record that it has received the message, and will receive it again upon restarting. The engine will save the state in the following circumstances:

1. The end of a transactional scope is reached.
The engine saves state at the end of a transactional scope so that the point at which the orchestration should resume is defined unambiguously, and so that compensation can be carried out correctly if necessary.

The orchestration will continue to run from the end of the scope if persistence was successful; otherwise, the appropriate exception handler will be invoked.

If the scope is transactional and atomic, the engine will save state within that scope.

If the scope is transactional and long-running, the engine will generate a new transaction and persist the complete state of the runtime.

2.A debugging breakpoint is reached.

3. A message is sent. The only exception to this is when a message is sent from within an atomic transaction scope.

4. The orchestration starts another orchestration asynchronously, as with the Start Orchestration shape.

5. The orchestration instance is suspended.

6. The system shuts down under controlled conditions. Note that this does not include abnormal termination; in that case, when the engine next runs, it will resume the orchestration instance from the last persistence point that occurred before the shutdown.

7. The engine determines that the instance should be dehydrated.

8.The orchestration instance is finished.

Serialization
All object instances that your orchestraion refers to directly or indirectly (as through other objects) must be serializable for your orchestration state to be persisted. There are two exceptions:

1. You can have a nonserializable object declared inside an atomic transaction. You can do this because atomic scopes do not contain persistence points.
2. System.Xml.XmlDocument is not a serializable class; it is handled as a special case and can be used anywhere.

Caution In order for a .NET object to be persisted, it must be marked as serializable.

COM Objects
COM objects cannot be persisted using standard .NET serialization procedures. If you want to call a COM object outside of an atomic transaction, you must wrap the COM object in a .NET object that is .NET serializable and knows how to persist and restore the state of the COM object.

Why messages are immutable inside Biztalk?

Most of us know that messages received inside biztalk are immutable, meaning they cannot be modified. If we need to modify the message say for example, if you want to change the price of the product inside the message, then a new message needs to be constructed (Inside orchestration you use Construct, Transform shape etc, inside pipeline you create a temporary stream). So, whats the reason for this immutable message behaviour. Reasons:

1. A received message might have multiple subscribers (orchestration, sendports etc) means each subscriber of a particular message references the same, single copy of that message. So, it make sense the message is not modified by any single service like Orchestration or pipelines.

2. Since single copy is referenced by multiple subscribers, it minimize storage. ( A ref counter is maintained for each message and messages with ref count of 0 are periodically removed.)

3. The concept of messages being immutable also allows for detailed tracking of message state as messages flow through the system.

Tech Eds

Tech Eds

Paul is
having fun at TechEd Australia talking about WF – I am looking forward to doing the
same at TechEd Hong Kong at the end of September (also just looking forward to going
to Hong Kong!).

I hope that the image on this
page
is the speaker “outfit” 🙂

I’ll also be doing two talks on Atlas – should be a blast.

Error – "Identifier expected" when the pipeline is compiling

Explanation

The execution mode value defined for some stage in the policy file is None.
The value None is not available for execution mode, the available values are FirstMatch or All only.

User Action

All pipeline templates have an associated policy file that determines pipeline’s stages,
the number of components allowed per stage, and the execution mode of each stage,
among others. To specify that one stage can not execute components, use minimum and
maximum occurs instead of execution mode.

To resolve this problem is necessary to edit the pipeline’s policy file. The file
name can be found in pipeline’s properties windows in Visual Studio 2005 (see figure
below), this policy file is stored in <Biztalk Server Installation Directory>\Developer
Tools\Pipeline Policy Files
directory.

After the file is opened, you must change the value for execution mode in policy file
to All or FirstMatch.

Changing the execution mode value

The execution mode is represented in the policy file by the execMethod attribute;
it is in the node /Document/Stages/Stage. Open the pipeline’s policy file and
identify where this attribute is with value equals to None and replace it by All or FirstMatch as
we shown:

Before:

<?xml version="1.0" encoding="utf-8"?>
<Document xmlns:xsd="" xmlns:xsi="" CategoryId="" FriendlyName="">
<Stages> <Stage Name="Decode" minOccurs="0" maxOccurs="-1" execMethod="None"></Stage>
</Stages> </Document>

After:

<?xml version="1.0" encoding="utf-8"?>
<Document xmlns:xsd="" xmlns:xsi="" CategoryId="" FriendlyName="">
<Stages> <Stage Name="Decode" minOccurs="0" maxOccurs="-1" execMethod="All"></Stage>
</Stages> </Document>

At last, close and open the pipeline file in Visual Studio 2005 to see these changes
replicated. The following is the explanation step by step.

One way, but not the right way

If you want that one stage can not execute any component, you must setting the
minimum and maximum occurs to 0 for the specific stage or simply delete it from the
policy file. 

CAUTION: if you change any of the following
values, the next pipelines files that you create based on the current policy files
will be affected.

Delete the stage tag

Identify the specific tag, and delete the complete <Stage /> tag from the policy
file.

Setting the minOccurs and maxOccurs to 0

Identify the specific stage and set new values for the minOccurs and maxOccurs attributes
to 0:

Before:

<?xml version="1.0" encoding="utf-8"?>
<Document xmlns:xsd="" xmlns:xsi="" CategoryId="" FriendlyName="">
<Stages> <Stage Name="Decode" minOccurs="0" maxOccurs="-1" execMethod="All"></Stage>
</Stages> </Document>

After:

<?xml version="1.0" encoding="utf-8"?>
<Document xmlns:xsd="" xmlns:xsi="" CategoryId="" FriendlyName="">
<Stages> <Stage Name="Decode" minOccurs="0" maxOccurs="0" execMethod="All"></Stage>
</Stages> </Document>

ps.  this post was published using Windows
Live Writer Beta
.