Interoperabilità tra applicazioni: un approccio orientato ai Web Service

II parte: Java e PHP. Framework di comunicazionedi

Interoperabilità e Web Service. In questo secondo articolo si parlerà di integrazione e interoperabilità dal punto di vista tecnologico. Quali strumenti utilizzare per produrre Web Service eterogenei che siano in grado di parlarsi? Come può un framework facilitare il lavoro di integrazione? Nelle righe successive saremo ancora legati ad una sorta di "teoria tecnologica". Poco codice, insomma. Verranno prese in esame le caratteristiche di un Web Service framework utili a un approccio integrativo, senza però passare alla parte di comunicazione vera e propria la quale sarà trattata nell‘ultimo articolo della serie.

Dall'interoperabilità in generale, passiamo questo mese ai Web Service come strumento per cercare di ottenerla. Un modello architetturale SOA può essere, come evidenziato nel primo articolo, un ottimo paradigma per lo sviluppo e la messa in opera di applicazioni eterogenee che hanno la necessità di comunicare. Ma, dato un modello, quello SOA appunto, lo sviluppatore andrà alla ricerca di tutti quegli strumenti tecnologici che gli possano rendere la vita più semplice nel processo di implementazione del modello. Alla fine, tra gli strumenti da scegliere, dovrà pescare quello che ritiene più adatto alla propria implementazione.
Il successo di un progetto dipende, in prima istanza, da una buona analisi dei requisiti e, in seconda istanza, da un' ottima progettazione: non me ne vogliano gli ingegneri del software se in questo contesto trascuro per semplicità altri fattori. Ma anche la scelta della tecnologia da adottare rappresenta un fattore importante: senza tecnologia è senz'altro ostico proporre al committente qualcosa di funzionante: e difficilmente i committenti amano discorrere di problematiche architetturali. Vogliono qualcosa che funzioni: tecnologia quindi, per sviluppare qualcosa che funzioni bene, che funzioni in fretta e che funzioni al meglio. E perche' questo avvenga, ripeto, non sarà soltanto l'aspetto tecnologico a dettar legge, ma è anche vero che la componente tecnologica è senz'altro da non sottovalutare.
Ora, le modalità di scelta vanno dall'affidare tutto al caso, al ponderare per bene i pro e i contro. Senza trascurare tutte le scale di grigio tra i due estremi.

WS02: Web Service All Inclusive

Una piacevole sorpresa è stata sfornata dalla WS02, azienda il cui business core è proprio la gestione di architetture SOA, dove per gestione si intende qualsiasi cosa ci si possa prendere la briga di immaginare attorno al concetto di servizio. Utilizzando prodotti Open Source già esistenti (tra cui il blasonato Apache Axis2) oppure creati ad hoc, il servizio viene lavorato dal framework e ne viene gestito il ciclo di vita attraverso una serie di strati tecnologici, ognuno dei quali si occupa di un particolare aspetto. Si passa dalla creazione del servizio, al collegamento e alla composizione di due o più servizi per formarne uno più complesso, fino alla gestione del ciclo di vita del servizio una volta in produzione.
In realtà, per le problematiche di integrazione di cui ci occuperemo non è necessaria la conoscenza di tutti gli strati applicativi, anzi sarebbe più corretto dire che non tutti gli strati applicativi sono necessari anche se, una volta individuato il setup minimo del framework, ci si può divertire utilizzando i componenti mancanti per ottimizzare il processo. In ogni caso ne forniremo una panoramica non certo esaustiva ma, come tutte le panoramiche, si spera che sia in grado di regalare qualche stimolo per futuri approfondimenti. Proviamo, quindi, a spendere qualche riga.
Perche' un'infrastruttura SOA inizi a vivere è necessario popolarla di quelli che ne sono i mattoncini costruttivi: i servizi. Ma se i servizi non nascono, sarà difficile passare alla fase di popolamento.
Per la creazione del servizio sono a disposizione dello sviluppatore tre strumenti:

  • Web Services Application Server
  • Web Services Framework
  • Data Services Server

Il primo è un motore di Web Service costruito sulla piattaforma Apache Axis2, gira tranquillamente come applicativo standalone e già out-of-the-box è pronto a creare Web Service utilizzando varie fonti, dalla classe POJO, al JAR, al Web Service Spring. Il secondo (Web Services Framework) è un middleware che permette la creazione di Web Service utilizzando linguaggi diversi, dal C al PHP passando per Python e Ruby. La terza e ultima piattaforma creativa consente, invece, di esporre direttamente come Web Service dati presenti in database relazionali, fogli excel e file CSV. Ottima soluzione per chi ha una necessità immediata di rendere disponibile un servizio senza voler immergersi nell'utilizzo di una soluzione specifica.

