Orchestration Expression Window Sizeable in BizTalk 2010

8 April 2010

The text below is based on the beta release of BizTalk 2010. It might not (completely) apply to the RTM release.

So what is the greatest new feature in BizTalk 2010? For me it is by far sizeable code window for expression shapes and message assignment shapes in the orchestration designer.

Although this seems like a small improvement it was many times requested and really makes the live of a BizTalk developer easier.

If you follow my blog you might know I wrote the expression maximizer utility a couple of months ago. This was actually a fun project for me to be able to join in the BizTalk tip contest on BizTalk gurus. I must admit though that I use it in my day to day development work.

I’m very excited that Microsoft has a similar feature out of the box. I gives me the same feeling when they added the browse button next for file ports in the admin console in BizTalk 2006 :-) .

The expression window is now a standard visual studio window. This means you can for example dock it into the right pane:

image

But you can also use it in the normal way:

image

and resize it:

image

image

Zooming in the window is also possible. Handy if you need to do a demo:

image

Cool! Thank you Microsoft!


Untyped messages and Business Rules Engine (part 2)

4 March 2010

This is a follow up post to my previous post on this topic. The method described in that post doesn’t seem to work when the policy is called from an orchestration. For more background information see this blogpost.

I this post I will use the exact same sample as in the previous post. These are the schemas used:


<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns:b="http://schemas.microsoft.com/BizTalk/2003"

xmlns="http://UntypedBRE.FirstSchema"
targetNamespace='http://UntypedBRE.FirstSchema'

xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="FirstSchema">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="FirstName" type="xs:string" />
        <xs:element name="LastName" type="xs:string" />
        <xs:element name="IsJohn" type="xs:string" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

 

<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns:b="http://schemas.microsoft.com/BizTalk/2003"
xmlns="http://UntypedBRE.SecondSchema"
targetNamespace='http://UntypedBRE.SecondSchema'
xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="SecondSchema">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="FirstName" type="xs:string" />
        <xs:element name="LastName" type="xs:string" />
        <xs:element name="IsJohn" type="xs:string" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

 


<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns:b="http://schemas.microsoft.com/BizTalk/2003"

xmlns="http://UntypedBRE.ThirdSchema"
targetNamespace='http://UntypedBRE.ThirdSchema'

xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="ThirdSchema">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="FirstName" type="xs:string" />
        <xs:element name="LastName" type="xs:string" />
        <xs:element name="IsJohn" type="xs:string" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

In my sample policy I want to check the ‘FirstName’ element. If the value is equal to ‘John’ I want to fill the ‘IsJohn’ element with value ‘yes’. The policy (and single rule) should work for all the above schemas.

The problem is that mentioned schemas belong to a different namespace and have a different rood node, hence in BizTalk terms have a different message type. Because XML schemas facts in the BRE are by default tightly coupled to a specific schema the consequence is that those facts can only operate on a single type of message.

In order to make this generic you have to do the following:

1. Add one of the schemas to the Facts Explorer in the BRE

image

2. Make the schema general

As you can see the Document Type resembles the type of the schema I added. To make this generic I change this value to ‘Microsoft.XLANGs.BaseTypes.Any’. This will make sure that if I use a fact from this schema in a rule it will not be typed to this schema but will be generic:

image

3. Create the rule

In this step I create the rule. The facts will be filled in later.

image

4. Modify the XML facts

In the rule I need to evaluate the ‘FirstName’ fact and optionally set the ‘IsJohn’ fact. Because I want this to work on all schemas I need to define the facts in a generic way. If I click on the ‘FirstName’ fact I can see the xpath statements that point to this fact in the property pane:

image

The ‘Xpath Field’ and ‘Xpath Selector’ properties are directly referring to ‘FirstSchema’ root node and namespace. I change the values to make them generic also:

image

Note that I’m using ‘self::node()’ here. I described this trick before here.

Now the XML fact is no longer pointing to a specific namespace or root node. It just points to a ‘FirstName’ node somewhere in Xml message.

