Chamada via web service SOAP

Chamada via web service SOAP

Existe uma limitação no tamanho do pacote a ser enviada para nosso web service de integração com o Mega, onde caso o xml a ser enviado tenha um tamanho superior a 1,5Mb, o xml e o processo de envio necessitam ser particionados, e ser enviado uma porção do xml de cada vez.

 

Funcionamento

 

Para o envio do xml em partes, o web service deverá se ser chamado uma vez para cada parte e conforme as partes são enviadas elas ficarão salvas em disco no servidor, assim quando a última parte for enviada todas as outras partes já enviadas serão concatenadas formando novamente o xml e assim dando início ao processo de integração.
A primeira chamada deverá ter o parâmetro 'pPrimeiraParte' com o valor 'true' para indicar que é o início do envio, assim como a última parte também deverá ter o parâmetro 'pUltimaParte' com o valor 'true' para indicar o fim do envio. Ainda na primeira chamada o parâmetro pGUID pode ter o seu valor vazio, uma vez que esse parâmetro será utilizado nas próximas chamadas.

Quando a primeira parte do xml chegar no server, será gerado um 'GUID'(Identificador único universal) aleatoriamente, que será o retorno da primeira chamada dentro da tag 'Mensagem' do xml. Esse 'GUID' será utilizado para compor o nome de cada parte do xml salvo em disco, de forma que o nome será formado pelo 'GUID' seguido da ordem da parte, por exemplo, 1 para primeira parte, 2 para a segunda parte e assim por diante. Por isso, a necessidade de se passar no parâmetro 'pGuid'. 
O 'GUID' gerado na primeira chamada e em todas as demais, é o que determina a ligação entre as partes do xml. Para as demais partes, com exceção da última, a chamada deverá ser feita passando os parâmetros 'pPrimeiraParte' e 'pUltimaParte' com valor false. No parâmetro 'pNumeroParte' deverá ser passado o número da parte a ser enviada, e por fim o parâmetro 'pXml' com o valor da parte a ser enviada. A chamada da última parte é igual as demais, com exceção do parâmetro 'pUltimaParte', que deverá ter o valor 'true'. 
Ao chegar no servidor a última parte, será feita uma busca por todos os arquivos que comecem com o 'GUID passado por parâmetro e o conteúdo dos arquivos será concatenado na sequência, para então formar o xml a ser processado pelo Integrador. 


A responsabilidade de verificar o tamanho do xml é da aplicação que consome o serviço.
O tamanho máximo de uma parte do xml ou do xml inteiro deve ser de 1,5MB, ou transformado em string, a propriedade Length deverá ser menor que 1572864 caracteres.
O retorno da primeira chamada irá retornar um xml em string ou não, dependendo do método, o 'GUID' terá de ser extraído de dentro da tag 'Mensagem'.

 

Resposta

 

Existem dois métodos para enviar o xml em partes que diferem pelo seu retorno: o método IntegraXml retorna um xml e o método IntegraXmlString retorna o xml no formato de string.


Exemplo do retorno em forma de xml do método IntegraXml:

<?xmlversion="1.0"encoding="utf-8"?>
<SOAP-ENV:Envelopexmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:HNS="http://tempuri.org/"xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"xmlns:v1="http://tempuri.org/">
<SOAP-ENV:Header>
<ROClientIDHeaderSOAP-ENV:mustUnderstand="0"xmlns="urn:DefaultLibrary">
<ID>{79F10A36-B949-4D29-8259-DFB6DE03BD50}</ID>
</ROClientIDHeader>
</SOAP-ENV:Header>
<SOAP-ENV:Bodyxmlns:ro="http://tempuri.org/">
<v1:MegaIntegradorService___IntegraXMLPartesResponse>
<v1:Result>
<v1:Erro>false</v1:Erro>
<v1:Mensagem>{17CD37B8-6929-458E-9596-7DE71761D758}</v1:Mensagem>
<v1:CodTransacao>0</v1:CodTransacao>
<v1:PKMega>
</v1:PKMega>
</v1:Result>
</v1:MegaIntegradorService___IntegraXMLPartesResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>


Exemplo do retorno em forma de string do método IntegraXmlString:

