Setting the filename in send port (post number:1023054)

2 November 2010

This is probably the most blogged topic in the BizTalk community but I hope my attempt still adds something.

Let’s start with some simple questions:

Question1:
What syntax do you need to use to access the filename of a message you received using the file adapter in an orchestration?

In an expression shape you use something like this:

myVariable = myMessage(File.ReceivedFileName);

Question 2:
Ok, that one was easy! Now the same question for the a message received using the FTP adapter?

Again in an expression shape use:

myVariable = myMessage(FTP.ReceivedFileName);

Question 3:
Ok, makes sense. So what do you need to do when you wan to set the filename for a message that you send out using the file adapter?

Easy, two steps needed:

1). Set the filename property in the send port to use the macro %SourceFileName%.
2). Set the context property in the orchestration to the filename you want to use, like this:

myMessage(FILE.ReceivedFileName) = “MyFileName.xml”;

The file adapter will replace the macro with the value of the context property.

Question 4:
Last question; Same question for the FTP adapter. How do you set the filename for a message that you want to send out using the ftp adapter?

myMessage(FTP.ReceivedFileName) = “MyFtpFileName.xml”;

Wrong!!!!!!!! you also need to use the same syntax as with the file adapter:

myMessage(FILE.ReceivedFileName) = “MyFtpFileName.xml”;

This is something I encountered during development last week. I think this is a little confusing. It took me a while to find out what happened here. Also, by searching the internet, if found out this seems to confuse more people.

I think the idea behind this is an attempt to make an orchestration adapter agnostic and to create an abstraction layer between the logical process (orchestration) and the adapters which are bound to a certain technology or protocol. So whether you use the file or FTP adapter it is always ‘FILE.ReceivedFileName’ you need to use. This idea is good but my remarks are:

- This works different for receive side which makes it a little inconsistent.
- The word ‘FILE’ is (at least in my head) directly connected to the file adapter. The abstraction would be more clear if some other term was used.

Confusing!


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.


Follow

Get every new post delivered to your Inbox.