Una volta creati, i servizi hanno bisogno di venir fuori dall'isolamento e quindi di comunicare, tenendo ben in mente, però, il concetto di lasco accoppiamente discusso nella parte I. Per indirizzare questa necessità nasce Enterprise Service Bus, costruito a sua volta sulla piattaforma Apache Synapse ESB e in grado di creare strutture a diversi livelli di complessità fino a garantire piena affidabilità e sicurezza di comunicazione.

Ora, dati un mucchio di servizi che vivono e si parlano, è spesso indispensabile imparare ad utilizzare questi elementi per creare qualcosa di più complesso. E non è forse questa un'altra delle caratteristiche per cui si parla spesso di SOA? Stiamo parlando di composizione. E quindi di estensibilità e flessibilità. Mashup Server permette di utilizzare servizi, ma anche pagine web, feed ed altre fonti di informazione per creare altri servizi più complessi, mentre Business Process Server si occupa di composizione di processi scritti secondo lo standard WS-BPEL.

Adesso, con i servizi creati, comunicanti e combinati in strutture più complesse, sembra giunto il momento di gestire, controllare e garantire sicurezza. Abbiamo bisogno di qualcosa o qualcuno che governi e sorvegli, insomma. Governance Registry permette di gestire problematiche di accessibilità, mantenere una libreria di tutti i servizi esistenti e permettere agli utenti di condividere informazioni sui servizi. Identity Service, d'altro canto, fornisce una serie di strumenti per la gestione delle identità, in modo da rendere la piattaforma SOA sicura e ridurre il rischio di attacchi.

La figura 1 illustra l'architettura globale e sintetizza quanto espresso sopra. Per adesso ci soffermeremo sulla parte di creazione del servizio utilizzando in particolar modo Web Service Application Server per la parte Java e Web Application Framework for PHP per la parte PHP.

 

Figura 1 - WS02: panoramica dell'infrastruttura

 

WS02 WSAS: Web Service Application Server

WSAS utilizza Axis2 come Web Service engine. Come al solito un'introduzione ad Axis2 precederà il deployment di un piccolo Web Service d'esempio. Questo, poi, porrà le basi per l'integrazione vera e propria che sarà affrontata nell'ultimo articolo della serie. Per iniziare diciamo - soprattutto per chi ha già lavorato con Axis1 - che Axis2 non è una semplice evoluzione del suo predecessore, ma una rivoluzione vera e propria. Il mondo dei Web Service è forse quello che più ha avvertito cambiamenti profondi in un arco temporale ristretto, con la conseguenza di rendere quasi inutilizzabili framework di prima generazione e di condurre gli sviluppatori ad ingegnarsi per trovare soluzioni nuove che considerassero meglio le specifiche WS* e il fattore prestazionale. Le prestazioni, difatti, hanno spesso rappresentato il collo di bottiglia dei Web Service: però... chi avrebbe scommesso sulla velocità di Java a metà degli anni Novanta?
Prima di tutto Axis2 è un framework a struttura modulare. Prevede, infatti, come illustrato in figura 2, una parte di moduli Core ed una parte di moduli Non Core. I primi sono moduli praticamente indispensabili al funzionamento del framework, mentre i secondi aggiungono fuzionalità molto comode quali la generazione automatica di codice.

Figura 2 - Axis2: moduli

