Messaging mit dem Service Bus ermöglicht die...

Read more

Sebastian Meyer, Microsoft & SAP...

Read more

Für Entwickler, Architekten, Projektleiter und...

Read more

In der Welt der Softwareentwicklung ist die...

Read more

QUIBIQ spendet für den guten Zweck – und für...

Read more

Eine bestimmte Antwort auf einen HTTP Request zu...

Read more

In einer Welt, die von stetigem Wandel geprägt...

Read more

In einem unserer Kundenprojekte, war das Ziel eine...

Read more

QUIBIQ Hamburg wird mit dem Hamburger...

Read more

Zwei Tage lang wurde vom 14.-15.11 wieder das...

Read more

How-to: Message Batching

Im Gegensatz zum Auspacken von Messages gibt es für das Einpacken von Messages keine eingebaute Lösung im Biztalk. Hierfür wird den meisten das Verfahren 'Sequential Convoy' bekannt sein. Hier soll es allerdings nicht um den Convoy gehen, sondern um das Verfahren, einzelne Messages in einen Umschlag zu bekommen.

Kurz zur Erinnerung: Zum Debatchen genügt es, bei einem Schema die Property 'Envelope' auf 'yes' zu setzen und in der Property 'Body XPath' den übergeordneten Knoten der auszupackenden Messages anzugeben, um die XML-ReceivePipeline anzuweisen, alle Elemente unterhalb dieses Knotens als neue Message auszupacken und in der MessageBox abzulegen.

Leider ist das Einpacken nicht so einfach zu erledigen. Da muss man schon selbst Hand anlegen.

Den meisten wird das Verfahren 'Sequential Convoy' bekannt sein. Hier soll es allerdings nicht um den Convoy gehen, sondern um das Verfahren, einzelne Messages in einen Umschlag zu bekommen.

Variante 1 – Mapping

Zwei InputMessages eine OutputMessage:

Input

Process

Output

SammelMessage (n)

MassCopy

SammelMessage (n+1)

SingleMessage

MassCopy

 


Dabei wird die OutputMessage im nächsten Durchgang zur neuen InputMessage. Der Nachteil dieser Lösung besteht darin, dass mit einem Mapping lediglich ein Messagetype verarbeitet werden kann.

Variante 2 – XML Manipulation in Memory

Das Prinzip kurz und knapp:

Ein beliebiger Knoten einer konstruierten Message kann an einen beliebigen Knoten einer SammelMessage anghängt werden.

SingleNode:

XmlDocument xmlSourceDoc, xmlTargetDoc;
XmlElement parentElement,ChildElement;
string sourceChildNodesXPath, targetParentNodeXPath;

sourceChildNodesXPath = "//*[local-name()='Order']";
targetParentNodeXPath = "//*[local-name()='Body']";

xmlSourceDoc = "<Orders>
                                    <Order>
                                        <Nummer>1</Nummer>
                                    </Order>
                                </Orders>"
xmlTargetDoc = "<Envelope>
                                   <Header>
                                       <Party></Party>
                                       <URL></URL>
                                   </Header>
                                   <Body></Body>
                               </Envelope>"

parentElement = (XmlElement)targetDocument.DocumentElement.SelectSingleNode(targetParentNodeXPath);
childElement = (XmlElement)sourceDocument.DocumentElement.SelectSingleNode(sourceChildNodesXPath);

parentElement.AppendChild(childElement);

oder

parentElement.InnerXml = parentElement.InnerXml + childElement.OuterXml;

 

NodeList:

XmlDocument xmlSourceDoc, xmlTargetDoc;
XmlElement parentElement;
XmlNodeList childElements;

string sourceChildNodesXPath, targetParentNodeXPath;

sourceChildNodesXPath = "//*[local-name()='Order']";
targetParentNodeXPath = "//*[local-name()='Body']";

xmlSourceDoc = "<Orders>
                                    <Order>
                                        <Nummer>1</Nummer>
                                    </Order>
                                    <Order>
                                        <Nummer>2</Nummer>
                                    </Order>
                                    <Order>
                                        <Nummer>3</Nummer>
                                    </Order>
                                    <Order>
                                        <Nummer>4</Nummer>
                                    </Order>
                                </Orders>"
xmlTargetDoc = "<Envelope>
                                   <Header>
                                       <Party></Party>
                                       <URL></URL>
                                   </Header>
                                   <Body></Body>
                               </Envelope>"

parentElement = (XmlElement)targetDocument.DocumentElement.SelectSingleNode(targetParentNodeXPath);
childElements = (XmlElement) sourceDocument.SelectNodes(sourceChildNodesXPath);

foreach (XmlElement n in childElements)

{

parentElement.AppendChild(n);

}

oder

 

foreach (XmlElement n in childElements)

{

parentElement.InnerXml = parentElement.InnerXml + n.OuterXml;

}

 

Im BizTalk muss man natürlich die foreach -Schleife mit einer Loop umsetzen.

Da die .NET Klassen XmlElement und XmlNodeList non-serializable sind, ist es notwendig die Aktion mit einem 'atomic Scope' zu umschließen. Die 'SingleNode'-Variante kann in einem ExpressionShape umgesetzt werden.
Es ist allerdings empfehlenswert, den aufgezeigten Vorgang in eine Helper-Methode auszulagern.

Dann könnte man den ganzen Vorgang mit dem folgenden Call ausführen:

sourceChildNodesXPath = @"//*[local-name()='Order']";
targetParentNodeXPath = @"//*[local-name()='Body']";

xmlTargetDoc = MessageAggregator.aggregateElements
                    (xmlSourceDoc, xmlTargetDoc, sourceChildNodesXPath, targetParentNodeXPath);

Nachdem alle Messages eingepackt wurden, braucht man das xmlTargetDoc nur noch der typisierten Message zuweisen und versenden.

 

Variante 3 – XML Manipulation on Disk

Diese Variante stammt noch aus der Rubrik „Not macht erfinderisch“ aus dem Jahre 2006 von Richard Seroter
https://blogs.msdn.microsoft.com/richardbpi/2006/05/08/biztalk-aggregation-pattern-for-large-batches/
und ist insbesondere für sehr große oder sehr viele Messages interessant, wenn Mappings und Speicher zum Problem werden.

 

Wen es interessiert: Einfach den Beitrag unter der obigen Adresse ansehen.

Andreas ConradSenior Developer

© QUIBIQ GmbH · Imprint · Data protection