2012-02-29 14 views
5

Estoy intentando hacer un consumo de prueba de concepto de un servicio web usando Delphi 2010 e Indy. Mi código en este punto es:Debugging SOAP Transmission

procedure TForm1.Log(const sEvent, sMsg: String); 
const sPrior: String = ''; 
begin 
    if sEvent <> sPrior then begin 
    mTraffic.Lines.Append(''); 
    mTraffic.Lines.Append(Format('%s: %s', [sEvent, FormatDateTime('mm/dd/yyyy hh:nn:ss.zzz', Now)])); 
    mTraffic.Lines.Append('--------------------------------------------------------------------------------'); 
    sPrior := sEvent; 
    end; 
    mTraffic.Lines.Append(sMsg); 
    Application.ProcessMessages; 
end; 

function TForm1.BuildRequest: String; 
const MINPERDAY = 1440; 
var slRequest: TStringList; 
    sFileName: String; 
    sID: String; 
    sGUID: String; 
    oDoc: TNativeXML; 
    oNode: TXmlNode; 
    uNow: _SystemTime; 
    dtNow: TDateTime; 
    sNow: String; 
    sNonce: String; 
    oIdmd5: TIdHashMessageDigest5; 
begin 
    sFileName := 'Send.xml'; 
    slRequest := TStringList.Create; 
    oIdmd5 := TIdHashMessageDigest5.Create; 
    oDoc := TNativeXML.Create; 
    try 
    oDoc.LoadFromFile(sFileName); 
    SetAttrib(oDoc, 'inputMessage', 'utc', FormatDateTime('m/d/yyyy hh:mm:ss am/pm', Now)); 
    sGUID := 'urn:uuid' + MyCreateUUID; 
    SetAttrib(oDoc, 'inputMessage', 'messageId', sGUID); 
    SetNode(oDoc, 'wsa:messageId', sGUID); 
    Windows.GetSystemTime(uNow); 
    dtNow := SysUtils.SystemTimeToDateTime(uNow); 
    sNow := FormatDateTime('yyyy-mm-dd"T"hh:mm:ss"Z"', dtNow); 
    sNonce := oIdmd5.HashStringAsHex(sNow + 'Jack' + 'Test' + 'Salt'); 
    SetNodes(oDoc, 'wsu:Created', FormatDateTime('yyyy-mm-dd"T"hh:mm:ss"Z"', dtNow)); 
    SetNode(oDoc, 'wsu:Expires', FormatDateTime('yyyy-mm-dd"T"hh:mm:ss"Z"', dtNow + 5 /MINPERDAY)); 
    SetNode(oDoc, 'wsse:Nonce', sNonce); 
    SetNode(oDoc, 'ElectronicPostmark', FormatDateTime('yyyy-mm-dd"T"hh:mm:ss.zz-8.00', dtNow)); 
    SetNode(oDoc, 'wsse:Username', '#MyUserName#'); 
    SetNode(oDoc, 'wsse:Password', '#MyPassword#'); 
    oDoc.XmlFormat := xfReadable; 
    Result := oDoc.WriteToString; 
    finally 
    slRequest.Free; 
    oIdmd5.Free; 
    oDoc.Free; 
    end; 

end; 

function TForm1.SSLPost(const url: String; sRequest: String): String; 
var lHTTP: TIdHTTP; 
    lIOHandler: TIdSSLIOHandlerSocketOpenSSL; 
    lIDLogDebug: TIdLogDebug; 
    ss: TStringStream; 
begin 
    lHTTP := TIdHTTP.Create(nil); 
    lIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil); 
    lIDLogDebug := TIdLogDebug.Create(nil); 
    ss := TStringStream.Create; 
    try 
    ss.WriteString(sRequest); 
    ss.Position := 0; 
    lIOHandler.SSLOptions.Method := sslvSSLv3; 
    lIOHandler.OnStatusInfo := IdSSLIOHandlerSocketOpenSSL1StatusInfo; 
    lHTTP.IOHandler := lIOHandler; 
    lIdLogDebug.OnSend := IdLogDebug1Send; 
    lIDLogDebug.OnReceive := IdLogDebug1Receive; 
    lIDLogDebug.Active := True; 
    lHTTP.Intercept := lIdLogDebug; 
    try 
     lHTTP.Request.CustomHeaders.Add('SOAPAction: "http://edd.ca.gov/SendTransmission"'); 
     Result := lHTTP.Post(url, ss); 
    except 
     On e: Exception do begin 
     Result := e.Message + #13#10 + '**No Response**'; 
     end; 
    end; 
    finally 
    lHTTP.Free; 
    lIOHandler.Free; 
    lIdLogDebug.Free; 
    ss.Free; 
    end; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
