2012-02-29 17 views
5

Sto tentando di eseguire un consumo proof-of-concept di un servizio Web utilizzando Delphi 2010 e Indy. Il mio codice a questo punto è:Debug di trasmissione SOAP

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: Sono particolarmente incerto su questa linea appena prima del POST

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

Secondo la documentazione servizio web, dovrei ottenere sia un successo ACK1 o un errore ACK1 con una spiegazione. Ecco il risultato che sto ottenendo a questo punto:

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> 

Sono stato nel telefono ed e-mail di contatto con l'agenzia che mantiene il servizio web (California EDD). Sono motivati ​​ad avere il maggior numero di persone possibile per adottare questa tecnologia e ridurre la quantità di carta che devono gestire ma non hanno una conoscenza approfondita del sistema perché è stata creata da un fornitore esterno.

Ho scaricato SOAPUI per cercare di capire meglio il servizio ed eliminare eventuali errori che potrebbero essere causati dalla mia implementazione e possibile uso improprio della libreria di Indy. Non sono sicuro di come usare SOAPUI per questo scopo. Le istruzioni non sembrano affrontare la mia situazione. Se carico il WSDL nel programma e provo a testare una delle funzioni, ottengo il risultato che il test è terminato con lo stato [FINITO] e non so cosa fare di questo.

Apprezzerei qualsiasi aiuto sul mio piccolo problema.

+2

In primo luogo, non è "un piccolo problema", da quello che ho capito tu non hai praticamente documentazione, prova a importare il WSDL in Delphi e fai il tuo percorso da lì, se Delphi l'importatore di WSDL lo importerà, allora potremmo essere in grado di lavoro con quello ... – ComputerSaysNo

+0

@Dorin Sono d'accordo che non è un piccolo problema. Quello era un tentativo di mantenere la prospettiva. Quando ho iniziato questo processo, ho utilizzato l'utilità di importazione WSDL per creare il mio client. Questo è stato abbastanza presto in questo processo. Non ho capito bene le comunicazioni web e nasconderne alcune parti mentre cercavo di capire e fare il debug del mio processo mi sembrava controproducente. Quando ho letto di altri utenti che hanno scoperto che l'Importer WSDL ha avuto problemi e ha svolto un lavoro incompleto, l'ho abbandonato a favore di un approccio più basilare che pensavo di poter seguire meglio. – jrodenhi

+2

della mia esperienza passata con Delphi WSDL Importer, posso assicurarti che non è facile, ma il primo passo è utilizzare l'interfaccia utente SOAP per testare alcune funzioni, quindi SALVA la "Richiesta/Risposta" dall'interfaccia utente SOAP, usando l'importazione e l'importazione wsdl di delphi per ottenere la stessa richiesta/risposta o simili, quindi penso che possiamo aiutare, ma non sarà facile, questo è sicuro): – ComputerSaysNo

risposta

6

SoapUI è la strada da percorrere, per vedere come dovrebbero funzionare le cose. Utilizzare gli eventi RIO.OnBeforeExecute e AfterExecute per esaminare il codice XML che si sta inviando e ricevendo. Confronta quelli con ciò che SoapUI invia e riceve. Ignora le differenze negli spazi dei nomi, che non dovrebbero avere importanza. Idealmente, dovresti essere in grado di prendere l'XML che esce dall'evento OnBeforeExecute (salva lo stream in un file di testo o in un log), incollalo in SoapUI, (fai clic con il tasto destro del mouse per pulire/riformattare in SoapUI) e vedi se l'XML ha senso, e vedere cosa succede quando lo si sottomette.

Se risulta che il vostro XML è vicino al funzionamento, ma è necessario un "aggiustamento", è possibile modificare l'XML nell'evento OnBeforeExecute con StringReplace, ecc. E "correggere" l'XML in modo che funzioni.

+1

Grazie per la risposta, Chris. Questo sarà il processo che seguo ora. Ho ancora un altro problema, ma ho bisogno di aprire un'altra domanda per questo. – jrodenhi