In a pipeline component, some streams are not seekable: Improvements to the Archiver


A while back, I presented my Archiver Component. It archives messages as they enter a receive pipeline or right before they leave a send pipeline. It turns out that “DT” found a problem with this component (thank you for reporting this). I have updated the original entry and fixed the code.

The error in the code I originally provided was to use BodyPart.GetOriginalDataStream() even if I had the right comment above it!:

   // Get a *copy* of the original input stream
   originalStrm = bodyPart.GetOriginalDataStream();

I should have used BodyPart.Data which in the case of custom pipeline components makes a copy of the inbound message:

   // Get a *copy* of the original input stream
   originalStrm = bodyPart.Data;

At this point, rewinding the stream into the finally block is not needed anymore. The updated source code can be found here.

Comments (6)

  1. david wei says:

    it’s great helpful! thanks.

  2. aman says:

    This works perfectly fine in the receive and send pipelines when dealing with flat file data on the receive and xml data on the send.

    However, I am having trouble archiving when flat file data is on the send pipeline.. giving a forward read only error, can’t seem to get any data . Any suggestions?

    best regards,

    aman

  3. Gilles says:

    Aman: Without more information about that "read only error", I won’t be able to help you. One thing to verify: we actually write a file to the file system, so does the user which runs the pipeline (the host running it) actually has the rights to write a file on the path you specified?

    Attach a debugger to BTSNTSVC.EXE, break on first chance exceptions and give me the call stack when the error happens and I’ll be able to help you further.

  4. aman says:

    Its not a permissions issue cuz i get 0 bytes written. I wrote the error to the event log and here is what I get:

    I’ve got it working by creating a new stream if its not seekable. The stream seems to be not writebale as well

    If originalStrm.CanSeek Then

    originalStrm.Seek(0, SeekOrigin.Begin)

    Else

    newStrm = New MemoryStream(a_Buffer, 0, totalSizeRead)

    newStrm.Position = 0

    …..

    End If

    Event Type: Error

    Event Source: Archiver

    Event Category: None

    Event ID: 0

    Date: 30/09/2004

    Time: 4:39:14 PM

    User: N/A

    Computer: MIS…

    Description:

    ForwardOnlyEventingReadStream does not support Seek()n at Microsoft.BizTalk.Streaming.ForwardOnlyEventingReadStream.Seek(Int64 offset, SeekOrigin origin)

    at BIZ_PIPELINECOMPONENT_ARCHIVER.BIZ_PIPELINECOMPONENT_ARCHIVER.ArchiveFile.Execute(IPipelineContext pc, IBaseMessage inmsg)

    For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.

  5. In BizTalk Server 2002 I wrote a custom pipeline component in C# to archive inbound messages "just in case" something messed up and the interchange was lost. In BTS2004 I used Gilles Zunino’s [MSFT] excellent Archiver pipeline component.