suneet's profileSuneet's SpaceBlogLists Tools Help

Blog


    July 14

    Moving blog home

    I have now moved on to my own space at http://www.suneet.net
     
    See you there! :)
    May 09

    "IsSensitive" property in Property Schema

    Well, I tried using this property "IsSensitive" and found out that Biztalk essentially doesn't show this as an option while tracking the properties. But when you save the message context from HAT it does show you the value for that property. Quite strange.
    March 16

    MCTS Exam 70-235 Questions/Topics I Suggest

    Well, let me put it in this way. I am writing down whatever stuff I remember from the exam 70-235-
     
    1. There were questions about TPE and BAM. Like Why TPE is used and what should you do if dont see BAM view in portal. Also, there were questions about BM.exe tool
     
    2. There were many questions about BTSTask.exe which is a new util in BTS 2006 replacing many features in BTSDeploy.exe.
     
    3. There were no questions on SSO and HWS.
      
     
    I will keep it this entry running and will add up as and when I recall. Any particular questions, ping me on mail.
     
    Overall, exam wasnt that tough as I expected it to be.
    February 28

    Looking at deployed Message Types

    Ever wondered how to check in particular message type is deployed in Biztalk or not??
    Simple way to check it is-
     
    1. Open SQL Server Query Analyser
    2. Use BiztalkMgmtDB
    3. Run the query "Select * From bt_DocumentSpec"
     
    This is result in listing of all the message types deployed on Biztalk Server currently. Column "msgType" shows all the message types deployed.
    November 27

    How to see the code for dlls [Orchestrations] created in Biztalk

    Just a quick one here...
    Ever wondered if you could see the code which turns into Dll by compiling orchestration in Biztalk. Here is the quick way showing how you can achieve it.
     
    Giving you a background, XLang engine creates the .cs files for the orchestration and then calls csc compiler to create dlls. We will tweak the registry to see these .cs files which Xlang engine creates.
     
    Add a registry key named BizTalkProject at HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\8.0 for Visual Studio 2005. If you are using BizTalk 2004 and Visual Studio .NET 2003, the key is HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\7.1. Next, create a DWORD value named GenerateCSFiles and set it to 1.
     
    If you rebuild your project, you will see C# files in your project directory.
     
    November 25

    Using Bizunit 2.0 for unit testing BizTalk 2006 solutions

    So you have developed a Biztalk solution. Great job, but did you test your solution for load and spikes? Mixed answers are expected... nevermind. Lets see how we can use BizUnit 2.0 along with NUnit 2.0.2.2.8 to do the above in most automated manner. I would say thanks to Kevin for developing BizUnit 2.0.
     
    Understanding the big picture...
    You create managed dll containing class which is having methods decorated with specific attributes. These attributes defines what the methods will do in NUnit. You compile the project and place the dll in the directory of NUnit project. Open the dll in NUnit and it will show you the methods which you decorated there in GUI. You also have config files which are specified in methods above. These config files actually tells NUnit what steps to perform while running tests by calling the methods you defined.
     
    I would not show you how to create simple BTS project for message processing, instead I would show you the way you would create unit testing blocks i.e bizunit driver class, config files etc.
     
    Step 1. Creating BTS project-
    I am not creating BTS project as this would be diverting you from the topic. What you need to have is-
    Biztalk application which take file from receive location and places the file in another location or do whatever with it.
     
    Step2. Creating NUnit driver DLL-
    This is where we start actual BizUnit work.
     
    You create a library project in vs.net and create the class as below-
     
    using System;
    using System.Collections.Generic;
    using System.Text;
    using Microsoft.Services.BizTalkApplicationFramework.BizUnit;
    using NUnit.Framework;

    namespace BizUnitDriver
    {
        [TestFixture]
        public class BizUnitDriver
        {
            //This is attribute is used to tell Nunit to run this method as setup for the test for firstime only in a single run.
            [TestFixtureSetUp]
            public void SetUp()
            {
                BizUnit bu = new BizUnit(@"C:\BTSLocations\ProBTSCrap\BizunitSetup\ValidLoad.xml", BizUnit.TestGroupPhase.TestGroupSetup);
            }
     
            //This is attribute is used to tell Nunit to run this method as one of the tests. This will appear in NUnit GUI.
            [Test]
            public void ValidLoad()
            {
                BizUnit bu = new BizUnit(@"C:\BTSLocations\ProBTSCrap\BizunitSetup\ValidLoad.xml");
                    bu.RunTest();
             }
            
        }
    }
     
    You will need to use the namespace using "Microsoft.Services.BizTalkApplicationFramework.BizUnit" and using "NUnit.Framework" which are defined in dll "C:\Program Files\Microsoft Services\BizUnit 2.1\bins\Microsoft.Services.BizTalkApplicationFramework.BizUnit.dll" and "C:\Program Files\NUnit-Net-2.0 2.2.8\bin\nunit.framework.dll" respectively.
    Please see my comments in the methods above for understanding.
     
    Step3. Creating configuration file for NUnit to run steps in the test-
     
    This file is configuration for NUnit to run the steps in test defined by the method we decorated with "[Test]". How NUnit recognize that this is the config which it has to read for running the test? This is via the config file specified in method by "BizUnit bu = new BizUnit(@"C:\BTSLocations\ProBTSCrap\BizunitSetup\ValidLoad.xml");". So ideally one file makes one test case. Now lets see how it looks like...
     
    <TestCase testName="ProcessPOTest">
    <TestSetup>
    <TestStep assemblyPath="" typeName="Microsoft.Services.BizTalkApplicationFramework.BizUnit.HostConductorStep">
        <Action>stop</Action>
        <HostInstanceName>BiztalkServerApplication</HostInstanceName>
    </TestStep>
    <TestStep assemblyPath="" typeName="Microsoft.Services.BizTalkApplicationFramework.BizUnit.HostConductorStep">
        <Action>start</Action>
        <HostInstanceName>BiztalkServerApplication</HostInstanceName>
    </TestStep>
    </TestSetup>
    <TestExecution>
        <TestStep assemblyPath="" typeName="Microsoft.Services.BizTalkApplicationFramework.BizUnit.FileCreateStep">
            <SourcePath>C:\BTSLocations\ProBTSCrap\BizunitSetup\InputFiles\PO.xml</SourcePath>
            <CreationPath>C:\BTSLocations\ProBTSCrap\In\PO_001.xml</CreationPath>
        </TestStep>
    </TestExecution>
    <!-- Test cleanup: test cases should always leave the system in the state they found it -->
    <TestCleanup>
    </TestCleanup>
    </TestCase>
    This is probably the simplest form of it and essentially it only stops and starts the host as setup of test and then executes the test steps in <TestExecution> section.
     
    Explained-
     
    <TestSetup> tag tells the NUnit to executes the steps in it in the beginning of the test case once only. I am restarting host instance in above case.
    <TestExecution> tag tells the NUnit to execute the steps in it as test case steps. I am placing the file in pick folder of BTS for execution in our case.
    <TestCleanup>tag tells the NUnit to perform it after test case has run. You can write any script which you like to execute as a cleanup tasks. I am not using it currently.
     
     
    Step4. Using the NUnit driver dll in NUnit-
     
    This is trivial step. What you need to do is-
    1. Compile the driver project.
    2. Copy the generated Dll and paste it in the NUnit project directory.
    3. Open this dll in NUnit and NUnit will show you something like below.
    4. Select the "ValidLoad" test case and press "Run". [Notice the name of test case here "ValidLoad", which is the name of decorated method in driver class]. This will use the config file we specified in this method.
    5. See the result in BTS and in "Console.out" tab window.

    I would recommend reading chm file for BizUnit which you get when you install it for detailed config file and driver dll features...

     

    November 17

    Using SSO as configuration store

    There are ways you can store your configuration for Biztalk components[pipeline components etc] or otherwise. Some of the popular ones are storing it in app.config or app.exe.config file of BTSNTSvc.exe service. Another option could be to create your own config getter/setter infrastructure and use it in your code.
    The otherway and the better way would be to use the same technique which BTS uses itself to store configuration of its components. This is done using SSO as configuration manager.
     
    There  are couple of benefits of this approach. One, you dont have to code the DB or IO logic to access or update configuration. Two, your configuration is secured and only avialable to the configured group. Three, all caching and optimizations comes along with the package.
     
    Mind it, you 'll be accessing COM libraries to access Biztalk SSO configuration. You will need to add refrence to the dll called "Microsoft.BizTalk.Interop.SSOClient.dll" which resides in "C:\Program Files\Common Files\Enterprise Single Sign-On" depending upon your installation.
     
    you will be using some of the types defined in this dll for manipulating SSO configuration.
     
    Step1. Lets start with creating application in SSO to store your configuration.
     
    ISSOAdmin ssoa = new ISSOAdmin();
    ssoa.CreateApplication("AppName", "Test Configuration Data", "suneetmohan@gmail.com", @"Domain\UserGroup", @"Domain\ManagerGroup",SSOFlag.SSO_FLAG_APP_CONFIG_STORE|SSOFlag.SSO_FLAG_APP_ALLOW_LOCAL,2);
     
    //User ID
    ssoa.CreateFieldInfo(AppName, "AnyUserId", SSOFlag.SSO_FLAG_FIELD_INFO_SYNC);
        
    //Credential 1
    ssoa.CreateFieldInfo(AppName, "Prop1", SSOFlag.SSO_FLAG_FIELD_INFO_SYNC);
     
    //Enabling the application...
    ssoa.UpdateApplication(AppName, null, null, null, null, SSOFlag.SSO_FLAG_ENABLED, SSOFlag.SSO_FLAG_ENABLED);
     
    Step2. Create and save configuration you need to store. Probably some XML.
     
    ISSOConfigStore store = new ISSOConfigStore();  
    ConfigurationPropertyBag pb = new ConfigurationPropertyBag();
    string val1 = "<config>This is dummy config</config>";
    object obj1 = val1;
    pb.Write("Prop1",ref obj1);
    store.SetConfigInfo("AppName", "{F07D8E15-C861-40DE-985E-C71E383844D5}",pb);      
     
    Step3. Reading configuration from SSO
     
     ISSOConfigStore store = null;   
     store = new ISSOConfigStore();
     ConfigurationPropertyBag localPropertyBag = new ConfigurationPropertyBag();
     
     store.GetConfigInfo(AppName, "{F07D8E15-C861-40DE-985E-C71E383844D5}", 0, (IPropertyBag)localPropertyBag);
     
     object pvar;
     localPropertyBag.Read("Prop1",out pvar,0); //pvar will have the configuration after this statement executes.
     
    Step4. Finally if you want, you can remove the application
     
    ISSOAdmin ssoa = new ISSOAdmin();
    ssoa.DeleteApplication("AppName");
     
    Step5. Defining PropertyBag class
    ConfigurationPropertyBag class used in this code is standard propertybag class implementing "IPropertyBag" interface defined in the same dll.
    Here is the code in case you need.
     
    class ConfigurationPropertyBag : IPropertyBag
    {
     Hashtable _ht = new Hashtable();
     public void Write(string propName, ref object ptrVar)
     {
      _ht.Add(propName,ptrVar);
     }
     public void Read(string propName, out object ptrVar, int errorLog)
     {
      ptrVar = null;
      ptrVar = _ht[propName] ;
     }
    }
     
     
    I would suggest you to read about SSO at MSDN to get fair idea about whats going on in the above code in case you dont understand the code.
    November 06

    Using static methods in business rules [BTS 2006]

    There is general myth that method call can be made only on the objects passed as facts to the rule. In BTS 2006 [also, in BTS 2004 after some tweaking] you can used static methods [not passed as facts] directly in rules which can either be evaluated at rule translation time or execution time depending on the configuration.
     
    This requires a bit of tweaking in the registry [you can use config file also to have the same affect].
    Please follow the steps below for the same-
  • Click Start; click Run, type RegEdit, and then click OK.
  • Expand HKEY_LOCAL_MACHINE, expand Software, expand Microsoft, expand BusinessRules, and then select 3.0.
  • In the right pane, right-click, point to New, and then click DWORD value.
  • For Name, type StaticSupport.
  • For Value, choose from below-
      • 0 - This is the default value of the key and this value mimics the behavior of BizTalk Server 2004 where an instance of an object is always required as an input fact, and the method is only called when the rule is evaluated or executed.
      • 1 - An instance of the object is NOT required, and the static method is called whenever the rule is evaluated or executed
      • 2 - An instance of the object is NOT required, but the static method will be called at rule translation time (only if the parameters are constants). This value is primarily meant as a performance optimization. However, note that static members used as actions will NOT be executed at translation time, but static methods used as parameters may be executed.
    You can choose option 1 or 2 depending upon your performance and data change trade-off requirements.
    Lets see the quick example here-
     
    Step1-
    Create static method-
     
    namespace PeakPriority
    {
        public class Priority
        {
            public static int GetPriority()
            {
                //apply some logic here
                return 4;
            }
        }
    }
     
    Step2-
    Create fact class-
     
    namespace PeakPriority
    {
       public class FactClass
        {
            private int _priority;
            public int Priority
            {
                get { return _priority; }
                set { _priority = value; }
            }
            private int _orderID;
            public int OrderID
            {
                get { return _orderID; }
                set { _orderID = value; }
            }
        }
    }
     
    before proceeding to next steps, please GAC the above classes.
     
    Step3-
    Create vocabulary and policy in business rule composer-
     
    You can create the normal vocabulary here, only point to remember is that now you can also select static method while creating .Net Class Or Class Member defination.
     
    In the below screen shot I have created the "Priority" defination as static method from GetPriority method of Priority class defined above.
     
     
     

    Step4-
    Create caller in C#
     
    Use the code below for console application to run the policy.
     
     static void Main(string[] args)
            {
                Policy pl = new Policy("POPolicy");
                FactClass fc = new FactClass();
                fc.OrderID = 2356;
                pl.Execute(fc);
                Console.WriteLine(string.Format("Priority is: {0}",fc.Priority.ToString()));
                Console.Read();
            }
     
    The above code requires the ref to Microsoft.RuleEngine namespace in Microsoft.RuleEngine.dll
    October 17

    Error Handling Pattern in Biztalk

    Error handling is a sort of confusing problem in Biztalk... whether exception or compensation??? Here is the simple pattern that works on Error Handling...
     
    1. Create the status string as variable for the long running scope.
    2. Update this string at each expression shape in orchestration.
    3. Append <.net Exception> exception shape and select type as System.Exception
    In this shape log the status string and exception message to the log file or event log
    4. Append second <generic Exception> shape after the above one.
    In this shape log the status string only as exception object is not aviable in this shape. This shape will only be executed in remote cases where exception is not caught by <.net Exceptoin> shape.
    Please post your comments for clarifications.
    October 16

    Envelope Processing with SQL Adapter

    I was working on SQL adapter as poller to SQL Server 2000. Following below explains the scenario as in how to use it-

     

    Step 1. Create Document Schema

    In my case i created a schema for message in a batch. Value in "Body XPath" property of schema root node should point to the tag which will have envelope contents [messages].

    It looks like below-

    Schema-

       <?xml version="1.0" encoding="utf-16" ?>
      <xs:schema xmlns:ns0="http://Somecompany.Ordering.POSIntegration.Schemas.POSIntegrationPropertySchema" xmlns="http://Somecompany.Ordering.PosIntegration.Schemas.PETPaymentRefund" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" targetNamespace="http://Somecompany.Ordering.PosIntegration.Schemas.PETPaymentRefund" xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <xs:annotation>
      <xs:appinfo>
      <b:imports xmlns:b="http://schemas.microsoft.com/BizTalk/2003">
      <b:namespace prefix="ns0" uri="http://Somecompany.Ordering.POSIntegration.Schemas.POSIntegrationPropertySchema" location="Somecompany.Ordering.PosIntegration.Schemas.PosIntegrationPropertySchema" />
      </b:imports>
      </xs:appinfo>
      </xs:annotation>
      <xs:element name="PET_PAYMENT_REFUND">
      <xs:annotation>
      <xs:appinfo>
      <b:properties>
      <b:property distinguished="true" xpath="/*[local-name()='PET_PAYMENT_REFUND' and namespace-uri()='http://Somecompany.Ordering.PosIntegration.Schemas.PETPaymentRefund']/*[local-name()='Header' and namespace-uri()='']/@*[local-name()='IsPayment' and namespace-uri()='']" />
      </b:properties>
      </xs:appinfo>
      </xs:annotation>
      <xs:complexType>
      <xs:sequence>
      <xs:element form="unqualified" name="Header">
      <xs:complexType>
      <xs:attribute name="TransactionId">
      <xs:simpleType>
      <xs:restriction base="xs:string">
      <xs:maxLength value="40" />
      </xs:restriction>
      </xs:simpleType>
      </xs:attribute>
      <xs:attribute name="OrderId">
      <xs:simpleType>
      <xs:restriction base="xs:string">
      <xs:maxLength value="32" />
      </xs:restriction>
      </xs:simpleType>
      </xs:attribute>
      <xs:attribute name="IsTest">
      <xs:simpleType>
      <xs:restriction base="xs:boolean" />
      </xs:simpleType>
      </xs:attribute>
      <xs:attribute name="TransactionTimestamp">
      <xs:simpleType>
      <xs:restriction base="xs:dateTime" />
      </xs:simpleType>
      </xs:attribute>
      <xs:attribute name="ShipmentId">
      <xs:simpleType>
      <xs:restriction base="xs:string">
      <xs:maxLength value="32" />
      </xs:restriction>
      </xs:simpleType>
      </xs:attribute>
      <xs:attribute name="StoreId">
      <xs:simpleType>
      <xs:restriction base="xs:string">
      <xs:maxLength value="13" />
      </xs:restriction>
      </xs:simpleType>
      </xs:attribute>
      <xs:attribute name="Marketplace">
      <xs:simpleType>
      <xs:restriction base="xs:string">
      <xs:maxLength value="1024" />
      </xs:restriction>
      </xs:simpleType>
      </xs:attribute>
      <xs:attribute name="IsPayment">
      <xs:simpleType>
      <xs:restriction base="xs:boolean" />
      </xs:simpleType>
      </xs:attribute>
      </xs:complexType>
      </xs:element>
      <xs:element form="unqualified" name="Body" type="xs:string" />
      </xs:sequence>
      </xs:complexType>
      </xs:element>
      </xs:schema>

     

    Intance-

    <ns0:PET_PAYMENT_REFUND xmlns:ns0="http://Somecompany.Ordering.PosIntegration.Schemas.PETPaymentRefund">
      <Header TransactionId="TransactionIdTransactionIdTransactionIdT" OrderId="OrderIdOrderIdOrderIdOrderIdOrde" IsTest="true" TransactionTimestamp="1999-05-31T13:20:00.000-05:00" ShipmentId="ShipmentIdShipmentIdShipmentIdSh" StoreId="StoreIdStoreI" Marketplace="MarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceMarketplaceM" IsPayment="true" />
      <Body>Body_0</Body>
      </ns0:PET_PAYMENT_REFUND>

     

     

    Step 2. Create Envelope Schema

    In my case I created a schema for envelope [batch] which looks like-

     

    Schema-

      <?xml version="1.0" encoding="utf-16" ?>
     <xs:schema xmlns="http://schemas.somecompany.com/biztalk/pos/genericenvelope" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://schemas.somecompany.com/biztalk/pos/genericenvelope" xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <xs:annotation>
     <xs:appinfo>
      <b:schemaInfo is_envelope="yes" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" schema_type="document" />
      </xs:appinfo>
      </xs:annotation>
     <xs:element name="GenericEnvelopeWrapper">
     <xs:annotation>
     <xs:appinfo>
      <b:recordInfo body_xpath="/*[local-name()='GenericEnvelopeWrapper' and namespace-uri()='http://schemas.somecompany.com/biztalk/pos/genericenvelope']" />
      </xs:appinfo>
      </xs:annotation>
     <xs:complexType>
     <xs:sequence>
      <xs:any namespace="Http://DummyNameSpace" processContents="skip" />
      </xs:sequence>
      </xs:complexType>
      </xs:element>
      </xs:schema>

     

    Intance-

    <ns0:GenericEnvelopeWrapper xmlns:ns0="http://schemas.somecompany.com/biztalk/pos/genericenvelope">
      <any0 xmlns="Http://DummyNameSpace">anyContents0</any0>
      </ns0:GenericEnvelopeWrapper>

     

    Point to be noted is that in normal envelope processing scenrios, envelope with messages in it is provided from source system. Here, envelope doesnt come from SQL Server [source system]. It is created by SQL adapter with configuration given below. 

    Sample XML generated after SQL adapter would look like-

     

    <ns0:GenericEnvelopeWrapper xmlns:ns0="http://schemas.somecompany.com/biztalk/pos/genericenvelope">
    <ns0:PET_PAYMENT_REFUND xmlns:ns0="http://Somecompany.Ordering.PosIntegration.Schemas.PETPaymentRefund">
    <Header TransactionId="TransactionId1" OrderId="OrdrId1" IsTest="0" TransactionTimestamp="1999-05-31T18:20:00" ShipmentId="Ship1" StoreId="Store1" Marketplace="MPlace1" IsPayment="true"></Header>
    <Body>Any data here</Body>

    </ns0:PET_PAYMENT_REFUND>

    </ns0:GenericEnvelopeWrapper>

     

    Notice the envelope tag and its namespace and relate it to SQL Adapter config below.

     

    Step 3.  SQL Adapter has configuration [Its not complete, only important nodes are shown] -

    Document Root Element Name : GenericEnvelopeWrapper

    Document Target Name Space : http://schemas.somecompany.com/biztalk/pos/genericenvelope

    Sql Command : EXEC uspMsgReplay_SoapFault 'http://Somecompany.Ordering.PosIntegration.Schemas.PETPaymentRefund', 20

     

    Flow Explained-

    1. Two messages are returned by SQL Stored Proc.

    2. Messages arrive at SQL Adapter.

    3. SQL adapter places them in envelope.

    This is done due to the configuration [root element name and target namespace ] of SQL adapter.

    4. Envelope then moves to the pipeline.

    5. XML dissassembler then pulls out the messages from envelope.

    Xml dissasembler get to know about it from the envelope schema deployed in biztalk. [Body Xpath property of envelope schema to be precise]

     

    Problem faced-

    XML coming from SQL Server Stored Proc was having <Header> and <Body> child nodes. When XML dissassebler pulls out the message from Envelope, it places the 'xmlns = http://schemas.somecompany.com/biztalk/pos/genericenvelope ' attribute in the above specified tags. This changes the namespace of these tags and hence fails the orchestration logic. To resolve this, please place blank 'xmlns=""' attribute in each tag generated by stored proc. This step makes sure that dissassembler doesnt put envelope's namespace in these tags.

     

    Benefit-

    The main benefit here I see is batching of messages from SQL Server... multiple round trips to SQL server are saved and batch size of messages to be pulled from SQL can be specified in SQL Command of SQL Adapter as Stored Proc parameter.

     

     

    October 14

    Promoting Properties Inside Orchestration

    I was facing problem while trying to promote property in contex within orchestration. Searched on the net but could get any direct solution to it. Finally there I get to know about the trick which can be used to promote properties within orchestration. Here you go...
    the problem of promoting context properties:
    When you create a context property, not based on a message field, and you assign a value inside an orchestration, it is written, but not promoted. What does it means? it means that you cannot route the message based on this property.
    Some days ago I had the situation where needed exactly this: content based routing based on a custom context property that had a value calculated inside an orchestration.
    A common solution is to create a custom pipeline component that writes and promotes properties. Jon Flanders has created a good generic component to do this: the ContextAdder Pipeline Component.
    the trick:
    In my case, the pipeline solution is not an option, since I’m routing between orchestrations via Direct Port Binding. Also, coding a custom component to promote a property seems to complex for me…
    Somebody told me a good trick to promote context properties inside an orchestration, easy and direct:
    Create a CorrelationSet based on the property.
    Even if you are not going to use it, when you initialize a CorrelationSet, the Orchestration engine makes the promotion of the properties involved, since correlation is just an special kind of routing.
    So now I have some dummy CorrelationSets, that I call <Property>Promote_CorrelationSet
     
    This excerpt is from David Hurtado's Integration Traces Blog.