Falkontre’s Blog

Salve a tutti.

Come ben saprete, H3G ha erogato qua e la un bel numero di card “Cinema 3” che permettono la visione di film gratuitamente nei cinema convenzionati.

Il problema nasce dal fatto che la maggior parte della gente, decide in ritardo di andare al cinema, magari solo una volta che ci si è riuniti con gli amici e quindi, conoscere quali film e quali cinema sono convenzionati in quel momento è indispensabile.

Ecco che quindi è spuntata sull’App store una utilissima applicazione per i possessori di Iphone.

Con pochi click è possibile conoscere quale cinema e quale film è disponibile in zona e….via, tutti al cinema.

Potete consultare la pagina dell’autore dell’applicazione qui:

http://www.mariomosca.org/cinema3/

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).

Ciao a tutti.

Con questo post iniziamo il nostro (spero lungo) tutorial sul framework Spring.

Prima di spiegare come funziona Spring, credo sia più opportuno chiarire cos’è e cosa fa.

Cos’è Spring?

Forse una delle cose più difficili quando si parla di Spring come tecnologia, è classificare esattamente cos’è. Tipicamente, Spring viene descritto come un framework lightweight (leggero) per costruire applicazioni Java; Questa frase porta con se due punti interessanti su cui discutere.

La prima cosa da sottolineare è che è possibile utilizzare Spring per ogni tipologia di applicazione Java e, a differenza di altri framework, quali Apache Struts, non ci si limita solo a web applications.

Il secondo punto a cui prestare attenzione è l’aggettivo lightweight il quale non si riferisce al minor numero di classi da scrivere o alla grandezza finale dell’applicazione, bensì è riferito al principio che sta alla base della filosofia di Spring, ovvero, impatto minimo.

Spring è definito leggero nel senso che è necessario apportare davvero pochissime modifiche alla vostra applicazione per poter usufruire della sua potenza.

I benefici apportati al vostro progetto sono notevoli e principalmente:

  • Spring promuove le pratiche di buona programmazione riducendo il costo di programmare via interfacce, piuttosto che tramite classi, quasi a zero.
  • Spring è progettato in modo tale che le applicazioni che ne fanno uso abbiano una dipendenza dal framework molto bassa, anzi buona parte dei business objects non ne hanno alcuna
  • Le applicazioni sviluppate con Spring sono facilmente testabili. Spring Framework fornisce diversi mock objects e classi di supporto per i test.
  • Spring fornisce un framework consistente per l’accesso ai database, sia che si usi JDBC o un O/R mapper tipo TopLink, Hibernate oppure una implementazione di JPA o JDO.

Grazie a Spring, è possibile sviluppare applicazioni complesse dedicandosi solamente alla scrittura di componenti POJO (Plain Old Java Objects) contenenti solo logica di business, lasciando al framework il compito di implementare le soluzioni che non rientrano nella business logic ma che sono necessarie per l’espletamento completo della vostra applicazione.
Vale la pena sottolineare che, siccome la business logic viene astratta dagli aspetti tecnologici (spesso frutto di mode), molto probabilmente questa avrà una vita più lunga, garantendo un ritorno nell’investimento iniziale. Inoltre la business logic dovrebbe evolvere insieme alle esigenze del cliente/committente e l’impatto sul codice viene minimizzato solo se a questa vengono nascosti i dettagli dell’infrastruttura e della tecnologia utilizzata.

Tag: ,

  • 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