Pages

BizTalk : Making Web / WCF service Call implementing Fault Exception Handling & Retry Mechanism

Thursday, December 27, 2012

This blog post contains some guidelines for consuming web services, with a focus on exception handling.  We will both handle pure messaging scenario and web service calls from within an orchestration.  I also make a distinguishment between asynchronous and synchronous flows.  Synchronous means that the flow needs to return a message to the original caller.  So in case of troubles, a SoapFault needs to be returned to the calling application.  In an asynchronous flow, you just need to make sure that your web service call is resumable.


Messaging Scenario – Asynchronous

When an error occurs during the web service call, the default behavior of BizTalk retry 3 times and will suspend the request message on the BizTalk Send Port and this instance will be resumable.  This is the perfect behavior for this asynchronous process.


Messaging Scenario - Synchronous

If you are in a synchronous process, a suspended Send Port will lead to a timeout on your Receive Port.  In this scenario you need to enable "Propagate Fault Message" on the Send Port and a SoapFault will be returned to the original caller.  Also think about the Retry Count and Retry Interval settings, because a bad configuration can also lead to timeouts.
image


Orchestration - Asynchronous

When you consume a web service from within an orchestration, it's getting more complex.  If the consumed web service throws an exception, BizTalk creates by default 2 suspended service instances.  Resuming them does not always have the expected behavior.

-  The Orchestration is suspended.  A resume will not change anything to the state of the Orchestration.
-  The Send Port is suspended.  A resume will resume the web service call as expected, but the Orchestration will not be able to continue processing afterwards.

image

How can we now achieve a resumable web service call?

First of all enable "Propagate Fault Message" on the Send Port.

Also modify the calling orchestration:
-  You need to create a loop.  This loop continues as long as the Boolean bSuccess equals false.
-  Modify the logical Orchestration Send Port and add a Fault Message.  To keep it general, you can choose the SoapFault (which is part of the Microsoft.BizTalk.GlobalPropertySchemas).
clip_image002        clip_image003
-  Add an exception handler to the web service call. Catch the Fault Message that was returned.  Add a suspend shape for human intervention. Note that it’s a good practice to also add an extra exception handler which catches a System.Exception.
-  If the web service call fails: set bSuccess == false in the exception handler.  If the call succeeds, set bSuccess == true, so the orchestration will exit the loop.

The result should look like this:
image

Now we've created a resumable web service call from within an orchestration.  When testing the orchestration in a failure scenario, you will see that there are still two suspended service instances:
-  The Orchestration is suspended.  This is the one that we've made resumable.
-  The Send Port is suspended.  To avoid this second service instance to be suspended, you can enable "Routing for Failed Messages".  This will generate an ErrorReport, instead of suspending the Send Port.  Subscribe on the ErrorReport with the filter ErrorReport.ErrorType == “FailedMessage”.

clip_image006


Orchestration - Synchronous

In this scenario, you will also need to catch the SoapFault (or other exception) and make sure that you don’t end up with suspended send port instances. See “Orchestration – Asynchronous”

The extra functionality that you’ll need to add is returning a SoapFault to the original caller.
- Add a Fault Message to the Request/Response receive port of your orchestration.
- You can choose to return a typed Fault or, to keep it general, a SoapFault (which is part of the Microsoft.BizTalk.GlobalPropertySchemas).
- Make sure you return the catched SoapFault (or the created SoapFault in case of other exception) in case of errors.
- Remark that you’ll need to add a decide shape to determine you’re in a success/failure scenario. Otherwise, the compiler will fail (complaining about unconstructed messages).

clip_image002[4]

Again, think about the Retry Count and Retry Interval settings on the send port.

post by Toon Vanhoutte
Read more ...

BizTalk Q & A: Convert pipeline message to XDocument

Thursday, December 27, 2012
Q:
How can I transform an  Microsoft.BizTalk.Message.Interop.IBaseMessaget to XDocument to make changes in the message. And how I canrecreate my message after changes ?publicMicrosoft.BizTalk.Message.Interop.IBaseMessageExecute(Microsoft.BizTalk.Component.Interop.IPipelineContextpc,                                                                      Microsoft.BizTalk.Message.Interop.
IBaseMessageinmsg)        {
returninmsg;        }
thank you
Sol:
public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg)
        {
            //To get Incoming message
            System.IO.Stream originalStream = pInMsg.BodyPart.GetOriginalDataStream();
            //Working with XDocument
            XDocument xDoc;
            using (XmlReader reader = XmlReader.Create(originalStream))
            {
                reader.MoveToContent();
                xDoc = XDocument.Load(reader);
            }
            
            // Returning stream
            byte[] output = System.Text.Encoding.ASCII.GetBytes(xDoc.ToString());
            MemoryStream memoryStream = new MemoryStream();
            memoryStream.Write(output, 0, output.Length);
            memoryStream.Position = 0;
            pInMsg.BodyPart.Data = memoryStream;
            return pInMsg;
        }

or
Converting it to XmlDocument:
// Load original message to XmlDocument
Stream originalMessage = inMsg.BodyPart.GetOriginalDataStream();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(originalMessage);
//
//Set output message
IBaseMessage outMsg = pipelineContext.GetMessageFactory().CreateMessage();
outMsg.AddPart("Body", pipelineContext.GetMessageFactory().CreateMessagePart(), true);
Stream outputStream = new MemoryStream();
xmlDoc.Save(outputStream);
outputStream.Position = 0;
outMsg.BodyPart.Data = outputStream;
return outMsg;

