Showing posts with label Orchestrations. Show all posts
Showing posts with label Orchestrations. Show all posts

Monday, 13 June 2011

Using Parties and RoleLinks to dynamically route a message to a destination (BizTalk 2010)

Configuring and Using Parties, RoleLinks in BizTalk a huge concept.
This post will show you simple steps in Using Parties and RoleLinks to dynamically route a message to a different destination.


Example Scenario:


Consider you receive a message from some sources. This message has a node called Name. Based on the value of Name node, you have to route the message to that party. Each party saves the message to a different folder using FILE Adapter.


Sample:


1. Create an empty BizTalk Solution. Add a schema with two nodes ID and Name. For simplicity make both nodes as Distinguished Fields.



2. Add an orchestration to the solution and a receive Shape to it, to receive a message of the Type Schema1 created in step1.



3. Right Click the Port Surface and add a new RoleLink to it.



4. Follow the Wizard. Give the RoleLink a suitable name and Create a new Role Link Type. In the Last Step, select the Consumer Role (I will be sending the First Message).



5. From the resultant RoleLink, delete the Provider Role. Right Click the Consumer Role and select Add Port Type.



6. In the Port Type Wizard, select the communication Pattern as One-Way and Access Restriction to Public. Complete the Wizard.


7. Now we should add a line of code, to indicate how to determine the Destination Party to which the message should be routed.


Add an expression shape to the orchestration and put the following code in that.



Keep note of “SomeId”. This is the identifier that the part should have to route the message to it. We will use this back in Admin Console.


8. Add a Send Shape to the Orchestration and Send the Input Message (received in step2) to the Role Link. Resulting Orchestration will be as follows.



9. Sign the solution and deploy to Admin Console.

10. Create two Send Ports with File Adapter. These two Ports will then be used by two parties to route the message to the corresponding Folder.



11. In Admin Console, right click the Parties Node and Select new Party.



12. In the General Tab you can add any Name Value Pairs (I m yet to find where these will be used).



13. In the Send Ports Tab, Add Party1 Send Port which is created in step 10 and Click ok to complete the step.



14. Expand the Party1 you just created and open the Party1_Profile. Go to Identity Tab and set the Identity as shown below.



Here the Qualifier is the same value that we gave in step 7.


What this means is, whenever the Name node of the input message has a value of Party1, it will be routed to the party we just created.


15. Repeat the same Steps and Create another Party named Party2.


16. Once the party creation is done, Refresh the Applications. This is important, else parties might not reflect in Configuration.


17. Right Click the Parties Application in Admin Console and Click Configure. Create a new Receive port (File Adapter) for the Logical Port of the Orchestration.



18. Select the Role_1 Tab. Click on Enlist and select the two parties you created in previous steps.


19. Now select Party1 and Click on Bind. Select the Party1 Send Port available for Party1.


20. Repeat the Same step and Bind the Party2. Complete the Configuration and Start the Applicaion.


Testing the Parties:


1. Drop the below file in the Receive Location Folder of the Application.


<ns0:Root xmlns:ns0="http://Parties.Schema1">
  <ID>ID_0</ID>
  <Name>Party2</Name>
</ns0:Root> 

2. Here Name node has the value Party2. It will mach this value with SomeId Key for the two Parties. Since the Party Party2 has SomeId value set to Party2, this file will be send to the send port linked with Party2.


3. If the Name node has a Value Party1, the file will be sent to the sendport linked with Party1.


Hope it helps..
- Shiv


Web Counters

Thursday, 2 June 2011

How to check if promoted property value exists before using it? (or) Using Exists Function in BizTalk.

Promoted properties are used in Content Based Routing and to access a frequently used value easily instead of loading the Full Message into Memory.

Generally we promote a property assuming that value for that Property exists at all the time. But what happens when a Promoted Property doesn’t exist?

Answer is MissingPropertyException.

Consider the below sample:

1. Create a new BizTalk Project with a Sample Schema having a promoted field.

 



 

2. Create a simple Orchestration to receive the message for the Schema you created in step 1 and add write the value for promoted field to EventLog.



 

3. Deploy the solution and Create a FILE receive location for the Orchestration Receive port. Try to drop the below file into the folder.

 
<ns0:MyRoot xmlns:ns0="http://PromotedProerties.Schema1">



  <NormalField>NormalField_0</NormalField>



  <PromotedField>PromotedField_0</PromotedField>


</ns0:MyRoot>

4. As expected, an entry is made in event log as shown below.




 

5. Now change the input file by removing the Promoted Field.
<ns0:MyRoot xmlns:ns0="http://PromotedProerties.Schema1">



  <NormalField>NormalField_0</NormalField>


</ns0:MyRoot>


6. Now you see the below exception in EventLog.

xlang/s engine event log entry: Uncaught exception (see the 'inner exception' below) has suspended an instance of service 'PromotedProerties.BizTalk_Orchestration1(c5ac04d8-5aa3-a384-8957-00649b78fbaf)'.
The service instance will remain suspended until administratively resumed or terminated.
If resumed the instance will continue from its last persisted state and may re-throw the same unexpected exception.
InstanceId: 6d22d40a-d5f8-4e78-9226-f4d87883b5b9
Shape name: Expression_1
ShapeId: bbb266d5-bd6f-497e-9357-83602ea1f3d9
Exception thrown from: segment 1, progress 8
Inner exception: There is no value associated with the property 'PromotedProerties.PropertySchema.CustomContextProperty' in the message.

Exception type: MissingPropertyException

Using exists function to Check if Promoted Property exists or not:

To overcome the above error you can use the BizTalk Built in function called exists.

1. Modify the expression shape code given in step 2 as below.

if(PromotedProerties.PropertySchema.PromotedField exists Message_1)

{
System.Diagnostics.EventLog.WriteEntry("BTIS","Promoted Property: "
+ Message_1(PromotedProerties.PropertySchema.PromotedField));
}
else
{
System.Diagnostics.EventLog.WriteEntry("BTIS","Promoted Property doesn't Exist");
}

2. Now when you drop the file without having the promoted field, your else part of code is executed and no exception is thrown.

 


 

This is the same even if the promoted property is of MessageContextPropertyBase Type.

Observations:

1. MissingPropertyException will be thrown whenever you try to access a promoted property whose value is not assigned.

2. Use Exists function to check if the promoted property value exists or not before using the value.

3. MissingPropertyException occurs for both MessageContextPropertyBase and MessageDataPropertyBase

 

Hope it helps.

- Shiv


Web Counters

Monday, 21 February 2011

Debugging Orchestrations in BizTalk 2009 using C# .cs file

An Orchestration *.odx file contains an XML file and code written in a language specific to BizTalk called X#.

You can easily find these, when you right click an orchestration and open it with XML Editor or Notepad.

XML Representation of the Orchestration is used by the Graphical Designer to show the shapes on the screen.

X# code is in turn converted to C# at runtime using XSharp.exe file and this C# assembly will be executed.

This C# file can be found inside <ProjectFolder>\obj\Debug\BizTalk\Xlang\File0.cs once the project is built.

Unlike in earlier versions of BizTalk, only one .cs file will be created irrespective of number of orchestration you have in your project.

This File0.cs file has different sealed internal classes for each of the orchestration in your project.

To debug your orchestration or code written in an expression shape, open this File0.cs and keep a break point. Attach BizTalk Server to the BtsNTSvc Process.

Now you will be able to debug your orchestration using C# Code.

Hope it helps.

-       Shiv

Thursday, 20 January 2011

Can we use Non-Serializable Classes or Types in an Orchestration ?

Biztalk is entirely Stateless. This is achieved by using Persistence Points. Incase of any failure during the processing of an Orchestration (for eg: power failure or Server Restart etc) BizTalk Server will continue to restart the Orchestration from the Last Persistence Point.

Details about the Persistence points will be Stored in BizTalk SQL Server DataBase by serializing all the data.

Hence Non-Serializable Classes or Types cannot be used directly in Orchestrations.

Don’t worry, we can use them in orchestration with an Atomic Scope.
Because persistence does not happen within an Atomic scope. The persistence point is created only when the scope completes its execution as it’s an All-or-Nothing scope.So, we can use Non – Serializable Classes or Types inside Atomic Scopes in an Orchestration.

Consider the below Sample:

1. Create a new BizTalk Project and add any dummy Schema.



2. Create a new Orchestration and add a receive shape to receive the message of the Type Schema1 which is created in Step1.



