Falkontre’s Blog

Archive for aprile 2010

Lavorando con Jmeter, ho trovato diverse difficoltà nel trovare esempi o codice che illustrassero il funzionamento di beanshell all’interno della suite di Apache.

Partirei con l’illustrazione del contesto.

Per esigenze particolari, ci è stato richiesto di sviluppare dei web services che accettano come unico parametro l’intero xml di request…ovviamente anche il valore di ritorno è stato gestito allo stesso modo. A questo punto, nelle richieste (e risposte) SOAP viaggia una stringa codificata in Base64 (come array di Byte).

A titolo puramente di esempio, si può immaginare il parametro della request come illustrato di seguito:

<xml>
   <auth>
     <login>pippo</login>
     <password>topolino</password>
   </auth>
   <codiceDocumento>1234</codiceDocumento>
</xml>

Pertanto il messaggio Request SOAP sarà composto nel seguente modo:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://webservice.components.theApp">
 <soapenv:Header/>
 <soapenv:Body>
    <web:recuperaFascicolo>
        <web:firma><xml><auth><login>pippo</login><password>topolino</password></auth><codiceDocumento>1234</codiceDocumento></xml></web:firma>
    </web:recuperaFascicolo>
 </soapenv:Body>
</soapenv:Envelope>

In questo scenario, sono stati utilizzati:

Una volta preparata la test suite, al primo lancio ci siamo resi conto che qualcosa non andava… l’xml di request non può essere passato così come testo, ma va convertito in Base64, pertato la request diviene:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://webservice.components.theApp">
 <soapenv:Header/>
 <soapenv:Body>
    <web:recuperaFascicolo>
        <web:firma>PHhtbD4NCgk8YXV0aD4NCgkJPGxvZ2luPnBpcHBvPC9sb2dpbj4
NCgkJPHBhc3N3b3JkPnRvcG9saW5vPC9wYXNzd29yZD4NCgk8L2F1dGg+DQoJPGNvZGl
jZURvY3VtZW50bz4xMjM0PC9jb2RpY2VEb2N1bWVudG8+DQo8L3htbD4=</web:firma>
    </web:recuperaFascicolo>
 </soapenv:Body>
</soapenv:Envelope>

Ovviamente, qualcosa del genere è decisamente poco human-friendly e cambiare anche un solo parametro nell’xml di richiesta richiede la ricodifica in base64.

Per ovviare a tutto ciò, la soluzione adottata bisogna:

  • Inserire la richiesta xml in una variabile (o in un csv per avere più casistiche)
  • BeanShell PreProcessor per l’encode
  • WebService (SOAP) Request con variabile contenente l’xml di request codificato in base 64
    ........
    <web:recuperaFascicolo>
        <web:firma>${requestMsg}</web:firma>
    </web:recuperaFascicolo>
    ........
  • Regular Expression Extractor per estrarre la risposta codificata in base64
  • BeanShell PostProcessor per effetture il decode cella risposta estratta precedentemente
  • BeanShell Assertion (per effettuare la valutazione della risposta decodificata)

Prima di esaminare nel dettaglio i vari componenti, è necessario copiare nella directory lib di Jmeter (o altrove) le librerie di “beanshell” e di “java base64″ e far puntare quest’ultima nel test plan.

Vediamo ora nel dettaglio i componenti.

  • User defined Variables:
    • Definisco la variabile “input” il cui valore è il file xml rappresentante il parametro della request SOAP

  • Beanshell Coder PreProcessor:
    • All’interno del Thread Group, inserisco il beanshell preprocessor e codifico il seguente script bsh:

import it.sauronsoftware.base64.Base64;
encoded = Base64.encode(vars.get("input")).trim();
vars.put("requestMsg",encoded)

nella riga 1 si esegue l’import della classe Base64 contenuta nel file javabase64-x.x.x.jar, dopodichè viene valorizzata la variabile encoded contenuta nella Jmeter Variable input (importante effettuare il trim( ) per evitare errori di parsing). Per finire, copio la stringa codificata in base64 nella Jmeter Variable requestMsg.

  • WebService (SOAP) Request:
    • Nel messaggio SOAP verrà usata la variabile ${requestMsg} e assicurarsi di usare di impostare il flag Read SOAP Response
    ........
    <web:recuperaFascicolo>
        <web:firma>${requestMsg}</web:firma>
    </web:recuperaFascicolo>
    ........
  • Regular Expression Extractor:
    • Questo componente estrae una porzione dalla response. Nel nostro caso, siamo interessati a tutto ciò che viene restituito dal messaggio SOAP (ad eccezione della SOAP response stessa).

Il primo valore è il nome della variabile in cui verrà inserito il risultato dell’estrazione, mentre nel secondo dobbiamo indicare l’espressione regolare da estrarre. Le altre tre, in questo contesto, non hanno utilità.

  • Beanshell Decoder PostProcessor:
    • In questo caso si effettua l’operazione di decoder similmente al preProcessor con lo script bsh:

import it.sauronsoftware.base64.Base64;
decoded = Base64.decode(vars.get("RESULT")).trim();
vars.put("decoded",decoded)

  • Beanshell Assertion:
    • Visto che non è possibile effettuare una normale Response Assertion (la risposta contiene i dati binari), è necessario effettuare la verifica delle condizioni con un apposito script bsh:

if (vars.get("decoded").contains ("<codicemessaggio>"+vars.get("codeOk")+"</codicemessaggio>") ) {
 Failure=true;
 FailureMessage =  vars.get("decoded");
}

Viene verificato che nel messaggio di risposta decodificato ci sia il tag <codicemessaggio>xxx</codicemessaggio>, se così fosse si imposta la variabile predefinita Failure a true e si stampa l’xml di response (visibile nell’ Assertion results listener).



  • Nessuno.
  • Roberto: ma il nuovo articolo sarà a pagamento? giù alla stella vogliono imparare spring :-)
  • Luca: Non per dire ma il contenuto di questo articolo lo trovi ovunque tu vada. Un tutorial è utile se spiega in maniera completa l'argomento in questione.
  • falkontre: Mi rincuora davvero molto questo tuo commento...anzi, mi stimola a prendere in considerazione l'idea di trovare il tempo per riprendere a scrivere! Gr

Categorie