There are of course other possible values for ‘Xpath selector’ and ‘Xpath Field’ to solve this. It all depends on the schemas. If for example the facts you need all have the same parent node you can make the ‘Xpath selector’ select the parent node and the ‘Xpath Field’ select the ‘FirstName’ element.

I do the same for the fact I want to update in the action of the rule:

image

5. Complete the rule by adding the facts

Finally I can drag the XML facts from the Facts Explorer to my rule to complete the condition and create a new action. Like this:

image

You can see that the both the condition and the action are not referring (anymore) to any specific schema  but instead to any schema that has ‘FirstName’  and ‘IsJohn’  elements.

Testing the rule with instances from two different schemas shows that this works:

image

image

One thing to note about this is that the way I changed the xpath statements for the Xml facts comes with a performance penalty. Using things like ‘//*…….’.  will make the engine go through the whole xml tree which is less efficient then using the original full xpath statement. So if performance is a strict requirement be careful using techniques like these.

Another thing is that I do not check for the existence of the nodes first. The policy will crash when an message is processed that does not contain on of the nodes used in the rule.


ExpressionMaximizer

30 October 2009

A bigger expression shape window is a feature that almost always appears on “next version of BizTalk wish lists”.

Every time Microsoft releases a new version of BizTalk we are all very disappointed that they did not make the expression window resizable or at least bigger.

There are rumors that this is done to discourage developers to write a lot of code in those windows and move to external assemblies with helper classes instead.

Although I agree with that I still think it would be very nice to have a bigger window occasionally.

Like the “Orchestration Variable Retriever Functoid” this was on my “experimental things to do list” for a long time. I never had or took the chance to try it until BizTalk king Stephen W. Thomas announced his competition for the best BizTalk tip or trick.

Of course I want to join this competition so I started coding. Now that it is finished I must admit it has become quite a hack but it seems to work :-) .

Anyway the “ExpressionMaximizer” will be my entry for the competition.

A quick walkthrough:

I have an orchestration with an expression shape containing a lot of code:

orchestration

I double click the expression shape to open it (in normal mode):

normal_expressionwindow

With expression window still open I press CTRL+SHIFT+ALT+M (nice key combination :-) ) and ……:

maximized_expressionwindow

I have a big expression window where I can type many long lines of code!!!!

Everything is back to normal when you close the window and open it again.

Note that you first have to open the expression shape before pressing the key combination.

Want to try it yourself?
(description below is based on Visual Studio 2008)

- Download this zip file and extract it somewhere.
- Click ‘Tools’ –> ‘External Tools…’
- Press the ‘Add’ button
- Type a title, e.g. ‘Expression Window Maximizer’
- Fill in the command text box by browsing to the extracted ‘ExpressionMaximizer.exe’

ExternalTools

- Press the ‘OK’ button
- Select ‘Tools’ –> ‘Customize…’
- Press the ‘Keyboard…’ button
- In the ‘Show commands containing:’ text box type ‘Tools.External’
- Select the correct ‘Tools.ExternalCommandX’ from the list. (You need to find out the correct entry by counting the external tools in the Tools menu).
- Click in the text box ‘Press shortcut keys:’ to set the focus to it.
- Press CTRL+ALT+SHIFT+M
- Click the ‘Assign’ button.

Customize

- Press the ‘Ok’ button.
- Press the ‘Close’ button.

I tried this on ‘Windows Server 2008 R2/VS2008′ and ‘Windows Server 2003 R2/VS2005’ without problems but I still take no responsibility for malformed windows or other disasters :-) After all it is a big hack!

If you’re interested you can find the (VS2008) source code here.


Was promoted

15 June 2009

Ever wanted to know in a send pipeline if a property was promoted before? The BizTalk API comes with an object called ‘ContextPropertyType’ which you can use for this purpose.

I have a very simple schema and corresponding instance:

waspromoted_schema

waspromoted_schema_instance