Il motore principale è un motore di tipo SOAP non ibrido, nel senso che funziona solo e soltanto qualcosa con "carburante" SOAP. Tutto quello che invece non è SOAP deve essere convertito prima di alimentare il motore. Ma come funziona questo aggeggio? Quali sono i moduli che lo compongono?
Come detto più volte SOAP e XML sono legati, nel senso che un messaggio SOAP non è altro che un documento XML che contiene un envelope che identifica il messaggio, un header con informazioni sul messaggio, un body con chiamata e risposta ed un elemento fault per la gestione degli errori.
Da qui una delle operazioni fondamentali che un motore Web Service deve eseguire è proprio processare i messaggi XML. XML Processing Model si occupa di tale gestione e non è difficile immaginare che l'efficienza di questa operazione è quella che più impatta sulle prestazioni globali del sistema, trattandosi di un'operazione di parsing che potrebbe rivelarsi notevolmente dispendiosa. Oltre a ciò, l'infrastruttura deve essere capace di spedire e ricevere messaggi SOAP e se ne prende cura il SOAP Processing Model, dotato di un'architettura cosiddetta a due pipe: InPipe per la ricezione e OutPipe per la trasmissione, senza considerare due flussi aggiuntivi per la gestione degli errori in ingresso ed in uscita.
Non appena un messaggio SOAP viene spedito da un applicativo (figura 2) che utilizza il modulo ClientAPI, il motore procede prima di tutto all'attivazione di OutPipe per il flusso in uscita, che a sua volta invoca dei gestori di messaggio registrati (handler) che intercettano il messaggio e lo elaborano, in genere a livello di header, anche se in realtà possono operare anche sul body. Processato, il messaggio viene dato in pasto ad un TrasportSender che lo spedisce ad un TransportReceiver dall'altra parte delle connessione. Il messaggio viene letto e la InPipe attivata: il processo ora è simmetrico a quello di partenza. Dopo aver traversato un'altra catena di handler, il messaggio finalmente può essere dato in pasto a un MessageReceiver che lo consuma.
Dal quadro precedente in realtà mancano due moduli: Information Model e Deployment Model. Il primo si occupa sostanzialmente del ciclo di vita del servizio e della gestione delle sessioni, mentre il secondo si occupa, come dice il nome stesso, della fase di deployment del servizio.
La figura 3 illustra graficamente le fasi principali dell'elaborazione.

Figura 3 - Axis2: elaborazione di un messaggio SOAP

Quanto detto sopra serve per dare un'idea di cosa governa WS02 WSAS. L'installazione dell'infrastruttura è elementare e non richiede nient'altro che la decompressione del binary package (per la versione già compilata) da scaricare dal sito, la JRE 1.5 o superiore ed un sistema operativo quale Linux, Windows o MacOS. Una volta decompresso il package (Windows) è sufficiente settare la variabile d'ambiente JAVA_HOME e lanciare il file /bin/install.bat. Verrà creato un servizio avviabile dalla console di amministrazione. Il sistema funziona tranquillamente in modalità standalone senza necessità di installare alcun Web Server. Istruzioni di installazione dettagliate sono riportate nella guida di installazione. Il codice dell'articolo è stato testato con la versione 3.1.0 su piattaforma Windows 2003 server. Per l'installazione su altre piattaforme ri rimanda alla guida di installazione[7].
Per avere un assaggio delle potenzialità del framework diamo un'occhiata all'interfaccia e proviamo il deployment di una semplice classe POJO come Web Service.

Prima, però, la preparazione della classe. E cosa c'è di meglio per iniziare se non un buon echo service? Il servizio non dovrà fare altro che restituirci la stessa stringa che gli passiamo come parametro. Anzi, facciamogli restituire la stringa senza il primo carattere, tanto per movimentare un attimo le cose. Il codice è quello riportato sotto:

public class NoHeadEchoService {
    public String noHeadEcho (String str) {
        String noHeadString = "";
        if (str!=null && str.length() > 1) {
            noHeadString = str.substring(1);
        }
        return noHeadString;
    }
}

A classe compilata, a meno che non abbiate cambiato qualcosa in fase di installazione, da https://localhost:9443/carbon/ si accede tramite web browser a una pagina in cui sono presenti alcune funzioni di accesso pubblico e una finestra di login sulla destra con la solita richiesta di credenziali per l'accesso alla piattaforma. Quelle di default sono, come non è difficile immaginare, username: admin e password: admin. E' naturale che in fase di produzione occorrerebbe addestrare il nostro cervello ad inventarsi qualcosa di più congeniale.
Una volta autenticati, dal menu di gestione a sinistra attraverso la voce List è possible accedere alla lista dei Web Service attivi e, con la stessa facilità, dal menu Add è possibile aggiungere un Web Service, sia esso una classe POJO, un file JAR, un Web Service Axis2, JAX-WS, Spring. Nel nostro caso utilizziamo il file .class della classe NoHeadEchoService che qualche riga su abbiamo avuto l'accortezza di preparare e compilare.
Ora, utilizzando la voce Pojo Service verrà chiesto di quale file .class si ha la necessità di eseguire il deployment. Scegliamo il nostro EchoService.class e dopo pochi secondi ci ritroveremo con il Web Service attivo (visibile nella lista). Adesso è possible provare immediatamente il servizio (Try this service dalla lista dei Web Service attivi) senza la necessità di preparare alcun client. Ne viene poi presentata la struttura WSDL sia nel formato 1.1 che nel formato 2.0. Selezionando il servizio poi, si ha accesso ai dettagli e ad innumerevoli opzioni di tuning quali sicurezza e affidabilità.
Con qualche click, insomma, siamo venuti a capo del deployment di un servizio implementato in una classe POJO. Si tratta di una semplice classe POJO, certo, ma l'interfaccia grafica intuitiva e il motore potente su cui poggia rendono il framework utilizzabile in contesti ben più complessi.

