Criando Custom Pipeline Disassembler - Quebra de FF em N Registros. Parte 2
|
terça-feira, 6 de março de 2012
|
Olá Pessoal. Essa é o segundo post sobre como criar um Custom Pipeline Disassembler.
Na primeira parte do post, falamos sobre quando criar esse tipo de componente, como criar o projeto e adicionar as referencias necessárias.
Como prometido vamos implementar a Interface IDisassemblerComponent.
Nessa interface exige que implementemos basicamente dois métodos: o Disassemble e o GetNext.Adicionando as Bibliotecas
Antes de começar, vamos adicionar a dll Microsoft.Biztalk.XpathReader e Microsoft.BizTalk.Component.UtilitiesBasta clicar em Add Reference e apontar para o caminho abaixo:
C:\Windows\assembly\GAC_MSIL\Microsoft.Biztalk.XpathReader\3.0.1.0__31bf3856ad364e35\Microsoft.Biztalk.XpathReader.dllE precisamos adicionar as seguintes bibliotecas:
C:\Windows\assembly\GAC_MSIL\Microsoft.BizTalk.Component.Utilities\3.0.1.0__31bf3856ad364e35\Microsoft.BizTalk.Component.Utilities.dll
Adicione as váriaveis globais:using System.Resources;
using System.Reflection;using System.Diagnostics;using System.Collections;
using System.ComponentModel;
using System.Xml.XPath;
using System.Xml;
using Microsoft.BizTalk.XPath;
using Microsoft.BizTalk.Message.Interop;
using Microsoft.BizTalk.Component.Interop;
using Microsoft.BizTalk.Component;
using Microsoft.BizTalk.Messaging;
using Microsoft.BizTalk.Component.Utilities;
using Microsoft.Samples.BizTalk.Pipelines.CustomComponent;
Compilando a classe SeekableReadOnlyStreamprivate ArrayList outboundMessages = null; private int currentMessage = 0; private bool stopCollectingMessages = false;
No mundo do Biztalk devemos evitar usar a classe xmlDocument para tratar mensagens grandes (leia-se > 2mb). Junto com a instalação do Biztalk a Microsoft disponibiliza a classe SeekableReadOnlyStream, que pode tratar arquivos > 100 mb. Bastante hein?
Só que, essa classe não é nativa do .NET, ela esta disponivel em um Sample e deve ser compilado e publicado no GAC com strong key (chave de registro).
1 - Então vá até o diretório:
%Diretorio_de_Instalacao%\Microsoft BizTalk Server 2010\SDK\Samples\Pipelines\SchemaResolverComponent\SchemaResolverFlatFileDasm2 - Abra a solution SchemaResolverFlatFileDasm.sln
3 - Acrescente uma strong key e faça o deploy normalmente.
Implementando as Interfaces
Agora no nosso projeto adicione a dll que foi gerada e cole o código abaixo na classe TrataFlatFile.cs1: void IDisassemblerComponent.Disassemble(IPipelineContext pContext, IBaseMessage pInMsg)
2: {3: try
4: {5: base.DocumentSpecName = this.DocumentSpecName;
6: base.Disassemble(pContext, pInMsg);
7: }8: catch (Exception ex)
9: {10: System.Diagnostics.EventLog.WriteEntry("SampleDisassemble", ex.Message,
11: EventLogEntryType.Error); 12: } 13: 14: } 15: 16: IBaseMessage IDisassemblerComponent.GetNext(IPipelineContext pContext) 17: {18: //System.Diagnostics.EventLog.WriteEntry("GetNext:Called", currentMessage.ToString());
19: try
20: {21: if (stopCollectingMessages == false)
22: {23: outboundMessages = new ArrayList();
24: IBaseMessage ibmTemp = base.GetNext(pContext);
25: GetSplittedMessages(ibmTemp, pContext);26: stopCollectingMessages = true;
27: if (0 == outboundMessages.Count)
28: return null;
29: } 30: }31: catch (Exception ex)
32: {33: System.Diagnostics.EventLog.WriteEntry("SampleDisassemble", ex.Message,
34: EventLogEntryType.Error); 35: } 36: 37: if (currentMessage == outboundMessages.Count)
38: return null;
39: // Return the current collected message
40: return (IBaseMessage)outboundMessages[currentMessage++];
41: 42: }Segue o código:
1: private void GetSplittedMessages(IBaseMessage ibmParam, IPipelineContext pCxt)
2: {3: XmlDocument xDoc = new XmlDocument();
4: 5: SeekableReadOnlyStream seek = new SeekableReadOnlyStream(ibmParam.BodyPart.Data);
6: 7: XPathCollection xCollection = new XPathCollection();
8: XPathReader xReader = new XPathReader(new XmlTextReader(seek), xCollection);
9: 10: int iHeader = xCollection.Add("/*[local-name()='Root' and namespace-uri()='Namespace']/*[local-name()='Intercambio' and namespace-uri()='']");
11: 12: bool blnMoveNext = true;
13: int iCont = 1;
14: 15: while (blnMoveNext)
16: { 17: blnMoveNext = xReader.ReadUntilMatch(); 18: iCont++;19: XmlElement xeHeader = xDoc.CreateElement("Header");
20: 21: StringBuilder xml = new StringBuilder();
22: 23: do
24: {25: if ("Header" != xReader.LocalName)
26: {27: switch (xReader.NodeType)
28: {29: case XmlNodeType.Element:
30: xml.Append("<" + xReader.LocalName + ">");
31: if (xReader.IsEmptyElement)
32: xml.Append("<" + xReader.LocalName + "/>");
33: break;
34: case XmlNodeType.Text:
35: xml.Append(xReader.Value);36: break;
37: case XmlNodeType.EndElement:
38: xml.Append("</" + xReader.LocalName + ">");
39: break;
40: case XmlNodeType.XmlDeclaration:
41: xml.Append("</" + xReader.Name + ">");
42: //writer.WriteProcessingInstruction(xReader.Name, xReader.Value);
43: break;
44: } 45: }46: } while (xReader.Read() && !xReader.Match(iHeader));
47: 48: 49: if (iCont > 50) //Quantidade de Registros na quebra
50: { 51: iCont = 1;52: XmlElement xeRoot = xDoc.CreateElement("Root");
53: xeRoot.InnerXml = xml.ToString(); 54: 55: xDoc.AppendChild(xeRoot); 56: 57: IBaseMessage msg = null;
58: msg = pCxt.GetMessageFactory().CreateMessage(); 59: msg.Context = ibmParam.Context; 60: 61: IBaseMessagePart msgPart = pCxt.GetMessageFactory().CreateMessagePart();62: System.IO.MemoryStream memStrm = new MemoryStream();
63: xDoc.Save(memStrm); 64: 65: memStrm.Position = 0; 66: memStrm.Seek(0, System.IO.SeekOrigin.Begin); 67: msgPart.Data = memStrm;68: msg.AddPart(ibmParam.BodyPartName, msgPart, true);
69: 70: outboundMessages.Add(msg); 71: pCxt.ResourceTracker.AddResource(memStrm); 72: } 73: } 74: }Lembrando que é necessário publicar a dll no GAC com o strong key, assim o custom Disassembler criado irá aparecer na tag Pipeline Components.
Conclusão:
Aprendemos neste post a usar a classe SeekableReadOnlyStream que pode tratar arquivos > 100 mb e vimos como quebrar essas mensagens em 50 registros por vez.
Assim quando o Biztalk receber um arquivo com 200 registros irá ser criado 4 instancias contendo 50 registros cada uma.
Espero que tenham gostado! Até a próxima…



Postar um comentário