For additional information, check the following links
Read more ...

BizTalk EDI Error SOLVED : There was a failure executing the receive pipeline: Microsoft.BizTalk.Edi.DefaultPipelines.EdiReceive Reason: No Disassemble stage components can recognize the data.

Wednesday, December 26, 2012

In my last two posts I showed two possible errors, and their respective solutions, that can happen when we are validating dummy EDI message, provided by our partners, against the schema using Visual Studio, but these errors could also happen in runtime.
In this post I will show you one common error when we are validating an EDI solution.
After I deploy and correctly configured the solution, I was trying to receive an EDI document from a Receive Port, in order to convert it to XML format using the generic EDI pipeline: “Microsoft.BizTalk.Edi.DefaultPipelines.EdiReceive”, but I was always getting this error:
“There was a failure executing the receive pipeline:
“Microsoft.BizTalk.Edi.DefaultPipelines.EdiReceive,
Microsoft.BizTalk.Edi.EdiPipelines, Version=3.0.1.0, Culture=neutral,
PublicKeyToken1bf3856ad364e35″ Source: “EDI disassembler” Receive Port: “IN_ORDER_PORT” URI: “E:\PORTS\EDI\IN_ORDER\*.*” Reason: No Disassemble stage components can recognize the data.“.
The message provided by our partner was this:
01UNH+1000100+ORDERS:D:93A:UN:EAN007'
02BGM+220+01521710'
03DTM+137:120530:101'
04DTM+64:120604:101'
05DTM+63:120004:101'
06FTX+AAI+++SOME TEXT'
07FTX+AAI+++SOME TEXT'
08FTX+AAI+++SOME TEXT'
09NAD+BY+8000000001164::9'
10NAD+DP+8000000009463::9'
11NAD+IV+8000000013002::9'
12NAD+SU+8000001459008::9'
13NAD+PR+8000000016003::9'
14LIN+1++4001518722937:EN'
15PIA+1+00:PV+14001518722937:EN'
16IMD+F+M+:::SOME DESCRIPTION'
17QTY+21:52'
18LIN+2++5000014010034:EN'
19PIA+1+00:PV+15701014010031:EN'
20IMD+F+M+:::SOME DESCRIPTION'
21QTY+21:152'
22LIN+3++5000014016142:EN'
23PIA+1+00:PV+15701014016149:EN'
24IMD+F+M+:::SOME DESCRIPTION'
25QTY+21:304'
26LIN+4++5006879009752:EN'
27PIA+1+00:PV+15776879009759:EN'
28IMD+F+M+:::SOME DESCRIPTION'
29QTY+21:720'
30UNS+S'
31UNT+31+1000100'
CAUSE
After some time trying to understand the reason of this problem, I realize that’s nothing wrong with my project, the problem is actually in the message that I’m using.
This error occurs because the message does not contain the EDIFACT interchange envelope segments (UNB and UNZ). An EDIFACT interchange begins with a UNB. It contains version release information, syntax information, and partner information. An interchange ends with a UNZ.
UNA Segment: The UNA segment is optional in an EDIFACT interchange. The specifications in the UNA segment define the characters used as separators and indicators for the interchange. Use this segment only if the interchange contains non-standard separator characters. (More information here)
UNB Segment: The UNB segment is compulsory to an EDIFACT interchange. This segment acts as the interchange header for a set of EDIFACT documents. The UNB segment elements identify the sender and recipient of the interchange, together with the date and time that the interchange was prepared and the agency controlling the syntax of the interchange. (More information here)
UNZ Segment: This segment is the Interchange Trailer segment of an EDIFACT document. This segment indicates the end of an interchange and checks the interchange reference and number of documents in the interchange. (More information here)
SOLUTION
Add this segment to your message: UNA (optional), UNB and UNZ and the message will be processed correctly.
Correct message:
01UNA:+,?*'
02UNB+UNOB:1+UNB2.1+UNB3.1+012301:0123+UNB5'
03UNH+1000100+ORDERS:D:93A:UN:EAN007'
04BGM+220+01521710'
05DTM+137:120530:101'
06DTM+64:120604:101'
07DTM+63:120004:101'
08FTX+AAI+++SOME TEXT'
09FTX+AAI+++SOME TEXT'
10FTX+AAI+++SOME TEXT'
11NAD+BY+8000000001164::9'
12NAD+DP+8000000009463::9'
13NAD+IV+8000000013002::9'
14NAD+SU+8000001459008::9'
15NAD+PR+8000000016003::9'
16LIN+1++4001518722937:EN'
17PIA+1+00:PV+14001518722937:EN'
18IMD+F+M+:::SOME DESCRIPTION'
19QTY+21:52'
20LIN+2++5000014010034:EN'
21PIA+1+00:PV+15701014010031:EN'
22IMD+F+M+:::SOME DESCRIPTION'
23QTY+21:152'
24LIN+3++5000014016142:EN'
25PIA+1+00:PV+15701014016149:EN'
26IMD+F+M+:::SOME DESCRIPTION'
27QTY+21:304'
28LIN+4++5006879009752:EN'
29PIA+1+00:PV+15776879009759:EN'
30IMD+F+M+:::SOME DESCRIPTION'
31QTY+21:720'
32UNS+S'
33UNT+31+1000100'
34UNZ+1+UNB5'
Read more ...