Thursday 1 September 2016

WebApi Integration using Biztalk

problem statement:

need to integrate web api using Biztalk ,let's say we have a scenario where I need to form different URL  based on requirement.

sample URL'S

http://BiztalkPoc.blogspot.in/GetOrderDetail/{OrderID}
http://BiztalkPoc.blogspot.in/UpdateProduct/UpdateDesc/{OrderID}


solution:


  • Create Orchestration  in which we will be calling the web api service
  • promote desired  operation (GetOrderDetail,UpdateProduct) from orchestration using custom property schema
  • promote order id from orchestration so that we can bind the same in send port variable mapping property
  • Create a custom pipeline component for reading the operation name and promoting it again

       object obj = context.Read("Operation", "http://BiztalkPoc.Samaple.WebApiIntegration.PropertySchema1");
                //operation is the property promoted from orchestration 
                string operationName = Convert.ToString(obj);               

                pInMsg.Context.Promote("Operation", "http://schemas.microsoft.com/BizTalk/2003/system-properties", operationName);

  • Create WCF-WebHttp send port ,configure different urls using  BtsHttpUrlMapping propert


<BtsHttpUrlMapping>  <Operation Name="GetOrderDetail" Method ="GET" Url="/GetOrderDetail/{OrderID}"/>
  <Operation Name="UpdateProduct" Method ="POST" Url="/UpdateProduct/UpdateDesc/{OrderID}"/>
  <!--we can have as many operation based on our requiremenr-->
</BtsHttpUrlMapping>











DownloadSample Code Here



Monday 29 December 2014

Call Web service from Biztalk Orchestration

For demonstration I will be calling free currency converter service

  http://www.webservicex.net/CurrencyConvertor.asmx?WSDL


Right click on your biz talk solution and add generated item.









After adding the generated item we will get solution structure as below



open the orchestration file and drag shapes as per below screen shot


choose existing port type for request response(soap)



sample request

response










Merge multiple biztalk canonical message of same type into single message

Merge multiple canonical message inside orchestration of same type into single message

Create a .net helper class as below

using System.Collections;
   [Serializable]
    public class BiztalkMessageHelper
    {  

        public XmlDocument UpdateXML(ArrayList msgs)
        {
            DataSet ds1 = new DataSet();
            DataSet ds2 = new DataSet();          
            XmlDocument mergedMessage = new XmlDocument();      
            ds1.ReadXml(new XmlNodeReader((XmlDocument)msgs[0]));

            for (int i = 1; i < msgs.ToArray().Length;i++ )
            {
                ds2.ReadXml(new XmlNodeReader((XmlDocument)msgs[i]));
                ds1.Merge(ds2);
                //ds3 = ds1;
            }
            mergedMessage.LoadXml(ds1.GetXml());
            return mergedMessage;
        }
 
    }
variables need to be added

  •  System.Collections.ArrayList let's say variable name is  arrayList
  •  "class written above" lets say variable name is biztalkMessageHelper
  •  XmlDocument lets say variable is xdoc

suppose we want to merge three messages of the same type: msg1,msg2,msg3
then we can  write the below code inside expression shape to merger all three message

arrayList=new System.Collections.ArrayList(3);
arrayList.Add(msg1);
arrayList.Add(msg2);
arrayList.Add(msg3);
xdoc=biztalkMessageHelper.UpdateXML(arrayList);






Sunday 28 December 2014

Dynamic mapping

Dynamic Mapping demo

SCHEMA'S




















Mapping





Transformation logic inside expression shape:


MapType = System.Type.GetType("DynamicMappingDemo.CanonicalToCustomerA,DynamicMappingDemo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1e189bdf5b6a5b37");

construct customerA
{
transform (customerA) = MapType(generic);
}

//log meesgae
xmlDoc=customerA;
System.Diagnostics.EventLog.WriteEntry("DynamicTransformDemo","customerA:"+xmlDoc.OuterXml);



MapType = System.Type.GetType("DynamicMappingDemo.CanonicalToCustomerB,DynamicMappingDemo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1e189bdf5b6a5b37");

construct CustomerB
{
transform (CustomerB) = MapType(generic);
}

//log meesgae
xmlDoc=CustomerB;
System.Diagnostics.EventLog.WriteEntry("DynamicTransformDemo","customerB:"+xmlDoc.OuterXml);


solution files



sample inputs:

<ns0:Canonical xmlns:ns0="http://DynamicMappingDemo.Canonical">
  <Customer>
    <id>A</id>
    <name>name_A</name>
  </Customer>
</ns0:Canonical>


<ns0:Canonical xmlns:ns0="http://DynamicMappingDemo.Canonical">
  <Customer>
    <id>B</id>
    <name>name_B</name>
  </Customer>
</ns0:Canonical>




sample out put that will be logged inside event viewer

customerA:<ns0:CustomerA xmlns:ns0="http://DynamicMappingDemo.CustomerA"><ID>A</ID><NAME>name_A</NAME></ns0:CustomerA>


customerB:<ns0:CustomerB xmlns:ns0="http://DynamicMappingDemo.CustomerB"><ID>B</ID><NAME>name_B</NAME></ns0:CustomerB>




MessageAggregation

MessageAggregation using sendpipeline


order schema structure
shippingInfoStructure



envelope schema


Set envelope property to yes (goto schema property set envelope property to yes)

set body xpath to record 

/*[local-name()='Envelope' and namespace-uri()='http://MessageAgrregator.OrderEnvelope']/*[local-name()='Record' and namespace-uri()='']


set document schema and envelope property as shown below




aggregation logic

Microsoft.XLANGs.Pipeline.XLANGPipelineManager.ExecuteSendPipeline(typeof(MessageAgrregator.MessageAggregatorSend),MessagesToAggregate,AggregatedMessage);

solution structure




sample input 


sample output in event viewer







Friday 26 December 2014

table looping functoid

Consider the following schemas:
Source schema:

Destination schema:

One’s first attempt at a map to transform the source to destination might look something like this:

We'll use the following input file to test the map.

The output isn't quite what we were hoping for. Rather than creating two borrower nodes, the two first names, last names, and SSNs are within a single borrower node.

The Table Looping functoid is the key to what we're trying to achieve. Below is the map that uses the Table Looping and Table Extractor functoids to create the desired output.

The Borrower fields are used as inputs into the Table Looping functoid as well as some definitions about how many rows and columns there will be. One tip I gleaned from Dan Shultz is to label the input links, as they'll be infinitely more readable within the Table Looping inputs window.

The first two arguments are akin to defining the number of rows and the number of columns for the table, and the rest of the arguments define the values that will be used within the table. By opening up the Table Looping Grid, we're able to view which fields will go into certain columns/rows:

The Table Extractor functoids are used to define which columns from the table map to use as inputs. Each Table Extractor functoid corresponds to a column within the Table Looping Grid.

And finally the output from Table Looping functoid to the Borrower node dictates that a Borrower node be created for each row within the Table Looping Grid. With that said, here’s the output from testing the second map: