Pages

Solved : MSMQ Error Rcv Pipeline No Disassemble stage components can recognize the data & A message received by adapter "MSMQ" on receive location is suspended.

Friday, September 30, 2011
Q:

When I try process a file, I receive the following two errors - 
There was a failure executing the receive pipeline:  Receive Port: : No Disassemble stage components can recognize the data.

and 


A message received by adapter "MSMQ" on receive location  is suspended.

Error details: There was a failure executing the receive pipeline: Source: "Flat file disassembler" Receive Port:  URI: "FORMATNAME: DIRECT=OS: " Reason: No Disassemble stage components can recognize the data.
MessageId: {77F9D67C-3575-4993-926E-BDD24B020C89}
InstanceID: {B72BA496-9194-4003-84FF-83070DB5941B}

Input file is Flat file and the receive pipeline has a Flatfile disassembler. Also configured the flat file disassembler with the Document schema.

Any help appreciated?

sol:
This problem frequently occurs because of header or extra format information that is added to an MSMQ message. If you open up the MSMQ service uinder Administrative Tools \ Computer Management \ Services, you can see the MSMQ messages that are in the queue. I would stop your BizTalk application and then send in a message. You can see the body value of the message and determine whether extra characters are being added to the message before BizTalk receives it and tries to parse it
Also check the MSMQ.BodyType context property which will determine how the Biztalk will handle the message.
References:
and




Read more ...

Dynamic Pipeline For BizTalk Tool To Create Pipeline Using XML in BizTalk

Friday, September 30, 2011
Dynamic Pipeline For BizTalk 
This Tool  Adds/Removes Pipeline components Dynamically
I happened to come Across this tool in Code Plex

Project Description
This tool/pipeline will help in Adding/Removing Pipeline components to the existing solution dynamically.

This tool/pipeline does not require you to Redeploy the application or Restart the Host Instance (*-Please see the limitations in the Documentation) if you need to add a Pipeline component.

Pipeline components can be Added/Removed by editing an XML file.

Please refer the detailed Documentation (available in the downloaded zip file) for more details.
  • This is Tested in BizTalk Server 2010. However it works for Other BizTalk Server versions too

Hope This Helps Some One !!...


Read more ...

BizTalk custom pipeline DECODE component to REPLACE a Special Character inside the Message

Friday, September 30, 2011
Q:

Hello Friends,

I am new to create a custom pipeline DECODE component but stuck at the logic which modifies the message (replacing some prespecified character with some default character).
What i know is what to REPLACE and with WHAT along with the format of file type which is Flat File.

For eg.
10ç0ç6140314101  02368A794 004 01000081224081223AAAPA    000000011270000000A000000024340000A         
2000000024340000A000000024340000A000000000000000A000000000000000A000000000000000A000000000000000A    
3000000000000000A000000000000000A00000023858A00000023858A00000000000A00000000000A00000A 2AçAAVLAA    
4AAEAACAA AEACOA     AAAL EAUAAY AAVEAAOA                                                            
5                    000000000000000A000000000000000A000000000000000A                                
6             00000033917C00000033917CH06        AEAAE       000000000000000000000A0000000274311A    
7000ç000000A000000000000000000A0000000000        A00000000                                           
As you can see, there is one special character (ç : Cedilla), which i want to replace with "x"

Below is the code i was banging my head with

public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(Microsoft.BizTalk.Component.Interop.IPipelineContext pc, Microsoft.BizTalk.Message.Interop.IBaseMessage inmsg)
{
    if (inmsg.BodyPart != null)
    {
    	IBaseMessagePart bodyPart = inmsg.BodyPart;
        Stream sOriginalStream = bodyPart.GetOriginalDataStream();
        if (sOriginalStream != null)
        {
            MemoryStream memStream = new MemoryStream();
            try
            {
                Regex reReplaceChar = new Regex("ç", RegexOptions.None);
                StreamReader sReader = new StreamReader(sOriginalStream);
                StringBuilder sBuilder = null;
                byte[] byteArray = new byte[sOriginalStream.Length];
                while (sReader.Peek() != -1)
                {
                    sBuilder = new StringBuilder(sReader.ReadLine());
                    sBuilder = new StringBuilder(reReplaceChar.Replace(sReader.ReadLine().ToString(), "x"));
                    byteArray = System.Text.Encoding.ASCII.GetBytes(sBuilder.ToString());
                    memStream.Write(byteArray, 0, byteArray.Length);
                }
                bodyPart.Data = memStream;
                memStream.Position = 0;
                inmsg.BodyPart.Data = bodyPart.Data;
                pc.ResourceTracker.AddResource(memStream);
            }
            catch (Exception ex)
            {
                System.Diagnostics.EventLog.WriteEntry("ReplaceCharacter", "Exception Occurred : " + ex.Message, EventLogEntryType.Error, iEventID, 5);
            }
            finally
            {
            	sBuilder = null;
            	sReader.Close();
            	sReader.Dispose();
            	memStream.Close();
            	memStream.Dispose();
            }
        }
    }
    return inmsg;
}
Problem area for me is:
1. How to loop throu the message?
2. Replace doesn't work, so i created another function which find out the position of the character, remove it and insert "x" (the Replacement Character) at the same position.
3. Not getting the proper message in output.