WS02 Web Services Framework for PHP

WS02 Web Service Framewor for PHP è il tassello mancante della nostra piccola infrastruttura di comunicazione tra applicazioni eterogenee. Almeno perchè i due applicativi si parlino. Poi, naturalmente, è possibile far intervenire tutte le altre parti del framework (Enterprise Service Bus, Identity Service, etc...) perchè si parlino per bene.
Web Services Framework for PHP non è nient'altro che un'estensione PHP che permette di produrre e consumare Web Service. E non eravamo forse alla ricerca di qualcosa che ci permettesse di lavorare con Web Service utilizzando del codice PHP?
L'installazione del framework è un po' più laboriosa rispetto al precedente, ma in ogni caso non complessa e naturalmente richiede la presenza di Apache Web Server con supporto PHP. Per le istruzioni di installazione si rimanda alla guida [8], invitandovi a prestare particolare attenzione ai prerequisiti (in particolar modo alle librerie) necessari al corretto funzionamento del framework. Il codice per l'articolo è stato testato su Windows 2003 server con Apache Web Server 2.2.10, PHP 5.2.6, OpenSSL 0.9.8k, libxml2 2.6.30, iconv 1.9.2. Come IDE PHP è stato utilizzato Aptana 1.5.
Partiamo, anche in questo caso, con lo scrivere un po' di codice e, senza troppa fantasia, anche in questo caso un echo service. Il processo di creazione del servizio prevederà la scrittura della funzione corrispondente all'operazione del Web Service (naturalmente ce ne possono essere più d'una), la creazione di un oggetto WSService e la chiamata del metodo reply dello stesso oggetto per la preparazione della risposta da inviare al richiedente. Prima di tutto la descizione dell'operazione: data una stringa in ingresso,  deve restituire in uscita la stessa stringa. Anzi,  per far le cose simili al Web Service echo scritto in Java, il metodo deve restiruire la stringa in ingresso senza il primo carattere:

function echoNoTail($inMessage) {
    //Payload della richiesta XML
    $simpleXml = new SimpleXMLElement($inMessage->str);
    //Elaborazione del payload XML ed eliminazione della prima lettera
    $retrievedString = $simpleXml->text[0];
    $noHeadString = substr($retrievedString, 1);
    //Preparazione del payload XML per la risposta
    $resPayload = <<<XML
           $noHeadString
    XML;
    //Creazione del messaggio di risposta
    $outMessage = new WSMessage($resPayload);
    return $outMessage;
}

Una volta implementata la funzione che si occuperà di gestire la logica di business (in questo caso in realtà non è che ce ne sia molta di logica) passiamo al mapping della funzione sull'operazione del servizio (richiamata con la richiesta del client) , attraverso la creazione dell'oggetto WSService. Gli passiamo come parametro un array del tipo riportato sotto dove la variabile $operations contiene il mapping operazione => funzione.

//Mapping operazione => funzione
$operations = array("echoString" => "echoNoTail");
//Creazione del Web Service
$service = new WSService(array("operations" => $operations));

A mappatura avvenuta è sufficiente invocare il metodo reply, sempre dell'oggetto WSService, per la preparazione della risposta da spedire al client. Il nostro Web Service è adesso pronto per il deployment. Sotto è riportato il codice completo (file no_head_echo_service.php)

function echoNoTail($inMessage) {
        //Payload della richiesta XML
        $simpleXml = new SimpleXMLElement($inMessage->str);
        //Elaborazione del payload XML ed eliminazione della prima lettera
        $retrievedString = $simpleXml->text[0];
        $noHeadString = substr($retrievedString, 1);
        //Preparazione del payload XML per la risposta
        //Il tag XML finale non deve essere indentato
        $resPayload = <<<XML
        $noHeadString
XML;
        //Creazione del messaggio di risposta
        $outMessage = new WSMessage($resPayload);
        return $outMessage;
}

//Mapping operazione => funzione
$operations = array("echoString" => "echoNoTail");
//Creazione del Web Service
$service = new WSService(array("operations" => $operations));
//Preparazione de invio della risposta al richiedente
$service->reply();
?>

Una volta completato il codice, basterà inserire il file PHP nella directory htdocs del Web Server ed il servizio sarà pronto per essere invocato.
Adesso qualche riga per un client di test. Inizializziamo un oggetto WSClient indicandogli il punto di aggancio del servizio, poi passiamo alla preparazione del payload del messaggio SOAP fino ad inoltrare la richiesta e stampare il payload di risposta. Sotto il codice commentato del client (file no_head_echo_client.php). Dopo aver copiato anch'esso nella directory htdocs del Web Server è possibile invocarlo (http://localhost/no_head_echo_client.php se Apache Web Server è in ascolto sulla porta 80).

    try {
    
    //Costruzione del client
    $client = new WSClient(array( "to" => "http://localhost/no_head_echo_service.php" ));
    
    //Generazione del payload del messaggio di richiesta
    //Il tag XML finale non deve essere indentato
    $requestPayloadXML = <<<XML
    Mokabyte
XML;
    
    //Costruzione del messaggio di richiesta            
    $reqMessage = new WSMessage($requestPayloadXML);
//Invio della richiesta al Web Service
    $responseMessage = $client->request($reqMessage);
    
    //Stampa del payload del messaggio di risposta
    printf("Risposta: %s
",htmlspecialchars($responseMessage->str));
          
    } catch (Exception $e) {
        if ($e instanceof WSFault) {
        printf("Eccezione SOAP: %s
", $e->Reason);
    } else {
        printf("Messaggio = %s
",$e->getMessage());
    }
}
?>

Abbiamo scritto un Web Service in PHP invocato da un client scritto anch'esso in PHP. Nel prossimo articolo analizzeremo in modo più approfondito le problematiche di interoperabilità e le dinamiche di scambio tra client e server.

Conclusioni

In questo articolo sono stati evidenziati alcuni aspetti dell'infrastruttura WS02, in particolar modo un Web Service Application Server che, poggiando su Axis2, riesce a garantire il deployment di Web Service Java della natura più disparata e un framework per costruire e utilizzare Web Service in PHP. Le due piattaforme non sono certo sole, immerse in un contesto Web Service oriented che, oltre alla creazione e al consumo di Web Service in Java e PHP, permette un controllo quasi illimitato del ciclo di vita dei servizi, dalle problematiche di composizione a quelle di autenticazione. Anche in questo caso la trattazione, non potendo certo essere esaustiva, ha cercato di fornire qualche strumento da utilizzare in maniera più intesiva nel prossimo articolo, quando finalmente due applicativi, uno scritto in Java e l'altro scritto in PHP, inizieranno a dialogare.

Riferimenti

[1] Thomas Erl, "SOA, Principles of Service Design", Prentice Hall, 2008

[2] Deepal Jayasinghe, "Quickstart Apache Axis2", Packt Publishing, 2008

[3] W3C,  Web Service Activity
http://www.w3.org/2002/ws/

[4] WS02, The Developer Porta for SOA
http://www.ws02.org

[5] WS02, WSAS Project
http://wso2.org/projects/wsas/java

[6] WS02, WSF for PHP Project
http://wso2.org/projects/wsf/php

[7]WS02, WSAS Installation Guide
http://wso2.org/project/wsas/java/3.1.0/docs/installation_guide.html#Installing

[8]WS02, WSF for PHP Installation Guide
http://wso2.org/project/wsf/php/2.0.0/docs/manual.html

 

 

 

Condividi

Pubblicato nel numero
144 ottobre 2009
Francesco Fumarola si è laureato in Ingegneria Informatica presso il Politecnico di Milano e si occupa di tecnologia Java sin dalla fine degli anni Novanta. Ha lavorato come consulente e project manager in numerosi progetti in ambito Gestionale, CRM e Gestione Documentale. Attualmente si occupa di consulenza Java in ambiente…
Articoli nella stessa serie
Ti potrebbe interessare anche