<?xmlversion="1.0"encoding="utf-8"?>
<SOAP-ENV:Envelopexmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:HNS="http://tempuri.org/"xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"xmlns:v1="http://tempuri.org/">
<SOAP-ENV:Header>
<ROClientIDHeaderSOAP-ENV:mustUnderstand="0"xmlns="urn:DefaultLibrary">
<ID>{3C441095-BE6A-48DE-A7D8-89380452F11D}</ID>
</ROClientIDHeader>
</SOAP-ENV:Header>
<SOAP-ENV:Bodyxmlns:ro="http://tempuri.org/">
<v1:MegaIntegradorService___IntegraXMLPartesStringResponse>
<v1:Result>&lt;Resultado&gt;&lt;Erro&gt;False&lt;/Erro&gt;&lt;Mensagem&gt;{5512BC3A-1FB4-41B3-960A-A15D39D0B1CC}&lt;/Mensagem&gt;&lt;CodTransacao&gt;0&lt;/CodTransacao&gt;&lt;PKMega&gt;&lt;/PKMega&gt;&lt;/Resultado&gt;</v1:Result>
</v1:MegaIntegradorService___IntegraXMLPartesStringResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

 

Exemplos

 

Implementação em C# .NET.

 

Consumindo em C#

 

Nos links abaixo são exibidos códigos fontes de exemplos, onde é feita uma chamada utilizando a classe IntegradorRequestSoap, que é encarregada de fazer a chamada SOAP. 

 

Chamada

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Xml;

 

namespace Mega.Integrador.WebRequest.Soap

{

publicclassMegaIntegradorClient

{

 

publicXmlDocument IntegraXML(string pServidor, int pPorta, int pPRO_IN_CODIGO, int pUSU_IN_CODIGO, string pXML, string pXMLHeader, string pObs, string pEnviaRecebe, int pTransacao = 0, int ptimeOut = 360000)

{

Mega.Integrador.WebRequest.Soap.IntegradorRequestSoap request = newIntegradorRequestSoap();

string metodo = "IntegraXML";

string responsePrimeiroParte = String.Empty;

string response = String.Empty;

var partesXML = request.QuebraString(pXML);

if(partesXML.Count > 1)

{

metodo = "IntegraXMLPartes";

responsePrimeiroParte = request.CallWebService(pServidor, pPorta, pPRO_IN_CODIGO, pUSU_IN_CODIGO, partesXML[0], pXMLHeader, pObs, pEnviaRecebe, pTransacao, ptimeOut, metodo,"",true);

int indexInicioAux = responsePrimeiroParte.IndexOf("<v1:Mensagem>");

int indexFimAux = responsePrimeiroParte.IndexOf("</v1:Mensagem>");

responsePrimeiroParte = responsePrimeiroParte.Substring(indexInicioAux, indexFimAux - indexInicioAux).Replace("<v1:Mensagem>", "").Replace("</v1:Mensagem>", "");

 

for (int i = 1; i < partesXML.Count - 1; i++)

{

request.CallWebService(pServidor, pPorta, pPRO_IN_CODIGO, pUSU_IN_CODIGO, partesXML[i], pXMLHeader, pObs, pEnviaRecebe, pTransacao, ptimeOut, metodo, responsePrimeiroParte,false,i + 1);

}

 

response = request.CallWebService(pServidor, pPorta, pPRO_IN_CODIGO, pUSU_IN_CODIGO, partesXML[partesXML.Count - 1], pXMLHeader, pObs, pEnviaRecebe, pTransacao, ptimeOut, metodo, responsePrimeiroParte, false, partesXML.Count, true);

}

else

{

response = request.CallWebService(pServidor, pPorta, pPRO_IN_CODIGO, pUSU_IN_CODIGO, pXML, pXMLHeader, pObs, pEnviaRecebe, pTransacao, ptimeOut, metodo);

}

XmlDocument responseDocXml = newXmlDocument();

responseDocXml.LoadXml(response);

return responseDocXml;

}

 

publicstring IntegraXMLString(string pServidor, int pPorta, int pPRO_IN_CODIGO, int pUSU_IN_CODIGO, string pXML, string pXMLHeader, string pObs, string pEnviaRecebe, int pTransacao = 0, int ptimeOut = 360000)

{

Mega.Integrador.WebRequest.Soap.IntegradorRequestSoap request = newIntegradorRequestSoap();

string metodo = "IntegraXMLString";

string responsePrimeiroParte = String.Empty;

string response = String.Empty;

var partesXML = request.QuebraString(pXML);

if(partesXML.Count > 1)

{

metodo = "IntegraXMLPartesString";

responsePrimeiroParte = request.CallWebService(pServidor, pPorta, pPRO_IN_CODIGO, pUSU_IN_CODIGO, partesXML[0], pXMLHeader, pObs, pEnviaRecebe, pTransacao, ptimeOut, metodo, "", true);

int indexInicioAux = responsePrimeiroParte.IndexOf("<v1:Mensagem>");

if (indexInicioAux < 0)

indexInicioAux = responsePrimeiroParte.IndexOf("Mensagem&gt;");

int indexFimAux = responsePrimeiroParte.IndexOf("</v1:Mensagem>");

if (indexFimAux < 0)

indexFimAux = responsePrimeiroParte.IndexOf("&lt;/Mensagem&gt");

 

responsePrimeiroParte = responsePrimeiroParte.Substring(indexInicioAux, indexFimAux - indexInicioAux).Replace("<v1:Mensagem>", "").Replace("</v1:Mensagem>", "").Replace("Mensagem&gt;", "").Replace("&lt;/Mensagem&gt", "");

 

for (int i = 1; i < partesXML.Count - 1; i++)

{

request.CallWebService(pServidor, pPorta, pPRO_IN_CODIGO, pUSU_IN_CODIGO, partesXML[i], pXMLHeader, pObs, pEnviaRecebe, pTransacao, ptimeOut, metodo, responsePrimeiroParte, false, i + 1);

}

 

response = request.CallWebService(pServidor, pPorta, pPRO_IN_CODIGO, pUSU_IN_CODIGO, partesXML[partesXML.Count - 1], pXMLHeader, pObs, pEnviaRecebe, pTransacao, ptimeOut, metodo, responsePrimeiroParte, false, partesXML.Count, true);

}

else

{

response = request.CallWebService(pServidor, pPorta, pPRO_IN_CODIGO, pUSU_IN_CODIGO, pXML, pXMLHeader, pObs, pEnviaRecebe, pTransacao, ptimeOut, metodo);

}

int indexInicio = response.IndexOf("<v1:Result>");

int indexFim = response.IndexOf("</v1:Result>");

return response.Substring(indexInicio, indexFim - indexInicio).Replace("v1:","");

}

}

}

 