I am stuck very badly, please help me. 
Thanks a tonne in advance.

Regards
harry
Sol:
Your code is very close - I haven't tried it, but from reading it I think the only problem may be that you're closing the memory stream? 
you're assigning your memory stream to the message you're returning to BizTalk, but then your'e closing the stream, which would inevidebly mean BizTalk won't be able to read the message?

You've correctly added it to the resource tracker which would allow Biztalk to dispose of it when done processing the message, so you should be ok removing the two lines from the finally block.

I would emphasie again the points I've made yesterday - your code will read the entire message to memory, which may cause issues under load, and you really ought to be createing a new message and not replace the stream on the existing one (but while I'm quite strickt on the first point I'll admit to be more 'flexible' on the second sometimes)
 Here, do this - it should work:


The line:

      sBuilder = new StringBuilder(sReader.ReadLine());

Replace with:

      sBuilder = new StringBuilder(sReader.ReadLine(), Encoding.Default);

This will allow your code to recognize your cedilla character.

Then just have ONE string replace line like this in your loop:

      sBuilder = new StringBuilder(sReader.ReadLine().Replace("ç", "x")); 

You don't need any of that Regex stuff.
Here's the test method I just wrote to validate the above.  You can use it for reference.

        private static string BizTalkHelp(string input)
        {
                StreamReader sReader = new StreamReader(@"C:\BizTalkTestDir\sample.txt", Encoding.Default);
                StringBuilder sBuilder = null;
                while (sReader.Peek() != -1)
                {
                    sBuilder = new StringBuilder(sReader.ReadLine().Replace("ç", "x"));
                }
                return sBuilder.ToString();
        }
Read more ...

Sending text for an MSMQ message body using the .NET namespace System.Messaging XmlMessageFormatter to BizTalk || Use of ActiveXMessageFormatter

Friday, September 30, 2011
Recently I was asked to send an MSMQ message which only contained the data from a flat file. The reason for this was the need to simply relay messages that came in through MSMQ onto a distant trading partner using MQSeries. Through BizTalk this is made possible through send port filters which can essentially query messages coming into the BizTalk MessageBox database through receive locations and then forward them onto the send ports based on the filters. So in this scenario the goal was to reduce latency as much as possible by simply forwarding the message received through BizTalk to the distant partner. The challenge is in getting the format of the MSMQ message body to simply be the flat file string.

Sending text for an MSMQ message body using the .NET namespace System.Messaging will by default use the XmlMessageFormatter in the body of the message. Switching over to the BinaryMessageFormatter will almost accomplish this goal but you will see some extra characters in the body if you look at the body contents as shown here for an MSMQ message (the desired message does not begin until the 0120 on the fourth line):




One formatter that accomplishes these objectives but does receive much written about it is the ActiveXMessageFormatter (in System.Messaging), which will serialize a string exactly like you would expect it to w/o any additional header or wrapping content. This is very useful when you want to send something across to MSMQ without any extra wrapping or header content.
Read more ...

Solution : Delimited Flat File Schema Misssing Fields At End

Friday, September 30, 2011
Q:
I have a Flat File Schema with records delimited by CRLF and fields delimited by a pipe symbol (|).  Occasionally we receive a record with some of the fields on the end of one record missing.  The file is not being processed correctly.  Since those fields are optional, I would like to be able to accept both type of file.
For example, a normal record might look like this:
TAG1|A1|B1|C1|D1
TAG2|A2|B2|C2|D2|E2|F2
TAG3|A3|B3|C3
But sometimes we get one like this (note that D2, E2, and F2 are missing):
TAG1|A1|B1|C1|D1
TAG2|A2|B2|C2
TAG3|A3|B3|C3
Is there any way that we can accommodate this requirement? I would like for both files to be processed.  The resulting xml should just have empty nodes for the missing fields.
Any help will be appreciated.

