BizTalk Server General - REPOSTING - Only get one message from a disassembler

This is Interesting: Free IT Magazines  
Home > Archive > BizTalk Server General > May 2005 > REPOSTING - Only get one message from a disassembler





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author REPOSTING - Only get one message from a disassembler
Devon Cochenour

2005-05-02, 5:50 pm

Reposting since I never heard anything back from the first post.

I have created a custom disassembler that is being used to do some work on a
large XML file that is received and then parsed into many smaller docs, some
work done on those docs and then sent back to bts as many small docs.

I have gotten the code to run successfully, but all that ever happens is
that I only ever get ONE document back. Its the first one of the batch of
smaller documents, but thats it. I am at a loss as to what I am missing.

The code looks like this.

public IBaseMessage GetNext(IPipelineContext pContext)
{


return disassembler.GetNext(pContext);
}

public void Disassemble(IPipelineContext pContext, IBaseMessage pInMsg)
{
if (null == pContext)
throw new ArgumentNullException("pContext");

if (null == pInMsg)
throw new ArgumentNullException("pInMsg");


// Check whether input message doesn't have a body part or it is set to
null, fail probe in those cases
if (null == pInMsg.BodyPart || null ==
pInMsg.BodyPart.GetOriginalDataStream())
throw new ArgumentNullException("pInMessage","The inbound message has no
message body");

Stream sourceStream = pInMsg.BodyPart.GetOriginalDataStream();


try
{

IDocumentSpec documentSpec =
pContext.GetDocumentSpecByType("urn:mdWebService#ResponseRecord");

pInMsg.Context.Write(DocumentSpecNamePropertyName, "urn:mdWebService",
documentSpec.DocSpecStrongName);

originalMsgContext = PipelineUtil.CloneMessageContext(pInMsg.Context);

xmlDoc.Load(sourceStream);



if (xmlDoc != null)
{
XmlNodeList xmlNodeList = xmlDoc.GetElementsByTagName("ResponseRecord");

string sNodeData;


sNodeData = xmlNodeList.Item(i).OuterXml;

while(i<xmlNodeList.Count)
{

XmlDocument xmlNewDoc = new XmlDocument();
xmlNewDoc.LoadXml(sNodeData);
EventLog.WriteEntry("CASS_Orchestration",xmlNewDoc.OuterXml.ToString());

MemoryStream newStream = new MemoryStream();

byte[] bData = System.Text.Encoding.UTF8.GetBytes(sNodeData);

newStream.Flush();

newStream.Write(bData,0,bData.Length);

newStream.Seek(0,SeekOrigin.Begin);

newMsg = pContext.GetMessageFactory().CreateMessage();

IBaseMessagePart newMsgPart =
pContext.GetMessageFactory().CreateMessagePart();

newMsgPart.Charset = "UTF-8";

newMsgPart.Data = newStream;

newMsg.AddPart("body", newMsgPart, true);

for (int iProp = 0; iProp < originalMsgContext.CountProperties; iProp++)

{

string strName;

string strNSpace;

object val = originalMsgContext.ReadAt(iProp, out strName, out
strNSpace);


if (originalMsgContext.IsPromoted(strName, strNSpace))

newMsg.Context.Promote(strName, strNSpace, val);

else

newMsg.Context.Write(strName, strNSpace, val);

}

pContext.ResourceTracker.AddResource(newStream);

i++;

disassembler.Disassemble(pContext,newMsg);


}
sourceStream.Seek(0,SeekOrigin.End);

}

}

--
Devon Cochenour
MCSD, MCT MSF Master Trainer


Michel Prévost

2005-05-03, 5:52 pm

I went through your code, and I cannot see the content of the GetNext()
method. I refer to the return disassembler.GetNext(pContext) call. It is
difficult to see what is wrong here.
But you seem to build numerous messages and pass them to the
disassembler.Disassemble() method many times. (By the way, what is that
"disassembler" object?).

Usually, the Disassemble() method is called only once. In your
implementation, you usually save the incoming message. Then, the BTS
framework calls your GetNext() method repeatedly, until you return "null",
to indicate BizTalk that there are no more messages.

Some advice here:

- You mention that your document may be large. Don't load it into an
XmlDocument object. Instead use a XmlTextReader object.
- Save that reader into a member variable, and access it as needed, when
your GetNext() method is called. That way, you will be more memory-friendly,
and probably will execute faster.

So, in your Disassemble() implementation, instead of building all your
messages, just save the XmlTextReader object you opened on the input stream
(pInMsg.BodyPart.Data). Position the reader at the first "ResponseRecord"
node, and exit the Disassemble method.

When the GetNext() method is called, read the content of the node, build the
message to return, position the reader to the next "ResponseRecord" node (if
there is no more nodes, set a member flag that indicates there is no more
messages, so you can return null on the next GetNext() call), and return the
newly built message. Again, I would avoid using MemoryStream. Here is a good
link to pipeline processing:
http://geekswithblogs.net/cyoung/articles/13490.aspx

Hope this helps
Michel

"Devon Cochenour" <devonc_1@msn.com> wrote in message
news:96462717-2837-40FD-B4B9-807484D9870C@microsoft.com...
> Reposting since I never heard anything back from the first post.
>
> I have created a custom disassembler that is being used to do some work on
> a
> large XML file that is received and then parsed into many smaller docs,
> some
> work done on those docs and then sent back to bts as many small docs.
>
> I have gotten the code to run successfully, but all that ever happens is
> that I only ever get ONE document back. Its the first one of the batch of
> smaller documents, but thats it. I am at a loss as to what I am missing.
>
> The code looks like this.
>
> public IBaseMessage GetNext(IPipelineContext pContext)
> {
>
>
> return disassembler.GetNext(pContext);
> }
>
> public void Disassemble(IPipelineContext pContext, IBaseMessage pInMsg)
> {
> if (null == pContext)
> throw new ArgumentNullException("pContext");
>
> if (null == pInMsg)
> throw new ArgumentNullException("pInMsg");
>
>
> // Check whether input message doesn't have a body part or it is set to
> null, fail probe in those cases
> if (null == pInMsg.BodyPart || null ==
> pInMsg.BodyPart.GetOriginalDataStream())
> throw new ArgumentNullException("pInMessage","The inbound message has no
> message body");
>
> Stream sourceStream = pInMsg.BodyPart.GetOriginalDataStream();
>
>
> try
> {
>
> IDocumentSpec documentSpec =
> pContext.GetDocumentSpecByType("urn:mdWebService#ResponseRecord");
>
> pInMsg.Context.Write(DocumentSpecNamePropertyName, "urn:mdWebService",
> documentSpec.DocSpecStrongName);
>
> originalMsgContext = PipelineUtil.CloneMessageContext(pInMsg.Context);
>
> xmlDoc.Load(sourceStream);
>
>
>
> if (xmlDoc != null)
> {
> XmlNodeList xmlNodeList = xmlDoc.GetElementsByTagName("ResponseRecord");
>
> string sNodeData;
>
>
> sNodeData = xmlNodeList.Item(i).OuterXml;
>
> while(i<xmlNodeList.Count)
> {
>
> XmlDocument xmlNewDoc = new XmlDocument();
> xmlNewDoc.LoadXml(sNodeData);
> EventLog.WriteEntry("CASS_Orchestration",xmlNewDoc.OuterXml.ToString());
>
> MemoryStream newStream = new MemoryStream();
>
> byte[] bData = System.Text.Encoding.UTF8.GetBytes(sNodeData);
>
> newStream.Flush();
>
> newStream.Write(bData,0,bData.Length);
>
> newStream.Seek(0,SeekOrigin.Begin);
>
> newMsg = pContext.GetMessageFactory().CreateMessage();
>
> IBaseMessagePart newMsgPart =
> pContext.GetMessageFactory().CreateMessagePart();
>
> newMsgPart.Charset = "UTF-8";
>
> newMsgPart.Data = newStream;
>
> newMsg.AddPart("body", newMsgPart, true);
>
> for (int iProp = 0; iProp < originalMsgContext.CountProperties; iProp++)
>
> {
>
> string strName;
>
> string strNSpace;
>
> object val = originalMsgContext.ReadAt(iProp, out strName, out
> strNSpace);
>
>
> if (originalMsgContext.IsPromoted(strName, strNSpace))
>
> newMsg.Context.Promote(strName, strNSpace, val);
>
> else
>
> newMsg.Context.Write(strName, strNSpace, val);
>
> }
>
> pContext.ResourceTracker.AddResource(newStream);
>
> i++;
>
> disassembler.Disassemble(pContext,newMsg);
>
>
> }
> sourceStream.Seek(0,SeekOrigin.End);
>
> }
>
> }
>
> --
> Devon Cochenour
> MCSD, MCT MSF Master Trainer
>
>



Devon Cochenour

2005-05-03, 5:52 pm

That did the trick, The problem was more when I was returning the message,
and how the class was called that was confusing me. Once you explained how
to use the GetNext Method and I moved all my message construction there, I
was golden! Thanx for your assistance! Dev

"Michel Prévost" wrote:

> I went through your code, and I cannot see the content of the GetNext()
> method. I refer to the return disassembler.GetNext(pContext) call. It is
> difficult to see what is wrong here.
> But you seem to build numerous messages and pass them to the
> disassembler.Disassemble() method many times. (By the way, what is that
> "disassembler" object?).
>
> Usually, the Disassemble() method is called only once. In your
> implementation, you usually save the incoming message. Then, the BTS
> framework calls your GetNext() method repeatedly, until you return "null",
> to indicate BizTalk that there are no more messages.
>
> Some advice here:
>
> - You mention that your document may be large. Don't load it into an
> XmlDocument object. Instead use a XmlTextReader object.
> - Save that reader into a member variable, and access it as needed, when
> your GetNext() method is called. That way, you will be more memory-friendly,
> and probably will execute faster.
>
> So, in your Disassemble() implementation, instead of building all your
> messages, just save the XmlTextReader object you opened on the input stream
> (pInMsg.BodyPart.Data). Position the reader at the first "ResponseRecord"
> node, and exit the Disassemble method.
>
> When the GetNext() method is called, read the content of the node, build the
> message to return, position the reader to the next "ResponseRecord" node (if
> there is no more nodes, set a member flag that indicates there is no more
> messages, so you can return null on the next GetNext() call), and return the
> newly built message. Again, I would avoid using MemoryStream. Here is a good
> link to pipeline processing:
> http://geekswithblogs.net/cyoung/articles/13490.aspx
>
> Hope this helps
> Michel
>
> "Devon Cochenour" <devonc_1@msn.com> wrote in message
> news:96462717-2837-40FD-B4B9-807484D9870C@microsoft.com...
>
>
>

Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com