var sResponse: String; 
begin 
    sResponse := SSLPost('https://FSETTESTPROD.EDD.CA.GOV', BuildRequest); 
    Log('Response', sResponse); 
end; 

Nota: Estoy particularmente incierto sobre esta línea justo antes de que el POST

lHTTP.Request.CustomHeaders.Add('SOAPAction: "http://edd.ca.gov/SendTransmission"'); 

De acuerdo con la documentación de los servicios web, que debería llegar ya sea un éxito ACK1 o un error ACK1 con una explicación. Aquí está el resultado que estoy recibiendo en este momento:

SSL: 02/28/2012 16:33:55.609 
    -------------------------------------------------------------------------------- 
    SSL status: "before/connect initialization" 
    SSL status: "before/connect initialization" 
    SSL status: "SSLv3 write client hello A" 
    SSL status: "SSLv3 read server hello A" 
    SSL status: "SSLv3 read server certificate A" 
    SSL status: "SSLv3 read server done A" 
    SSL status: "SSLv3 write client key exchange A" 
    SSL status: "SSLv3 write change cipher spec A" 
    SSL status: "SSLv3 write finished A" 
    SSL status: "SSLv3 flush data" 
    SSL status: "SSLv3 read finished A" 
    SSL status: "SSL negotiation finished successfully" 
    SSL status: "SSL negotiation finished successfully" 
    Cipher: name = RC4-MD5; description = RC4-MD5     SSLv3 Kx=RSA  Au=RSA Enc=RC4(128) Mac=MD5 
    ; bits = 128; version = TLSv1/SSLv3; 

    Send: 02/28/2012 16:33:55.859 
    -------------------------------------------------------------------------------- 
    POST/HTTP/1.0 
    Content-Length: 3130 
    SOAPAction: "http://edd.ca.gov/SendTransmission" 
    Host: FSETTESTPROD.EDD.CA.GOV 
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
    Accept-Encoding: identity 
    User-Agent: Mozilla/3.0 (compatible; Indy Library) 


    <?xml version="1.0" encoding="utf-8"?> 
    <log> 
     <inputMessage utc="2/28/2012 04:32:28 pm" messageId="urn:uuid{4A995507-9E23-49C3-A17C-19C30693C6C1}"> 
     <processingStep description="Unprocessed message"> 
      <soap:Envelope xmlns:xop="http://www.w3.org/2004/08/xop/include" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 
      <soap:Header> 
       <wsa:Action>http://edd.ca.gov/Sendtransmission</wsa:Action> 
       <wsa:MessageID>urn:uuid{4A995507-9E23-49C3-A17C-19C30693C6C1}</wsa:MessageID> 
       <wsa:ReplyTo> 
       <wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address> 
       </wsa:ReplyTo> 
       <wsa:To>http://localhost:3031/EDD.DMRC.FSET.WebServices/FsetService.asmx</wsa:To> 
       <wsse:Security soap:mustUnderstand="1"> 
       <wsu:Timestamp wsu:Id="Timestamp-db31b09e-9283-4ff1-9a57-5b97971328d4"> 
        <wsu:Created>2012-02-29T00:32:28Z</wsu:Created> 
        <wsu:Expires>2012-02-29T00:37:28Z</wsu:Expires> 
       </wsu:Timestamp> 
       <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="SecurityToken-0ac2cf06-b8da-46c8-9314-8081144b09d5"> 
        <wsse:Username>#MyUserName#</wsse:Username> 
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">#MyPassword#</wsse:Password> 
        <wsse:Nonce>0D78327F3F671183149EEC5907A6A5F6</wsse:Nonce> 
        <wsu:Created>2012-02-29T00:32:28Z</wsu:Created> 
       </wsse:UsernameToken> 
       </wsse:Security> 
      </soap:Header> 
      <soap:Body> 
       <SendTransmission xmlns="http://edd.ca.gov/"> 
       <SendTransmissionRequest xmlns="http://www.irs.gov/a2a/mef/MeFTransmitterServiceWse.xsd"> 
        <transmissionDataList> 
        <Count>1</Count> 
        <transmissionData> 
         <transmissionId>123456789</transmissionId> 
         <ElectronicPostmark>2012-02-29T00:32:28.750-8.00</ElectronicPostmark> 
        </transmissionData> 
        </transmissionDataList> 
       </SendTransmissionRequest> 
       <fileBytes>UEsDBBQAAAAIAAaJUzYwks2W0QYAAD2IAAALAAAAREU2</fileBytes> 
       </SendTransmission> 
      </soap:Body> 
      </soap:Envelope> 
     </processingStep> 
     </inputMessage> 
    </log> 