Above message travels through BizTalk using the following path:

receive port -> orchestration -> send port

I defined the ‘Firstname’ element as promoted property to have it promoted by the out-of-the-box XmlReceive pipeline. After that the message is sent to the message box and picked up by the orchestration to do some processing. Next the orchestration will send the message to the message box again using a send shape. Finally the send port picks up the message and sends it to some URI using an adapter.

In the send port I used a custom pipeline containing a pipeline component with this code:

waspromoted_code

 After the message has been picked up by the send port the messaging engine will alter the context of the message. The ‘Firstname’ element that was promoted before is not promoted anymore now. To prove this I call the IsPromoted method for the specific property (see code above).

So what if you want to know if the property was promoted before? This is where the ContextPropertyType object comes in. Together with the ‘GetPropertyType’ method on the context object I’m able to find the status of the property.

Running this example shows the following output in DebugView:

waspromoted_debug_view

 As you can see the PropertyType has a value equal to ContextPropertyType.WasPromoted. In the above sample I used an orchestration in the middle but the same will also apply to messaging only scenarios.

Although I recently made use of this API while implementing a very simple repair and resubmit feature, there might not be so many real world scenarios where one would use this. At least I couldn’t think of many. (Suggestion? Ping me, please.).  Also be aware that is an undocumented feature for which the BizTalk help states it is for internal use only. This basically means Microsoft will not guarantee any backward compatibility for this when new versions or SPs are released.


Orchestration variable retriever functoid (and why you should not use it)

5 April 2009

This week I spend some time on writing a functoid that retrieves the value of a variable in an orchestration. Lets take a look on the functoid’s usage first.

Usage

This is the declaration of a string variable ‘lastName’ in a very simple test orchestration:

image

This is the expression shape where the value of that variable is set to my last name:

image

This is the map that is executed using a transform shape right after the expression shape above. The map contains the variable retriever functoid. It has one parameter that takes the name of the variable to fetch.

Please pay special attention to the icon because that bloody thing took me 50% of the development time. The result shows why I try to stay away from UI development as much as possible. :-)

image

Finally this is the Xml message returned from the orchestration via the file adapter.

image

Disadvantages

At first I was a little excited that I got this working. I did some testing with different orchestrations and it seems to work OK. After a while (and thinking this over) my excitement was tempered because I think the functoid has three big disadvantages:

  1. Although questions related to this popup regularly in the BizTalk newsgroups I could not think of any real world examples. The sample above could also be implemented by using a message assignment shape after the map. In the message assignment shape the value of the variable can be assigned using xpath, properties or distinguished fields. The only way the functoid can be useful is when you need an orchestration variable value in a map to do some processing while the actual value is not mapped to the destination schema. But then again there are other ways to implement that. (Using a helper message and a multi message map). 
  2.  The functoid code contains a considerable amount of reflection code. I didn’t do any performance tests but it is obvious that reflection comes with a cost. So in terms of performance it will probably be much better  to use alternative methods.
  3.  This is probably not supported by MS. Mainly because it uses XLANG code which is normally hidden from the developers. 

These disadvantages make me conclude that this functoid is not very useful in real world scenarios. I really want to know what others think about this. So whether you agree or don’t agree please share your thoughts on this!

The other way around

Now that I figured out a way to access a variable it is a small step to take this a little further and build a functoid that WRITES the value of a variable in an orchestration. I didn’t implement such a functoid because of above mentioned points. I also think writing, as opposed to, reading is very tricky because you need to take things like serialization and locking into account.

If your still not convinced that you should not use this you can download the functoid “dll” from here.

Installation instructions:

  • copy the .dll to the ‘Mapper Extensions’ folder which resides in the BizTalk installation folder.
  • put the .dll in the gac.
  • Open a map in Visual Studio, click right in the toolbox area and choose the functoids tab.
  • Browse the the functoid dll in the ‘Mapper Extensions’ folder to add it to the toolbox.

The source is also available here. It is build using BizTalk 2006 R2.