Diffuser en continu Flat-File des IDOC dans SAP à l’aide du modèle de canal WCF
L’adaptateur Microsoft BizTalk pour mySAP Business Suite prend en charge la diffusion en continu de valeur de nœud pour les opérations SendIdoc et ReceiveIdoc. Ces opérations sont utilisées pour envoyer et recevoir des AIDO de fichier plat (chaîne) vers et depuis l’adaptateur. Dans ces deux opérations, les données de l’ensemble de l’IDOC sont contenues dans une chaîne sous un seul nœud (<idocData>). Pour les IDOC volumineux, la diffusion en continu des données IDOC entre l’adaptateur et votre code peut économiser des ressources mémoire importantes.
Pour obtenir des informations générales sur la façon dont l’adaptateur prend en charge la diffusion en continu, consultez Streaming et l’adaptateur SAP. Vous devez lire cette rubrique avant de continuer.
Les sections de cette rubrique décrivent comment implémenter la diffusion en continu de valeur de nœud pour les opérations SendIdoc et ReceiveIdoc lorsque vous utilisez le modèle de canal WCF.
Streaming Outbound Flat-File IDOCs vers l’adaptateur
L’adaptateur prend en charge la diffusion en continu de valeur de nœud sur le message de demande pour l’opération SendIdoc.
Pour prendre en charge la diffusion en continu de valeur de nœud sur les opérations SendIdoc dans le modèle de canal WCF, vous devez :
Implémentez un System.ServiceModel.Channels.BodyWriter capable de diffuser en continu les données IDOC (en effectuant une diffusion en continu de valeur de nœud sur les données IDOC).
Créez le System.ServiceModel.Message utilisé pour appeler l’opération en fournissant le corps du message avec ce BodyWriter à l’aide d’une surcharge appropriée de la méthode Message.Create .
Implémentation d’un BodyWriter
L’exemple suivant montre une implémentation d’un BodyWriter qui effectue une diffusion en continu de valeur de nœud.
/// <summary>
/// This class overrides the OnWriteBodyContents function to do node-value streaming
/// </summary>
class StreamingBodyWriter : BodyWriter, IDisposable
{
XmlReader m_reader = null;
int m_chunkSize;
/// <summary>
/// Initializes the body writer
/// </summary>
/// <param name="reader">Reader for input</param>
/// <param name="chunkSize">The chunksize in which the data is passed to adapter</param>
public StreamingBodyWriter(XmlReader reader, int chunkSize)
: base(false)
{
m_reader = reader;
if (chunkSize <= 0)
throw new ApplicationException("ChunkSize should be a positive value");
m_chunkSize = chunkSize;
}
protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
{
if (m_reader == null)
throw new ApplicationException("Reader cannot be null");
while (m_reader.Read())
{
switch (m_reader.NodeType)
{
case XmlNodeType.Element:
writer.WriteStartElement(m_reader.LocalName, m_reader.NamespaceURI);
break;
case XmlNodeType.Text:
#region Streaming Code
char[] tempBuffer = new char[m_chunkSize];
int length = 0;
while ((length = m_reader.ReadValueChunk(tempBuffer, 0, m_chunkSize)) > 0)
{
writer.WriteString(new String(tempBuffer, 0, length));
}
#endregion
break;
case XmlNodeType.EndElement:
writer.WriteEndElement();
break;
}
}
}
#region IDisposable Members
public void Dispose()
{
if (m_reader != null)
{
m_reader.Close();
m_reader = null;
}
}
#endregion
}
Création d’un message à l’aide d’un BodyWriter
L’exemple suivant montre comment créer un message de requête SendIdoc à l’aide de BodyWriter dans l’exemple précédent. Les données de message sont lues à partir d’un fichier.
XmlReader readerIn = XmlReader.Create ("sendidoc.xml");
// StreamingBodyWrtier class is responsible for streaming
StreamingBodyWriter stBW = new StreamingBodyWriter(readerIn, chunkSize);
Message InputMsg = Message.CreateMessage(MessageVersion.Default,
"http://Microsoft.LobServices.SAP/2007/03/Idoc/SendIdoc",
stBW);
Streaming inbound Flat-File IDOCs à partir de l’adaptateur
Vous recevez un fichier plat IDOCs dans l’opération ReceiveIdoc entrante. L’adaptateur prend en charge le streaming node-value sur le message de demande pour l’opération ReceiveIdoc.
Pour prendre en charge la diffusion en continu de valeur de nœud sur les opérations ReceiveIdoc dans le modèle de canal WCF, vous devez :
Implémentez un System.Xml. XmlDictionaryWriter capable de diffuser en continu les données IDOC (exécution d’une diffusion en continu de valeur de nœud sur les données IDOC).
Consommez le message en appelant sa méthode WriteBodyContents avec ce XmlDictionaryWriter.
Implémentation d’un XmlDictionaryWriter
L’exemple suivant montre une implémentation d’un XmlDictionaryWriter qui effectue une diffusion en continu de valeur de nœud.
using System;
using System.Xml;
using System.Text;
class FileXmlWriter : XmlDictionaryWriter
{
XmlTextWriter xts;
public FileXmlWriter(string file)
{
xts = new XmlTextWriter(file, Encoding.UTF8);
}
public override void WriteBase64(byte[] buffer, int index, int count)
{
xts.WriteBase64(buffer, index, count);
}
public override void WriteCData(string text)
{
xts.WriteCData(text);
}
public override void WriteCharEntity(char ch)
{
xts.WriteCharEntity(ch);
}
public override void WriteChars(char[] buffer, int index, int count)
{
xts.WriteChars(buffer, index, count);
}
public override void WriteComment(string text)
{
xts.WriteComment(text);
}
public override void WriteDocType(string name, string pubid, string sysid, string subset)
{
xts.WriteDocType(name, pubid, sysid, subset);
}
public override void WriteEndAttribute()
{
xts.WriteEndAttribute();
}
public override void WriteEndDocument()
{
xts.WriteEndDocument();
}
public override void WriteEndElement()
{
xts.WriteEndElement();
}
public override void WriteEntityRef(string name)
{
xts.WriteEntityRef(name);
}
public override void WriteFullEndElement()
{
xts.WriteFullEndElement();
}
public override void WriteProcessingInstruction(string name, string text)
{
xts.WriteProcessingInstruction(name, text);
}
public override void WriteRaw(string data)
{
xts.WriteRaw(data);
}
public override void WriteRaw(char[] buffer, int index, int count)
{
xts.WriteRaw(buffer, index, count);
}
public override void WriteStartAttribute(string prefix, string localName, string ns)
{
xts.WriteStartAttribute(prefix, localName, ns);
}
public override void WriteStartDocument(bool standalone)
{
xts.WriteStartDocument(standalone);
}
public override void WriteStartDocument()
{
xts.WriteStartDocument();
}
public override void WriteStartElement(string prefix, string localName, string ns)
{
xts.WriteStartElement(localName);
}
public override void WriteString(string text)
{
xts.WriteString(text);
}
public override void WriteSurrogateCharEntity(char lowChar, char highChar)
{
xts.WriteSurrogateCharEntity(lowChar, highChar);
}
public override void WriteWhitespace(string ws)
{
xts.WriteWhitespace(ws);
}
public override void Close()
{
xts.Close();
}
public override void Flush()
{
xts.Flush();
}
public override string LookupPrefix(string ns)
{
return xts.LookupPrefix(ns);
}
public override WriteState WriteState
{
get { return xts.WriteState; }
}
}
Consommation d’un message à l’aide d’un xmlDictionaryWriter
L’exemple suivant montre comment utiliser un message de requête ReceiveIdoc à l’aide de FileXmlWriter implémenté dans l’exemple précédent. (La classe FileWriter a été créée en sous-classant XmlDictionaryWriter.) L’exemple utilise un canal IReplyChannel pour recevoir l’opération ReceiveIdoc. Les détails de la création du canal ont été omis. Le message de demande ReceiveIdoc est écrit dans un fichier.
// Receive the ReceiveIdoc request message from the adapter.
RequestContext rc = channel.ReceiveRequest();
Message inputMsg = rc.RequestMessage;
// Stream the request message to received_idoc.xml using the custom XmlDictionaryWriter.
FileXmlWriter fileXmlWriter = new FileXmlWriter("received_idoc.xml");
inputMsg.WriteBodyContents(fileXmlWriter);
fileXmlWriter.Flush();
fileXmlWriter.Close();
Voir aussi
Développer des applications en utilisant le modèle de canal WCF