Receive: 02/28/2012 16:33:56.234 
-------------------------------------------------------------------------------- 
HTTP/1.1 200 OK 
Connection: close 
Date: Wed, 29 Feb 2012 00:33:51 GMT 
Server: Microsoft-IIS/6.0 
X-Powered-By: ASP.NET 
Content-Length: 195 
Content-Type: text/html 
Set-Cookie: ASPSESSIONIDCQSQQDSS=BPLHDJLCKCLDKBDMLBNJOMHP; path=/ 
Cache-control: private 

<html> 
<head> 
<title>This location has been marked as available</title> 
</head> 
<body> 
<h1>AVAILABLE</h1> 
This IP address has been assigned to EDD FSET User Test web site. 
</body> 
</html> 

Response: 02/28/2012 16:33:56.281 
-------------------------------------------------------------------------------- 
<html> 
<head> 
<title>This location has been marked as available</title> 
</head> 
<body> 
<h1>AVAILABLE</h1> 
This IP address has been assigned to EDD FSET User Test web site. 
</body> 
</html> 

He estado en el teléfono y correo electrónico de contacto con la agencia que mantiene el servicio web (California EDD). Están motivados para lograr que la mayor cantidad posible de personas adopten esta tecnología y reduzcan la cantidad de papel que tienen que manejar, pero no tienen un conocimiento profundo del sistema porque fue creado por un proveedor externo.

He descargado SOAPUI para tratar de entender mejor el servicio y eliminar cualquier error que pueda ser causado por mi implementación y posible uso indebido de la biblioteca de Indy. No estoy seguro de cómo usar SOAPUI para este propósito. Las instrucciones no parecen abordar mi situación. Si cargo el WSDL en el programa e intento probar una de las funciones, obtengo el resultado de que la prueba terminó con el estado [TERMINADO] y no sé qué hacer con eso.

Agradeceria cualquier ayuda en mi pequeño problema.

+2

Primero, no es "un pequeño problema", por lo que entiendo que prácticamente no tiene documentación, intente importar el WSDL en Delphi y siga su camino desde allí, si el importador WSDL de Delphi lo va a importar, entonces podremos trabaja con eso ... – ComputerSaysNo

+0

@Dorin Estoy de acuerdo en que no es un pequeño problema. Ese fue un intento de mantener la perspectiva. Cuando comencé este proceso usé el importador WSDL para construir mi cliente. Eso fue muy temprano en este proceso. No entendí bien las comunicaciones web y esconder partes de ellas al intentar comprender y depurar mi proceso me pareció contraproducente. Cuando leí de otros usuarios que encontraron que el Importador de WSDL tuvo problemas e hizo un trabajo incompleto, lo abandoné a favor de un enfoque más básico que pensé que podría seguir mejor. – jrodenhi

+2

de mi experiencia pasada con Delphi WSDL Importer, puedo asegurarle que no es fácil, pero el primer paso es usar SOAP UI para probar algunas funciones, luego GUARDAR la "Solicitud/Respuesta" de la interfaz de usuario de SOAP, usando el importador wsdl de Delphi e intento para obtener la misma solicitud/respuesta o similar, entonces creo que podemos ayudar, pero no será fácil, eso es seguro): – ComputerSaysNo

Respuesta

6

SoapUI es el camino a seguir, para ver cómo deberían funcionar las cosas. Utilice los eventos RIO.OnBeforeExecute y AfterExecute para examinar el XML que está enviando y recibiendo. Compare esos a lo que SoapUI envía y recibe. Ignora las diferencias en los espacios de nombres, lo que no debería importar. Idealmente, debería ser capaz de tomar el XML que sale del evento OnBeforeExecute (guardar la secuencia en un archivo de texto o registro), pegarlo en SoapUI, (clic derecho para limpiar/reformatear en SoapUI) y ver si el XML tiene sentido, y vea qué sucede cuando lo envía.

Si resulta que su XML está cerca de funcionar, pero se necesita un 'tweak', puede editar el XML en el evento OnBeforeExecute con StringReplace, etc., y 'arreglar' el XML para que funcione.

+1

Gracias por la respuesta, Chris. Este va a ser el proceso que sigo ahora. Todavía tengo otro problema, pero necesito abrir otra pregunta para él. – jrodenhi