3. Create two variables of types System.Xml.XmlDocument and System.Xml.XmlNode


4. Now add an Expression shape to the orchestration and add code to extract a node from the incoming message and assign that to the variable you created in step3.



5. Try to build the solution. You end up with an error as shown below.

Error 1 a non-serializable object type 'System.Xml.XmlNode xmlnode' can only be declared within an atomic scope or service.

6. To resolve this, make the following changes to the solution.

     i. Click on the white space of the Orchestration and make the Transaction Type of the Orchestration to Long Running.



     ii. Add a Scope Shape and set the Transaction Type of the Scope to Atomic and move the Expression shape inside the Atomic Scope.



     iii. Move the xmlnode Variable inside the Atomic Scope.



7. Now build the solution. It should work without any errors.

This is just an example. Although this approach is useful, this should be avoided for performance reasons. Alternatives such as XPaths should be considered.

Hope it Helps.

- Shiv
Web Counters

Wednesday, 1 December 2010

How to modify a BizTalk Message using C# or External Dll ?

In many situations the Mapper available with BizTalk Server or Xpath functions might not be sufficient to construct the Required Message in BizTalk Server.

In these scenarios, we can pass the necessary inputs to an external library and construct the message there using C# code.

This article will show two possible ways of achieving this.

Scenario:

You have a schema in your BizTalk Project. You receive a message of this type in a receive folder and pass this message to an External Library, update the message and send it back to BizTalk. Save the updated message to a new location.

Solution:
There are two possible ways of doing this.

Create an equivalent class file for the Schema and pass the message as class object to the External dll

Pass the message contents as an XML Document to the External Dll and modify the message using XMLDocument or XLinkq or any other thing else.

1. Create a new BizTalk Project and add a Sample schema Schema1 as shown below.


2. Use the XSD.EXE utility to convert the schema created above into a serializable class. For this, Go to Visual Studio Command Prompt and give the following Command at the directory where Schema is located.

XSD Schema1.xsd /c /o:c:\

Note: See this for more details on xsd.exe

3. Create a Class Library Project and add the above class file to the Project. Now we have an equivalent class file for the schema.
4. Create a Static method in the Class that updates the Received Object and sends it back using C #as shown below.


5. Build it and add a reference of this class library to the BizTalk Project.
6. Add an orchestration to the BizTalk Project and create two messages of the Type Schema1
7. Add a Receive Shape and Message Constructor shape and a send shape and complete the orchestration as shown below.


8. Add the below code in the Message assignment shape.

Message_2 = ClassLib.Root.GetClassReference(Message_1);

9. This will call the GetClassReference and the Message Message_1 will be automatially serialized into the class Object. Within the method, schema elements and attributs can be accessed just like class properties.
10. To Test this project, deploy both BizTalk project and Class Library to GAC and put an input file, you will see that the values are updated.
11. The same can also be achieved by passing the Message Contents as an XML object as given below.

Variable_1 = Message_1;
Variable_1.LoadXml(ClassLib.Root.GetClassReferenceUsingXML(Variable_1.OuterXml));
Message_3 = Variable_1;

Note: Variable_1 is of tpye XMLDocument.

12. Now you should have a method in the External Library that modifies the message using XML Operations. A sample is given below.


While I tested with Schemas with more than 50 Elements, I find that using XMLDocument to modify the Contents was very much faster that using Class Objects.

Hope it helps.
- Shiv


Web Counters

Thursday, 25 November 2010

How to Send & Receive Custom Headers from a WCF Service in Orchestration?

In many practical scenarios, Headers of the WCF Message are used to Establish Session / Send some sensitive / routing information
In this post I will show you how to Send and Receive data through Custom Headers from a WCF Service.

Solution:

Scenario:
Orchestration adds Header and Sends to the Service -> Service Receives the Header and writes to EventLog -> Service adds and outbound header and sends back to Orchestration -> Orchestration Receives the Header

1. Create a Sample WCF Service that gets the value from the Incoming Message and adds an outbound header to the outgoing message. Sample code is given below.

public string GetHeaderValue(string HeaderName, string URI)
{
// Receive Inbound Header

string val = OperationContext.Current.IncomingMessageHeaders.GetHeader(HeaderName, URI);
EventLog.WriteEntry("Received Header", "Header Value: " + val);

// Send Outbound Header
MessageHeader header = MessageHeader.CreateHeader("Test","Test.com","TestValue");
OperationContext.Current.OutgoingMessageHeaders.Add(header);

return val;
}