Sol:


Use the choice group node in your schema to achieve this. Create a choice group with option for fileds "C2|D2|E2|F2" and for "C2" only. Get more details about choice group from:
or
1) Set the "Allow Early Termination" property on the "schema" node of your flat file schema to "Yes".
2) Then set the "Min Occurs" property on all the fields which are optional to "0".
3) Validate your instance and have fun.

Regards
Read more ...

Handling Custom SOAP Exceptions in BizTalk

Monday, September 26, 2011
 Post by Romiko's Blog
Sometimes in Orchestrations you would like to throw a custom exception. Before we begin, remember this rule:
  • Never throw a general exception outside the catch block in an Orchestration
The rule above is a bit funny, because when you drag a default exception shape in a try block within an orchestration, it will default to General Exception and you cannot choose any other exception type.
Imagine we need to call a web service and then handle the response from it within an orchestration. However, sometimes I may get a timeout from the web service or I would only like to wait a 1 minute or so to get the response. What I usually do in these cases is create a listen shape after I have called the web service and then I use a delay shape to wait a specified amount of time for the web service response, if it does not respond within the time span , I simple throw a Timeout Exception.

However, as mentioned when you drag a default throw shape, the only option is to throw a general exception, to solve the problem, create a variable of type .NET Class
Then, navigate to the mscrolib library:
And choose the exception type as illustrated below.
Give the variable a friendly name in the Orchestration View
Add a throw exception under the Delay shape and assign the type of exception to the variable name you created (Weird I know, but this is how it is done)
Below are the properties of the Throw Exception Shape
As you can see above, I have a listen shape after sending a message to a web service and am now waiting for a response.
And you nearly done, what you then do is add a Catch Exception by right clicking the scope and clicking add exception handler:
  • Remember all transaction should be in a scope, so your catch blocks will automatically be appended to it. Now it is time to customize the catch block.
Right click the new Catch Block and set the type of exception to catch, in my case, a timeout exception.
There are two properties to set here:
  • Exception Object Type
  • Exception Object Name
In my case this will be
Exception Object Type = System.TimeoutException (I had to choose .NET Class and navigate through the mscrolib again)
Exception Object Name = e ( I chose e, as this is what we use in coding most of the time, you can choose anything you like)
So the Exception Object Name is similar to doing this:
catch (Exception ex)
{
}
This is how looks is now.

Don't forget to add custom code to handle the exception in the Catch Block, maybe to update a log table or send a message somewhere, like I have done above, so now when a web service times out, the orchestration will throw a timeout exception, this is much more intuitive than seeing a general exception!

SOAP exceptions from a web service

In order to catch soap exception from a web service, what you do is add a reference to the BizTalk project for:
System.Web.Services

Then add an exception handle block:


You can then access the information of the exception message like this:
e.Message
e.g.

Or you can create a Soap Exception message and send it to the message box for failure routing, here is an example from:
Source: Saravana Kumar, http://www.digitaldeposit.net/blog/2007/05/orchestration-handle-soap-exception-and.html

A word of warning, if a web service throws a soap exception, the port will retry by default 3 times at intervals of 5 minutes, I changed the retry here to 0 for my example, so that the soap exception is caught and a log in made in SQL, however if you using a delay shape make sure the amount in the delay is greater than the total interval in the send point, else you will never catch the soap exception and will just catch timeout exceptions!
So below, works fine with a delays of 2.5 minutes, however if I made retry count = 1, then the delay should be greater than 5 minutes! You can really get confused when a soap exception occurs and the orchestration does not catch it, it will only catch it after the retry count is done in the send port of the web service!

Here is the exception in SQL
Summary:
  1. Create a VARIABLE in the orchestration view of the exception type you want to catch, use mscorlib to assign the variable type to an exception
  2. Drag a throw shape and set the type of exception to throw to the variable name (yes it is automatically instantiated)
  3. Add a custom Catch block to the SCOPE where the throw shape is located and once again, set the properties of Exception Object Name and Exception Object Type, where type will come from mscorlib and name is anything you like!
Read more ...