Fonte da classe IntegradorRequestSoap

 

Classe encarregada de montar o pacote da chamada SOAP e consumir o webservice, devolvendo uma string com o xml do resultado:

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Net;

using System.Xml;

using System.IO;

using System.Net;

 

namespace Mega.Integrador.WebRequest.Soap

{

publicclassIntegradorRequestSoap

{

 

internalstringCallWebService(string pServidor, int pPorta, int pPRO_IN_CODIGO, int pUSU_IN_CODIGO, string pXML, string pXMLHeader, string pObs, string pEnviaRecebe, int pTransacao = 0, int pTimeOut = 360000, string pMetodo = "IntegraXML", string pGuidMedateXml = "", bool pPrimeiraParte = false, int pNumeroParte = 1, bool pUltimaParte = false)

{

var _url = "http://" + pServidor + ":" + pPorta.ToString() + "/Integrador";

var _action = pMetodo;

 

XmlDocument soapEnvelopeXml = CreateSoapEnvelope(pPRO_IN_CODIGO, pUSU_IN_CODIGO, pXML, pXMLHeader, pObs, pEnviaRecebe, pTransacao, pMetodo, pGuidMedateXml, pPrimeiraParte, pNumeroParte, pUltimaParte );

HttpWebRequest webRequest = CreateWebRequest(_url, _action, pTimeOut);

InsertSoapEnvelopeIntoWebRequest(soapEnvelopeXml, webRequest);

 

//Início do web request assíncrono.

IAsyncResult asyncResult = webRequest.BeginGetResponse(null, null);

asyncResult.AsyncWaitHandle.WaitOne();

//Recuperando a resposta da requisição web completa.

string soapResult;

using (WebResponse webResponse = webRequest.EndGetResponse(asyncResult))

{

using (StreamReader rd = newStreamReader(webResponse.GetResponseStream()))

{

soapResult = rd.ReadToEnd();

}

Console.Write(soapResult);

return soapResult;

}

}

 

 

privateHttpWebRequest CreateWebRequest(string url, string action, int timeOut)

{

HttpWebRequest webRequest = (HttpWebRequest)System.Net.WebRequest.Create(url);

webRequest.Headers.Add("SOAPAction", action);

webRequest.ContentType = "application/x-www-form-urlencoded";

webRequest.Accept = "text/xml";

webRequest.Method = "POST";

webRequest.Timeout = timeOut;

return webRequest;

}

 

private XmlDocument CreateSoapEnvelope(int pPRO_IN_CODIGO, int pUSU_IN_CODIGO, string pXML, string pXMLHeader, string pObs, string pEnviaRecebe, int pTransacao, string metodo = "IntegraXML", string pGuidMedateXml = "", bool pPrimeiraParte = false, int pNumeroParte = 1, bool pUltimaParte = false)

{

XmlDocument soapEnvelop = newXmlDocument();

 

StringBuilder str = newStringBuilder();

str.AppendLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");

str.AppendLine("<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"");

str.AppendLine("xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\"");

str.AppendLine("xmlns:xsd=\"http://www.w3.org/1999/XMLSchema\"> ");

str.AppendLine("<SOAP-ENV:Body>");

str.AppendLine("<" + metodo + " xmlns=\"MegaIntegradorService\"");

str.AppendLine("SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">");

str.AppendLine("<pPRO_IN_ID xsi:type=\"xsd:integer\">" + pPRO_IN_CODIGO.ToString() + "</pPRO_IN_ID>");

str.AppendLine("<pUSU_IN_CODIGO xsi:type=\"xsd:integer\">" + pUSU_IN_CODIGO.ToString() + "</pUSU_IN_CODIGO>");

str.AppendLine("<pXML xsi:type=\"xsd:string\"><![CDATA[" + pXML + "]]></pXML>");

 

if (metodo == "IntegraXMLPartes" || metodo == "IntegraXMLPartesString")

str.AppendLine("<pGuidFile xsi:type=\"xsd:string\">" + pGuidMedateXml + "</pGuidFile>");

str.AppendLine("<pXMLHeader xsi:type=\"xsd:string\"> " + pXMLHeader + "</pXMLHeader>");

str.AppendLine("<pObs xsi:type=\"xsd:string\">" + pObs + "</pObs>");

str.AppendLine("<pEnviaRecebe xsi:type=\"xsd:string\">" + pEnviaRecebe + "</pEnviaRecebe>");

str.AppendLine("<pTransacao xsi:type=\"xsd:integer\">" + pTransacao.ToString() + "</pTransacao> ");

 

if (metodo == "IntegraXMLPartes" || metodo == "IntegraXMLPartesString")

{

str.AppendLine("<pPrimeiraParte xsi:type=\"xsd:boolean\">" + Convert.ToInt32(pPrimeiraParte).ToString() + "</pPrimeiraParte> ");

str.AppendLine("<pNumeroParte xsi:type=\"xsd:integer\">" + pNumeroParte.ToString() + "</pNumeroParte> ");

str.AppendLine("<pUltimaParte xsi:type=\"xsd:boolean\">" + Convert.ToInt32(pUltimaParte).ToString() + "</pUltimaParte> ");

}

str.AppendLine("</" + metodo + ">");

str.AppendLine("</SOAP-ENV:Body>");

str.AppendLine("</SOAP-ENV:Envelope>");

 

soapEnvelop.LoadXml(str.ToString());

return soapEnvelop;

}

 

privatevoid InsertSoapEnvelopeIntoWebRequest(XmlDocument soapEnvelopeXml, HttpWebRequest webRequest)

{

using (Stream stream = webRequest.GetRequestStream())

{

soapEnvelopeXml.Save(stream);

}

}

 

publicList<string> QuebraString(string pXml)

{

int tamanhoLimitParteXml = 1572864;// ~ 1,5Mb

List<string> resultado = newList<string>();

 

if (pXml.Length > tamanhoLimitParteXml)

{

int partes = pXml.Length / tamanhoLimitParteXml;

int restoDivisao = pXml.Length % tamanhoLimitParteXml;

 

if (restoDivisao > 0)

partes++;

 

resultado.Add(pXml.Substring(0, tamanhoLimitParteXml));

 

for (int vContador = 1; vContador < partes - 1; vContador++)

{

resultado.Add(pXml.Substring(tamanhoLimitParteXml * vContador, tamanhoLimitParteXml));

}

 

int inicioUltimaParte = tamanhoLimitParteXml * (partes - 1);

resultado.Add(pXml.Substring(inicioUltimaParte, pXml.Length - inicioUltimaParte));

}

else

resultado.Add(pXml);

 

return resultado;

}

}

}


 

Comments