2. Deploy the Service and Consume it in a BizTalk Project. It creates input message schema, orchestration, output message schema, port type and Binding Files.
3. Create 3 Message as shown below in the Orchestration.

Let Message_1 and Message_2 represent Input Message Schema and Message_3 represent Output message Schema

4. Create a Receive Shape, set the Message property to Message_1, activate to True
5. Add a Construct messsage shape, set the Message Constructed property to Message_2. We pass header message to the Service by using the property (WCF.OutboundCustomHeaders). Add the following code in the Message Assignment shape.

Message_2 = Message_1;
Message_2(WCF.OutboundCustomHeaders) = @"From Clietn";

Resulting Orchestration should be like below


Note: In this step, I created a new message Message_2 (same schema as Message_1) rather than editing a Message_1 because, messages in BizTalk are Immutable. I alse added the header to the message which will be passed to the Server.

6. Add a send shape, and set the Message property to Message_2.
7. Add a port to the Orchestration and set the port type to the existing port type which is created automatically while consuming the Service.
8. Join the Send shape with the receive port of Service. Resulting orchestration should be like below

9. Add a receive shape and set the Message Property to Message_3 and connect the Response port of the Service with the Send shape.


10. Create a string variable and add an expression shape to extract the Headers that the service sent using the property

Variable_1 = Message_3(WCF.InboundHeaders);
System.Diagnostics.EventLog.WriteEntry("InBound Headers", "Received InBound Headers: " + Variable_1);

11. Now add a Send Shape, Receive and Send ports and complete the Orchestration


12. Deploy the Service and place the below file in the input folder.
<ns0:GetHeaderValue xmlns:ns0="http://tempuri.org/">



<ns0:HeaderName>FromClient</ns0:HeaderName>



<ns0:URI>FromClient.com</ns0:URI>


</ns0:GetHeaderValue>


Note: Input will vary depending on the Logic you use.

13. In the event log, it should display two events.


14. One will be created by the service (Step 1) after it received the inbound header) and One will be Created by the Client Orchestration after it receives the header from the service. (Step 10).

Hope it is helpful. Mail me if you need the source code.
- Shiv


Web Counters

Tuesday, 23 November 2010

Issue: Unable to add parameters in Call Rules Shape

I created my first BRS Rule (using  XSD) in BizTalk Server Business Rules Composer and deployed it.

When I tried to call this rule from Call Rules shape of an Orchestration, it didn’t give my any option to add an input parameter to the Rules

After browsing for some time, I find that it happened because, the Document Type Property for the Schema in the Facts Explorer (shown above) is different from the Fully Qualified name of the Actual Schema in the BizTalk Project

So, I modified Document Type Property of the Schema in the Business Rules Composer to the Fully Qualified Name as in the BizTalk Server Project as shown below

Then the parameter is shown in the Call Rules Shape



Result:

The issue is that, in the beginning, Call Rules shape was not able to find any matching Message to the Schema which is deployed with the Rule.

Since I modified the schema in BRE with the Fully Qualified Name of the BizTalk solution, it found a matching message and displayed in the Call Rules Shape.

Hope it is useful..

- Shiv


Web Counters

Sunday, 21 November 2010

Catching SOAP Faults from WCF Service in BizTalk Orchestration

This Link has the Structure of Soap Version 1.1 & 1.2 Fault Message

This post will show how to Catch a Soap Fault returned by a WCF Service in a BizTalk Orchestration.

  1. Consume a WCF Service and Implement the Logic for Sending the Request and Receiving the Response from the WCF Service.

  2. Right Click on the PortType and Select New Fault Message as shown below.

  3. A new fault port will then be created as shown below

  4. Now set the Message Type to either Soap Fault 1.1 or 1.2 as shown below

  5. Add a scope block to the Orchestration, set the transaction type to None and an Exception handler

  6. Give any Valid Name to the Object Name and Set Object Type to Fault_1

  7. Keep a Message Assignment shape in the Exception Handler and assign the captured fault to another Message

  8. Handle the Message as required


Note: Message_3 should be of Soap_Fault type as selected in Step 4.
- Shiv


Web Counters