11.04.2013 Views

Implementazione di un linguaggio di base per servizi web

Implementazione di un linguaggio di base per servizi web

Implementazione di un linguaggio di base per servizi web

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Università degli Stu<strong>di</strong> <strong>di</strong> Firenze<br />

FACOLTÀ DI SCIENZE MATEMATICHE, FISICHE E NATURALI<br />

Relatore:<br />

Prof. Rosario Pugliese<br />

Correlatore:<br />

Dott. Francesco Tiezzi<br />

Tesi <strong>di</strong> Laurea in Informatica<br />

<strong>Implementazione</strong> <strong>di</strong> <strong>un</strong><br />

<strong>linguaggio</strong> <strong>di</strong> <strong>base</strong><br />

<strong>per</strong> <strong>servizi</strong> <strong>web</strong><br />

Anno Accademico 2008/2009<br />

Can<strong>di</strong>dato:<br />

Leonardo Nuti


Ai miei genitori,<br />

ai miei amici<br />

e a Eleonora.


In<strong>di</strong>ce<br />

1 Introduzione 11<br />

2 Supporti <strong>per</strong> la realizzazione <strong>di</strong> <strong>servizi</strong> <strong>web</strong> 15<br />

2.1 Piattaforma <strong>per</strong> l’esecuzione dei <strong>servizi</strong> . . . . . . . . . . . . . . . . . . 15<br />

2.1.1 Definizione <strong>di</strong> <strong>servizi</strong>o <strong>web</strong> . . . . . . . . . . . . . . . . . . . . . 16<br />

2.1.2 Modello dei sevizi <strong>web</strong> . . . . . . . . . . . . . . . . . . . . . . . 16<br />

2.1.3 Architettura dei <strong>servizi</strong> <strong>web</strong> . . . . . . . . . . . . . . . . . . . . 19<br />

2.2 SOAP, WSDL e WS-BPEL . . . . . . . . . . . . . . . . . . . . . . . . 22<br />

2.2.1 SOAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22<br />

2.2.2 WSDL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25<br />

2.2.3 WS-BPEL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27<br />

2.3 JAX-WS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31<br />

3 Il <strong>linguaggio</strong> COWSlite 35<br />

3.1 Il calcolo <strong>di</strong> processi COWS . . . . . . . . . . . . . . . . . . . . . . . . 36<br />

3.1.1 µCOWS m . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37<br />

3.1.2 Esempi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41<br />

3.2 Descrizione <strong>di</strong> COWSlite . . . . . . . . . . . . . . . . . . . . . . . . . 45<br />

3.2.1 Sintassi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45<br />

3.2.2 Tipi <strong>di</strong> dato e vettori <strong>di</strong> variabili write-once . . . . . . . . . . . 48<br />

3.2.3 Regole <strong>di</strong> matching . . . . . . . . . . . . . . . . . . . . . . . . . 49<br />

3.2.4 Semantica e <strong>di</strong>fferenze con µCOWS m . . . . . . . . . . . . . . 50<br />

5


INDICE<br />

3.3 Esempi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52<br />

4 <strong>Implementazione</strong> <strong>di</strong> COWSlite 59<br />

4.1 Obiettivi e scelte implementative . . . . . . . . . . . . . . . . . . . . . 59<br />

4.2 Un <strong>servizi</strong>o COWSlite in Java . . . . . . . . . . . . . . . . . . . . . . 61<br />

4.3 Il package cowslite.engine . . . . . . . . . . . . . . . . . . . . . . . . . 64<br />

4.3.1 L’<strong>un</strong>ità <strong>di</strong> com<strong>un</strong>icazione . . . . . . . . . . . . . . . . . . . . . 66<br />

4.3.2 Descrittori <strong>di</strong> <strong>servizi</strong>o <strong>web</strong> e variabili<br />

(WsDescriptor e PartnerLink) . . . . . . . . . . . . . . . . . . . 71<br />

4.3.3 Descrizione del <strong>servizi</strong>o COWSlite . . . . . . . . . . . . . . . 76<br />

4.3.4 Spazio dei <strong>servizi</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . 84<br />

4.4 Generazione del compilatore . . . . . . . . . . . . . . . . . . . . . . . . 85<br />

4.4.1 Componenti <strong>di</strong> SableCC . . . . . . . . . . . . . . . . . . . . . . 88<br />

4.4.2 Generazione del co<strong>di</strong>ce . . . . . . . . . . . . . . . . . . . . . . . 90<br />

5 Uso <strong>di</strong> COWSlite 99<br />

5.1 Compilatore COWSlite . . . . . . . . . . . . . . . . . . . . . . . . . . 99<br />

5.1.1 Script <strong>per</strong> automatizzare la compilazione e la build . . . . . . . 102<br />

5.1.2 Utility <strong>di</strong> supporto . . . . . . . . . . . . . . . . . . . . . . . . . 103<br />

5.2 Note sul compilatore . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105<br />

5.2.1 Linguaggio accettato dal compilatore . . . . . . . . . . . . . . . 105<br />

5.2.2 Linee guida <strong>per</strong> la scrittura e la compilazione dei file COWSlite106<br />

5.3 Caso <strong>di</strong> stu<strong>di</strong>o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107<br />

6 Conclusioni 117<br />

A Grammatica 121<br />

A.1 Grammatica COWSlite <strong>per</strong> SableCC . . . . . . . . . . . . . . . . . . 121<br />

B Deploy su application server 127<br />

Bibliografia 131<br />

6


Elenco delle tabelle<br />

2.1 Struttura <strong>di</strong> <strong>un</strong> processo WS-BPEL . . . . . . . . . . . . . . . . . . . 29<br />

3.1 Sintassi <strong>di</strong> COWS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37<br />

3.2 Sintassi <strong>di</strong> µCOWS m . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38<br />

3.3 Congruenza strutturale <strong>di</strong> µCOWS m . . . . . . . . . . . . . . . . . . . 39<br />

3.4 Regole <strong>di</strong> matching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39<br />

3.5 Semantica o<strong>per</strong>azionale <strong>di</strong> µCOWS m . . . . . . . . . . . . . . . . . . . 40<br />

3.6 Sintassi <strong>di</strong> COWSlite . . . . . . . . . . . . . . . . . . . . . . . . . . . 46<br />

4.1 Co<strong>di</strong>ce <strong>di</strong> <strong>un</strong> <strong>servizi</strong>o . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63<br />

4.2 Web Service Proxy con JAX-WS . . . . . . . . . . . . . . . . . . . . . 70<br />

4.3 Web Service - Messaggio SOAP . . . . . . . . . . . . . . . . . . . . . . 71<br />

4.4 Costruttori della classe WOVar . . . . . . . . . . . . . . . . . . . 74<br />

4.5 Classe CowsProcess . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79<br />

4.6 Receive - ?(partner,o<strong>per</strong>ation,).continuazione . . . . . . . . . . 82<br />

4.7 Invoke - !(partner,o<strong>per</strong>ation,) . . . . . . . . . . . . . . . . . . . 82<br />

4.8 Delimitation - [x1,...,xn]p . . . . . . . . . . . . . . . . . . . . . . . . . 82<br />

4.9 Replication - *[n](p) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83<br />

4.10 Parallel - |(p1,p2) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83<br />

4.11 Choice - +(p1,p2) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84<br />

4.12 Assign - x:=exp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84<br />

4.13 Esempio <strong>di</strong> co<strong>di</strong>ce generato <strong>per</strong> la logica del <strong>servizi</strong>o . . . . . . . . . . 95<br />

7


8<br />

ELENCO DELLE TABELLE<br />

4.14 Esempio <strong>di</strong> co<strong>di</strong>ce generato <strong>per</strong> la scelta con<strong>di</strong>zionata . . . . . . . . . . 97<br />

5.1 Messaggio <strong>di</strong> errore del compilatore . . . . . . . . . . . . . . . . . . . . 101<br />

5.2 Messaggio <strong>di</strong> errore exec . . . . . . . . . . . . . . . . . . . . . . . . . . 104<br />

5.3 Messaggio <strong>di</strong> errore makeXmlStub . . . . . . . . . . . . . . . . . . . . 105<br />

5.4 File COWSlite da compilare . . . . . . . . . . . . . . . . . . . . . . . 108


Elenco delle figure<br />

2.1 Ruoli, Attività e Artefatti nelle architetture orientate ai <strong>servizi</strong> . . . . 17<br />

2.2 Pila dei <strong>servizi</strong> <strong>web</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20<br />

2.3 Messaggi XML in SOAP . . . . . . . . . . . . . . . . . . . . . . . . . . 23<br />

2.4 Descrizione <strong>di</strong> <strong>un</strong> <strong>servizi</strong>o . . . . . . . . . . . . . . . . . . . . . . . . . 26<br />

2.5 Processo WS-BPEL . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30<br />

4.1 Struttura del progetto . . . . . . . . . . . . . . . . . . . . . . . . . . . 60<br />

4.2 Compilazione <strong>di</strong> <strong>un</strong> <strong>servizi</strong>o COWSlite . . . . . . . . . . . . . . . . . 62<br />

4.3 Architettura dell’engine . . . . . . . . . . . . . . . . . . . . . . . . . . 65<br />

4.4 Classi del sottosistema <strong>di</strong> com<strong>un</strong>icazione . . . . . . . . . . . . . . . . . 68<br />

4.5 Diagramma delle classi delle variabili WO . . . . . . . . . . . . . . . . 72<br />

4.6 Diagramma delle classi dei processi COWSlite . . . . . . . . . . . . . 78<br />

4.7 AST generato <strong>per</strong> l’espressione (45 + 36/2) ∗ 3 + 5 ∗ 2 . . . . . . . . . . 86<br />

4.8 Albero AST <strong>per</strong> il costrutto Parallel . . . . . . . . . . . . . . . . . . . 94<br />

4.9 Albero AST <strong>per</strong> il costrutto Choice . . . . . . . . . . . . . . . . . . . . 96<br />

5.1 Test dell’o<strong>per</strong>azione con S<strong>un</strong> Applicatioin Server . . . . . . . . . . . . 116<br />

B.1 Pagina <strong>di</strong> amministrazione dell’application server . . . . . . . . . . . . 128<br />

B.2 Pagina <strong>di</strong> amministrazione dei <strong>servizi</strong> in esecuzione . . . . . . . . . . . 129<br />

9


10<br />

ELENCO DELLE FIGURE


Capitolo 1<br />

Introduzione<br />

In questi ultimi anni il ruolo dell’Information Technology (IT) all’interno delle azien-<br />

de si è spesso orientato verso problematiche <strong>di</strong> integrazione e fornitura <strong>di</strong> <strong>servizi</strong>.<br />

Acronimi come SOA e SOC sono ormai <strong>di</strong>venuti parole <strong>di</strong> uso com<strong>un</strong>e. SOA (Servi-<br />

ce Oriented Architecture) sta ad in<strong>di</strong>care <strong>un</strong> para<strong>di</strong>gma architetturale <strong>per</strong> i sistemi<br />

aziendali, mentre SOC (Service Oriented Computing) in<strong>di</strong>vidua <strong>un</strong> para<strong>di</strong>gma utiliz-<br />

zato <strong>per</strong> la progettazione <strong>di</strong> sistemi enterprise. Anche se ultimamente l’espressione<br />

SOA sta lasciando il posto a SOC, essi in<strong>di</strong>cano <strong>un</strong>o stesso scopo, costruire siste-<br />

mi che siano debolmente accoppiati, intero<strong>per</strong>abili, ad elevata scalabilità, sfruttando<br />

il più possibile tecnologie già esistenti all’interno degli standard aziendali. L’uso <strong>di</strong><br />

questi para<strong>di</strong>gmi <strong>per</strong>mette <strong>di</strong> mantenere in f<strong>un</strong>zione tutti quei sistemi che, sebbene<br />

siano costruiti con tecnologie <strong>un</strong> po’ datate, hanno ormai passato tutti i test ‘sul<br />

campo’ e possono essere considerati ‘maturi’, integrandoli ed estendendoli con nuove<br />

f<strong>un</strong>zionalità sfruttando tecnologie più recenti.<br />

All’interno <strong>di</strong> tutto ciò i <strong>servizi</strong> <strong>web</strong> sono fra le applicazioni che meglio interpretano<br />

questa filosofia. La loro <strong>di</strong>ffusione e il supporto da parte della stragrande maggioranza<br />

dei linguaggi esistenti, <strong>per</strong>mette <strong>di</strong> creare applicazioni complete. Uno dei p<strong>un</strong>ti <strong>di</strong> forza<br />

dei <strong>servizi</strong> <strong>web</strong> è la composizionalità, cioè la capacità <strong>di</strong> comporre <strong>servizi</strong> semplici <strong>per</strong><br />

crearne <strong>di</strong> più complessi. Questa capacità ha fatto si che si sviluppassero dei linguaggi<br />

che hanno fra le loro caratteristiche principali <strong>di</strong>versi costrutti <strong>per</strong> l’orchestrazione <strong>di</strong><br />

11


CAPITOLO 1 Introduzione<br />

<strong>servizi</strong> <strong>web</strong>, cioè <strong>di</strong> poter aggregare <strong>servizi</strong> <strong>web</strong> descrivendo il flusso <strong>di</strong> esecuzione e le<br />

interazioni fra i <strong>servizi</strong> stessi; fra questi linguaggi <strong>un</strong>o dei più noti è WS-BPEL.<br />

Tutti i linguaggi <strong>di</strong> programmazione, a partire da C, C++, Java, fino a WS-BPEL<br />

non <strong>per</strong>mettono <strong>di</strong> verificare o specificare proprietà sul co<strong>di</strong>ce prodotto, non è ad<br />

esempio possibile fare verifiche su proprietà relative ai <strong>servizi</strong> concorrenti (liveness,<br />

deadlock, ecc.), sulla corretta gestione delle risorse o sui <strong>servizi</strong> stessi (affidabilità,<br />

<strong>di</strong>sponibilità, responsività, ecc.). Per poter provare ad analizzare tali proprietà <strong>di</strong>versi<br />

sistemi formali sono stati proposti quali i calcoli <strong>di</strong> processo (ad es. CCS [29] e<br />

π-calcolo [30]).<br />

Vari calcoli <strong>di</strong> processo sono stati recentemente progettati con l’intento <strong>di</strong> stu<strong>di</strong>are<br />

e valutare <strong>di</strong>verse combinazioni <strong>di</strong> primitive <strong>per</strong> il SOC. Tra questi solo <strong>per</strong> citarne<br />

alc<strong>un</strong>i troviamo COWS[25], SOCK [18], SCC [9] e CaSPiS [7].<br />

COWS è <strong>un</strong> <strong>linguaggio</strong> che, ispirandosi a WS-BPEL da <strong>un</strong> p<strong>un</strong>to <strong>di</strong> vista f<strong>un</strong>-<br />

zionale, presenta tutte le caratteristiche <strong>di</strong> <strong>base</strong> <strong>per</strong> modellare <strong>servizi</strong> <strong>web</strong> racchiuse<br />

in <strong>un</strong> calcolo <strong>di</strong> processi che, con la sua definizione formale, <strong>per</strong>mette anche la verifica<br />

<strong>di</strong> proprietà.<br />

Vari strumenti sono stati sviluppati <strong>per</strong> investigare le specifiche <strong>di</strong> COWS, come<br />

le estensioni stocastiche definite in [37] che <strong>per</strong>mettono ragionamenti quantitativi sul<br />

comportamento dei <strong>servizi</strong>, il sistema <strong>di</strong> tipi introdotto in [26] <strong>per</strong> controllare proprietà<br />

<strong>di</strong> confidenzialità e la logica e il model checker presentati in [14] <strong>per</strong> esprimere e testare<br />

proprietà f<strong>un</strong>zionali dei <strong>servizi</strong>.<br />

Lo scopo <strong>di</strong> questa tesi sarà quello <strong>di</strong> introdurre <strong>un</strong> <strong>linguaggio</strong> <strong>di</strong> programmazione<br />

<strong>per</strong> <strong>servizi</strong> <strong>web</strong> e <strong>di</strong> realizzarne il compilatore. Il <strong>linguaggio</strong> sarà progettato partendo<br />

da COWS e cercando <strong>di</strong> scrivere la grammatica in modo da accettare istruzioni che<br />

siano il più possibile somiglianti ai termini COWS. Il compilatore dovrà generare <strong>un</strong><br />

co<strong>di</strong>ce interme<strong>di</strong>o che sia compilabile ed eseguibile su <strong>un</strong>a piattaforma esistente <strong>per</strong><br />

<strong>servizi</strong> <strong>web</strong> senza dover installare altro software.<br />

Per fare ciò partiremo col descrivere quelle che sono le tecnologie <strong>di</strong> <strong>base</strong> che<br />

costituiscono l’architettura dei <strong>servizi</strong> <strong>web</strong> [19], su cui dovremo appoggiarci <strong>per</strong> poter<br />

12


ealizzare il compilatore del <strong>linguaggio</strong>, introducendo <strong>un</strong> po’ <strong>di</strong> concetti sui <strong>servizi</strong> <strong>web</strong><br />

e analizzando i protocolli necessari <strong>per</strong> il trasporto dei messaggi, <strong>per</strong> la descrizione<br />

e pubblicazione dei <strong>servizi</strong> e i pacchetti necessari <strong>per</strong> sviluppare il software; daremo<br />

anche <strong>un</strong>o sguardo a WS-BPEL che è tra i linguaggi <strong>di</strong> specifica attualmente più<br />

utilizzati e che ha ispirato il <strong>linguaggio</strong> formale dal quale abbiamo preso sp<strong>un</strong>to.<br />

In seguito descriveremo COWS ponendo l’attenzione su µCOWS m , il frammento<br />

che si avvicina <strong>di</strong> più a COWSlite, il <strong>linguaggio</strong> proposto nel presente lavoro, e li<br />

metteremo a confronto.<br />

Descriveremo infine il processo <strong>di</strong> progettazione e realizzazione del compilatore e<br />

del supporto <strong>per</strong> l’esecuzione del <strong>linguaggio</strong> in questione concludendo con degli esempi<br />

<strong>di</strong> uso del software realizzato.<br />

Il CD allegato a questa tesi contiene il software sviluppato, i file sorgenti e i file<br />

<strong>di</strong> installazione dell’ambiente <strong>di</strong> sviluppo e <strong>di</strong> alc<strong>un</strong>i application server usati nei test.<br />

13


14<br />

CAPITOLO 1 Introduzione


Capitolo 2<br />

Supporti <strong>per</strong> la realizzazione <strong>di</strong><br />

<strong>servizi</strong> <strong>web</strong><br />

In questo capitolo descriveremo cosa si intende con il termine <strong>servizi</strong>o <strong>web</strong> e analizze-<br />

remo alc<strong>un</strong>e delle tecnologie che stanno alla <strong>base</strong> della costruzione e del f<strong>un</strong>zionamento<br />

<strong>di</strong> <strong>un</strong> <strong>servizi</strong>o <strong>web</strong>. Introdurremo anche <strong>un</strong> <strong>linguaggio</strong> <strong>per</strong> lo sviluppo <strong>di</strong> <strong>servizi</strong> in<br />

ambiente SOA dal quale COWS ha preso sp<strong>un</strong>to. Concluderemo il capitolo con <strong>un</strong><br />

breve panoramica <strong>di</strong> JAX-WS, l’API <strong>di</strong> SUN <strong>per</strong> la costruzione e l’interrogazione <strong>di</strong><br />

<strong>servizi</strong> <strong>web</strong>.<br />

2.1 Piattaforma <strong>per</strong> l’esecuzione dei <strong>servizi</strong><br />

I <strong>servizi</strong> <strong>web</strong> <strong>per</strong>mettono <strong>di</strong> costruire <strong>un</strong> architettura tale da consentire l’integrazione<br />

<strong>di</strong> software e l’accesso a sistemi proprietari in maniera semplice. Questo fa si che<br />

possano essere mantenuti in f<strong>un</strong>zione i vecchi sistemi informativi aziendali facendoli<br />

colloquiare con moduli <strong>di</strong> nuova concezione. Di conseguenza i costi <strong>per</strong> la produzione<br />

e la messa in o<strong>per</strong>a <strong>di</strong> nuove f<strong>un</strong>zionalità e <strong>servizi</strong> sono ridotti.<br />

15


CAPITOLO 2 Supporti <strong>per</strong> la realizzazione <strong>di</strong> <strong>servizi</strong> <strong>web</strong><br />

2.1.1 Definizione <strong>di</strong> <strong>servizi</strong>o <strong>web</strong><br />

Un <strong>servizi</strong>o <strong>web</strong> (<strong>web</strong> service) è <strong>un</strong>a collezione <strong>di</strong> f<strong>un</strong>zionalità, dette o<strong>per</strong>azioni, ac-<br />

cessibili via rete che possono essere utilizzate e richieste attraverso messaggi XML<br />

standard. L’interfaccia <strong>di</strong> <strong>un</strong> <strong>servizi</strong>o <strong>web</strong> è descritta usando WSDL [12], <strong>un</strong>a no-<br />

tazione basata su XML alla quale ci si riferisce generalmente come descrizione del<br />

<strong>servizi</strong>o. Questa descrizione copre tutti i dettagli necessari a interagire con il <strong>servizi</strong>o,<br />

incluso il formato dei messaggi, il protocollo <strong>di</strong> com<strong>un</strong>icazione e la locazione. Una ca-<br />

ratteristica dell’interfaccia è quella <strong>di</strong> nascondere i dettagli dell’implementazione del<br />

<strong>servizi</strong>o, rendendone possibile l’uso in<strong>di</strong>pendentemente dalla piattaforma hardware o<br />

software utilizzata. Questo fa si che le applicazioni basate su <strong>servizi</strong> <strong>web</strong> siano debol-<br />

mente accoppiate (losely-coupled), orientate ai componenti e implementate sfruttando<br />

tecnologie <strong>di</strong>fferenti (cross-technology). I <strong>servizi</strong> <strong>web</strong> possono eseguire <strong>un</strong> compito spe-<br />

cifico oppure <strong>un</strong> insieme <strong>di</strong> compiti; possono altresí essere usati in congi<strong>un</strong>zione ad<br />

altri <strong>servizi</strong> <strong>web</strong> <strong>per</strong> svolgere compiti complessi o o<strong>per</strong>azioni transazionali (ad esempio<br />

economico-finanziarie).<br />

2.1.2 Modello dei sevizi <strong>web</strong><br />

Il modello dei <strong>servizi</strong> <strong>web</strong> in<strong>di</strong>vidua tre ruoli <strong>di</strong>fferenti che interagiscono fra loro: for-<br />

nitore del <strong>servizi</strong>o (service provider), registro dei <strong>servizi</strong> (server registry) e richiedente<br />

dei <strong>servizi</strong> (service requestor). L’interazione si concretizza in tre attività: pubblica-<br />

zione, ricerca e utilizzo. I ruoli e le attività agiscono insieme sugli artefatti del <strong>servizi</strong>o<br />

<strong>web</strong>, cioè il modulo software del <strong>servizi</strong>o <strong>web</strong> e la sua descrizione, come descritto in<br />

Figura 2.1.<br />

In <strong>un</strong> tipico scenario, <strong>un</strong> fornitore <strong>di</strong> <strong>servizi</strong> ospita <strong>un</strong> modulo software accessibile<br />

attraverso la rete (l’implementazione del <strong>servizi</strong>o <strong>web</strong>). Il fornitore del <strong>servizi</strong>o pro-<br />

duce la descrizione del <strong>servizi</strong>o e la pubblica ad <strong>un</strong> richiedente o ad <strong>un</strong> registro. Il<br />

richiedente utilizza <strong>un</strong>a o<strong>per</strong>azione <strong>di</strong> ricerca <strong>per</strong> recu<strong>per</strong>are la descrizione del <strong>servizi</strong>o<br />

localmente oppure dal registro dei <strong>servizi</strong>, usa questa descrizione <strong>per</strong> collegarsi col<br />

fornitore del <strong>servizi</strong>o, infine invoca o interagisce con l’implementazione del <strong>servizi</strong>o<br />

16


2.1 Piattaforma <strong>per</strong> l’esecuzione dei <strong>servizi</strong><br />

Figura 2.1: Ruoli, Attività e Artefatti nelle architetture orientate ai <strong>servizi</strong><br />

<strong>web</strong>. I ruoli <strong>di</strong> fornitore e richiedente sono costrutti logici e <strong>un</strong> <strong>servizi</strong>o può esibire<br />

caratteristiche <strong>di</strong> entrambi i ruoli.<br />

Ruoli<br />

I ruoli definiti in <strong>un</strong> modello orientato ai <strong>servizi</strong> possono essere visti da due prospet-<br />

tive <strong>di</strong>verse in f<strong>un</strong>zione della logica del <strong>servizi</strong>o (business logic) oppure in relazione<br />

all’architettura.<br />

Fornitore del <strong>servizi</strong>o Da <strong>un</strong>a prospettiva <strong>di</strong> business è il proprietario del <strong>servizi</strong>o,<br />

mentre da <strong>un</strong>a prospettiva architetturale è la piattaforma che ospita l’accesso<br />

al <strong>servizi</strong>o.<br />

Richiedente del <strong>servizi</strong>o Dalla prospettiva <strong>di</strong> business sono le attività che richie-<br />

dono che siano sod<strong>di</strong>sfatte determinate f<strong>un</strong>zioni. Da <strong>un</strong>a prospettiva architet-<br />

turale è l’applicazione che si prepara a invocare o iniziare <strong>un</strong>’interazione con <strong>un</strong><br />

17


CAPITOLO 2 Supporti <strong>per</strong> la realizzazione <strong>di</strong> <strong>servizi</strong> <strong>web</strong><br />

<strong>servizi</strong>o. Questo ruolo può essere interpretato da <strong>un</strong> browser utilizzato da <strong>un</strong>a<br />

<strong>per</strong>sona oppure da <strong>un</strong> programma senza interfaccia utente.<br />

Registro dei <strong>servizi</strong> Da <strong>un</strong>a prospettiva <strong>di</strong> business è <strong>un</strong> elenco <strong>di</strong> <strong>servizi</strong> <strong>di</strong>sponi-<br />

bili all’interno della rete. È <strong>un</strong> registro <strong>di</strong> descrizioni <strong>di</strong> <strong>servizi</strong> ricercabili in cui<br />

i fornitori del <strong>servizi</strong>o pubblicano le descrizioni dei loro <strong>servizi</strong>. I richiedenti del<br />

<strong>servizi</strong>o cercano dei <strong>servizi</strong> e ottengono le informazioni <strong>per</strong> il collegamento; tale<br />

collegamento può essere definito in modo statico durante lo sviluppo oppure <strong>di</strong>-<br />

namicamente durante l’esecuzione. Nel caso <strong>di</strong> <strong>servizi</strong> collegati staticamente, il<br />

ruolo <strong>di</strong> registro dei <strong>servizi</strong> è opzionale, in quanto il fornitore può inviare <strong>di</strong>ret-<br />

tamente i dati al richiedente. Un richiedente potrebbe ricevere tali informazioni<br />

anche in altro modo, ad esempio da <strong>un</strong> file locale, da <strong>un</strong> sito FTP, da <strong>un</strong> sito<br />

Web, o tramite altri <strong>servizi</strong> <strong>di</strong> <strong>di</strong>scovery tipo Advertisement and Discovery of<br />

Service (ADS) [33] o Discovery of Web Service (DISCO) [38] <strong>di</strong> Microsoft.<br />

Artefatti <strong>di</strong> <strong>un</strong> <strong>servizi</strong>o <strong>web</strong><br />

Dalla Figura 2.1 si nota che gli artefatti sono:<br />

Servizio Un <strong>servizi</strong>o è <strong>un</strong> modulo software in esecuzione su <strong>un</strong>a piattaforma accessi-<br />

bile tramite la rete e fornito da <strong>un</strong> fornitore <strong>di</strong> <strong>servizi</strong>. Esiste <strong>per</strong> essere invocato<br />

o interagire con <strong>un</strong> richiedente <strong>di</strong> <strong>servizi</strong>. Può f<strong>un</strong>zionare anche da richiedente<br />

usando altri <strong>servizi</strong> <strong>web</strong> nella sua implementazione.<br />

Descrizione del <strong>servizi</strong>o La descrizione del <strong>servizi</strong>o contiene i dettagli dell’inter-<br />

18<br />

faccia e dell’implementazione del <strong>servizi</strong>o. Questa include i tipi <strong>di</strong> dati, le<br />

o<strong>per</strong>azioni, le informazioni <strong>di</strong> collegamento e la localizzazione sulla rete. Può<br />

anche contenere altri metadati <strong>per</strong> facilitare la ricerca e l’utilizzo da parte del<br />

richiedente. Può essere pubblicata dal fornitore o dal registro.


2.1 Piattaforma <strong>per</strong> l’esecuzione dei <strong>servizi</strong><br />

2.1.3 Architettura dei <strong>servizi</strong> <strong>web</strong><br />

Possiamo pensare concettualmente l’architettura con cui costruire i <strong>servizi</strong> <strong>web</strong> come<br />

se fosse organizzata <strong>per</strong> strati; ogni strato fornisce determinate f<strong>un</strong>zionalità ed è<br />

implementato me<strong>di</strong>ante specifiche tecnologie. Questo viene denominato pila dei <strong>servizi</strong><br />

<strong>web</strong> (Web Service Stack).<br />

Pila dei <strong>servizi</strong> <strong>web</strong><br />

Per eseguire le tre o<strong>per</strong>azioni <strong>di</strong> pubblicazione, ricerca e utilizzo in modo intero<strong>per</strong>abile<br />

ci deve essere <strong>un</strong>a pila <strong>di</strong> <strong>servizi</strong> <strong>web</strong> che utilizza tecnologie standard ad ogni livello.<br />

La Figura 2.2 mostra concettualmente le tecnologie legate ai <strong>servizi</strong> <strong>web</strong> organiz-<br />

zate come <strong>un</strong>a pila. Gli strati su<strong>per</strong>iori sono sviluppati sfruttando le capacità fornite<br />

dagli strati inferiori. I livelli più bassi della pila che descrive i <strong>servizi</strong> <strong>web</strong> sono re-<br />

lativamente più maturi e standar<strong>di</strong>zzati rispetto agli altri strati. Le barre verticali<br />

rappresentano i requisiti che devono essere affrontati a tutti i livelli della pila. Il testo<br />

a sinistra in<strong>di</strong>ca le tecnologie standard applicabili ad ogni livello della pila.<br />

Le fondamenta su cui poggiano i componenti della pila dei <strong>servizi</strong> <strong>web</strong> è la rete.<br />

I <strong>servizi</strong> <strong>web</strong> devono essere accessibili in rete <strong>per</strong> poter essere invocati da <strong>un</strong> richie-<br />

dente. Perché ciò sia possibile è necessario sfruttare i protocolli <strong>di</strong> rete com<strong>un</strong>emente<br />

impiegati. A causa della sua ubiquità, HTTP è lo standard <strong>di</strong> fatto fra i protocolli <strong>di</strong><br />

rete <strong>per</strong> i <strong>servizi</strong> <strong>web</strong> <strong>di</strong>sponibili su Internet. Altri protocolli Internet sono com<strong>un</strong>que<br />

supportati, ad es. SMTP e FTP. Oppure nei domini intranet è possibile utilizzare<br />

infrastrutture <strong>per</strong> la messaggistica affidabile e le chiamate come MQSeries, CORBA<br />

e altre.<br />

Lo strato successivo (XML-Based Messaging) evidenzia l’uso del <strong>linguaggio</strong> XML<br />

come <strong>base</strong> <strong>per</strong> il protocollo <strong>di</strong> messaggistica. La scelta <strong>di</strong> SOAP <strong>per</strong> questo scopo è<br />

principalmente dovuta ai seguenti motivi:<br />

• È il meccanismo <strong>di</strong> incapsulamento standar<strong>di</strong>zzato <strong>per</strong> la com<strong>un</strong>icazione<br />

document-centric <strong>di</strong> messaggi e chiamate <strong>di</strong> procedura remota eseguita tramite<br />

il <strong>linguaggio</strong> XML.<br />

19


CAPITOLO 2 Supporti <strong>per</strong> la realizzazione <strong>di</strong> <strong>servizi</strong> <strong>web</strong><br />

Figura 2.2: Pila dei <strong>servizi</strong> <strong>web</strong><br />

• È semplice, <strong>per</strong>ché si appoggia alla f<strong>un</strong>zionalità HTTP POST con <strong>un</strong> contenitore<br />

<strong>di</strong> dati XML nel payload.<br />

• È preferibile usare <strong>un</strong> meccanismo semplice <strong>per</strong> inviare messaggi XML come<br />

l’HTTP POST in quanto definisce <strong>un</strong> meccanismo standard ortogonale <strong>per</strong><br />

includere le estensioni nel messaggio usando <strong>un</strong> header SOAP e <strong>un</strong>a co<strong>di</strong>fica<br />

standard <strong>per</strong> l’o<strong>per</strong>azione o la f<strong>un</strong>zione.<br />

• Supporta le attività definite <strong>per</strong> l’architettura dei <strong>servizi</strong> <strong>web</strong> (pubblicazione,<br />

ricerca ed utilizzo).<br />

Il livello <strong>di</strong> <strong>servizi</strong>o è costituito da <strong>un</strong> insieme <strong>di</strong> documenti <strong>di</strong> descrizione. Tra<br />

questi documenti <strong>un</strong>o dei più importanti è il WSDL, lo standard attuale <strong>per</strong> la descri-<br />

zione dei <strong>servizi</strong> basati su XML che <strong>per</strong>mette l’intero<strong>per</strong>abilità sul <strong>web</strong>. Il documento<br />

WSDL definisce l’interfaccia ed i meccanismi <strong>di</strong> interazione <strong>di</strong> <strong>un</strong> <strong>servizi</strong>o. Può es-<br />

20


2.1 Piattaforma <strong>per</strong> l’esecuzione dei <strong>servizi</strong><br />

sere integrato da altri documenti <strong>per</strong> descrivere aspetti <strong>di</strong> livello più elevato come il<br />

contesto <strong>di</strong> business, la qualità del <strong>servizi</strong>o e le relazioni fra i <strong>servizi</strong>. Ad esempio il<br />

contesto <strong>di</strong> business può essere descritto utilizzando i dati forniti da UDDI (Universal<br />

Description Discovery and Integration) [34] in aggi<strong>un</strong>ta ai documenti WSDL, la com-<br />

posizione e il flusso del <strong>servizi</strong>o possono essere descritti <strong>per</strong> mezzo <strong>di</strong> <strong>un</strong> documento<br />

WSFL (Web Services Flow Language) [28] oppure WS-BPEL.<br />

I primi tre strati <strong>di</strong> questa pila sono necessari <strong>per</strong> fornire o utilizzare qualsiasi<br />

<strong>servizi</strong>o <strong>web</strong>. Questo implica che la configurazione <strong>di</strong> <strong>base</strong> della pila <strong>per</strong> l’intero<strong>per</strong>a-<br />

bilità, sia <strong>per</strong> <strong>servizi</strong> <strong>web</strong> pubblici che privati, sia formata dai protocolli HTTP <strong>per</strong> il<br />

livello <strong>di</strong> rete, SOAP <strong>per</strong> il livello <strong>di</strong> messaggistica XML e da WSDL <strong>per</strong> il livello <strong>di</strong><br />

descrizione del <strong>servizi</strong>o.<br />

Questo <strong>per</strong>ò non impe<strong>di</strong>sce che altri <strong>servizi</strong> intranet o privati supportino altri<br />

protocolli <strong>di</strong> rete o tecnologie <strong>di</strong> calcolo <strong>di</strong>stribuito.<br />

La pila raffigurata in Figura 2.2 fornisce l’intero<strong>per</strong>abilità e <strong>per</strong>mette ai <strong>servizi</strong><br />

<strong>web</strong> <strong>di</strong> sfruttare l’infrastruttura Internet già esistente. Le richieste <strong>di</strong> intero<strong>per</strong>abilità<br />

non compromettono com<strong>un</strong>que la flessibilità del sistema, <strong>per</strong>ché è com<strong>un</strong>que possibile<br />

supportare tecnologie alternative e a valore aggi<strong>un</strong>to. Ad esempio, oltre a SOAP<br />

over HTTP, è possibile supportare anche SOAP over MQ senza particolari sforzi<br />

implementativi.<br />

Qualsiasi azione che mette a <strong>di</strong>sposizione <strong>un</strong> documento WSDL ad <strong>un</strong> <strong>servizi</strong>o<br />

richiedente in qual<strong>un</strong>que fase del ciclo <strong>di</strong> vita del <strong>servizi</strong>o richiedente è chiamato ser-<br />

vizio <strong>di</strong> pubblicazione. A questo livello, l’esempio più semplice <strong>per</strong> la fornitura statica<br />

<strong>di</strong> <strong>servizi</strong> è l’invio <strong>di</strong> <strong>un</strong> documento WSDL <strong>di</strong>rettamente ad <strong>un</strong> <strong>servizi</strong>o richiedente;<br />

tale o<strong>per</strong>azione viene chiamata pubblicazione <strong>di</strong>retta. Questa è spesso utilizzata <strong>per</strong><br />

applicazioni a collegamento statico. In alternativa, il fornitore <strong>di</strong> <strong>servizi</strong> è in grado<br />

<strong>di</strong> pubblicare il documento WSDL che descrive il <strong>servizi</strong>o in <strong>un</strong> registro <strong>di</strong> documenti<br />

WSDL sull’host locale, in <strong>un</strong> registro privato UDDI o in <strong>un</strong> nodo o<strong>per</strong>atore UDDI.<br />

Dal momento che l’implementazione <strong>di</strong> <strong>un</strong> <strong>servizi</strong>o <strong>web</strong> è <strong>un</strong> modulo software, è<br />

naturale produrre <strong>servizi</strong> <strong>web</strong> me<strong>di</strong>ante la loro composizione. Tale composizione fa<br />

21


CAPITOLO 2 Supporti <strong>per</strong> la realizzazione <strong>di</strong> <strong>servizi</strong> <strong>web</strong><br />

si che <strong>un</strong> <strong>servizi</strong>o <strong>web</strong> svolga contemporaneamente più ruoli. I <strong>servizi</strong> <strong>web</strong> <strong>di</strong> <strong>un</strong>a<br />

intranet possono collaborare fra loro e presentare come interfaccia pubblica quella <strong>di</strong><br />

<strong>un</strong> <strong>un</strong>ico <strong>servizi</strong>o <strong>web</strong>, oppure <strong>servizi</strong> <strong>di</strong> <strong>di</strong>fferenti imprese possono collaborare <strong>per</strong><br />

eseguire o<strong>per</strong>azioni macchina-macchina o business-business. Potrebbe anche esistere<br />

<strong>un</strong> gestore <strong>di</strong> workflow che si prende carico <strong>di</strong> chiamare altri <strong>servizi</strong> <strong>web</strong> partecipando<br />

al processo aziendale. Il livello più alto dello stack descrive come devono avvenire<br />

le com<strong>un</strong>icazioni fra <strong>servizi</strong>, come essi devono collaborare e come vengono eseguiti i<br />

flussi. Per descrivere queste interazioni possono essere usati linguaggi come WSFL o<br />

WS-BPEL.<br />

2.2 SOAP, WSDL e WS-BPEL<br />

Fra tutte le tecnologie che possono essere utilizzate <strong>per</strong> implementare i vari strati<br />

all’interno della pila dei <strong>servizi</strong> <strong>web</strong> è interessante soffermarsi su quelli che occupano i<br />

livelli inferiori, che sono quelli che considereremo <strong>per</strong> gli scopi <strong>di</strong> questa tesi. Questa<br />

scelta è stata fatta in quanto ormai sono implementati con standard consolidati ed al<br />

tempo stesso supportati dalla maggior parte dei produttori <strong>di</strong> software. Tralasceremo<br />

la descrizione dello strato <strong>di</strong> rete, ed in particolare <strong>di</strong> HTTP, <strong>per</strong>ché basato su standard<br />

affermati ormai da tantissimo tempo. Inseriremo in questa carrellata anche WS-<br />

BPEL, che si posiziona invece nello strato più alto della pila, in quanto tecnologia<br />

che implementa la gestione del flusso o<strong>per</strong>ativo <strong>di</strong> <strong>un</strong> <strong>servizi</strong>o e <strong>per</strong>ché da esso trae<br />

ispirazione COWS.<br />

2.2.1 SOAP<br />

La parte fondamentale su cui poggia l’architettura dei <strong>servizi</strong> <strong>web</strong> è la messaggistica<br />

XML. Lo standard attuale <strong>di</strong> settore <strong>per</strong> la messaggistica XML è SOAP [31].<br />

SOAP è <strong>un</strong> protocollo semplice e leggero <strong>per</strong> lo scambio <strong>di</strong> dati strutturati tra<br />

applicazioni in rete. Un messaggio SOAP si compone <strong>di</strong> tre parti: <strong>un</strong> involucro che<br />

definisce <strong>un</strong>a sezione nella quale inserire la descrizione <strong>di</strong> ciò che c’è in <strong>un</strong> messaggio,<br />

22


2.2 SOAP, WSDL e WS-BPEL<br />

<strong>un</strong>a serie <strong>di</strong> regole <strong>di</strong> co<strong>di</strong>fica <strong>per</strong> esprimere istanze <strong>di</strong> tipi <strong>di</strong> dati definiti dall’appli-<br />

cazione e <strong>un</strong>a convenzione <strong>per</strong> rappresentare le chiamate <strong>di</strong> procedura remota (RPC)<br />

e le risposte. SOAP può essere utilizzato in combinazione, o ‘reincapsulato’, con <strong>un</strong>a<br />

varietà <strong>di</strong> protocolli <strong>di</strong> rete come ad esempio HTTP, SMTP, FTP, RMI over IIOP o<br />

MQ.<br />

La Figura 2.3 mostra come la messaggistica XML basata su SOAP e i protocolli<br />

<strong>di</strong> rete costituiscono la <strong>base</strong> dell’architettura dei <strong>servizi</strong> <strong>web</strong>.<br />

Figura 2.3: Messaggi XML in SOAP<br />

I requisiti <strong>di</strong> <strong>base</strong> che <strong>un</strong> nodo <strong>di</strong> rete deve avere <strong>per</strong> svolgere il ruolo <strong>di</strong> fornitore<br />

o <strong>di</strong> richiedente in <strong>un</strong> ambiente <strong>di</strong> calcolo <strong>di</strong>stribuito basato su messaggistica XML<br />

sono la capacità <strong>di</strong> costruire e/o analizzare <strong>un</strong> messaggio SOAP e la capacità <strong>di</strong><br />

com<strong>un</strong>icare su <strong>un</strong>a rete (ricevere e/o inviare messaggi). Tipicamente, <strong>un</strong> server SOAP<br />

in esecuzione in <strong>un</strong> Web application server svolge tutte queste f<strong>un</strong>zioni. In alternativa<br />

può essere utilizzata <strong>un</strong>a libreria specifica <strong>per</strong> <strong>un</strong> <strong>linguaggio</strong> <strong>di</strong> programmazione che<br />

incapsula queste f<strong>un</strong>zioni all’interno <strong>di</strong> <strong>un</strong> API. L’integrazione delle applicazioni con<br />

SOAP può essere ottenuta con l’uso <strong>di</strong> quattro passi fondamentali:<br />

23


CAPITOLO 2 Supporti <strong>per</strong> la realizzazione <strong>di</strong> <strong>servizi</strong> <strong>web</strong><br />

1. Un’applicazione che richiede <strong>servizi</strong> crea <strong>un</strong> messaggio SOAP. Questo messaggio<br />

rappresenta la richiesta necessaria <strong>per</strong> invocare l’o<strong>per</strong>azione resa <strong>di</strong>sponibile dal<br />

fornitore <strong>di</strong> <strong>servizi</strong>. Il documento XML contenuto nel corpo del messaggio può<br />

essere <strong>un</strong>a richiesta SOAP RPC oppure <strong>un</strong> messaggio data-centric, come spe-<br />

cificato nella descrizione del <strong>servizi</strong>o. Il richiedente presenta questo messaggio<br />

insieme all’in<strong>di</strong>rizzo <strong>di</strong> rete del fornitore del <strong>servizi</strong>o all’infrastruttura SOAP.<br />

L’infrastruttura interagisce con i protocolli <strong>di</strong> rete dello strato sottostante <strong>per</strong><br />

inviare il messaggio SOAP sulla rete.<br />

2. L’infrastruttura <strong>di</strong> rete consegna il messaggio al r<strong>un</strong>time SOAP del fornitore<br />

del <strong>servizi</strong>o. Il r<strong>un</strong>time server SOAP inoltra il messaggio <strong>di</strong> richiesta al fornito-<br />

re del <strong>servizi</strong>o. Il r<strong>un</strong>time è responsabile <strong>di</strong> convertire il messaggio XML nelle<br />

strutture dati specifiche del <strong>linguaggio</strong> <strong>di</strong> programmazione usato <strong>per</strong> l’applica-<br />

zione. La conversione è guidata dagli schemi <strong>di</strong> deco<strong>di</strong>fica contenuti all’interno<br />

del messaggio.<br />

3. Il <strong>servizi</strong>o <strong>web</strong> è responsabile <strong>di</strong> elaborare il messaggio <strong>di</strong> richiesta ed eventual-<br />

mente formulare <strong>un</strong>a risposta; la risposta è a sua volta <strong>un</strong> messaggio SOAP. Il<br />

messaggio <strong>di</strong> risposta SOAP è presentato al r<strong>un</strong>time SOAP come richiedente<br />

del <strong>servizi</strong>o verso la destinazione. In caso <strong>di</strong> protocolli richiesta/risposta sin-<br />

crona su HTTP, il protocollo <strong>di</strong> messaggistica sfrutta la caratteristica naturale<br />

del protocollo <strong>di</strong> rete <strong>di</strong> essere app<strong>un</strong>to richiesta/risposta. Il r<strong>un</strong>time invia il<br />

messaggio SOAP attraverso la rete al richiedente.<br />

4. Il messaggio <strong>di</strong> risposta che è gi<strong>un</strong>to al richiedente del <strong>servizi</strong>o attraverso l’in-<br />

frastruttura <strong>di</strong> rete, viene in<strong>di</strong>rizzato attraverso l’infrastruttura SOAP, conver-<br />

tito secondo gli standard del <strong>linguaggio</strong> <strong>di</strong> programmazione <strong>di</strong> destinazione, se<br />

necessario, e infine presentato all’applicazione che lo ha richiesto.<br />

Questo esempio sfrutta le primitive <strong>di</strong> trasmissione richiesta/risposta presenti in<br />

molti ambienti <strong>di</strong> programmazione <strong>di</strong>stribuita. Lo scambio dei messaggi può avve-<br />

24


2.2 SOAP, WSDL e WS-BPEL<br />

nire in modo sincrono o asincrono con l’applicazione richiedente. Altre primitive <strong>di</strong><br />

com<strong>un</strong>icazione utilizzabili con SOAP sono one-way e notification.<br />

2.2.2 WSDL<br />

Attraverso la descrizione del <strong>servizi</strong>o il fornitore del <strong>servizi</strong>o com<strong>un</strong>ica tutte le specifi-<br />

che necessarie <strong>per</strong> l’invocazione del <strong>servizi</strong>o da parte del richiedente. La descrizione del<br />

<strong>servizi</strong>o è la chiave <strong>per</strong> rendere l’architettura dei <strong>servizi</strong> <strong>web</strong> debolmente accoppiata e<br />

<strong>per</strong> ridurre la quantità <strong>di</strong> informazioni da con<strong>di</strong>videre fra il fornitore e il richiedente<br />

del <strong>servizi</strong>o <strong>per</strong> la comprensione, la programmazione e l’integrazione del <strong>servizi</strong>o. Ad<br />

esempio, né il fornitore né il richiedente devono essere a conoscenza della piattaforma,<br />

del <strong>linguaggio</strong> <strong>di</strong> programmazione e degli oggetti <strong>di</strong>stribuiti utilizzati dall’altra parte.<br />

La descrizione del <strong>servizi</strong>o insieme all’infrastruttura SOAP devono essere sufficienti<br />

ad incapsulare tutti i dettagli necessari a far colloquiare l’applicazione del richiedente<br />

con il <strong>servizi</strong>o <strong>web</strong> del fornitore.<br />

Il descrittore <strong>di</strong> <strong>servizi</strong>o<br />

All’interno dell’architettura dei <strong>servizi</strong> <strong>web</strong>, il <strong>linguaggio</strong> WSDL (versione 1.1) [12]<br />

è utilizzato <strong>per</strong> fornire <strong>un</strong>a descrizione <strong>di</strong> <strong>base</strong> <strong>di</strong> <strong>un</strong> <strong>servizi</strong>o. WSDL è ormai <strong>un</strong>o<br />

standard, formalizzato dal consorzio W3C 1 . Un documento WSDL descrive il <strong>servizi</strong>o<br />

<strong>web</strong> come <strong>un</strong> insieme <strong>di</strong> endpoint (terminali <strong>di</strong> com<strong>un</strong>icazione) che o<strong>per</strong>ano attraverso<br />

messaggi il cui contenuto può essere a sua volta <strong>un</strong> documento oppure <strong>un</strong>a chiamata<br />

<strong>di</strong> procedura (tipo RPC). WSDL è <strong>un</strong> formalismo estensibile che consente <strong>di</strong> definire<br />

gli endpoint e i messaggi in relazione al formato dei messaggi e ai protocolli <strong>di</strong> rete<br />

usati nella com<strong>un</strong>icazione. Tuttavia al momento sono supportati solo SOAP, HTTP<br />

POST e MIME.<br />

WSDL <strong>di</strong>vide convenzionalmente la descrizione <strong>di</strong> <strong>base</strong> dei <strong>servizi</strong> in due parti:<br />

descrizione concreta e descrizione astratta. Questo <strong>per</strong>mette <strong>di</strong> definire ogni parte<br />

1 World Wide Web Consortium<br />

25


CAPITOLO 2 Supporti <strong>per</strong> la realizzazione <strong>di</strong> <strong>servizi</strong> <strong>web</strong><br />

Figura 2.4: Descrizione <strong>di</strong> <strong>un</strong> <strong>servizi</strong>o<br />

separatamente, in maniera in<strong>di</strong>pendente e riusabile dalle altre parti. Le o<strong>per</strong>azioni e<br />

i messaggi sono definiti in modo astratto e collegati con <strong>un</strong> protocollo <strong>di</strong> rete reale.<br />

La definizione della descrizione astratta del <strong>servizi</strong>o è riusabile e può essere istan-<br />

ziata e referenziata da più descrizioni concrete del <strong>servizi</strong>o. Basti pensare alla descri-<br />

zione astratta come ad <strong>un</strong> <strong>linguaggio</strong> IDL (Interface Definition Langauge), alle inter-<br />

facce in Java oppure a dei tipi nei <strong>servizi</strong> <strong>web</strong>. Questo <strong>per</strong>mette <strong>di</strong> definire e implemen-<br />

tare tipi che siano standard industriali com<strong>un</strong>i in modo da avere più implementazioni<br />

<strong>per</strong> lo stesso <strong>servizi</strong>o.<br />

La descrizione astratta del <strong>servizi</strong>o contiene degli elementi WSDL che compongono<br />

la parte riutilizzabile della descrizione del <strong>servizi</strong>o (illustrati in Figura 2.4):<br />

26<br />

• bin<strong>di</strong>ng;<br />

• portType;<br />

• message;<br />

• type.


2.2 SOAP, WSDL e WS-BPEL<br />

L’elemento portType definisce le o<strong>per</strong>azioni esposte dal <strong>servizi</strong>o <strong>web</strong>, cioè quali tipi <strong>di</strong><br />

messaggi XML possono apparire nel flusso dei dati in input e output, in modo analogo<br />

a come si definisce la segnatura <strong>di</strong> <strong>un</strong> metodo in <strong>un</strong> <strong>linguaggio</strong> <strong>di</strong> programmazione.<br />

L’elemento message specifica i tipi <strong>di</strong> dati XML che costituiscono le varie parti <strong>di</strong><br />

<strong>un</strong> messaggio, è usato <strong>per</strong> definire i parametri <strong>di</strong> input ed output <strong>di</strong> <strong>un</strong>’o<strong>per</strong>azione.<br />

Dati complessi possono essere usati all’interno delle definizione se sono stati definiti<br />

tramite l’elemento type.<br />

L’elemento bin<strong>di</strong>ng descrive il protocollo, il formato dei dati, la sicurezza e altri<br />

attributi relativi ad <strong>un</strong>a specifica descrizione astratta del <strong>servizi</strong>o.<br />

Un <strong>servizi</strong>o <strong>web</strong> è modellato con <strong>un</strong> elemento service che contiene <strong>un</strong>a collezione (in<br />

genere <strong>un</strong>o solo) <strong>di</strong> elementi port. Il compito dell’elemento port è quello <strong>di</strong> associare<br />

<strong>un</strong> endpoint (ad esempio <strong>un</strong> in<strong>di</strong>rizzo <strong>di</strong> rete o <strong>un</strong> URL) con <strong>un</strong> elemento bin<strong>di</strong>ng<br />

contenuto nella descrizione astratta del <strong>servizi</strong>o.<br />

L’<strong>un</strong>ione della descrizione astratta e <strong>di</strong> quella concreta costituiscono <strong>un</strong>a defini-<br />

zione completa del <strong>servizi</strong>o secondo lo standard WSDL. Questa coppia <strong>di</strong> definizioni<br />

contiene informazioni sufficienti <strong>per</strong> descrivere ai richiedenti del <strong>servizi</strong>o come invocare<br />

e interagire con il <strong>servizi</strong>o <strong>web</strong>.<br />

2.2.3 WS-BPEL<br />

WS-BPEL (Web Services Business Process Execution Language) [2, 4] è <strong>un</strong> linguag-<br />

gio <strong>per</strong> la definizione <strong>di</strong> processi <strong>di</strong> business e interazione <strong>di</strong> protocolli <strong>di</strong> business in<br />

ambiente SOA. Estende il modello <strong>di</strong> interazione dei <strong>servizi</strong> <strong>web</strong> e li abilita a sup-<br />

portare le transazioni tipiche dei processi <strong>di</strong> business aziendali. Definisce, inoltre,<br />

<strong>un</strong> modello <strong>di</strong> integrazione intero<strong>per</strong>abile tale da facilitare l’espansione <strong>di</strong> processi<br />

automatizzati interni alle aziende e le o<strong>per</strong>azioni in ambienti business-to-business.<br />

Nato dallo sforzo congi<strong>un</strong>to <strong>di</strong> alc<strong>un</strong>i dei maggiori produttori <strong>di</strong> software del mondo<br />

(Microsoft, IBM, Bea Weblogic, SAP e Sibel) come evoluzione e fusione <strong>di</strong> alc<strong>un</strong>i<br />

famosi linguaggi (XLANG [42] e WSFL [28]) è stato standar<strong>di</strong>zzato da OASIS 2 nel<br />

2 Organization for the Advancement of Structured Information Standards<br />

27


CAPITOLO 2 Supporti <strong>per</strong> la realizzazione <strong>di</strong> <strong>servizi</strong> <strong>web</strong><br />

2002 ed è gi<strong>un</strong>to alla sua seconda versione nel 2007.<br />

WS-BPEL consente, tramite <strong>un</strong> <strong>linguaggio</strong> <strong>di</strong> descrizione basato su XML, <strong>di</strong><br />

specificare la logica <strong>di</strong> business <strong>di</strong> <strong>un</strong> processo <strong>per</strong>mettendo <strong>di</strong> eseguire attività in pa-<br />

rallelo, <strong>di</strong> manipolare dati, gestire eccezioni e interagire con <strong>servizi</strong> <strong>web</strong>. Data la sua<br />

spiccata propensione all’interazione con i <strong>servizi</strong> <strong>web</strong>, possiamo fare rientrare WS-<br />

BPEL nella categoria degli orchestratori <strong>di</strong> <strong>servizi</strong> <strong>web</strong>. Uno <strong>di</strong> motivi <strong>per</strong> cui è stato<br />

scelto l’XML come <strong>linguaggio</strong> <strong>per</strong> la specifica dei processi WS-BPEL è la sua <strong>di</strong>ffe-<br />

renza dai normali linguaggi <strong>di</strong> programmazione. Questo potrebbe far pensare che sia<br />

più semplice definire <strong>un</strong> processo anche da parte <strong>di</strong> utenti che non sono propriamente<br />

dei programmatori, sicuramente questo ha agevolato la realizzazione <strong>di</strong> tool grafici<br />

<strong>per</strong> la programmazione.<br />

Per poter eseguire <strong>un</strong> processo specificato tramite WS-BPEL è necessario met-<br />

terlo in esecuzione su <strong>un</strong> apposito server <strong>di</strong> applicazioni detto app<strong>un</strong>to BPEL<br />

engine.<br />

Un processo è <strong>un</strong> contenitore in cui vengono <strong>di</strong>chiarate le relazioni con i partner<br />

esterni, i dati, collegamenti necessari <strong>per</strong> altri scopi e soprattutto le attività da ese-<br />

guire, offrendo la possibilità <strong>di</strong> aggregare <strong>servizi</strong> <strong>web</strong> e definire <strong>un</strong>a logica <strong>per</strong> ogn<strong>un</strong>a<br />

delle possibili interazioni, come si può vedere dalla Figura 2.5. Un esempio della<br />

struttura <strong>di</strong> <strong>un</strong> generico processo WS-BPEL è riportata in Tabella 2.1.<br />

Per riferirsi ed interagire con altri <strong>servizi</strong> <strong>web</strong> WS-BPEL fa uso <strong>di</strong> <strong>un</strong> apposita<br />

<strong>di</strong>chiarazione che si chiamano partnerLink. Ogn<strong>un</strong>o <strong>di</strong> questi partnerLink associa ad<br />

ogni <strong>servizi</strong>o <strong>un</strong> nome, <strong>un</strong> ruolo e il tipo <strong>di</strong> porta (secondo lo standard WSDL) che<br />

saranno utilizzati all’interno del contesto del processo e nelle relazioni che intercorrono<br />

fra tutti i <strong>servizi</strong> utilizzati. Un partnerLink può essere visto come <strong>un</strong> particolare<br />

canale <strong>di</strong> com<strong>un</strong>icazione e più partnerLink possono essere associati allo stesso partner.<br />

Questa interazione è bi<strong>di</strong>rezionale; il partner invoca il processo e il processo invoca il<br />

partner. Ogni link è caratterizzato da <strong>un</strong> tipo e <strong>un</strong> ruolo.<br />

Un dato <strong>per</strong> WS-BPEL è <strong>un</strong>a variabile il cui tipo può essere <strong>di</strong>chiarato all’interno<br />

<strong>di</strong> <strong>un</strong> processo oppure all’interno <strong>di</strong> <strong>un</strong>o scope del processo. Le variabili mantengono<br />

28


2.2 SOAP, WSDL e WS-BPEL<br />

<br />

<br />

<br />

. . .<br />

<br />

. . .<br />

<br />

<br />

. . .<br />

<br />

<br />

. . .<br />

<br />

<br />

. . .<br />

<br />

<br />

Tabella 2.1: Struttura <strong>di</strong> <strong>un</strong> processo WS-BPEL<br />

i dati che costituiscono lo stato <strong>di</strong> <strong>un</strong> processo WS-BPEL durante l’esecuzione.<br />

Per specificare il comportamento <strong>di</strong> <strong>un</strong> processo WS-BPEL si usano le attività.<br />

Queste possono essere <strong>di</strong> due tipi: <strong>di</strong> <strong>base</strong> o strutturate.<br />

Le attività <strong>di</strong> <strong>base</strong> rappresentano le azioni primitive del <strong>linguaggio</strong> e sono:<br />

receive attende <strong>un</strong> messaggio,<br />

replay invia <strong>un</strong> messaggio come risposta ad <strong>un</strong>o ricevuto,<br />

invoke invia <strong>un</strong> messaggio ad <strong>un</strong> partner,<br />

assign mo<strong>di</strong>fica i valori delle variabili,<br />

validate verifica il valore delle variabili confrontandolo con il tipo <strong>di</strong>chiarato nel<br />

WSDL associato,<br />

wait mette il processo in attesa <strong>per</strong> <strong>un</strong> tempo definito,<br />

empty non esegue alc<strong>un</strong>a o<strong>per</strong>azione,<br />

29


CAPITOLO 2 Supporti <strong>per</strong> la realizzazione <strong>di</strong> <strong>servizi</strong> <strong>web</strong><br />

Figura 2.5: Processo WS-BPEL<br />

throw genera <strong>un</strong> fallimento nel processo (cioè <strong>un</strong>a sorta <strong>di</strong> eccezione),<br />

compensate esegue la compensazione <strong>di</strong> default a seguito <strong>di</strong> <strong>un</strong> fallimento,<br />

compensateScope esegue la compensazione <strong>di</strong> <strong>un</strong>o scope a seguito <strong>di</strong> <strong>un</strong> fallimento,<br />

exit termina il processo,<br />

rethrow rilancia <strong>un</strong> fallimento precedentemente catturato verso lo scope <strong>di</strong> livello<br />

su<strong>per</strong>iore,<br />

extensionActivity estende WS-BPEL introducendo nuovi tipi <strong>di</strong> attività,<br />

Le attività strutturate sono quelle che <strong>per</strong>mettono la creazione <strong>di</strong> <strong>un</strong> flusso logico<br />

delle attività:<br />

sequence esegue sequenzialmente alc<strong>un</strong>e attività<br />

flow esegue concorrentemente alc<strong>un</strong>e attività<br />

scope definisce <strong>un</strong> ambiente <strong>di</strong> esecuzione isolato <strong>per</strong> le attività contenute<br />

30


2.3 JAX-WS<br />

if seleziona <strong>un</strong>’attività rispetto ad <strong>un</strong> insieme <strong>di</strong> scelte<br />

while, forEach, repeatUntil ripetono <strong>un</strong>’attività fino al sod<strong>di</strong>sfacimento <strong>di</strong> <strong>un</strong>a<br />

specifica con<strong>di</strong>zione<br />

pick tiene in sospeso <strong>un</strong> insieme <strong>di</strong> attività fino al verificarsi <strong>di</strong> <strong>un</strong> determinato evento<br />

che comporta la scelta <strong>di</strong> <strong>un</strong>a delle attività in attesa.<br />

Per far sì che durante l’esecuzione <strong>di</strong> <strong>un</strong> processo sia possibile mantenere la con-<br />

nessione con i partner coinvolti nell’esecuzione, WS-BPEL fa uso dei Correlation Set.<br />

Sono istanziati insieme allo scope del processo ed hanno il compito <strong>di</strong> identificare le<br />

istanze del processo in modo che siano <strong>di</strong>stinguibili fra loro. Le attività <strong>di</strong> invoke,<br />

receive, pick e replay possono riferirsi ad <strong>un</strong> correlation set <strong>per</strong> mantenere la comu-<br />

nicazione, al fine <strong>di</strong> implementare <strong>un</strong> meccanismo <strong>per</strong> il mantenimento della sessione<br />

<strong>di</strong> com<strong>un</strong>icazione.<br />

WS-BPEL prevede infine <strong>un</strong> meccanismo <strong>di</strong> gestione delle eccezioni <strong>per</strong> soppe-<br />

rire ad eventuali errori che si possono generare durante l’esecuzione <strong>di</strong> <strong>un</strong> processo<br />

<strong>di</strong> business con dei meccanismi <strong>di</strong> correzione e compensazione che vengono definiti<br />

nell’apposita sezione del documento XML e vengono richiamati dalle attività <strong>di</strong> <strong>base</strong><br />

throw, compensate, rethrow e compensateScope.<br />

2.3 JAX-WS<br />

JAX-WS [24], acronimo <strong>di</strong> Java API for XML Web Services, è <strong>un</strong>a tecnologia <strong>per</strong><br />

realizzare <strong>servizi</strong> <strong>web</strong> e client che com<strong>un</strong>icano tramite messaggi XML sfruttando la<br />

tecnologia Java. Come abbiamo visto, <strong>un</strong>o dei protocolli usati <strong>per</strong> scambiare messaggi<br />

<strong>di</strong> tipo XML sulla rete è SOAP. Questi messaggi hanno <strong>per</strong>ò la caratteristica <strong>di</strong><br />

avere <strong>un</strong>a struttura molto complessa. Lo scopo dell’API JAX-WS è proprio quello <strong>di</strong><br />

nascondere la complessità della com<strong>un</strong>icazione allo sviluppatore. Dal lato server lo<br />

sviluppatore deve specificare le procedure remote definendo i meto<strong>di</strong> in <strong>un</strong>’interfaccia<br />

scritta me<strong>di</strong>ante il <strong>linguaggio</strong> <strong>di</strong> programmazione Java. Il compito dello sviluppatore è<br />

quello <strong>di</strong> co<strong>di</strong>ficare <strong>un</strong>a o più classi che implementano i meto<strong>di</strong> desiderati. Lo sviluppo<br />

31


CAPITOLO 2 Supporti <strong>per</strong> la realizzazione <strong>di</strong> <strong>servizi</strong> <strong>web</strong><br />

della parte client è altrettanto semplice. L’applicazione client crea dei proxy (oggetti<br />

che rappresentano localmente i <strong>servizi</strong>) e invoca semplicemente i meto<strong>di</strong> dei proxy.<br />

JAX-WS è molto flessibile <strong>per</strong>ché utilizza tecnologie definite dal W3C come HTTP,<br />

SOAP e WSDL; in più si appoggia ad altre API <strong>di</strong> com<strong>un</strong>icazione standard <strong>per</strong> il<br />

mondo Java in modo tale da <strong>per</strong>mettere <strong>un</strong>a migliore integrazione con altre tecnologie<br />

Java-oriented e favorire l’adeguamento verso standard nuovi e in via <strong>di</strong> definizione.<br />

Una delle API alle quali si appoggia è l’API JAX-RPC che fornisce alla piattaforma<br />

Java il supporto RPC <strong>per</strong> lo scambio <strong>di</strong> messaggi XML fra <strong>servizi</strong> <strong>web</strong>. Nelle versioni<br />

successive alla prima è stato aggi<strong>un</strong>to il supporto al WS-I Basic Profile al fine <strong>di</strong><br />

migliorare l’intero<strong>per</strong>abilità fra JAX-RPC e implementazioni analoghe che usano altre<br />

tecnologie.<br />

La versione <strong>di</strong> JAX-WS 2.0 supporta le specifiche JAX-RPC 1.1 che fornisce il<br />

supporto ad altri standard già citati come SOAP 1.2, WSDL 2.0, WS-I Basic Profile<br />

e ad altre tecnologie e specifiche quali:<br />

Java Architecture for XML Bin<strong>di</strong>ng (JAXB) Framework <strong>per</strong> la definizione e<br />

la trasformazione <strong>di</strong> documenti XML in oggetti Java e viceversa, porta notevoli<br />

benefici se comparato con i meto<strong>di</strong> precedentemente usati come ad esempio<br />

l’utilizzo del Document Object Model (DOM). Questa tecnologia consente <strong>un</strong>a<br />

gestione flessibile del WSDL, <strong>per</strong>ché <strong>per</strong>mette <strong>di</strong> accedere a tutti gli elementi<br />

del documento XML allo stesso modo del DOM, ma con costrutti che le rendono<br />

più comprensibili e veloci al programmatore.<br />

Web service Security (JSR 183) supporto all’integrazione della sicurezza secon-<br />

do le specifiche del Java Comm<strong>un</strong>ity Process.<br />

L’API inoltre introduce il supporto <strong>per</strong> le o<strong>per</strong>azioni asincrone lato client, semplifi-<br />

ca l’utilizzo <strong>di</strong> JAX-WS con protocolli <strong>di</strong> trasporto <strong>di</strong>versi da HTTP <strong>di</strong>minuendo la<br />

correlazione fra messaggi XML e lo strato <strong>di</strong> trasporto in modo da facilitare l’imple-<br />

mentazione <strong>di</strong> nuovi standard, semplifica l’accesso ai messaggi scambiati dai mecca-<br />

32


2.3 JAX-WS<br />

nismi sottostanti e aggi<strong>un</strong>ge il supporto <strong>per</strong> la gestione delle sessioni nello scambio <strong>di</strong><br />

messaggi.<br />

Uno degli aspetti importanti <strong>di</strong> quest’API è che il suo supporto è parte integrante<br />

della piattaforma Java in quanto è stato incluso nella J2SE (<strong>per</strong> la precisione a partire<br />

dalla versione 6 <strong>di</strong> JAVA, mentre <strong>per</strong> le precedenti versioni, in particolare Java 1.4 e<br />

Java 5, esistono appositi pacchetti <strong>per</strong> l’integrazione).<br />

L’API è composta da <strong>un</strong>a serie <strong>di</strong> package ogn<strong>un</strong>o con <strong>un</strong>o specifico scopo: <strong>un</strong>o<br />

<strong>per</strong>mettere il mapping fra gli oggetti Java e il WSDL, <strong>un</strong>o esegue il mapping inverso fra<br />

WSDL e oggetti Java, <strong>un</strong>o <strong>per</strong>mette <strong>di</strong> implementare client <strong>per</strong> i <strong>servizi</strong> JAX-WS, <strong>un</strong><br />

altro si occupa della parte server ed, infine, <strong>un</strong>o contiene il nucleo <strong>di</strong> classi necessarie<br />

a far f<strong>un</strong>zionare l’intera API. Vedremo nei capitoli successivi qualche dettaglio.<br />

Un concetto molto importante quando si parla <strong>di</strong> <strong>servizi</strong> <strong>web</strong> è relativo all’inter-<br />

locutore a cui vengono richiesti i <strong>servizi</strong>. Ci si riferisce all’interlocutore in termini <strong>di</strong><br />

Endpoint (o porte <strong>di</strong> com<strong>un</strong>icazione) <strong>per</strong> identificare tutti i <strong>servizi</strong> che esso fornisce<br />

ad <strong>un</strong> richiedente esterno, <strong>per</strong> cui è estremamente importante poter <strong>un</strong>iformare ed<br />

astrarre il concetto in modo da rendere fruibile tali <strong>servizi</strong> a tutti i possibili richieden-<br />

ti. Si parla quin<strong>di</strong> <strong>di</strong> interfaccia esposta da <strong>un</strong> <strong>servizi</strong>o o, utilizzando la terminologia<br />

inglese, Service Endpoint Interface (SEI).<br />

Più formalmente potremmo <strong>di</strong>re che è <strong>un</strong> interfaccia Java che esporta i meto-<br />

<strong>di</strong> del <strong>servizi</strong>o che <strong>un</strong> client può invocare. Non è necessario descriverla o definirla<br />

quando si costruisce <strong>un</strong> <strong>servizi</strong>o con JAX-WS, in quanto è la stessa classe a definirlo<br />

implicitamente.<br />

33


34<br />

CAPITOLO 2 Supporti <strong>per</strong> la realizzazione <strong>di</strong> <strong>servizi</strong> <strong>web</strong>


Capitolo 3<br />

Il <strong>linguaggio</strong> COWSlite<br />

COWSlite è <strong>un</strong> frammento <strong>di</strong> COWS [25] esteso in modo da essere usato come<br />

<strong>linguaggio</strong> <strong>di</strong> programmazione <strong>per</strong> <strong>servizi</strong> <strong>web</strong>, cercando al contempo <strong>di</strong> mantenere<br />

le caratteristiche espressive del <strong>linguaggio</strong> originale e <strong>di</strong> introdurre gli elementi ne-<br />

cessari <strong>per</strong> renderlo utilizzabile <strong>per</strong> scrivere <strong>servizi</strong> eseguibili. Il risultato ottenuto<br />

è <strong>un</strong> <strong>linguaggio</strong> concorrente basato sulle com<strong>un</strong>icazioni fra <strong>servizi</strong> <strong>web</strong> in cui sono<br />

presenti primitive <strong>di</strong> invocazione e ricezione <strong>di</strong> richieste, <strong>un</strong> costrutto <strong>per</strong> l’esecuzio-<br />

ne concorrente dei processi, <strong>un</strong> costrutto <strong>di</strong> scelta non deterministica, <strong>un</strong> o<strong>per</strong>atore<br />

<strong>per</strong> la delimitazione dello scopo delle variabili e <strong>un</strong>o <strong>per</strong> la replicazione <strong>di</strong> processi.<br />

Nel <strong>linguaggio</strong> sono anche presenti le definizioni dei tipi <strong>di</strong> dato, <strong>per</strong> cui le variabili<br />

utilizzate devono essere obbligatoriamente definite.<br />

Lo scopo del <strong>linguaggio</strong> è quello <strong>di</strong> <strong>per</strong>mettere <strong>di</strong> sviluppare <strong>servizi</strong> <strong>web</strong> utilizzando<br />

la sintassi COWS e <strong>di</strong> poterli eseguire all’interno <strong>di</strong> <strong>un</strong> <strong>web</strong> server che supporti le<br />

specifiche JAX-WS definite da S<strong>un</strong> e dal Java Comm<strong>un</strong>ity Process.<br />

In questo capitolo descriveremo brevemente COWS, del quale esporremo solo la<br />

sintassi, soffermandoci su <strong>un</strong> suo frammento chiamato µCOWS m , che descriveremo<br />

più a fondo, presentando sia la sintassi che la semantica. Successivamente intro-<br />

durremo la sintassi <strong>di</strong> COWSlite e <strong>di</strong>scuteremo la sua semantica confrontandola<br />

con quella <strong>di</strong> µCOWS m . Per meglio descrivere il comportamento dei due linguaggi<br />

presenteremo anche alc<strong>un</strong>i esempi.<br />

35


3.1 Il calcolo <strong>di</strong> processi COWS<br />

CAPITOLO 3 Il <strong>linguaggio</strong> COWSlite<br />

COWS (Calculus for Orchestration of Web Services) è <strong>un</strong> <strong>linguaggio</strong> <strong>per</strong> la specifica<br />

formale <strong>di</strong> processi orientati all’orchestrazione <strong>di</strong> <strong>servizi</strong> <strong>web</strong>. Fa parte della famiglia<br />

dei calcoli <strong>di</strong> processo dalla quale ere<strong>di</strong>ta la possibilità <strong>di</strong> esprimere formalmente<br />

proprietà <strong>di</strong>mostrabili sul processo descritto. Possibilità che in generale non si applica<br />

ai linguaggi <strong>di</strong> programmazione tra<strong>di</strong>zionali.<br />

In Tabella 3.1 è riportata la sintassi <strong>di</strong> COWS. Lo scopo è quello <strong>di</strong> evidenziare le<br />

<strong>di</strong>fferenze con il frammento µCOWS m che verrà esposto successivamente, in modo da<br />

poter <strong>di</strong>scutere future estensioni <strong>di</strong> COWSlite. La notazione utilizzata è la stessa<br />

<strong>di</strong> µCOWS m e verrà en<strong>un</strong>ciata successivamente.<br />

COWS si basa su due concetti car<strong>di</strong>ne: com<strong>un</strong>ication endpoint (p • o) e ser-<br />

vizio (s). Questo fornisce <strong>un</strong> meccanismo molto flessibile <strong>per</strong> l’identificazione dei<br />

<strong>servizi</strong> (come succede con i ruoli dei partner in WS-BPEL).<br />

Un com<strong>un</strong>ication endpoint è la co<strong>di</strong>fica della locazione del <strong>servizi</strong>o da orchestrare<br />

me<strong>di</strong>ante <strong>un</strong>a rappresentazione composta da due entità, partner e o<strong>per</strong>azione, che<br />

identificano rispettivamente la località che ospita il <strong>servizi</strong>o che si sta richiedendo e<br />

l’o<strong>per</strong>azione specifica che si intende richiedere. Questa particolare notazione <strong>per</strong>mette<br />

<strong>di</strong> fruire dello stesso <strong>servizi</strong>o da parte <strong>di</strong> siti <strong>di</strong>versi il che potrebbe anche prevedere<br />

che i <strong>servizi</strong> richiesti eseguano la f<strong>un</strong>zione esposta me<strong>di</strong>ante implementazioni <strong>di</strong>verse,<br />

rendendo questa rappresentazione molto flessibile.<br />

Il <strong>servizi</strong>o invece è l’entità computazionale <strong>di</strong> <strong>base</strong> <strong>di</strong> COWS. In genere, ogni<br />

<strong>servizi</strong>o crea <strong>un</strong>’istanza specifica <strong>per</strong> gestire ogni richiesta che gli <strong>per</strong>viene, a sua volta<br />

ogni istanza è composta da thread concorrenti in grado <strong>di</strong> offrire la scelta fra <strong>di</strong>verse<br />

attività <strong>di</strong> ricezione. Un <strong>servizi</strong>o deve essere capace <strong>di</strong> ricevere messaggi multipli in<br />

<strong>un</strong> or<strong>di</strong>ne non pre<strong>di</strong>cibile in modo tale che il primo messaggio provochi la creazione<br />

<strong>di</strong> <strong>un</strong>’istanza del <strong>servizi</strong>o alla quale verranno in<strong>di</strong>rizzati tutti i messaggi successivi.<br />

Il meccanismo utilizzato <strong>per</strong> correlare i messaggi che appartengono logicamente alla<br />

stessa sessione è il pattern-matching.<br />

36


3.1 Il calcolo <strong>di</strong> processi COWS<br />

s::= (service) g::= (input-guarded choice)<br />

kill(k) (kill) 0 (nil)<br />

| u • u ′ !¯ɛ (invoke) | p • o? ¯w.s (receive)<br />

| g (choice) | g + g (choice)<br />

| s | s (parallel)<br />

| {|s|} (protection)<br />

| [d] s (delimitation)<br />

| ∗ s (replication)<br />

3.1.1 µCOWS m<br />

Tabella 3.1: Sintassi <strong>di</strong> COWS<br />

µCOWS m è <strong>un</strong> frammento <strong>di</strong> COWS nel quale sono state eliminate le attività <strong>di</strong><br />

kill e la protezione <strong>di</strong> <strong>un</strong> insieme <strong>di</strong> attività dalla terminazione forzata. La sintassi<br />

fra i due calcoli è stata mantenuta compatibile. Inoltre, in µCOWS m non esiste <strong>un</strong>a<br />

priorità sulla selezione fra più attività <strong>di</strong> ricezione attive compatibili con l’attività <strong>di</strong><br />

invocazione ricevuta, la selezione dell’attività avviene in maniera non deterministica.<br />

Sintassi<br />

La sintassi <strong>di</strong> µCOWS m è in<strong>di</strong>cata in Tabella 3.2. La sintassi è basata su due insiemi<br />

<strong>di</strong>sgi<strong>un</strong>ti: l’insieme dei valori (tipo v, v ′ ,. . . ) e l’insieme delle variabili ’write-once’<br />

(tipo x, y,. . . ). L’insieme dei valori è volutamente non formalizzato, anche se si<br />

suppone che contenga almeno dei nomi (tipo n, m, p, o,. . . ) che sono utilizzati<br />

<strong>per</strong> descrivere i partner e le o<strong>per</strong>azioni. C’è anche <strong>un</strong> altro insieme, quello delle<br />

espressioni (ɛ), del quale omettiamo la sintassi esatta, anche se supponiamo contenga<br />

almeno valori e variabili.<br />

In seguito utilizzeremo w <strong>per</strong> in<strong>di</strong>care valori e variabili ed u <strong>per</strong> in<strong>di</strong>care no-<br />

mi e variabili. La notazione ¯· sta ad in<strong>di</strong>care <strong>un</strong>a tupla; ad esempio ¯x rappresenta<br />

〈x1, . . . , xn〉 (con n ≥ 0), dove ogni variabile all’interno della tupla è <strong>di</strong>versa da tutte<br />

le altre. Scriveremo a, ¯ b <strong>per</strong> in<strong>di</strong>care le tuple ottenute concatenando l’elemento a con<br />

la tupla ¯ b. Il termine n rappresenta <strong>un</strong> endpoint <strong>di</strong> com<strong>un</strong>icazione che non contiene<br />

variabili (ad es. p • o), mentre u rappresenta <strong>un</strong> endpoint <strong>di</strong> com<strong>un</strong>icazione che può<br />

37


CAPITOLO 3 Il <strong>linguaggio</strong> COWSlite<br />

s ::= (services) g ::= (receive-guarded choice)<br />

u • u ′ !¯ɛ (invoke) 0 (nil)<br />

| g (choice) | p • o? ¯w.s (request processing)<br />

| s | s (parallel) | g + g (choice)<br />

| [u] s (delimitation)<br />

| ∗ s (replication)<br />

Tabella 3.2: Sintassi <strong>di</strong> µCOWS m<br />

contenere variabili (ad es. u • u ′ ). Utilizzeremo la notazione I s <strong>per</strong> assegnare <strong>un</strong><br />

nome I al termine s.<br />

Assumeremo la convenzione che gli o<strong>per</strong>atori mona<strong>di</strong>ci abbiano la precedenza sul-<br />

la composizione parallela e che l’o<strong>per</strong>atore prefisso abbia la precedenza sulla scelta.<br />

L’<strong>un</strong>ico costrutto legante è la delimitazione: [u] s lega u nell’ambito s.<br />

Le com<strong>un</strong>icazioni fra <strong>servizi</strong> danno luogo alla sostituzione delle variabili con i valo-<br />

ri. Il campo <strong>di</strong> applicazione delle sostituzioni generate dalle com<strong>un</strong>icazioni è regolato<br />

dall’o<strong>per</strong>atore <strong>di</strong> delimitazione; tale o<strong>per</strong>atore, inoltre, <strong>per</strong>mette <strong>di</strong> generare nomi<br />

nuovi (fresh). Quin<strong>di</strong> le occorrenze <strong>di</strong> <strong>un</strong> nome o <strong>di</strong> <strong>un</strong>a variabile sono libere (free)<br />

se non sono sotto l’influenza <strong>di</strong> <strong>un</strong>a delimitazione. In<strong>di</strong>cheremo con fu(t) l’insieme <strong>di</strong><br />

nomi o variabili libere che occorrono in t. Due termini si <strong>di</strong>cono α-equivalenti se <strong>un</strong>o<br />

può essere ottenuto dall’altro <strong>per</strong> mezzo <strong>di</strong> <strong>un</strong>a ridenominazione consistente che leghi<br />

i nomi e le variabili.<br />

Semantica O<strong>per</strong>azionale<br />

La semantica o<strong>per</strong>azionale <strong>di</strong> µCOWS m è definita solo <strong>per</strong> <strong>servizi</strong> chiusi, cioè <strong>servizi</strong><br />

senza variabili libere. La semantica è data formalmente me<strong>di</strong>ante <strong>un</strong>a relazione <strong>di</strong><br />

congruenza strutturale e <strong>un</strong>a relazione <strong>di</strong> transizione etichettata.<br />

La congruenza strutturale (≡) identifica sintatticamente <strong>servizi</strong> <strong>di</strong>fferenti che in-<br />

tuitivamente rappresentano lo stesso <strong>servizi</strong>o. È definita come la più piccola relazione<br />

indotta dalle leggi mostrate in Tabella 3.3. Le leggi che esprimono la congruenza strut-<br />

turale sono semplici da interpretare. In particolare, la proprietà commutativa sulle<br />

delimitazioni consecutive implica che l’or<strong>di</strong>ne in cui sono scritte le ui in [〈u1, . . . , <strong>un</strong>〉] s<br />

38


3.1 Il calcolo <strong>di</strong> processi COWS<br />

∗ 0 ≡ 0 ∗ s ≡ s |∗ s<br />

s | 0 ≡ s s1 | s2 ≡ s2 | s1 (s1 | s2) | s3 ≡ s1 | (s2 | s3)<br />

g + 0 ≡ g g1 + g2 ≡ g2 + g1 (g1 + g2) + g3 ≡ g1 + (g2 + g3)<br />

[u] 0 ≡ 0 [u1] [u2] s ≡ [u2] [u1] s s1 | [u] s2 ≡ [u] (s1 | s2) if u /∈fu(s1)<br />

Tabella 3.3: Congruenza strutturale <strong>di</strong> µCOWS m<br />

M(x, v) = {x ↦→ v} M(v, v) = ∅ M(〈〉, 〈〉) = ∅ M(w1, v1) = σ1 M( ¯w2, ¯v2) = σ2<br />

M((w1, ¯w2), (v1, ¯v2)) = σ1 ⊎ σ2<br />

Tabella 3.4: Regole <strong>di</strong> matching<br />

è irrilevante, <strong>per</strong>mettendo così <strong>di</strong> usare <strong>un</strong>a notazione più semplice come [u1, . . . , <strong>un</strong>] s.<br />

L’ultima legge <strong>per</strong>mette <strong>di</strong> estendere l’ambito <strong>di</strong> nomi e variabili, rendendo possibile<br />

la com<strong>un</strong>icazione fra <strong>servizi</strong>.<br />

Per definire la relazione <strong>di</strong> transizione etichettata sono necessarie delle f<strong>un</strong>zioni<br />

ausiliarie. In primo luogo la f<strong>un</strong>zione [_] <strong>per</strong> valutare le espressioni chiuse: data in<br />

ingresso <strong>un</strong>’espressione chiusa restituisce <strong>un</strong> valore. Non verrà definita esplicitamente<br />

in quanto la sintassi delle espressioni non è stata deliberatamente specificata. La<br />

seconda è <strong>un</strong>a f<strong>un</strong>zione parziale M(_ , _) che <strong>per</strong>mette <strong>di</strong> eseguire il pattern-matching<br />

su dati semi-strutturati, in modo da determinare se <strong>un</strong>a receive ed <strong>un</strong>a invoke possono<br />

sincronizzarsi sullo stesso endpoint. Le regole <strong>per</strong> il pattern-matching sono mostrate<br />

nella Tabella 3.4. Da queste si evince che due tuple corrispondono se hanno lo stesso<br />

numero <strong>di</strong> campi e i rispettivi valori o variabili <strong>di</strong> ogni campo corrispondono. Una<br />

variabile corrisponde a qualsiasi valore e due valori corrispondono solo se sono identici.<br />

Quando si ha <strong>un</strong>a corrispondenza fra due tuple ¯w e ¯v , allora M( ¯w, ¯v) restituisce <strong>un</strong>a<br />

sostituzione <strong>per</strong> le variabili in ¯w; altrimenti è indefinita. Una sostituzione σ è <strong>un</strong>a<br />

f<strong>un</strong>zione che mappa variabili in valori e si scrive come <strong>un</strong> insieme <strong>di</strong> coppie del tipo<br />

x ↦→ v. L’effetto <strong>di</strong> applicare <strong>un</strong>a sostituzione σ a s (s · σ) è quello <strong>di</strong> sostituire<br />

tutte le occorrenze libere <strong>di</strong> x in s con v, <strong>per</strong> ogni x ↦→ v ∈ σ, possibilmente usando<br />

α-conversione in modo da evitare che v sia catturata da <strong>un</strong>a delimitazione all’interno<br />

<strong>di</strong> s.<br />

39


n!¯ɛ<br />

[¯ɛ] = ¯v<br />

s<br />

[x] s<br />

n ✁ ¯v<br />

−−−−→ 0<br />

(inv)<br />

σ⊎{x↦→v}<br />

−−−−−−−−→ s ′<br />

σ<br />

−−→ s ′ ·{x ↦→ v}<br />

g α<br />

−−→ s<br />

′ α<br />

g + g −−→ s<br />

s1<br />

n ✄ ¯w<br />

−−−−−→ s ′ 1<br />

(choice)<br />

s2<br />

s1 | s2<br />

s ≡ s1 s1<br />

CAPITOLO 3 Il <strong>linguaggio</strong> COWSlite<br />

(delcom)<br />

n ✁ ¯v<br />

−−−−→ s ′ 2<br />

n? ¯w.s<br />

n ✄ ¯w<br />

−−−−−→ s (rec)<br />

s α<br />

−−→ s ′ u /∈ u(α)<br />

(del)<br />

[u] s α<br />

−−→ [u] s ′<br />

s1<br />

s1 | s2<br />

σ<br />

−−→ s ′ 1 | s ′ 2<br />

α<br />

−−→ s2 s2 ≡ s ′<br />

s α<br />

−−→ s ′<br />

α<br />

−−→ s ′ 1<br />

α<br />

−−→ s ′ 1 | s2<br />

(par)<br />

M( ¯w, ¯v)=σ (com)<br />

(str)<br />

Tabella 3.5: Semantica o<strong>per</strong>azionale <strong>di</strong> µCOWS m<br />

La relazione <strong>di</strong> transizione etichettata<br />

α<br />

−−→ è la più piccola relazione sui <strong>servizi</strong><br />

indotta dalle regole della Tabella 3.5, in cui l’etichetta α è generata dalla seguente<br />

grammatica:<br />

α ::= n ✁ ¯v | n ✄ ¯w | σ<br />

Il significato delle etichette è il seguente: n ✁ ¯v e n ✄ ¯w in<strong>di</strong>cano rispettivamente<br />

l’esecuzione delle attività <strong>di</strong> invocazione e ricezione sull’endpoint n con argomenti ¯v e<br />

¯w, mentre σ in<strong>di</strong>ca l’esecuzione <strong>di</strong> <strong>un</strong>a com<strong>un</strong>icazione fra <strong>servizi</strong> che genera la sostitu-<br />

zione σ. I passi computazionali corrispondo a transizioni etichettate dalla sostituzione<br />

vuota ∅, cioè corrispondono alle com<strong>un</strong>icazioni interne al <strong>servizi</strong>o considerato.<br />

Analizziamo ora i p<strong>un</strong>ti salienti delle regole o<strong>per</strong>azionali. L’invocazione <strong>di</strong> <strong>un</strong><br />

<strong>servizi</strong>o può avvenire solo se l’espressione nell’argomento può essere valutata (regola<br />

(inv)). Ciò significa, <strong>per</strong> esempio, che se essa contiene <strong>un</strong>a variabile x, l’invocazione è<br />

bloccata fino a quando x non viene sostituito da <strong>un</strong> valore <strong>per</strong> mezzo <strong>di</strong> <strong>un</strong>a ricezione<br />

che assegna <strong>un</strong> valore a x.<br />

40


3.1 Il calcolo <strong>di</strong> processi COWS<br />

Un’attività <strong>di</strong> ricezione rappresenta <strong>un</strong> o<strong>per</strong>azione invocabile rispetto ad <strong>un</strong> deter-<br />

minato nome del partner (regola (rec)), allo stesso modo l’esecuzione <strong>di</strong> <strong>un</strong>a ricezione<br />

<strong>per</strong>mette <strong>di</strong> prendere <strong>un</strong>a decisione riguardo a dei comportamenti alternativi (regola<br />

(choice)). Una com<strong>un</strong>icazione può avvenire quando due <strong>servizi</strong> in parallelo eseguo-<br />

no delle attività <strong>di</strong> invocazione e ricezione <strong>per</strong> cui si ha <strong>un</strong>a corrispondenza (regola<br />

(com)). La com<strong>un</strong>icazione genera <strong>un</strong>a sostituzione che è riportata nella transizione<br />

etichettata <strong>per</strong> le attività successive. Quando <strong>un</strong>a variabile delimitata x è argomento<br />

<strong>di</strong> <strong>un</strong>a ricezione facente parte <strong>di</strong> <strong>un</strong> processo <strong>di</strong> com<strong>un</strong>icazione allora la delimitazione<br />

imposta dalla variabile viene rimossa appena si verifica la sostituzione della variabile<br />

ad o<strong>per</strong>a dell’azione <strong>di</strong> com<strong>un</strong>icazione (delcom)). La variabile x sparisce dal termine<br />

e non è più possibile riassegnargli <strong>un</strong> valore (questo è il motivo <strong>per</strong> cui in COWS<br />

si <strong>di</strong>ce che le variabili sono ’write-once’). [u] s si comporta come s (regola (del)) ad<br />

eccezione del caso in cui in α sia contenuto u. L’esecuzione <strong>di</strong> <strong>servizi</strong> in parallelo è<br />

interleaved (regola (par)). La regola (str) è <strong>un</strong>a regola <strong>di</strong> inferenza usuale <strong>per</strong> cui dei<br />

<strong>servizi</strong> congruenti hanno le stesse transizioni. Vale la pena <strong>di</strong> notare che quando vie-<br />

ne applicata la regola (openrec) ad <strong>un</strong> <strong>servizi</strong>o µCOWS m chiuso, il termine risultante<br />

potrebbe essere a<strong>per</strong>to.<br />

3.1.2 Esempi<br />

Ve<strong>di</strong>amo alc<strong>un</strong>i esempi <strong>per</strong> chiarire ed evidenziare alc<strong>un</strong>i aspetti <strong>di</strong> µCOWS m .<br />

Com<strong>un</strong>icazione<br />

La com<strong>un</strong>icazione fra <strong>servizi</strong> deve sfruttare l’estensione dello scope <strong>per</strong> far si che<br />

possano interagire attività <strong>di</strong> ricezione e <strong>di</strong> invocazione. Infatti queste attività pos-<br />

sono sincronizzarsi solo se entrambe sono all’interno dello stesso ambito rispetto alle<br />

delimitazioni che legano le variabili delle attività <strong>di</strong> ricezione.<br />

odds • throw!〈first, cbA, 2〉 | [xp, xnum] (odds • throw?〈first, xp, xnum〉).s | s ′ ) ≡<br />

[xp, xnum] (odds • throw!〈first, cbA, 2〉 | odds • throw?〈first, xp, xnum〉).s | s ′ )<br />

(s | s ′ ) · {xp ↦→ cbA, xnum ↦→ 2}<br />

∅<br />

−−→<br />

41


CAPITOLO 3 Il <strong>linguaggio</strong> COWSlite<br />

Da notare che la sostituzione {xp ↦→ cbA, xnum ↦→ 2} è applicata a tutti i termini<br />

delimitati da [xp, xnum] , non soltanto alla continuazione s del <strong>servizi</strong>o che esegue la<br />

ricezione.<br />

Istanze <strong>di</strong> <strong>servizi</strong>o e correlazione <strong>di</strong> messaggi<br />

Data la natura debolmente accoppiata dei <strong>servizi</strong> µCOWS m (come tutti i linguaggi<br />

usati in SOA) questo implica che la connessione tra istanze <strong>di</strong> <strong>servizi</strong> com<strong>un</strong>icanti non<br />

sono da considerarsi <strong>per</strong>sistenti <strong>per</strong> tutta la durata dell’attività <strong>di</strong> business. Quin<strong>di</strong> è<br />

necessario che sia fornito ad ogni singolo messaggio <strong>un</strong>a forma <strong>di</strong> contesto che <strong>per</strong>metta<br />

ad <strong>un</strong> <strong>servizi</strong>o <strong>di</strong> associare fra loro i messaggi. Questo si può ottenere inserendo dei<br />

valori, chiamati dati <strong>di</strong> correlazione, all’interno del contesto del messaggio stesso.<br />

Il meccanismo <strong>per</strong> in<strong>di</strong>viduare i dati necessari <strong>per</strong> selezionare le istanze <strong>di</strong> <strong>servizi</strong>o<br />

interessate dallo scambio <strong>di</strong> messaggi è il pattern-matching. Consideriamo il seguente<br />

termine:<br />

(srv • throw!〈first, cbA, 2〉 | srv • throw!〈second, cbA, 3〉 | sA)<br />

| (srv • op!〈first, cbB, 1〉 | sB)<br />

| ∗ [xid, xp, xnum, yp, ynum] srv • throw?〈xid, xp, xnum〉.srv • op?〈xid, yp, ynum〉.s<br />

Supponiamo che le prime due sincronizzazioni siano relative alle due invocazioni lo<br />

stato del <strong>servizi</strong>o <strong>di</strong>venta:<br />

∗ [xid, xp, xnum, yp, ynum] (srv • throw?〈xid, xp, xnum〉.srv • op?〈xid, yp, ynum〉.s)<br />

| [yp, ynum] (srv • op?〈first, yp, ynum〉.s) · {xid ↦→ first, xp ↦→ cbA, xnum ↦→ 2}<br />

| [yp, ynum] (srv • op?〈second, yp, ynum〉.s) · {xid ↦→ second, xp ↦→ cbA, xnum ↦→ 3}<br />

| sA | (srv • op!〈first, cbB, 1〉 | sB)<br />

dopo la terza sincronizzazione si ottiene:<br />

∗ [xid, xp, xnum, yp, ynum] (srv • throw?〈xid, xp, xnum〉.srv • op?〈xid, yp, ynum〉.s)<br />

| s · {xid ↦→ first, xp ↦→ cbA, xnum ↦→ 2, yp ↦→ cbB, ynum ↦→ 1}<br />

| [yp, ynum] (srv • op?〈second, yp, ynum〉.s) · {xid ↦→ second, xp ↦→ cbA, xnum ↦→ 3}<br />

| sA | sB<br />

42<br />

Le due invocazioni srv • throw!〈〉 generano due istanze <strong>di</strong>verse del blocco repli-


3.1 Il calcolo <strong>di</strong> processi COWS<br />

cabile, il blocco srv • op!〈〉 si sincronizzerà con l’istanza in cui c’è corrispondenza, in<br />

questo caso quella con parametro ‘first’, dando luogo alla sostituzione. Sfruttando<br />

il pattern-matching sui parametri all’interno della richiesta è possibile correlare le<br />

richieste sulla stessa istanza in esecuzione.<br />

Descrizione ed esecuzione <strong>di</strong> <strong>un</strong> <strong>servizi</strong>o<br />

In µCOWS m <strong>un</strong> <strong>servizi</strong>o può essere modellato con <strong>un</strong> termine della forma ∗ [ū] s,<br />

dove la tupla ū contiene tutte le variabili libere presenti in s. L’uso dell’o<strong>per</strong>atore<br />

<strong>di</strong> replicazione fornisce tutte le istanze concorrenti necessarie, mentre la delimitazio-<br />

ne definisce lo stato del <strong>servizi</strong>o (restringendo la visibilità delle variabili). Questo<br />

significa che il termine appena descritto corrisponde ad <strong>un</strong> <strong>servizi</strong>o in cui le istanze<br />

sono eseguite concorrentemente senza con<strong>di</strong>videre <strong>un</strong>o stato. Ad esempio pren<strong>di</strong>amo<br />

il seguente <strong>servizi</strong>o:<br />

∗ [x1, . . . , xn] p • o?〈x1〉.s<br />

Se lo poniamo in parallelo ad <strong>un</strong>a invocazione del tipo p • o!〈v1〉 il risultato è <strong>un</strong><br />

sistema che evolve nel seguente modo:<br />

∗ [x1, . . . , xn] p • o?〈x1〉.s | p • o!〈v1〉<br />

∅<br />

−−→<br />

∗ [x1, . . . , xn] p • o?〈x1〉.s | [x2, . . . , xn] s · {x1 ↦→ v1}<br />

Allo stesso modo se pren<strong>di</strong>amo due clienti che tentano <strong>di</strong> utilizzare il medesimo<br />

<strong>servizi</strong>o:<br />

∗ [x1, . . . , xn] p • o?〈x1〉.s | p • o!〈v1〉 | p • o!〈v2〉<br />

∅<br />

−−→ ∅<br />

−−→<br />

∗ [x1, . . . , xn] p • o?〈x1〉.s | [x2, . . . , xn] s · {x1 ↦→ v1} | [x2, . . . , xn] s · {x1 ↦→ v2}<br />

La replication fornisce copie del <strong>servizi</strong>o ogni volta che c’è <strong>un</strong>a richiesta.<br />

Bank Acco<strong>un</strong>t<br />

Questo esempio è <strong>un</strong>a semplificazione <strong>di</strong> quello che potrebbe essere <strong>un</strong> reale <strong>servizi</strong>o<br />

<strong>di</strong> <strong>un</strong> sistema bancario. Il <strong>servizi</strong>o offerto <strong>per</strong>mette <strong>di</strong> eseguire accre<strong>di</strong>ti e addebiti sul<br />

conto in<strong>di</strong>cato.<br />

43


CAPITOLO 3 Il <strong>linguaggio</strong> COWSlite<br />

Il <strong>servizi</strong>o Bank è composto da due sotto<strong>servizi</strong> <strong>per</strong>sistenti, <strong>un</strong>o è invocabile<br />

pubblicamente degli ipotetici Client, l’altro è <strong>un</strong> <strong>servizi</strong>o interno che può interagire<br />

esclusivamente con Bank. Il <strong>servizi</strong>o Client simula il richiedente dell’o<strong>per</strong>azione.<br />

Bank [check, checkOK, checkF ail]<br />

(∗ [CUST, CC, AMOUNT, ID]<br />

bank • charge?〈CUST, CC, AMOUNT, ID〉.<br />

(bank • check!〈ID, CC, AMOUNT 〉 |<br />

bank • checkOK?〈ID〉.CUST • chargeOK!〈ID〉+<br />

bank • checkF ail?〈ID〉.CUST • chargeF ail!〈ID〉)<br />

| ∗ [CUST ID, CC, AMOUNT ]<br />

bank • check?〈CUST ID, CC, AMOUNT 〉.<br />

[p, o] (p • o!〈〉 |<br />

p • o?〈〉.bank • checkOK!〈CUST ID〉+<br />

p • o?〈〉.bank • checkF ail!〈CUST ID〉))<br />

Client bank • charge!〈client, 1234, 100, id1〉 |<br />

(client • chargeOK?〈id1〉.0 + client • chargeF ail?〈id1〉.0) |<br />

bank • charge!〈client, 1234, 200, id2〉 |<br />

(client • chargeOK?〈id2〉.0 + client • chargeF ail?〈id2〉.0)<br />

Il <strong>servizi</strong>o Bank quin<strong>di</strong> gestisce le richieste del Client <strong>per</strong>venute sull’endpoint con-<br />

trollando che la tupla <strong>di</strong> valori ricevuti combaci con i parametri passati. Inoltre,<br />

attraverso i canali <strong>di</strong> com<strong>un</strong>icazione checkOK e checkF ail, il <strong>servizi</strong>o bank gestisce<br />

le risposte, rispettivamente positive e negative, alle richieste ricevute. Ad ogni richie-<br />

sta, Bank crea <strong>un</strong> istanza specifica <strong>per</strong> sod<strong>di</strong>sfare quella richiesta ed è imme<strong>di</strong>atamente<br />

pronto a sod<strong>di</strong>sfare contemporaneamente altre richieste.<br />

Il <strong>servizi</strong>o Client, invece, invoca il <strong>servizi</strong>o Bank inviando <strong>un</strong>a tupla comprensiva<br />

<strong>di</strong> tipo utente, numero <strong>di</strong> conto, somma da versare e co<strong>di</strong>ce cliente.<br />

44


3.2 Descrizione <strong>di</strong> COWSlite<br />

3.2 Descrizione <strong>di</strong> COWSlite<br />

Adesso introdurremo il <strong>linguaggio</strong> COWSlite e ne descriveremo la sintassi e alc<strong>un</strong>i<br />

aspetti particolari legati alle variabili e al loro confronto; infine ne definiremo la<br />

semantica me<strong>di</strong>ante <strong>di</strong>fferenza con i calcoli precedentemente esposti ed in particolare<br />

con µCOWS m .<br />

3.2.1 Sintassi<br />

Dato che COWSlite è <strong>un</strong> <strong>linguaggio</strong> <strong>per</strong> l’orchestrazione <strong>di</strong> <strong>servizi</strong> <strong>web</strong>, <strong>un</strong>o degli<br />

aspetti principali da tenere in considerazione nello sviluppo è la necessità <strong>di</strong> definire<br />

in maniera semplice gli endpoint <strong>di</strong> com<strong>un</strong>icazione. A tal fine si mantiene la stessa<br />

modalità proposta <strong>per</strong> COWS e µCOWS m .<br />

La sintassi <strong>di</strong> COWSlite, definita in Tabella 3.6, è composta da <strong>un</strong>a serie <strong>di</strong><br />

produzioni sud<strong>di</strong>visibili in quattro gruppi: Programma, Dichiarazioni, Processi ed<br />

Espressioni.<br />

Il primo blocco è relativo alla struttura del programma ed è composto da <strong>un</strong>’<strong>un</strong>ica<br />

produzione, che definisce che <strong>un</strong> programma COWSlite è costituito da due sezioni:<br />

la prima, opzionale, riguarda le <strong>di</strong>chiarazioni globali, la seconda contiene <strong>un</strong>a serie<br />

<strong>di</strong> blocchi <strong>di</strong> descrizione <strong>di</strong> <strong>servizi</strong>, <strong>di</strong> cui almeno <strong>un</strong>o obbligatorio. Ogni blocco<br />

rappresenta <strong>un</strong> <strong>servizi</strong>o completo. Il fatto <strong>di</strong> poter definire più blocchi è solo <strong>per</strong><br />

agevolare il programmatore.<br />

Il secondo gruppo contiene le produzioni <strong>per</strong> il blocco delle <strong>di</strong>chiarazioni. Questo<br />

serve <strong>per</strong> <strong>di</strong>chiarare tutti gli identificatori che saranno globali a tutte le istanze del<br />

<strong>servizi</strong>o. Cioè ogni <strong>servizi</strong>o definito avrà come identificatori globali, con<strong>di</strong>visi fra<br />

tutte le istanze, quelli definiti all’interno della sezione dec{...}. Se ad esempio in<br />

<strong>un</strong> programma sono definiti due <strong>servizi</strong> S1 e S2 e D è l’insieme degli identificatori<br />

definiti in dec{...}, allora ogni istanza <strong>di</strong> S1 avrà <strong>un</strong>a copia <strong>di</strong> D con<strong>di</strong>visa fra tutte<br />

le istanze e ogni istanza <strong>di</strong> S2 avrà <strong>un</strong>’altra copia <strong>di</strong> D con<strong>di</strong>visa fra le istanze. Per<br />

definire identificatori privati ad <strong>un</strong>a istanza è necessario sfruttare la delimitazione.<br />

Dalle produzioni si ottiene che <strong>un</strong> identificatore può essere <strong>un</strong> partner, <strong>un</strong> nome,<br />

45


Programma:<br />

program = declaration ? cows_service +<br />

CAPITOLO 3 Il <strong>linguaggio</strong> COWSlite<br />

Dichiarazioni:<br />

declaration=dec {element ∗ }<br />

element=ide : lab_type;<br />

lab_type=var(var_type)<br />

| name<br />

| partner partner_name o<strong>per</strong>ation_name wsdl_link<br />

var_type = String<br />

| int<br />

| vect (number)<br />

Processi:<br />

cows_service = once ? service {proc}<br />

proc = (process)<br />

| process;<br />

process = |(proc,proc)<br />

| ∗[number] ? proc<br />

| [element*]proc<br />

| !(partner_name,o<strong>per</strong>ation_name,)<br />

| choice<br />

| ide := assignable.proc<br />

assignable = expr | const<br />

choice = +(choice, choice)<br />

| nil<br />

| ?(partner_value,o<strong>per</strong>ation_name,).proc<br />

Espressioni:<br />

expr = term | -term | +term | expr+term | expr-term<br />

term = fact | term*fact | term/fact<br />

fact = number | ide | (expr)<br />

Tabella 3.6: Sintassi <strong>di</strong> COWSlite<br />

oppure <strong>un</strong>a vera e propria variabile write-once che può contenere al momento tre tipi<br />

<strong>di</strong> dato: stringa, intero o vettore <strong>di</strong> variabili. Tra i tipi <strong>di</strong> identificatore esiste anche<br />

l’etichetta killer che non è stata inserita <strong>per</strong> appesantire la notazione, ma è presente<br />

nell’implementazione <strong>per</strong> estensioni future.<br />

46<br />

Il terzo e il quarto gruppo sono relativi al blocco <strong>di</strong> definizione dei <strong>servizi</strong>. Il terzo


3.2 Descrizione <strong>di</strong> COWSlite<br />

gruppo <strong>di</strong> produzioni descrive i processi che concorrono alla specifica della logica del<br />

<strong>servizi</strong>o COWSlite. Un <strong>servizi</strong>o comincia con la parola chiave service e contiene<br />

all’interno delle parentesi graffe la descrizione dei processi. La keyword service po-<br />

trebbe essere preceduta dalla parola chiave once che sta ad in<strong>di</strong>care che il <strong>servizi</strong>o<br />

potrà essere istanziato al massimo <strong>un</strong>a sola volta.La produzione proc non è impor-<br />

tante a livello semantico, serve solo <strong>per</strong> poter racchiudere <strong>un</strong>a sequenza <strong>di</strong> processi<br />

all’interno <strong>di</strong> <strong>un</strong>a coppia <strong>di</strong> parentesi tonde al fine <strong>di</strong> migliorare la leggibilità del li-<br />

stato. Le produzioni process, assignable e choice sono quelle che descrivono le azioni<br />

del <strong>servizi</strong>o COWSlite. Process definisce i processi principali costituenti <strong>un</strong> <strong>servizi</strong>o<br />

COWSlite. Il motivo <strong>per</strong> cui le o<strong>per</strong>azioni definite nelle produzioni vengono chia-<br />

mate processi saranno chiare successivamente quando verrà descritta l’architettura<br />

del motore <strong>di</strong> esecuzione. La produzione process definisce tutti i processi eseguibili<br />

del <strong>linguaggio</strong>: la composizione parallela, la replicazione, l’invocazione <strong>di</strong> <strong>un</strong> <strong>servizi</strong>o,<br />

la scelta guardata e l’assegnazione <strong>di</strong> <strong>un</strong> valore o <strong>di</strong> <strong>un</strong> espressione ad <strong>un</strong>a variabile.<br />

Fra queste assignable definisce il costrutto <strong>di</strong> assegnazione nel quale avviene anche la<br />

valutazione delle espressioni.<br />

La produzione choice descrive la singola o<strong>per</strong>azione <strong>di</strong> ricezione o il costrutto <strong>di</strong><br />

scelta guardata. Questo prevede che in caso <strong>di</strong> scelta questa venga eseguita in maniera<br />

non deterministica fra tutte le possibilità definite dalle o<strong>per</strong>azioni <strong>di</strong> ricezione, cioè<br />

solo la prima richiesta <strong>per</strong>venuta in or<strong>di</strong>ne temporale che corrisponde ad <strong>un</strong>a delle<br />

richieste collegate tramite l’o<strong>per</strong>atore <strong>di</strong> scelta provocherà la mo<strong>di</strong>fica dello stato del<br />

sistema e <strong>per</strong>metterà l’esecuzione dei processi ad esso successivi. La corrispondenza è<br />

definita dalle regole <strong>di</strong> matching fra invocazione e ricezione del <strong>servizi</strong>o. Se ci sono più<br />

ricezioni che sod<strong>di</strong>sfano l’invocazione allora la ricezione sarà selezionata in maniera<br />

non deterministica.<br />

Sarebbe stato forse più opport<strong>un</strong>o o più comodo definire degli o<strong>per</strong>atori n-ari<br />

anziché binari <strong>per</strong> il parallelo e la scelta guardata, ma è stato scelto <strong>di</strong> definirli binari<br />

<strong>per</strong> semplificare lo sviluppo del compilatore e <strong>per</strong> restare più fedeli possibile alla<br />

sintassi <strong>di</strong> COWS.<br />

47


CAPITOLO 3 Il <strong>linguaggio</strong> COWSlite<br />

Inoltre <strong>per</strong> essi valgono le proprietà associativa e commutativa.<br />

L’ultimo gruppo <strong>di</strong> produzioni definisce la struttura delle espressioni algebriche.<br />

Per realizzare il compilatore è necessario definire <strong>un</strong> sottoinsieme minimo <strong>di</strong> o<strong>per</strong>atori<br />

aritmetici. Al momento le espressioni supportate o<strong>per</strong>ano su variabili <strong>di</strong> tipo intero e<br />

implementano solo le quattro o<strong>per</strong>azioni algebriche (somma, sottrazione, moltiplica-<br />

zione e <strong>di</strong>visione) e l’uso delle parentesi <strong>per</strong> in<strong>di</strong>care la precedenza delle o<strong>per</strong>azioni. Il<br />

blocco <strong>di</strong> definizione è composto da tre definizioni expr, term e fact che rappresentano<br />

le o<strong>per</strong>azioni in or<strong>di</strong>ne <strong>di</strong> precedenza; in fact ci sono gli elementi <strong>di</strong> <strong>base</strong> (numeri e<br />

identificatori <strong>di</strong> variabili) e la possibilità <strong>di</strong> definire espressioni che abbiano precedenza<br />

sull’espressione corrente <strong>per</strong> mezzo delle parentesi; in term sono in<strong>di</strong>cate le o<strong>per</strong>azioni<br />

<strong>di</strong> prodotto e <strong>di</strong> <strong>di</strong>visione ed infine in expr sono in<strong>di</strong>cate le o<strong>per</strong>azioni <strong>di</strong> somma e<br />

<strong>di</strong>fferenza che hanno precedenza minima.<br />

3.2.2 Tipi <strong>di</strong> dato e vettori <strong>di</strong> variabili write-once<br />

Nella sintassi non sono state incorporate formalmente, <strong>per</strong> non appesantire la nota-<br />

zione, le definizioni dei valori numerici e letterali presenti nel corpo delle produzioni; i<br />

tipi <strong>di</strong> valori si <strong>di</strong>vidono in tre categorie: identificatori (ide), costanti letterali (const)<br />

e numeri (number). Il termine values è utilizzato <strong>per</strong> in<strong>di</strong>care <strong>un</strong>o qualsiasi dei tre<br />

tipi <strong>di</strong> <strong>base</strong>. Con il termine identificatori si intende <strong>un</strong>a qualsiasi sequenza <strong>di</strong> caratteri<br />

(lettere e numeri) che inizia obbligatoriamente con <strong>un</strong>a lettera. Una costante lettera-<br />

le, invece, è <strong>un</strong>a qualsiasi sequenza <strong>di</strong> simboli (lettere, numeri, segni <strong>di</strong> interp<strong>un</strong>zione,<br />

ecc.) racchiusi fra doppie virgolette. Anche gli elementi presenti all’interno delle<br />

o<strong>per</strong>azioni <strong>di</strong> invoke e receive, in<strong>di</strong>cate rispettivamente con i simboli ! e ?, sono dei<br />

valori, ma si è preferito dar loro <strong>un</strong> nome più significativo, <strong>per</strong> cui partner_name è <strong>un</strong><br />

identificatore, partner_value è <strong>un</strong> valore, o<strong>per</strong>ation_name e wsdl_link sono costanti,<br />

mentre con list_of_values si intende <strong>un</strong> sequenza, anche vuota, <strong>di</strong> valori separati da<br />

virgola.<br />

Il termine list_of_values rappresenta la lista dei parametri che vengono associati<br />

alle o<strong>per</strong>azioni <strong>di</strong> invocazione e ricezione, questa lista può essere formata quin<strong>di</strong> da<br />

48


3.2 Descrizione <strong>di</strong> COWSlite<br />

valori costanti, tipo stringhe racchiuse fra i doppi apici o valori numerici, e nomi <strong>di</strong><br />

variabili che devono essere stati precedentemente definiti all’interno della <strong>di</strong>chiarazione<br />

globale oppure all’interno <strong>di</strong> <strong>un</strong>a delimitazione.<br />

Dal momento che deve essere eseguita <strong>un</strong>a traduzione in Java del <strong>servizi</strong>o CO-<br />

WSlite, le variabili in gioco devono essere tipate al fine <strong>di</strong> essere compatibili con<br />

Java.<br />

Attualmente COWSlite supporta solo variabili <strong>di</strong> tipo string, intero e vettori <strong>di</strong><br />

variabili ad <strong>un</strong>a <strong>di</strong>mensione, in cui <strong>per</strong>ò ogni elemento può essere <strong>un</strong>o qual<strong>un</strong>que dei<br />

tre tipi appena nominati.<br />

Come <strong>per</strong> COWS anche in COWSlite le variabili utilizzate sono tutte <strong>di</strong> tipo<br />

write-once. Questo implica che <strong>un</strong>a volta assegnato <strong>un</strong> valore alla variabile, questo non<br />

può essere mo<strong>di</strong>ficato; ovvero <strong>un</strong>a qual<strong>un</strong>que azione successiva <strong>di</strong> mo<strong>di</strong>fica fatta con<br />

<strong>un</strong>a receive o con <strong>un</strong>’assegnazione non produrranno alc<strong>un</strong> effetto, non mo<strong>di</strong>ficheranno<br />

il valore della variabile e non genereranno alc<strong>un</strong> errore. Anche i vettori sono variabili<br />

<strong>di</strong> tipo write-once.<br />

3.2.3 Regole <strong>di</strong> matching<br />

Affinché sia possibile sincronizzare due <strong>servizi</strong> o accettare <strong>un</strong>a richiesta in ingresso<br />

è necessario definire l’o<strong>per</strong>atore <strong>di</strong> match fra <strong>un</strong>a invocazione e <strong>un</strong>a ricezione. Tale<br />

definizione è ricorsiva sulla struttura degli o<strong>per</strong>atori.<br />

Siano !(p, o, < lv >) e ?(p ′ , o ′ , < lv ′ >) rispettivamente <strong>un</strong>a invocazione ed <strong>un</strong>a<br />

ricezione, con p e p ′ partner, o e o ′ o<strong>per</strong>ation e lv e lv ′ parametri delle o<strong>per</strong>azioni. Il<br />

match è positivo fra le due o<strong>per</strong>azioni se: p = p ′ , o = o ′ e si ha match fra lv e lv ′ ,<br />

quin<strong>di</strong> se partner e o<strong>per</strong>azione coincidono e le liste <strong>di</strong> valori sono compatibili.<br />

Le liste <strong>di</strong> valori sono compatibili se hanno lo stesso numero <strong>di</strong> elementi e ogni<br />

singolo valore della lista è compatibile. Cioè siano lv = x1, .., xn e lv ′ = x ′ 1 , .., x′ m si<br />

ha match(lv, lv ′ ) = true se m = n e ∀i : match(xi, x ′ i ) = true.<br />

Due valori v e v ′ sono compatibili se sono dello stesso tipo e se v = v ′ , se invece<br />

v ′ non ha <strong>un</strong> valore assegnato,si parla allora <strong>di</strong> variabile x ′ , il match è ancora vero,<br />

49


ma genera <strong>un</strong>a sostituzione x ′ ↦→ v.<br />

3.2.4 Semantica e <strong>di</strong>fferenze con µCOWS m<br />

CAPITOLO 3 Il <strong>linguaggio</strong> COWSlite<br />

Analizzeremo la semantica <strong>di</strong> COWSlite facendo <strong>un</strong> parallelo con i costrutti <strong>di</strong><br />

µCOWS m in modo da evidenziarne le similitu<strong>di</strong>ni e <strong>di</strong>scuterne le <strong>di</strong>fferenze.<br />

La prima <strong>di</strong>fferenza che salta agli occhi rispetto al calcolo originale è la presenza<br />

<strong>di</strong> <strong>un</strong>a sezione <strong>di</strong> <strong>di</strong>chiarazione delle variabili utilizzate. Si presenta infatti la necessità<br />

<strong>di</strong> tipare le variabili che verranno usate all’interno del listato COWSlite in modo<br />

da semplificare la costruzione del compilatore, visto soprattutto che il <strong>linguaggio</strong><br />

<strong>di</strong> destinazione è <strong>un</strong> <strong>linguaggio</strong> fortemente tipato e con molti controlli in fase <strong>di</strong><br />

compilazione sulla congruenza degli oggetti utilizzati.<br />

Le variabili definite nella sezione <strong>di</strong>chiarativa sono globali a tutte le istanze del<br />

<strong>servizi</strong>o.<br />

Sempre <strong>per</strong> semplificare la stesura del compilatore tutte le azioni del <strong>linguaggio</strong><br />

sono state riscritte usando <strong>un</strong>a notazione prefissa o <strong>di</strong> tipo f<strong>un</strong>zionale, cioè sono tutte<br />

delle forma Azione(lista parametri); essendo tutte della stessa forma si semplifica il<br />

trattamento durante la compilazione.<br />

I costrutti <strong>di</strong> composizione parallela e <strong>di</strong> scelta hanno la stessa semantica.<br />

Il costrutto <strong>di</strong> replicazione si comporta come in µCOWS m anche <strong>per</strong> esso vale<br />

la regola <strong>di</strong> congruenza strutturale ∗ s ≡ s | ∗ s; in più in COWSlite ammette <strong>un</strong><br />

parametro numerico che <strong>per</strong>mette <strong>di</strong> definire il numero massimo <strong>di</strong> processi replicati<br />

contemporaneamente attivi; questo serve <strong>per</strong> non allocare infiniti processi in fase <strong>di</strong><br />

inizializzazione e limitare allo stesso tempo il carico sullo scheduler del Web Server,<br />

non incide sulla semantica del <strong>linguaggio</strong>.<br />

La delimitazione [d] s <strong>per</strong>mette <strong>di</strong> definire nomi che sono solo locali al processo<br />

s, allo stesso modo in COWSlite le variabili definite all’interno della delimitazione<br />

sono visibili ai soli costrutti contenuti in proc.<br />

Il costrutto <strong>di</strong> invocazione non supporta la valutazione <strong>di</strong> espressioni <strong>di</strong> ness<strong>un</strong><br />

tipo, ma accetta solo variabili write-once. Per eseguire la valutazione <strong>di</strong> espressioni<br />

50


3.2 Descrizione <strong>di</strong> COWSlite<br />

è stato introdotto il costrutto <strong>di</strong> assegnazione <strong>per</strong> cui <strong>per</strong> eseguire la valutazione <strong>di</strong><br />

<strong>un</strong>a espressione <strong>di</strong> <strong>un</strong> parametro da utilizzare nell’invocazione <strong>di</strong> <strong>un</strong> <strong>servizi</strong>o si devono<br />

usare entrambi i costrutti. Ad esempio il co<strong>di</strong>ce COWS relativo alla invoke:<br />

p1 • o1!〈a + b ∗ c, a − c/b〉<br />

deve essere tradotto nell’equivalente COWSlite:<br />

tmp1 := a + b ∗ x.tmp2 := a − c/b.!(p1, o1, < tmp1, tmp2 >)<br />

p • o? ¯w.s si comporta come ?(p, o, ¯w).s <strong>per</strong>ché entrambi accettano <strong>un</strong> insieme <strong>di</strong><br />

parametri in input e mo<strong>di</strong>ficano lo stato del processo successivo assegnando i valori<br />

dei parametri alle relative variabili.<br />

Una com<strong>un</strong>icazione fra due azioni, <strong>un</strong>a <strong>di</strong> invocazione ed <strong>un</strong>a <strong>di</strong> ricezione, da luogo<br />

ad <strong>un</strong>a sostituzione delle variabili interessate dall’o<strong>per</strong>azione <strong>di</strong> ricezione e comporta<br />

la terminazione dell’azione <strong>di</strong> invocazione, quello che rimane è solo la continuazione<br />

della ricezione alla quale è applicata la sostituzione.<br />

Anche <strong>per</strong> gli altri o<strong>per</strong>atori il comportamento è analogo nei due linguaggi.<br />

La keyword name può essere utilizzata <strong>per</strong> in<strong>di</strong>care <strong>un</strong> nome all’interno del co-<br />

strutto che non ha <strong>un</strong> tipo associato, ma che corrisponda semplicemente ad <strong>un</strong> nome<br />

non visibile dall’esterno.<br />

L’assegnazione, a <strong>di</strong>fferenza della definizione, non è <strong>un</strong> costrutto bloccante. Cioè,<br />

esso viene eseguito senza controlli sullo stato delle variabili, se le variabili non so-<br />

no tutte assegnate si genererà <strong>un</strong>’eccezione in fase <strong>di</strong> esecuzione che comporterà la<br />

terminazione del ramo in questione.<br />

L’attuale mancanza dei costrutti <strong>di</strong> kill e protection fa si che il <strong>linguaggio</strong> sia meno<br />

espressivo rispetto a COWS, ma il comportamento in tutti gli altri casi è coerente<br />

con quello <strong>di</strong> µCOWS m in cui non viene fatto uso <strong>di</strong> tali o<strong>per</strong>atori.<br />

COWS<br />

Una delle semplificazioni fatte a livello sintattico è stata la scelta <strong>di</strong> usare o<strong>per</strong>atori<br />

prefissi al posto degli o<strong>per</strong>atori infissi.<br />

51


CAPITOLO 3 Il <strong>linguaggio</strong> COWSlite<br />

Non sono state implementate le azioni <strong>di</strong> kill e protection, che vengono lasciate ad<br />

<strong>un</strong>a futura estensione. Invece le parole chiave KillerLabel e name sono presenti nella<br />

definizione del <strong>linguaggio</strong>, ma non hanno effetto sul co<strong>di</strong>ce generato, proprio <strong>per</strong>ché<br />

riguardano gli aspetti <strong>di</strong> COWS non ancora implementati.<br />

La progettazione e la definizione del <strong>linguaggio</strong> sono stati fatti <strong>per</strong> <strong>per</strong>mettere e<br />

agevolare l’implementazione delle o<strong>per</strong>azioni e dei costrutti mancanti in <strong>un</strong> momento<br />

successivo.<br />

3.3 Esempi<br />

Ripren<strong>di</strong>amo adesso alc<strong>un</strong>i degli esempi visti con µCOWS m in modo da chiarire il<br />

f<strong>un</strong>zionamento <strong>di</strong> COWSlite ed evidenziare che le <strong>di</strong>fferenze fra i due linguaggi sono<br />

sostanzialmente <strong>di</strong> natura sintattica.<br />

Dato che COWSlite non è <strong>un</strong> formalismo <strong>di</strong> specifica in senso stretto, ma si<br />

avvicina <strong>di</strong> più ai linguaggi <strong>di</strong> programmazione, non è stata definita <strong>per</strong> esso <strong>un</strong>a<br />

semantica o<strong>per</strong>azionale tramite regole <strong>di</strong> transizione, <strong>per</strong> cui negli esempi successivi<br />

abuseremo <strong>un</strong> po’ della notazione definita <strong>per</strong> µCOWS m <strong>per</strong> spiegare l’evoluzione<br />

<strong>di</strong> stato del sistema. Utilizzeremo<br />

∅<br />

−−→ <strong>per</strong> in<strong>di</strong>care <strong>un</strong>a com<strong>un</strong>icazione con sincro-<br />

nizzazione e utilizzeremo la sostituzione ·{...} <strong>per</strong> in<strong>di</strong>care l’assegnazione <strong>di</strong> valori a<br />

variabili a seguito <strong>di</strong> com<strong>un</strong>icazioni.<br />

Com<strong>un</strong>icazione<br />

Questo esempio, che nel calcolo viene eseguito tramite estensione dello scopo, mette<br />

in evidenza che tutti i processi all’interno <strong>di</strong> <strong>un</strong>a delimitazione subiscono l’effetto <strong>di</strong><br />

<strong>un</strong>a sostituzione (assegnazione delle variabili) a seguito <strong>di</strong> <strong>un</strong>a com<strong>un</strong>icazione.<br />

service{|(!(odds,throw,),<br />

[xp,xnum]|(?(odds,throw,).s,s’)} ∅<br />

−−→<br />

service{|(s,s’)·{xp ↦→ cbA, xnum ↦→ 2}}<br />

52


3.3 Esempi<br />

I due processi rimanenti s e s’ sono eseguiti all’interno dello stesso ambiente<br />

nel quale le due variabili ristrette (xp e xnum) hanno assegnati dei valori derivanti<br />

dall’avvenuta com<strong>un</strong>icazione.<br />

In COWSlite possiamo prendere ad esempio <strong>un</strong> altro tipo <strong>di</strong> com<strong>un</strong>icazione,<br />

quello fra due <strong>servizi</strong>.<br />

service{|(!(odds,throw,),s}<br />

service{[xp,xnum]|(?(odds,throw,).s,s’)} ∅<br />

−−→<br />

Il seguente sistema evolve dopo la com<strong>un</strong>icazione in:<br />

service{s}<br />

service{[xp,xnum]|(s,s’)·{xp ↦→ cbA, xnum ↦→ 2}}<br />

Cioè il <strong>servizi</strong>o che ha <strong>per</strong> nome odds riceve due valori e al suo posto rimane in<br />

esecuzione la sua continuazione che viene eseguita all’interno dell’ambiente delimitato<br />

dalle variabili [xp,xnum] alle quali è stato assegnato <strong>un</strong> valore dalla sostituzione<br />

generata dall’avvenuta com<strong>un</strong>icazione.<br />

Istanze <strong>di</strong> <strong>servizi</strong>o e correlazione <strong>di</strong> messaggi<br />

Ripren<strong>di</strong>amo l’esempio visto precedentemente sulla correlazione fra le istanze <strong>di</strong> <strong>un</strong><br />

<strong>servizi</strong>o.<br />

Divi<strong>di</strong>amo il <strong>servizi</strong>o visto in due <strong>servizi</strong> separati <strong>per</strong> evidenziare maggiormente<br />

il concetto <strong>di</strong> correlazione. Il primo dei due è il <strong>servizi</strong>o fornito, mentre il secondo<br />

simula due clienti che effettuano la richiesta. La parte <strong>di</strong> <strong>di</strong>chiarazione iniziale serve<br />

solo al <strong>servizi</strong>o client <strong>per</strong> in<strong>di</strong>viduare la locazione in cui verranno posti i <strong>servizi</strong>.<br />

dec{<br />

}<br />

srv : partner srv "o1"<br />

srv2: partner srv "o2"<br />

service {<br />

"http://localhost:8080/test/srvService?WSDL";<br />

"http://localhost:8080/test/srvService?WSDL";<br />

53


}<br />

[Xid:var(String);Xp:var(String);Xnum:var(int);<br />

Yp:var(String);Ynum:var(int);]<br />

CAPITOLO 3 Il <strong>linguaggio</strong> COWSlite<br />

?("srv","o1",).?("srv","o2",).nil<br />

once service {<br />

}<br />

|(<br />

)<br />

|(!(srv,"o1",),!(srv,"o1",)),<br />

!(srv2,"o2",)<br />

Le richieste dei client all’o<strong>per</strong>azione o1 genereranno nel <strong>servizi</strong>o srv due istanze<br />

<strong>di</strong>fferenti del <strong>servizi</strong>o stesso. La richiesta del <strong>servizi</strong>o o2 invece rimane in attesa fino<br />

a che non verrà avviata l’istanza <strong>di</strong> <strong>servizi</strong>o srv che ha come primo parametro ‘first’.<br />

In questo esempio la correlazione fra le istanze avviene utilizzando <strong>un</strong>a variabile, che<br />

chiameremo app<strong>un</strong>to variabile <strong>di</strong> correlazione.<br />

Dopo l’esecuzione delle due richieste dell’o<strong>per</strong>azione o1 da parte del cliente lo<br />

stato del <strong>servizi</strong>o è il seguente:<br />

service {<br />

}<br />

[Xid:var(String);Xp:var(String);Xnum:var(int);<br />

Yp:var(String);Ynum:var(int);]<br />

?("srv","o1",).?("srv","o2",).nil<br />

|[Yp:var(String);Ynum:var(int);]<br />

?("srv","o2",).nil·{Xp ↦→ ′′ cbA ′′ , Xnum ↦→ 2}<br />

|[Yp:var(String);Ynum:var(int);]<br />

?("srv","o2",).nil·{Xp ↦→ ′′ cbA ′′ , Xnum ↦→ 3}<br />

once service {<br />

}<br />

54<br />

!(srv2,"o2",)


3.3 Esempi<br />

Ed infine, dopo l’ultima com<strong>un</strong>icazione:<br />

service {<br />

}<br />

[Xid:var(String);Xp:var(String);Xnum:var(int);<br />

Yp:var(String);Ynum:var(int);]<br />

?("srv","o1",).?("srv","o2",).nil<br />

|nil·{Xid ↦→ first, Xp ↦→ cbA, Xnum ↦→ 2, Y p ↦→ cbB, Y num ↦→ 2}<br />

|[Yp:var(String);Ynum:var(int);]<br />

?("srv","o2",).nil·{Xp ↦→ cbA, Xnum ↦→ 3}<br />

once service {}<br />

Descrizione ed esecuzione <strong>di</strong> <strong>un</strong> <strong>servizi</strong>o<br />

La principale <strong>di</strong>fferenza fra µCOWS m e COWSlite è proprio nella definizione ini-<br />

ziale, in COWSlite ogni processo definito è <strong>un</strong> vero e proprio <strong>servizi</strong>o <strong>web</strong>.<br />

service{} in<strong>di</strong>ca <strong>un</strong> <strong>servizi</strong>o <strong>web</strong> vuoto in cui non ci sono <strong>servizi</strong> <strong>di</strong>chiarati.<br />

service {[x1:var(...);...;xn:var(...)]?(p,o,).s}<br />

è il più semplice <strong>servizi</strong>o <strong>web</strong> che può essere <strong>di</strong>chiarato, la presenza della keyword<br />

service fa la vece del costrutto <strong>di</strong> replicazione iniziale usata in µCOWS m . Quin<strong>di</strong><br />

l’esempio visto precedentemente si può scrivere come<br />

service {[x1:var(int)]?(p,"o",)}<br />

once service {!(p,"o",)}<br />

oppure nel caso <strong>di</strong> due richieste contemporanee<br />

once service {|(!(p,"o",),!(p,"o",))}<br />

che produce dopo due com<strong>un</strong>icazioni, con <strong>un</strong> po’ <strong>di</strong> abuso <strong>di</strong> notazione:<br />

service {[x1:var(int)]?(p,"o",)} | s·{x1 ↦→ v1} | s·{x1 ↦→ v2}<br />

55


Bank Acco<strong>un</strong>t<br />

CAPITOLO 3 Il <strong>linguaggio</strong> COWSlite<br />

Ripren<strong>di</strong>amo la simulazione <strong>di</strong> <strong>un</strong> <strong>servizi</strong>o bancario, soffermandoci sul <strong>servizi</strong>o<br />

bancario vero e proprio in<strong>di</strong>viduato dal processo bank.<br />

dec{<br />

}<br />

clientEndPoint : partner client "charge"<br />

"http://localhost:8080/bankAcco<strong>un</strong>t/clientService?WSDL";<br />

bankEndPoint : partner bank "charge"<br />

"http://localhost:8080/bankAcco<strong>un</strong>t/bankService?WSDL";<br />

service{ |(<br />

[CUST:var(String); CC:var(int); AMOUNT:var(int); ID:var(String);]<br />

?("bank", "charge", ).<br />

|(!("bank", "check", ),<br />

+( ?("bank", "checkOk", ).!(CUST, "chargeOK", ),<br />

?("bank", "checkFail", ).!(CUST, "chargeFail", ) )<br />

),<br />

[CUSTID:var(String); CC:var(int); AMOUNT:var(int);]<br />

}<br />

?("bank", "check", ).<br />

)<br />

|(<br />

)<br />

!("bank","o",),<br />

+( ?("bank", "o", ).!("bank", "checkOk", ),<br />

?("bank", "o", ).!("bank", "checkFail", ))<br />

once service { | (<br />

| ( !(bankEndPoint,"charge",),<br />

56


3.3 Esempi<br />

+(?("client", "chargeOk", ).nil ,<br />

?("client", "chargeFail", ).nil)),<br />

| ( !(bankEndPoint,"charge",),<br />

)<br />

}<br />

+(?("client", "chargeOk", ).nil ,<br />

?("client", "chargeFail", ).nil))<br />

Il processo bank è costituito da due endpoint <strong>di</strong> com<strong>un</strong>icazione <strong>un</strong>o esterno corri-<br />

spondente all’o<strong>per</strong>azione charge e <strong>un</strong>o interno l’o<strong>per</strong>azione check. Il secondo endpoint<br />

ha semplicemente la f<strong>un</strong>zione <strong>di</strong> simulare se la transazione richiesta è andata a buon<br />

fine ed avvisare dell’eventuale fallimento. Il <strong>servizi</strong>o principale esegue la richiesta e<br />

com<strong>un</strong>ica al client il risultato della transazione utilizzando <strong>per</strong> la risposta due <strong>di</strong>ver-<br />

si canali <strong>di</strong> com<strong>un</strong>icazione corrispondenti a due o<strong>per</strong>azioni che il client deve esporre<br />

(checkOk e checkFail).<br />

Nella parte <strong>di</strong> <strong>di</strong>chiarazione sono definiti gli endpoint <strong>di</strong> com<strong>un</strong>icazione sui quali<br />

si prevede <strong>di</strong> mettere in esecuzione i <strong>servizi</strong>. Questa definizione serve <strong>per</strong> il processo<br />

client.<br />

57


58<br />

CAPITOLO 3 Il <strong>linguaggio</strong> COWSlite


Capitolo 4<br />

<strong>Implementazione</strong> <strong>di</strong> COWSlite<br />

In questo capitolo descriveremo come è stato realizzato il compilatore COWSlite e<br />

il motore <strong>di</strong> esecuzione, introducendo le scelte tecnologiche e <strong>di</strong> progetto effettuate<br />

e gli obiettivi prefissati. Partiremo dalla descrizione <strong>di</strong> <strong>un</strong> <strong>servizi</strong>o <strong>web</strong> definito con<br />

il nostro <strong>linguaggio</strong> e descriveremo le strutture e i moduli realizzati <strong>per</strong> l’esecuzione<br />

del suddetto <strong>servizi</strong>o. Infine, ci soffermeremo sulla realizzazione del compilatore che<br />

produce il co<strong>di</strong>ce Java [40, 13] che rappresenta il <strong>servizi</strong>o.<br />

4.1 Obiettivi e scelte implementative<br />

Dal momento che sono necessarie più fasi <strong>per</strong> poter compilare il co<strong>di</strong>ce COWSlite,<br />

<strong>di</strong>stribuire il co<strong>di</strong>ce Java ottenuto ed eseguire il co<strong>di</strong>ce compilato all’interno <strong>di</strong> <strong>un</strong> Web<br />

Application Server, anche il nostro progetto dovrà essere sud<strong>di</strong>viso in più componenti<br />

<strong>per</strong> poter affrontare tutti i passi definiti nelle varie fasi.<br />

I componenti evidenziati in Figura 4.1 sono:<br />

1. Il motore <strong>di</strong> esecuzione dei <strong>servizi</strong> COWSlite che viene ospitato all’interno del<br />

server <strong>web</strong> e che esegue il co<strong>di</strong>ce Java compilato.<br />

2. Il compilatore COWSlite che traduce il co<strong>di</strong>ce in Java e fa uso dei <strong>servizi</strong> messi<br />

a <strong>di</strong>sposizione dal motore.<br />

59


CAPITOLO 4 <strong>Implementazione</strong> <strong>di</strong> COWSlite<br />

Figura 4.1: Struttura del progetto<br />

3. Alc<strong>un</strong>i programmi o script <strong>di</strong> utilità <strong>per</strong> agevolare la compilazione e il deploy<br />

del <strong>servizi</strong>o sviluppato.<br />

La realizzazione ha quin<strong>di</strong> comportato <strong>di</strong>verse fasi <strong>di</strong> analisi, progettazione e rea-<br />

lizzazione dei vari componenti del progetto. All’inizio della fase <strong>di</strong> analisi sono state<br />

fatte delle scelte, la prima, ormai chiara, è il <strong>linguaggio</strong> <strong>di</strong> programmazione utilizzato<br />

come target della compilazione. Questa scelta è stata fatta in <strong>base</strong> a molti parametri<br />

oggettivi: la facilità a re<strong>per</strong>ire compilatori, ambienti <strong>di</strong> sviluppo e documentazione a<br />

costo zero; la natura open source del <strong>linguaggio</strong> e quin<strong>di</strong> la libertà <strong>di</strong> ri<strong>di</strong>stribuzione<br />

del co<strong>di</strong>ce prodotto; la presenza <strong>di</strong> molte librerie <strong>di</strong> supporto anch’esse open source.<br />

Un altro aspetto importante è la spiccata propensione <strong>di</strong> Java verso il networking e<br />

tutti gli aspetti ad esso legati. Java infatti ha da sempre p<strong>un</strong>tato sull’utilizzo del<br />

<strong>web</strong> come <strong>un</strong>o dei principali sbocchi <strong>per</strong> le applicazioni prodotte, introducendo da<br />

subito librerie <strong>di</strong> sistema de<strong>di</strong>cate e tecnologie specifiche (basti pensate ad esempio<br />

alle applet). È stato anche <strong>un</strong>o dei primi linguaggi <strong>per</strong> cui sono comparsi strumenti<br />

e librerie specifiche <strong>per</strong> i <strong>servizi</strong> <strong>web</strong>. Questo è <strong>un</strong>o dei motivi principali che hanno<br />

pesato a favore <strong>di</strong> tale scelta.<br />

Un altro degli obiettivi <strong>per</strong>seguiti era quello <strong>di</strong> utilizzare meno materiale <strong>di</strong> terze<br />

parti possibile: librerie, API, ecc., in modo tale da non dover ri<strong>di</strong>stribuire troppi file<br />

aggi<strong>un</strong>tivi a corredo del co<strong>di</strong>ce prodotto, oppure obbligare il <strong>web</strong> master ad installare<br />

60


4.2 Un <strong>servizi</strong>o COWSlite in Java<br />

nel server pacchetti aggi<strong>un</strong>tivi <strong>per</strong> il supporto del prodotto. Tutto ciò che serve <strong>per</strong><br />

costruire ed eseguire l’engine è contenuto nel JDK 1.6, dal momento che le librerie<br />

<strong>di</strong> supporto ai <strong>servizi</strong> <strong>web</strong> sono state inglobate da SUN nella <strong>di</strong>stribuzione ufficiale<br />

proprio in questa release. Le librerie necessarie sono com<strong>un</strong>que presenti anche nel<br />

pacchetto Metro che è contenuto in molti application server <strong>di</strong> ultima produzione<br />

come ad esempio S<strong>un</strong> Application Server [39] e Glassfish [21].<br />

Per sviluppare il progetto è stato utilizzato l’ambiente <strong>di</strong> sviluppo open source<br />

NetBeans versione 5.5.1 e i test sono stati effettuati utilizzando gli application server<br />

SUN Application Server Platform E<strong>di</strong>tion 9.0 e Glassfish 2.1.<br />

4.2 Un <strong>servizi</strong>o COWSlite in Java<br />

Quello che vogliamo ottenere è <strong>un</strong> listato <strong>di</strong> co<strong>di</strong>ce Java, che realizzi il comportamento<br />

specificato da <strong>un</strong> programma COWSlite. Tale co<strong>di</strong>ce <strong>un</strong>a volta compilato deve poter<br />

essere eseguito all’interno <strong>di</strong> <strong>un</strong> server <strong>web</strong> come <strong>un</strong> com<strong>un</strong>e <strong>servizi</strong>o <strong>web</strong> prodotto<br />

secondo gli standard e deve poter interagire con altri <strong>servizi</strong> <strong>web</strong> presenti nella rete.<br />

Per far ciò è stato necessario realizzare <strong>un</strong> package <strong>di</strong> supporto al fine <strong>di</strong> <strong>per</strong>mettere<br />

l’interfacciamento fra il co<strong>di</strong>ce prodotto e il server <strong>web</strong> su cui verrà eseguito, in modo<br />

da poter scrivere più semplicemente il co<strong>di</strong>ce Java che descrive il processo COWSlite.<br />

Il compilatore COWSlite, quin<strong>di</strong>, produce del co<strong>di</strong>ce che utilizza i componenti<br />

definiti nel package <strong>per</strong> descrivere la logica del <strong>servizi</strong>o, le sue interfacce e tutte le<br />

interazioni e o<strong>per</strong>azioni specificate. Uno dei compiti del package, che d’ora in poi<br />

chiameremo engine o r<strong>un</strong>time, è quello <strong>di</strong> separare gli aspetti legati alla com<strong>un</strong>ica-<br />

zione da e verso altri <strong>servizi</strong> in modo da non doversi preoccupare <strong>di</strong> considerare tutti<br />

gli elementi necessari all’interazione fra <strong>servizi</strong> <strong>web</strong>. Allo stesso tempo deve fornire<br />

<strong>un</strong>’astrazione <strong>per</strong> la descrizione e l’esecuzione della logica dei processi e <strong>per</strong> la gestione<br />

delle variabili, delle etichette e dei dati da scambiare fra i <strong>servizi</strong>.<br />

La Figura 4.2 mostra tutti i passi necessari <strong>per</strong> ottenere <strong>un</strong> <strong>servizi</strong>o che può essere<br />

pubblicato su <strong>un</strong> server <strong>web</strong> partendo dal file sorgente contente la descrizione scritta<br />

in COWSlite. Per prima cosa è necessario usare il compilatore COWSlite <strong>per</strong><br />

61


CAPITOLO 4 <strong>Implementazione</strong> <strong>di</strong> COWSlite<br />

ottenere <strong>un</strong>o o più file Java che descrivono il <strong>servizi</strong>o. Dopo <strong>di</strong> che, questi file devono<br />

essere compilati con il compilatore Java, fornendo insieme il package mcows.engine,<br />

in modo da ottenere i file Java eseguibili (.class). Successivamente è necessario re-<br />

cu<strong>per</strong>are i file compilati, il file .jar contenente la libreria del motore ed alc<strong>un</strong>i file<br />

XML <strong>di</strong> descrizione del <strong>servizi</strong>o, organizzarli secondo le specifiche <strong>per</strong> realizzare <strong>un</strong>a<br />

<strong>web</strong> application e assemblarli utilizzando l’apposita utilità del JDK <strong>per</strong> produrre i file<br />

archivio. Con questo file archivio assemblato, avente estensione .war, sarà possibile<br />

eseguire il deploy del <strong>servizi</strong>o su <strong>un</strong> application server.<br />

Figura 4.2: Compilazione <strong>di</strong> <strong>un</strong> <strong>servizi</strong>o COWSlite<br />

Le specifiche dell’API JAX-WS [41] <strong>per</strong>mettono <strong>di</strong> definire <strong>un</strong> <strong>servizi</strong>o <strong>web</strong> tramite<br />

<strong>un</strong>a classe Java seguendo alc<strong>un</strong>i semplici accorgimenti. L’API in questione fa uso<br />

delle annotazioni, introdotte con la versione 1.5 <strong>di</strong> Java, <strong>per</strong> <strong>di</strong>chiarare che la classe in<br />

questione rappresenta <strong>un</strong> <strong>servizi</strong>o <strong>web</strong> e <strong>per</strong> definire le o<strong>per</strong>azioni esposte e le modalità<br />

<strong>di</strong> lavoro.<br />

Questo semplifica il lavoro allo sviluppatore in quanto non è più necessario definire<br />

a priori l’interfaccia del <strong>servizi</strong>o da esporre me<strong>di</strong>ante il formato WSDL. Infatti è<br />

62


4.2 Un <strong>servizi</strong>o COWSlite in Java<br />

l’application server stesso che genera la descrizione del <strong>servizi</strong>o esposto in maniera<br />

conforme con le specifiche e lo espone in modo che esso sia <strong>di</strong>sponibile a chi<strong>un</strong>que<br />

voglia usufruire <strong>di</strong> tale <strong>servizi</strong>o. Questa caratteristica dell’API si rivela utile anche<br />

agli scopi <strong>di</strong> questo progetto <strong>per</strong>ché ci <strong>per</strong>mette <strong>di</strong> non doverci preoccupare <strong>di</strong> fornire<br />

<strong>un</strong> WSDL del <strong>servizi</strong>o, dal momento che ci penserà l’application server a farlo <strong>per</strong><br />

noi appena il <strong>servizi</strong>o sarà stato <strong>di</strong>stribuito sul server. Quin<strong>di</strong> non è stato necessario<br />

realizzare f<strong>un</strong>zioni nel package <strong>per</strong> generare i file WSDL.<br />

Come si vede dal co<strong>di</strong>ce in Tabella 4.1, definire <strong>un</strong> <strong>servizi</strong>o <strong>web</strong> secondo le specifi-<br />

che è molto semplice con le API fornite da S<strong>un</strong>. Un <strong>servizi</strong>o altro non è che <strong>un</strong>a classe<br />

package _nomedelpackage_ ;<br />

import javax . jws . ∗ ;<br />

. . .<br />

@WebService<br />

public class S e r v i z i o {<br />

. . .<br />

public S e r v i z i o ( ) { // C o s t r u t t o r e d e l WS<br />

. . .<br />

/∗ Crea i p r o c e s s i d e l s e r v i z i o . ∗/<br />

CowsProcess f i r s t P r o c e s s = S e r v i c e C r e a t o r ( ) ;<br />

/∗ Esegue i l primo Processo ∗/<br />

f i r s t P r o c e s s . s t a r t ( ) ;<br />

}<br />

}<br />

@WebMethod<br />

@Oneway<br />

public void o<strong>per</strong>azione1 ( S t r i n g x ) {<br />

/∗ esegue l a r i c h i e s t a d i o<strong>per</strong>azione1 ∗/<br />

. . .<br />

}<br />

private CowsProcess S e r v i c e C r e a t o r ( ) {<br />

. . .<br />

/∗ d e s c r i z i o n e d e l s e r v i z i o ∗/<br />

. . .<br />

return ( r i f e r i m e n t o a l l a prima i s t r u z i o n e d e l s e r v i z i o )<br />

}<br />

Tabella 4.1: Co<strong>di</strong>ce <strong>di</strong> <strong>un</strong> <strong>servizi</strong>o<br />

63


CAPITOLO 4 <strong>Implementazione</strong> <strong>di</strong> COWSlite<br />

Java che segue alc<strong>un</strong>e regole e fa uso <strong>di</strong> annotazioni <strong>per</strong> marcare i p<strong>un</strong>ti principali<br />

della classe. È sufficiente assegnare <strong>un</strong> nome al package e importare le classi dell’API<br />

JAX-WS; dopo <strong>di</strong> che con l’annotazione @WebService, posta prima della <strong>di</strong>chiara-<br />

zione della classe, si <strong>di</strong>chiara che quella classe dovrà essere convertita in <strong>un</strong> <strong>servizi</strong>o<br />

<strong>web</strong> e poi si <strong>di</strong>chiarano le o<strong>per</strong>azioni esposte anteponendo l’annotazione @WebMethod<br />

alla <strong>di</strong>chiarazione <strong>di</strong> ogni metodo, in questo modo durante la compilazione del file la<br />

<strong>di</strong>chiarazione del metodo con la sua segnatura verrà utilizzata <strong>per</strong> ricavare tutti gli<br />

aspetti necessari <strong>per</strong> la realizzazione della Service Endopoint Interface (SEI). L’anno-<br />

tazione @OneWay, presente prima della definizione <strong>di</strong> <strong>un</strong> metodo, serve <strong>per</strong> impostare<br />

l’o<strong>per</strong>azione in modalità ‘sola richiesta’, come vuole app<strong>un</strong>to la definizione <strong>di</strong> CO-<br />

WSlite. Infine la parte introdotta da COWSlite è il metodo ServiceCreator()<br />

che conterrà la descrizione del <strong>servizi</strong>o sfruttando le istruzioni fornite nell’API del<br />

r<strong>un</strong>time.<br />

Il compito del compilatore COWSlite è quello <strong>di</strong> produrre il co<strong>di</strong>ce <strong>per</strong> il me-<br />

todo ServiceCreator() e riempire il corpo dei meto<strong>di</strong> che corrispondono alle ope-<br />

razioni esposte dal <strong>servizi</strong>o in modo che inoltrino le richieste all’engine. Vedremo<br />

successivamente con cosa riempire il corpo <strong>di</strong> questi meto<strong>di</strong>.<br />

4.3 Il package cowslite.engine<br />

Per poter completare il co<strong>di</strong>ce all’interno dello scheletro del <strong>servizi</strong>o visto preceden-<br />

temente si fa uso del package cowslite.engine che è stato realizzato <strong>per</strong> fornire con-<br />

temporaneamente l’ambiente <strong>per</strong> l’esecuzione del <strong>servizi</strong>o e <strong>un</strong>a serie <strong>di</strong> oggetti che<br />

<strong>per</strong>mettono <strong>di</strong> descriverne la logica <strong>di</strong> f<strong>un</strong>zionamento.<br />

Il motore <strong>di</strong> esecuzione dei <strong>servizi</strong> COWSlite è composto da quattro componenti<br />

principali come illustrato nella Figura 4.3: tre spazi <strong>di</strong> memorizzazione e <strong>un</strong>’<strong>un</strong>ità <strong>di</strong><br />

com<strong>un</strong>icazione.<br />

Gli spazi <strong>di</strong> memorizzazione hanno lo scopo <strong>di</strong> mantenere le informazioni necessarie<br />

affinché <strong>un</strong> <strong>servizi</strong>o possa essere eseguito. Questi sono tre <strong>per</strong>ché contengono le <strong>un</strong>ità<br />

fondamentali <strong>di</strong> <strong>un</strong> <strong>servizi</strong>o: la descrizione logica del <strong>servizi</strong>o, così come descritta <strong>per</strong><br />

64


4.3 Il package cowslite.engine<br />

Figura 4.3: Architettura dell’engine<br />

mezzo della sintassi, che sarà contenuta nello spazio denominato ProcessSpace; i dati<br />

gestiti dal <strong>servizi</strong>o e da ogn<strong>un</strong>a delle istanze in esecuzione che saranno organizzati<br />

in ambienti fra loro correlati e mantenuti in <strong>un</strong> apposito spazio <strong>di</strong> memorizzazione<br />

dati denominato DataSpace; le informazioni necessarie <strong>per</strong> gestire ogni com<strong>un</strong>icazione<br />

attiva interna ed esterna che saranno mantenute in <strong>un</strong> apposito spazio denominato<br />

app<strong>un</strong>to ServiceSpace.<br />

L’<strong>un</strong>ità <strong>di</strong> com<strong>un</strong>icazione, che si occupa <strong>di</strong> mantenere alc<strong>un</strong>e informazioni, invece<br />

fornisce le f<strong>un</strong>zioni <strong>per</strong> colloquiare con l’esterno interfacciandosi con il server <strong>web</strong> che<br />

ospita il motore <strong>di</strong> esecuzione COWSlite.<br />

I tre spazi <strong>di</strong> memorizzazione sono fra loro collegati <strong>per</strong>ché il contenuto del Da-<br />

taSpace è influenzato dalla logica del processo che genera nuove variabili e nuovi<br />

ambienti in f<strong>un</strong>zione dello stato <strong>di</strong> esecuzione e contemporaneamente le variabili con-<br />

tenute negli ambienti possono subire mo<strong>di</strong>fiche da parte <strong>di</strong> azioni avvenute nel Ser-<br />

viceSpace o a causa della logica del <strong>servizi</strong>o; il ServiceSpace influenza la logica del<br />

<strong>servizi</strong>o mo<strong>di</strong>ficando lo stato <strong>di</strong> esecuzione delle istanze a seguito <strong>di</strong> mo<strong>di</strong>fiche avve-<br />

nute nel DataSpace; infine la logica del <strong>servizi</strong>o non mo<strong>di</strong>fica <strong>di</strong>rettamente lo stato<br />

del ServiceSpace, ma lo fa attraverso l’interazione con l’<strong>un</strong>ità <strong>di</strong> com<strong>un</strong>icazione.<br />

Ogni richiesta proveniente dall’esterno e ogni attività <strong>di</strong> ricezione del <strong>servizi</strong>o pas-<br />

sano attraverso il ServiceSpace, dove vengono elaborate oppure archiviate in attesa<br />

65


CAPITOLO 4 <strong>Implementazione</strong> <strong>di</strong> COWSlite<br />

<strong>di</strong> <strong>un</strong>a possibile esecuzione. Il metodo <strong>per</strong> scegliere e/o selezionare <strong>un</strong> elemento con-<br />

tenuto all’interno del ServiceSpace è il matching fra <strong>un</strong>a richiesta ed <strong>un</strong>a ricezione.<br />

Se al momento della ricezione <strong>di</strong> <strong>un</strong>a richiesta esterna è presente <strong>un</strong>a attività <strong>di</strong> ri-<br />

cezione nel ServiceSpace <strong>per</strong> cui si ha <strong>un</strong> matching, le eventuali variabili correlate<br />

con l’o<strong>per</strong>azione vengono aggiornate e si procede con l’attività corrispondente alla<br />

continuazione dell’o<strong>per</strong>azione <strong>di</strong> ricezione così come definito nello spazio dei processi.<br />

Se non c’è corrispondenza invece la richiesta viene memorizzata all’interno del Ser-<br />

viceSpace. Analogamente, quando dall’esecuzione del <strong>servizi</strong>o COWSlite si ottiene<br />

<strong>un</strong>’attività <strong>di</strong> ricezione, questa viene inviata al ServiceSpace che controlla la presen-<br />

za <strong>di</strong> <strong>un</strong>a corrispondenza con <strong>un</strong>a delle richieste memorizzate e in caso affermativo<br />

la richiesta trovata viene eliminata dal ServiceSpace, quin<strong>di</strong> vengono aggiornate le<br />

variabili coinvolte nella ricezione e il <strong>servizi</strong>o continua la sua esecuzione. In caso ne-<br />

gativo l’attività viene memorizzata nel ServiceSpace e questo provoca la sospensione<br />

del <strong>servizi</strong>o o del ramo del <strong>servizi</strong>o interessato dall’attivita.<br />

Il ciclo <strong>di</strong> f<strong>un</strong>zionamento su cui si basa l’engine e in particolare il ServiceSpace si<br />

ispira allo ‘spazio delle tuple’ <strong>di</strong> Klaim [8, 5, 6], ma mentre Klaim gestisce solo tuple<br />

<strong>di</strong> dati, COWSlite gestisce i <strong>servizi</strong> con i relativi dati.<br />

4.3.1 L’<strong>un</strong>ità <strong>di</strong> com<strong>un</strong>icazione<br />

Per fornire tutti i <strong>servizi</strong> <strong>di</strong> com<strong>un</strong>icazione l’engine sfrutta le caratteristiche degli<br />

application server all’interno dei quali vengono inseriti i <strong>servizi</strong> compilati. In questo<br />

modo tutte le invocazioni provenienti dall’esterno sono gestite dal server <strong>web</strong> e passate<br />

all’engine che non deve preoccuparsi <strong>di</strong> trattare i dati provenienti dalla connessione,<br />

acquisirli e convertirli. Allo stesso modo le invocazioni <strong>di</strong> <strong>servizi</strong> esterni sono gestite<br />

dall’<strong>un</strong>ità <strong>di</strong> com<strong>un</strong>icazione <strong>per</strong> mezzo dell’API JAX-WS [24] associata all’application<br />

server, che fornisce tutto il supporto necessario <strong>per</strong> inviare sulla connessione i dati<br />

necessari <strong>per</strong> effettuare la richiesta.<br />

L’<strong>un</strong>ità <strong>di</strong> com<strong>un</strong>icazione, come già detto, si occupa <strong>di</strong> gestire tutte le com<strong>un</strong>i-<br />

cazioni da e verso il <strong>servizi</strong>o COWSlite. In particolare, il suo compito è quello <strong>di</strong><br />

66


4.3 Il package cowslite.engine<br />

trattare le o<strong>per</strong>azioni <strong>di</strong> invoke e receive del <strong>linguaggio</strong>, <strong>di</strong>scriminare quali richie-<br />

ste sono <strong>di</strong>rette internamente al <strong>servizi</strong>o e quali invece sono da richiedere all’esterno.<br />

Parte principale del lavoro dell’<strong>un</strong>ità è quella <strong>di</strong> occuparsi dell’interfacciamento con i<br />

<strong>servizi</strong> esterni.<br />

L’aspetto legato alle com<strong>un</strong>icazioni relative alle invocazioni delle o<strong>per</strong>azioni espo-<br />

ste dal <strong>servizi</strong>o <strong>web</strong> sono lasciate a totale carico del <strong>web</strong> application server. Infatti il<br />

server si comporta da fornitore <strong>di</strong> <strong>servizi</strong> occupandosi della ricezione della richiesta,<br />

della pubblicazione del <strong>servizi</strong>o e <strong>di</strong> gestire tutti gli strati dei protocolli <strong>di</strong> com<strong>un</strong>i-<br />

cazione in maniera trasparente <strong>per</strong> lo sviluppatore del <strong>servizi</strong>o, tanto che, come si è<br />

visto nello scheletro <strong>di</strong> co<strong>di</strong>ce del <strong>servizi</strong>o, il programmatore che realizza <strong>un</strong> servi-<br />

zio dovrà semplicemente preoccuparsi <strong>di</strong> definire quali, quanti e <strong>di</strong> che tipo sono le<br />

o<strong>per</strong>azioni e i relativi parametri. Non sarà quin<strong>di</strong> necessario preoccuparsi <strong>di</strong> definire<br />

qual è il WSDL che specifica l’interfaccia del <strong>servizi</strong>o, <strong>per</strong>ché questo verrà generato<br />

automaticamente nel momento in cui il <strong>servizi</strong>o verrà <strong>di</strong>stribuito sull’host.<br />

La Figura 4.4 mostra alc<strong>un</strong>e delle classi che compongono l’<strong>un</strong>ità <strong>di</strong> com<strong>un</strong>ica-<br />

zione. Queste classi rappresentano due aspetti presi in considerazione dall’<strong>un</strong>ità<br />

assolvendo ciasc<strong>un</strong>a <strong>un</strong> compito ben preciso. Sono sud<strong>di</strong>visibili in <strong>base</strong> alla clas-<br />

se <strong>di</strong> <strong>base</strong> della gerarchia <strong>di</strong> ere<strong>di</strong>tarietà: <strong>un</strong>a parte ha come origine l’interfaccia<br />

Com<strong>un</strong>icationServices, mentre l’altro gruppo deriva dalla classe astratta WsdlModel.<br />

Il blocco che implementa l’interfaccia Comm<strong>un</strong>icationServices, fornisce al siste-<br />

ma tutte le primitive <strong>di</strong> com<strong>un</strong>icazione e si interfaccia con il ServiceSpace. Le classi<br />

Com<strong>un</strong>ication e Com<strong>un</strong>icationSystem sono due implementazioni dell’interfaccia che<br />

si comportano in mainera <strong>di</strong>fferente rispetto all’invocazione dei <strong>servizi</strong> sulla rete, la<br />

classe Com<strong>un</strong>icationServiceFactory ha lo scopo <strong>di</strong> inizializzare <strong>un</strong>a delle due im-<br />

plementazioni a r<strong>un</strong>time. Nell’implementazione corrente l’engine sceglie sempre come<br />

istanza la classe Com<strong>un</strong>icationService, <strong>per</strong> cui l’altra può essere considerata soltan-<br />

to <strong>un</strong> puro esercizio stilistico dell’applicazione del pattern Factory [17] all’interno del<br />

lavoro.<br />

Il blocco che estende la classe astratta WsdlModel, come si può intuire dal nome,<br />

67


CAPITOLO 4 <strong>Implementazione</strong> <strong>di</strong> COWSlite<br />

Figura 4.4: Classi del sottosistema <strong>di</strong> com<strong>un</strong>icazione<br />

ha lo scopo <strong>di</strong> rappresentare internamente all’engine il modello WSDL <strong>di</strong> <strong>un</strong> <strong>servizi</strong>o.<br />

Anche se è stato ripetuto più volte che la generazione <strong>di</strong> tali WSDL non è neces-<br />

saria, <strong>per</strong>chè a carico del framework JAX-WS, <strong>per</strong> l’invocazione dei <strong>servizi</strong> richiesti<br />

a server esterni al motore è necessario recu<strong>per</strong>are e sfruttare la descrizione offerta<br />

dal WSDL <strong>per</strong> eseguire dei controlli semantici e <strong>di</strong> consistenza e <strong>per</strong> costruire cor-<br />

68


4.3 Il package cowslite.engine<br />

rettamente il blocco SOAP da innestare nel Payload della richiesta HTTP. La classe<br />

ServiceProxyFactory ha il compito <strong>di</strong> generare la rappresentazione dell’interfaccia<br />

descritta dal WSDL sufficiente ai fini del progetto. Gli approcci <strong>per</strong> la generazione<br />

<strong>di</strong> tale modello possono essere <strong>di</strong>versi; quelli com<strong>un</strong>emente usati con Java sono due e<br />

corrispondo a due modelli <strong>di</strong> parsing <strong>di</strong>fferente, <strong>un</strong>o sfrutta <strong>un</strong> parser SAX 1 mentre<br />

l’altro costruisce il DOM 2 a partire dall’XML. Entrambi i meto<strong>di</strong> hanno pro e con-<br />

tro. Dopo averne realizzata <strong>un</strong>a prima implementazione me<strong>di</strong>ante il modulo SAX, si<br />

è preferito sfruttare il DOM <strong>per</strong>ché, <strong>per</strong> via della <strong>per</strong>sistenza del modello in memoria,<br />

consente accessi multipli e successivi <strong>per</strong> la creazione della struttura <strong>di</strong> supporto a sca-<br />

pito della maggiore occupazione <strong>di</strong> memoria necessaria. Entrambe le implementazioni<br />

sono com<strong>un</strong>que presenti all’interno del Factory.<br />

La parte più delicata da trattare delle com<strong>un</strong>icazioni del <strong>servizi</strong>o COWSlite sono<br />

le invocazioni <strong>di</strong> <strong>servizi</strong> <strong>di</strong>versi da quello locale <strong>per</strong> cui è necessario interfacciarsi con il<br />

fornitore <strong>di</strong> <strong>servizi</strong> e recu<strong>per</strong>are le informazioni necessarie <strong>per</strong> realizzare la connessione<br />

e la com<strong>un</strong>icazione. Per questo tipo <strong>di</strong> com<strong>un</strong>icazioni ci si avvale dell’API JAX-WS<br />

ed in particolare della sezione de<strong>di</strong>cata ai <strong>servizi</strong> Client. Il package javax.xml.ws<br />

contiene le classi Service, Dispatch e l’interfaccia EndpointReference che <strong>per</strong>mettono<br />

<strong>di</strong> costruire <strong>di</strong>namicamente <strong>un</strong>a chiamata ad <strong>un</strong> <strong>servizi</strong>o <strong>web</strong> invocando <strong>un</strong>’o<strong>per</strong>azione<br />

esposta alla quale è possibile fornire i parametri necessari <strong>per</strong> mezzo <strong>di</strong> <strong>un</strong> messaggio<br />

in formato SOAP inserito all’interno della chiamata.<br />

La prima classe da utilizzare <strong>per</strong> invocare <strong>un</strong> <strong>servizi</strong>o esterno è la classe Service.<br />

Questa classe ha il compito <strong>di</strong> creare <strong>un</strong> proxy <strong>per</strong> interfacciarsi con il servizo <strong>web</strong><br />

e può essere usata in due mo<strong>di</strong>: statico o <strong>di</strong>manico. Con il metodo statico vengono<br />

generate, a partire dal WSDL, <strong>un</strong>a serie <strong>di</strong> classi che identificano il <strong>servizi</strong>o che deve<br />

essere invocato. Il metodo <strong>di</strong>namico viene utilizzato a tempo <strong>di</strong> esecuzione e con esso<br />

si ottiene <strong>un</strong> istanza dell’oggetto Service che agisce da proxy <strong>per</strong> le richieste.<br />

1<br />

SAX [1] (Simple API for XML) è <strong>un</strong>’API <strong>per</strong> accedere in maniera seriale ad <strong>un</strong> documento XML<br />

al fine <strong>di</strong> leggerne i dati contenuti.<br />

2<br />

Il Document Object Model [20] (DOM) è <strong>un</strong>a convenzione <strong>per</strong> rappresentare e interagire con<br />

documenti HTML, XHTML e XML <strong>per</strong> mezzo <strong>di</strong> <strong>un</strong> <strong>linguaggio</strong> in<strong>di</strong>pendente dal <strong>linguaggio</strong> e dalla<br />

piattaforma.<br />

69


CAPITOLO 4 <strong>Implementazione</strong> <strong>di</strong> COWSlite<br />

L’altra classe <strong>di</strong>rettamente utilizzata <strong>per</strong> invocare <strong>un</strong> <strong>servizi</strong>o è la classe Dispatch.<br />

Il suo scopo è quello <strong>di</strong> eseguire lo scambio <strong>di</strong> messaggi in formato XML fra il <strong>servizi</strong>o<br />

e il cliente. Ha due mo<strong>di</strong> <strong>di</strong> f<strong>un</strong>zionamento a seconda del controllo che si vuole avere<br />

sui messaggi scambiati: Message e Message Payload. Con il primo il client lavora<br />

<strong>di</strong>rettamente con l’intera struttura del messaggio nello specifico protocollo scelto; con<br />

il secondo tipo invece lavora solamente con la parte <strong>di</strong> messaggio relativa all’infor-<br />

mazione (Payload); ad esempio se i messaggi scambiati sono <strong>di</strong> tipo SOAP questo<br />

corrisponde al body del messaggio e non all’intero messaggio.<br />

Come si vede dal co<strong>di</strong>ce <strong>di</strong> Tabella 4.2, <strong>per</strong> invocare <strong>di</strong>namicamente <strong>un</strong> <strong>servizi</strong>o è<br />

sufficiente istanziare <strong>un</strong> proxy <strong>per</strong> mezzo del metodo statico create() fornendo come<br />

parametri l’URL che contiene il file WSDL e <strong>un</strong> oggetto <strong>di</strong> tipo QName (Qualified<br />

Name) composto dal nome del <strong>servizi</strong>o e dal namespace nel quale collocare la classe<br />

proxy. Infine tramite l’oggetto Dispatch, creato partendo dal <strong>servizi</strong>o ottenuto, si<br />

invierà la richiesta SOAP utilizzando il metodo invokeOneWay().<br />

URL wsdlLocation = " http : / / . . . . " ;<br />

QName serviceName = new QName( namespace , nomeServizio ) ;<br />

S e r v i c e s = S e r v i c e . c r e a t e ( wsdlLocation , serviceName ) ;<br />

QName p o r t S e r v i c e ;<br />

Dispatch d i s p a t c h =<br />

s . c r e a t e D i s p a t c h ( p o r t S e r v i c e , Source . class ,<br />

S e r v i c e . Mode .PAYLOAD) ;<br />

S t r i n g B u i l d e r contenuto =<br />

. . . D e f i n i z i o n e d e l Payload usando SOAP . . . ;<br />

ByteArrayInputStream b a i s =<br />

new ByteArrayInputStream ( contenuto . t o S t r i n g ( ) . getBytes ( ) ) ;<br />

Source input = new StreamSource ( b a i s ) ;<br />

<strong>di</strong>spatch . invokeOneWay ( input ) ;<br />

Tabella 4.2: Web Service Proxy con JAX-WS<br />

La struttura del messaggio SOAP da inviare è del tipo riportato in Tabella 4.3.<br />

La parte da inserire nel PAYLOAD del messaggio è quella contenuta all’interno<br />

del tag , nella quale viene specificato il nome dell’o<strong>per</strong>azione e poi,<br />

delimitati da tag appositi, i valori dei parametri.<br />

70


4.3 Il package cowslite.engine<br />

<br />

<br />

<br />

<br />

ok<br />

<br />

<br />

<br />

Tabella 4.3: Web Service - Messaggio SOAP<br />

4.3.2 Descrittori <strong>di</strong> <strong>servizi</strong>o <strong>web</strong> e variabili<br />

(WsDescriptor e PartnerLink)<br />

An<strong>di</strong>amo a guardare più in profon<strong>di</strong>tà il blocco relativo al DataSpace.<br />

Un’aspetto molto importante <strong>per</strong> tutto il package e <strong>per</strong> l’implementazione del<br />

<strong>linguaggio</strong> è la memorizzazione e la gestione dei dati. È importante definire i tipi<br />

<strong>di</strong> dato necessari <strong>per</strong> descrivere gli oggetti COWSlite e contemporaneamente <strong>per</strong><br />

gestire le entità logiche necessarie <strong>per</strong> l’esecuzione del <strong>servizi</strong>o.<br />

Si presenta quin<strong>di</strong> la necessità <strong>di</strong> trovare <strong>un</strong> modo <strong>per</strong> descrivere agevolmente e<br />

in maniera omogenea tutti gli elementi del <strong>linguaggio</strong> a partire dagli elementi più<br />

semplici come etichette, variabili write-once, <strong>per</strong> arrivare ai partner e ai <strong>servizi</strong>. Il<br />

requisito importante da seguire nella progettazione è quello <strong>di</strong> <strong>di</strong>segnare la struttura<br />

in modo omogeneo <strong>per</strong>ché ciò <strong>per</strong>mette <strong>di</strong> sfruttare le caratteristiche <strong>di</strong> ere<strong>di</strong>tarietà<br />

e polimorfismo tipiche del para<strong>di</strong>gma orientato agli oggetti (Object Oriented), sem-<br />

plificando la realizzazione delle classi <strong>per</strong> il trattamento dei dati in modo che siano<br />

‘intercambiabili’.<br />

Tra i tipi <strong>di</strong> dato trattati è stato menzionato anche il <strong>servizi</strong>o che, seppur non<br />

facendo parte dei tipi definiti dal <strong>linguaggio</strong>, ricopre <strong>un</strong>o dei ruoli principali all’interno<br />

del <strong>linguaggio</strong>. Basti pensare che ogni interazione svolta fra le istanze dei <strong>servizi</strong> o con<br />

i <strong>servizi</strong> esterni è basata sulla com<strong>un</strong>icazione <strong>di</strong> dati attraverso <strong>un</strong>’o<strong>per</strong>azione esposta<br />

da <strong>un</strong> <strong>servizi</strong>o.<br />

71


CAPITOLO 4 <strong>Implementazione</strong> <strong>di</strong> COWSlite<br />

La Figura 4.5 mostra il <strong>di</strong>agramma delle classi presenti nel package <strong>per</strong> trattare i<br />

dati usati in COWSlite. In essa spiccano <strong>un</strong>’interfaccia e due classi astratte: l’in-<br />

terfaccia DataModel ha lo scopo <strong>di</strong> definire i meto<strong>di</strong> <strong>per</strong> il confronto ed il matching <strong>di</strong><br />

tutte le classi che descrivono tipi <strong>di</strong> dati del <strong>linguaggio</strong>; la classe astratta LabelModel<br />

è la classe ra<strong>di</strong>ce <strong>di</strong> tutta la gerarchia e definisce le caratteristiche com<strong>un</strong>i a tutti gli<br />

elementi, come ad esempio la possibilità <strong>di</strong> assegnare <strong>un</strong> nome ad ogni elemento. Il<br />

nome impostato, tramite le proprietà esposte dalla classe, corrisponde alla stringa<br />

identificativa <strong>di</strong> <strong>un</strong> etichetta oppure al nome nel caso <strong>di</strong> <strong>un</strong>a variabile, <strong>di</strong> <strong>un</strong> vettore o<br />

<strong>di</strong> <strong>un</strong> partner. I dati veri è propri trattati dal <strong>linguaggio</strong> sono quelli contenuti nelle va-<br />

riabili write-once, il cui comportamento è espresso dalla classe astratta WOItem, da cui<br />

derivano tutte le classi reali che conterranno le entità memorizzabili con COWSlite<br />

(variabili, vettori e partner).<br />

72<br />

Figura 4.5: Diagramma delle classi delle variabili WO<br />

Label e LabelKiller sono state definite solo in previsione <strong>di</strong> <strong>un</strong>a estensione


4.3 Il package cowslite.engine<br />

del package che implementi il costrutto <strong>di</strong> kill e quello <strong>di</strong> protezione non presenti<br />

nell’attuale versione.<br />

La classe WOVar è la classe che implementa le variabili semplici <strong>di</strong> tipo write-<br />

once. È <strong>un</strong>a classe parametrica (Generics come viene chiamata in Java) in modo da<br />

poter coprire qual<strong>un</strong>que tipo <strong>di</strong> dato, anche se, al momento l’engine supporta solo<br />

due possibilità WOVar(Integer) e WOVar(String). L’uso della classe parametrica<br />

<strong>per</strong>metterà tuttavia <strong>di</strong> trattare anche gli altri tipi <strong>di</strong> dati con <strong>un</strong>o sforzo minimo. In<br />

Tabella 4.4 è riportata <strong>un</strong>a porzione della classe dove sono evidenziati i due costruttori<br />

principali. L’attributo value è parametrico e contiene la variabile vera e propria. Il<br />

costruttore che o<strong>per</strong>a su questa variabile è quello con due parametri, in cui il primo<br />

è il nome della variabile e il secondo è l’oggetto che rappresenta la variabile. Il<br />

costruttore con <strong>un</strong> <strong>un</strong>ico parametro ha il compito <strong>di</strong> inizializzare la classe assegnandole<br />

solamente il nome. Quin<strong>di</strong> se, ad esempio, vogliamo creare la varibile pippo come<br />

intero contenente il valore 3 utilizzeremo il seguente metodo:<br />

new WOVar("pippo", new Integer(3))<br />

Un altro aspetto in cui si rivela utile questa scelta è nel trattamento delle varia-<br />

bili non valorizzate o, come si <strong>di</strong>rebbe in ambito programmativo, nulle: sono quelle<br />

variabili delle quali è stato definito il nome, il tipo e a cui non è stato ancora as-<br />

segnato <strong>un</strong> valore. Per trattare questi casi occorrerebbe <strong>un</strong> elemento che faccia da<br />

segnaposto, in modo da <strong>per</strong>mettere la descrizione del <strong>servizi</strong>o e l’interazione <strong>di</strong> questi<br />

con il resto delle istruzioni. Altrimenti potrebbe essere più pratico utilizzare gli stessi<br />

oggetti sfruttando la loro definizione tramite generics invece <strong>di</strong> sostituire a r<strong>un</strong>time al<br />

momento dell’assegnazione i segnaposti definiti con le variabili istanziate.<br />

Per istanziare questa classe con <strong>un</strong> tipo <strong>di</strong> dato preciso occorrerebbe inserirvi<br />

all’interno <strong>un</strong> oggetto del tipo esatto che la variabile dovrebbe rappresentare, questo<br />

<strong>per</strong>ò impe<strong>di</strong>rebbe <strong>di</strong> poter istanziare variabili <strong>di</strong> <strong>un</strong> tipo predefinito senza valore,<br />

dal momento che inizializzare <strong>un</strong>a variabile write-once con <strong>un</strong> valore ne blocca il<br />

contenuto. Per <strong>per</strong>mettere ciò si ricorre al seguente espe<strong>di</strong>ente: si istanzia la variabile<br />

con <strong>un</strong> oggetto Class del tipo voluto. Così facendo la variabile è istanziata, ha il suo<br />

73


CAPITOLO 4 <strong>Implementazione</strong> <strong>di</strong> COWSlite<br />

public class WOVar extends WOItem {<br />

private T value ;<br />

. . .<br />

public WOVar( S t r i n g id ) {<br />

su<strong>per</strong> ( id ) ;<br />

this . setType ( this . g e t C l a s s ( ) . getName ( ) ) ;<br />

s e t = f a l s e ;<br />

this . value = null ;<br />

}<br />

public WOVar( S t r i n g id , T value ) {<br />

su<strong>per</strong> ( id ) ;<br />

i f ( value instanceof Class ) {<br />

s e t = f a l s e ;<br />

this . value = (T) value ;<br />

} else {<br />

s e t = true ;<br />

this . value = value ;<br />

}<br />

}<br />

. . .<br />

}<br />

Tabella 4.4: Costruttori della classe WOVar<br />

nome e il tipo che dovrà contenere rigidamente fissato, ma non esiste <strong>un</strong> valore ad<br />

essa assegnato.<br />

Ad esempio <strong>per</strong> <strong>un</strong> intero si utilizzerà <strong>un</strong>a <strong>di</strong>chiarazione del tipo<br />

new WOVar("nomevar", new Integer(0).getClass())<br />

mentre <strong>per</strong> <strong>un</strong>a stringa<br />

new WOVar("nomevar", new String().getClass())<br />

In questo modo l’attributo value della classe WOVar appena creata contiene <strong>un</strong><br />

oggetto che non ha valore, ma rappresenta il tipo che gli vogliamo assegnare, non sarà<br />

quin<strong>di</strong> possibile assegnare <strong>un</strong> intero ad <strong>un</strong>a stringa e viceversa.<br />

La classe WOVect <strong>per</strong>mette <strong>di</strong> definire vettori <strong>un</strong>i<strong>di</strong>mensionali <strong>di</strong> elementi write-<br />

once, ha <strong>un</strong> duplice ruolo quello <strong>di</strong> tipo <strong>di</strong> dato e quello <strong>di</strong> contenitore dei parametri<br />

scambiati fra i <strong>servizi</strong> come vedremo fra poco.<br />

74


4.3 Il package cowslite.engine<br />

La classe Partner è <strong>un</strong> tipo <strong>di</strong> variabile COWSlite complesso che serve <strong>per</strong><br />

rappresentare la locazione <strong>di</strong> <strong>un</strong> <strong>servizi</strong>o inglobando anche i dati necessari <strong>per</strong> po-<br />

ter contattare il fornitore dei <strong>servizi</strong>. Quin<strong>di</strong> oltre alle informazioni necessarie <strong>per</strong><br />

in<strong>di</strong>viduare l’endpoint <strong>di</strong> <strong>un</strong> <strong>servizi</strong>o deve contenere anche quelle <strong>per</strong> recu<strong>per</strong>are la<br />

descrizione del <strong>servizi</strong>o (in<strong>di</strong>rizzo del file WSDL) e altre informazioni necessarie <strong>per</strong><br />

il collegamento.<br />

Descrittore <strong>di</strong> <strong>servizi</strong>o (WsDescriptor)<br />

La classe WSDescriptor <strong>di</strong>scende dalla classe WOItem, ma non è <strong>un</strong> tipo <strong>di</strong> dato del<br />

<strong>linguaggio</strong>. Questa classe, che in<strong>di</strong>cheremo col nome <strong>di</strong> descrittore del <strong>servizi</strong>o è<br />

<strong>un</strong>a delle più importanti <strong>di</strong> tutto il motore. Il suo compito è quello <strong>di</strong> presentare e<br />

mantenere tutte le informazioni utili a descrivere ed utilizzare <strong>un</strong>’o<strong>per</strong>azione esposta<br />

da <strong>un</strong> <strong>servizi</strong>o. Il suo ruolo è quin<strong>di</strong> quello <strong>di</strong> rappresentare le o<strong>per</strong>azioni <strong>di</strong> invocazione<br />

e ricezione all’interno dello spazio dei <strong>servizi</strong>, <strong>di</strong> descrivere le o<strong>per</strong>azioni esposte dal<br />

<strong>servizi</strong>o locale e raccogliere le informazioni necessarie <strong>per</strong> invocare o<strong>per</strong>azioni fornite<br />

da <strong>servizi</strong> esterni.<br />

I suoi componenti principali sono il partner, l’o<strong>per</strong>azione e il vettore <strong>di</strong> dati da<br />

gestire, in quanto elementi che contrad<strong>di</strong>stinguono le o<strong>per</strong>azioni <strong>di</strong> receive e invoke.<br />

Di questi l’o<strong>per</strong>azione è <strong>un</strong>a stringa contenente il nome, il partner è l’omonimo oggetto<br />

definito nel package e <strong>per</strong> semplificare le o<strong>per</strong>azioni <strong>di</strong> matching i parametri sono<br />

contenuti in <strong>un</strong> vettore write-once (WOVect). Questo <strong>per</strong>mette <strong>di</strong> confrontare due<br />

WsDescriptor con i meto<strong>di</strong> definiti nell’interfaccia senza dover implementare ness<strong>un</strong>a<br />

classe apposita.<br />

All’interno <strong>di</strong> questa classe sono mantenute anche altre informazioni necessarie<br />

<strong>per</strong> l’esecuzione dell’intero <strong>servizi</strong>o, come il riferimento ad altri descrittori <strong>di</strong> <strong>servizi</strong>o<br />

rappresentanti <strong>un</strong>’o<strong>per</strong>azione <strong>di</strong> receive che hanno in com<strong>un</strong>e <strong>un</strong>a o<strong>per</strong>azione <strong>di</strong> scelta<br />

guardata e il riferimento al processo successivo dell’o<strong>per</strong>azione <strong>di</strong> receive.<br />

75


DataSpace e ambienti annidati<br />

CAPITOLO 4 <strong>Implementazione</strong> <strong>di</strong> COWSlite<br />

Il DataSpace non è soltanto <strong>un</strong>’<strong>un</strong>ità concettuale all’interno dell’engine, ma è anche<br />

<strong>un</strong> oggetto fisico che riveste <strong>un</strong> ruolo molto importante nella definizione e nell’esecu-<br />

zione dei processi. Questo oggetto rappresenta <strong>un</strong> ambiente <strong>di</strong> esecuzione del <strong>servizi</strong>o<br />

e contiene tutte le variabili alle quali fa riferimento l’istanza in esecuzione. Poiché<br />

l’oggetto implementa il concetto <strong>di</strong> ambiente ogni istanza del <strong>servizi</strong>o può fare uso <strong>di</strong><br />

più istanze <strong>di</strong> <strong>un</strong> DataSpace contemporaneamente. Infatti <strong>un</strong>’altra delle peculiarità<br />

del DataSpace è quella <strong>di</strong> poter essere annidati. Ogni DataSpace può avere <strong>un</strong> Data-<br />

Space padre e possedere dei DataSpace figli; l’<strong>un</strong>ico DataSpace senza padre è quello<br />

globale, com<strong>un</strong>e a tutti i <strong>servizi</strong>. In questo modo è possibile definire la stessa variabile<br />

all’interno <strong>di</strong> più ambienti e se questi sono fra loro annidati l’<strong>un</strong>ica visibile dal pro-<br />

cesso è quella dell’ambiente più interno. Questo <strong>per</strong>mette <strong>di</strong> gestire opport<strong>un</strong>amente<br />

lo scope dei nomi da parte dell’o<strong>per</strong>atore <strong>di</strong> delimitazione.<br />

Il DataSpace, oltre a contenere e fornire le f<strong>un</strong>zioni <strong>per</strong> la ricerca e l’accesso alle<br />

variabili, fornisce accesso agli altri elementi dell’engine COWSlite in quanto man-<br />

tiene <strong>un</strong> riferimento al ServiceSpace <strong>di</strong> lavoro e al Com<strong>un</strong>icationSystem. Questa scelta<br />

è stata fatta al fine <strong>di</strong> ridurre il numero <strong>di</strong> parametri che dovrebbero essere scambiati<br />

fra i processi <strong>per</strong> la loro esecuzione. Ogni DataSpace deve com<strong>un</strong>que conoscere a quale<br />

ServiceSpace è associato il dato <strong>per</strong> via delle variabili in gioco; resta <strong>per</strong>tanto facile<br />

sfruttare questo <strong>per</strong> semplificare le chiamate ai meto<strong>di</strong> e ai costruttori.<br />

4.3.3 Descrizione del <strong>servizi</strong>o COWSlite<br />

Uno dei problemi affrontati nella realizzazione dell’engine <strong>di</strong> COWSlite è stato quel-<br />

lo <strong>di</strong> definire delle modalità <strong>per</strong> descrivere ed eseguire i <strong>servizi</strong>. C’era la necessità <strong>di</strong><br />

trovare il modo <strong>per</strong> tradurre il co<strong>di</strong>ce scritto in azioni eseguibili e componibili in modo<br />

tale che potessero descrivere la logica del <strong>servizi</strong>o e ad essere contemporaneamente<br />

delle <strong>un</strong>ità eseguibili all’interno dell’engine. Se da <strong>un</strong>a parte le richieste <strong>di</strong> o<strong>per</strong>azioni<br />

del <strong>servizi</strong>o possono scatenare l’esecuzione dell’interazione, dall’altra è necessario de-<br />

76


4.3 Il package cowslite.engine<br />

scrivere quando e come queste richieste possono essere trattate e in che modo devono<br />

essere eseguite.<br />

L’idea <strong>di</strong> <strong>base</strong> è che dal momento in cui i linguaggi (quello che stiamo cercando <strong>di</strong><br />

descrivere e quello <strong>di</strong> programmazione scelto <strong>per</strong> l’implementazione) sono concorren-<br />

ti, risulta naturale affidarsi al modello multithrea<strong>di</strong>ng <strong>di</strong> Java in modo da sfruttare<br />

tutte le caratteristiche e le f<strong>un</strong>zionalità <strong>di</strong> esecuzione e gestione dei processi messe a<br />

<strong>di</strong>sposizione da quest’ultimo. Partendo da questi propositi il problema <strong>di</strong>venta come<br />

sud<strong>di</strong>videre le <strong>un</strong>ità <strong>di</strong> calcolo in modo da <strong>per</strong>metterne <strong>un</strong>a semplice descrizione in<br />

Java.<br />

Il costrutto <strong>di</strong> composizione parallela già ci obbliga a pensare che ogn<strong>un</strong>o dei<br />

blocchi concorrenti definiti dovrà essere delegato a <strong>un</strong> thread <strong>di</strong>verso. Ciò non è<br />

sufficiente <strong>per</strong> descrivere all’interno dei thread tutto il resto della logica del <strong>servizi</strong>o in<br />

modo da renderla modulare, componibile e anche <strong>di</strong> facile traduzione, <strong>per</strong>ché sarebbe<br />

com<strong>un</strong>que complessa e faticosa la traduzione del co<strong>di</strong>ce.<br />

La soluzione adottata è quin<strong>di</strong> quella <strong>di</strong> pensare ad ogni singola azione come ad<br />

<strong>un</strong> thread. Alc<strong>un</strong>e azioni terminano, altre invece hanno come conseguenza <strong>un</strong>a’altra<br />

azione gestita da <strong>un</strong> thread avviato dall’azione stessa.<br />

Ogni azione verrà chiamata d’ora in poi CowsProcess o processo <strong>per</strong>ché descritta<br />

<strong>per</strong> merito <strong>di</strong> <strong>un</strong>a classe derivata dalla classe padre CowsProcess che definisce l’azione<br />

generica.<br />

I processi<br />

Come si vede dal <strong>di</strong>agramma UML [35] che rappresenta l’insieme dei processi (Fi-<br />

gura 4.6) ogni azione è definita come <strong>un</strong>a classe ed ogn<strong>un</strong>a <strong>di</strong> queste classi ha come<br />

padre com<strong>un</strong>e la classe astratta CowsProcess. Ogni classe ere<strong>di</strong>ta dalla classe padre<br />

la caratteristica <strong>di</strong> essere <strong>un</strong>a classe <strong>di</strong> tipo Thread e tutte le o<strong>per</strong>azioni necessarie<br />

<strong>per</strong> eseguire lo start-up del thread all’interno dell’engine, insieme alla definizione <strong>di</strong><br />

altre o<strong>per</strong>azioni <strong>di</strong> contorno.<br />

77


CAPITOLO 4 <strong>Implementazione</strong> <strong>di</strong> COWSlite<br />

Figura 4.6: Diagramma delle classi dei processi COWSlite<br />

Il fatto <strong>di</strong> avere <strong>un</strong>a classe padre <strong>per</strong>mette <strong>di</strong> sfruttare il polimorfismo degli oggetti<br />

ottenendo così che tutte le classi derivate hanno <strong>un</strong> tipo com<strong>un</strong>e. Ciò consente <strong>di</strong> poter<br />

comporre fra loro le azioni, <strong>per</strong>ché <strong>per</strong>mette <strong>di</strong> scrivere cose del tipo<br />

|(CowsP rocess, CowsP rocess) oppure<br />

?(p, o, < data >).CowsP rocess<br />

dove CowsP rocess è <strong>un</strong>o qual<strong>un</strong>que dei possibili processi.<br />

Un altro scopo della classe CowsProcess è quello <strong>di</strong> definire <strong>un</strong>’interfaccia co-<br />

m<strong>un</strong>e <strong>per</strong> tutte le o<strong>per</strong>azioni definendo <strong>un</strong>’insieme <strong>di</strong> meto<strong>di</strong> che tutte le classi de-<br />

rivate (in questo caso ogni singola azione) devono ridefinire <strong>per</strong> fornire il corretto<br />

comportamento all’interno dell’engine.<br />

Osservando il co<strong>di</strong>ce della classe CowsProces (Tabella 4.5) si può notare che<br />

ogni sottoclasse dovrà obbligatoriamente implementare quattro meto<strong>di</strong>: execute(),<br />

changeDS(...), isDestroing() e clone(). Di questi il principale è execute() che<br />

78


4.3 Il package cowslite.engine<br />

package cows . engine ;<br />

public abstract class CowsProcess<br />

extends Thread implements Cloneable {<br />

boolean d e s t r o i n g , e x e c u t i n g ;<br />

private DataSpace wds ;<br />

public CowsProcess ( ) {<br />

su<strong>per</strong> ( ) ;<br />

e x e c u t i n g = f a l s e ;<br />

d e s t r o i n g = f a l s e ;<br />

}<br />

public CowsProcess ( DataSpace ds ){<br />

this ( ) ;<br />

setWds ( ds ) ;<br />

}<br />

f i n a l public void r<strong>un</strong> ( ) {<br />

// R e g i s t r a i l processo n e l ServiceSpace<br />

wds . g e t S e r v i z i ( ) . addProcess ( this ) ;<br />

e x e c u t i n g = true ;<br />

try{<br />

execute ( ) ;<br />

} catch ( CowsException ce ){<br />

ce . printStackTrace ( ) ;<br />

} f i n a l l y {<br />

e x e c u t i n g = f a l s e ;<br />

//Rimuove i l processo n e l ServiceSpace<br />

wds . g e t S e r v i z i ( ) . removeProcess ( this )<br />

d e s t r o i n g = true ;<br />

}<br />

}<br />

public DataSpace getWds ( ) {return wds ; }<br />

public void setWds ( DataSpace l d s ) { this . wds = l d s ; }<br />

// da d e f i n i r e n e l l e c l a s s i d e r i v a t e .<br />

public abstract void execute ( ) throws CowsException ;<br />

public abstract void changeDS ( DataSpace nds ) ;<br />

public abstract boolean i s D e s t r o i n g ( ) ;<br />

public abstract Object c l o n e ( ) ;<br />

}<br />

Tabella 4.5: Classe CowsProcess<br />

viene eseguito al momento dell’esecuzione del thread (viene infatti richiamato nel me-<br />

todo r<strong>un</strong>()) e contiene le istruzioni che realizzano il comportamento dell’o<strong>per</strong>azione<br />

determinata. Gli altri meto<strong>di</strong> devono essere definiti <strong>per</strong> eseguire <strong>un</strong>a corretta clona-<br />

zione dell’oggetto, <strong>per</strong> definire il comportamento del processo quando viene eseguito<br />

all’interno <strong>di</strong> <strong>un</strong> altro DataSpace e <strong>per</strong> eseguire la corretta terminazione del processo.<br />

79


CAPITOLO 4 <strong>Implementazione</strong> <strong>di</strong> COWSlite<br />

Oltre ai meto<strong>di</strong> da definire, la classe CowsProcess ha <strong>un</strong> costruttore con parametro<br />

DataSpace; questo serve <strong>per</strong> inizializzare la porzione <strong>di</strong> dati com<strong>un</strong>e a tutti i processi<br />

con il riferimento al DataSpace a cui deve riferirsi il processo. Come si vedrà in se-<br />

guito ogni sottoclasse insieme ai parametri del costruttore richiederà il DataSpace <strong>di</strong><br />

lavoro. Unica eccezione è la classe che identifica il processo nil; dal momento che nil<br />

è <strong>un</strong> processo vuoto che serve ad in<strong>di</strong>care la terminazione <strong>di</strong> <strong>un</strong> ramo non è necessario<br />

fornire ness<strong>un</strong> riferimento.<br />

Per poter scrivere la logica del <strong>servizi</strong>o COWSlite me<strong>di</strong>ante <strong>un</strong> blocco <strong>di</strong> co<strong>di</strong>ce<br />

Java che sfrutta le classi che descrivono i processi, sono necessarie altre entità ed altre<br />

informazioni. WsDescriptor e WOVect sono utilizzate <strong>per</strong> gestire le com<strong>un</strong>icazioni ed<br />

i dati scambiati, le azioni sono concatenate utilizzando la classe <strong>base</strong> CowsProcess,<br />

oppure nel caso <strong>di</strong> più azioni delle semplici liste <strong>di</strong> CowsProcess. Per realizzare il com-<br />

portamento desiderato le classi dell’<strong>un</strong>ità ProcessSpace si interfacciano soltanto con<br />

il DataSpace e in<strong>di</strong>rettamente con l’<strong>un</strong>ità <strong>di</strong> com<strong>un</strong>icazione e il ServiceSpace oppure<br />

con altre classi <strong>di</strong> tipo CowsProcess.<br />

Ogni classe che estende CowsProcess deve implementare la propria azione<br />

ridefinendo il metodo execute() nel seguente modo:<br />

ReceiveProcess Inserisce il descrittore del <strong>servizi</strong>o e la sua continuazione<br />

nel ServiceSpace, attraverso <strong>un</strong> metodo apposito fornito dall’<strong>un</strong>ità <strong>di</strong><br />

com<strong>un</strong>icazione.<br />

InvokeProcess Esegue il descrittore del <strong>servizi</strong>o se esterno, altrimenti lo inse-<br />

risce nel ServiceSpace, attraverso <strong>un</strong> metodo apposito fornito dall’<strong>un</strong>ità <strong>di</strong><br />

com<strong>un</strong>icazione.<br />

NilProcess Non fa niente.<br />

DelimitationProcess Crea <strong>un</strong> DataSpace annidato a quello corrente contenente le<br />

80<br />

variabili definite nel corpo della definizione e mo<strong>di</strong>fica il DataSpace <strong>di</strong> lavoro dei<br />

processi successivi con quello creato.


4.3 Il package cowslite.engine<br />

ReplicationProcess Esegue <strong>un</strong> numero <strong>di</strong> copie specificato del processo in thread<br />

separati, avviando nuove copie appena terminano le altre in modo che siano<br />

sempre attive <strong>un</strong> numero <strong>di</strong> copie. È stata imposta questa limitazione <strong>per</strong> non<br />

avviare <strong>un</strong> numero infinito <strong>di</strong> thread.<br />

ParallelProcess Esegue i thread <strong>di</strong> tutti i processi che devono essere eseguiti in<br />

parallelo.<br />

ChoiceProcess Inserisce nel ServiceSpace tutti i descrittori dei <strong>servizi</strong> che fanno<br />

parte della scelta guardata collegandoli fra loro. E’ <strong>un</strong>a specie <strong>di</strong> receive iterata<br />

che collega fra loro i descrittori.<br />

La classe AssignProcess è <strong>di</strong>fferente dalle altre appena elencate. Il suo compito<br />

è quello <strong>di</strong> <strong>per</strong>mettere l’assegnazione <strong>di</strong> valori alle variabili e l’esecuzione della valu-<br />

tazione delle espressioni. Dal momento in cui le espressioni sono definite all’interno<br />

del co<strong>di</strong>ce non è possibile sa<strong>per</strong>e a priori quale sarà la forma <strong>di</strong> tale processo, quin<strong>di</strong><br />

AssignProcess è <strong>un</strong>a classe astratta che implementa i meto<strong>di</strong> <strong>di</strong> <strong>base</strong> necessari all’e-<br />

secuzione del costrutto senza specificare <strong>per</strong>ò qual’è l’espressione in esso contenuta.<br />

Sarà quin<strong>di</strong> necessario costruire <strong>un</strong>a classe apposita che estende AssignProcess <strong>per</strong><br />

ogni assegnazione presente nel co<strong>di</strong>ce in modo che ogn<strong>un</strong>a implementi l’assegnazione<br />

dell’espressione descritta dal costrutto.<br />

Per costruire la logica del <strong>servizi</strong>o <strong>per</strong> ogn<strong>un</strong>a delle azioni sopra descritte dovrà<br />

essere inserito <strong>un</strong> blocco <strong>di</strong> co<strong>di</strong>ce all’interno del metodo ServiceCreator(), partendo<br />

dall’ultima azione definita fino ad arrivare alla prima, <strong>per</strong>correndo l’albero che descrive<br />

il processo in senso inverso dalle foglie alla ra<strong>di</strong>ce.<br />

I co<strong>di</strong>ci presenti nelle Tabelle dal 4.6 a 4.12 rappresentano i modelli <strong>di</strong> co<strong>di</strong>ce che<br />

deve essere scritto all’interno del metodo ServiceCreator() al fine <strong>di</strong> implementare<br />

la logica definita.<br />

Nei co<strong>di</strong>ci presentati nelle tabelle sono usati dei segnaposti che stanno ad in<strong>di</strong>care<br />

particolari porzioni <strong>di</strong> co<strong>di</strong>ce <strong>di</strong> cui descriviamo adesso il significato.<br />

81


CowsProcess cpxxx = null ;<br />

WOVect vxxx = new WOVect( data . l enght ) ;<br />

CAPITOLO 4 <strong>Implementazione</strong> <strong>di</strong> COWSlite<br />

vxxx . insVar ( (WOVar) x−x ) ; // data . l e n g h t v o l t e<br />

WsDescrioptor wdxxx = new WsDescriptor (xVx , "x" , vxxx ) ;<br />

wdxxx . setContinuazione ( cpyyy ) ;<br />

cpxxx = new ReceiveProcess ( wdxxx , ds ) ;<br />

Tabella 4.6: Receive - ?(partner,o<strong>per</strong>ation,).continuazione<br />

CowsProcess cpxxx = null ;<br />

WOVect vxxx = new WOVect( data . l enght ) ;<br />

WsDescriptor wdxxx = ( WsDescriptor ) ddd . c l o n e ( ) ;<br />

cpxxx = new InvokeProcess ( wdxxx , vxxx , ds ) ;<br />

Tabella 4.7: Invoke - !(partner,o<strong>per</strong>ation,)<br />

cpxxx definisce il nome della variabile associata al processo come concatenazione<br />

del prefisso cp e <strong>di</strong> <strong>un</strong> numero rappresentante <strong>un</strong> progressivo che in<strong>di</strong>vidua l’azione.<br />

vxxx definisce il nome <strong>di</strong> <strong>un</strong>a variabile, anche <strong>per</strong> questa il suffisso xxx è <strong>un</strong><br />

contatore in modo che tutte le variabili siano definite <strong>un</strong>ivocamente. Lo stesso vale<br />

anche <strong>per</strong> wdxxx relativa ai WSDescriptor, mentre ds è riferita ai DataSpace, ddd al<br />

descrittore <strong>di</strong> <strong>servizi</strong>o e xVx in<strong>di</strong>vidua <strong>un</strong> Partner.<br />

cpyyy in<strong>di</strong>vidua il processo cows che deve essere inteso come successore <strong>di</strong> quello<br />

<strong>di</strong> cui viene prodotto il co<strong>di</strong>ce dove yyy rappresenta <strong>un</strong>a altro valore numerico iden-<br />

tificativo. x-x in<strong>di</strong>ca <strong>un</strong>a variabile recu<strong>per</strong>ata dal DataSpace o <strong>un</strong> valore costante<br />

generato.<br />

DataSpace dsx = new DataSpace ( ds ) ;<br />

dsx . addVariable (new WOVar( " x i " ,new I n t e g e r ( 0 ) . g e t C l a s s ( ) ) ) ; //OR<br />

dsx . addVariable (new WOVar( " x i " ,new S t r i n g ( ) . g e t C l a s s ( ) ) ) ; //<br />

CowsProcess cpxxx = null ;<br />

cpxxx = new D e l i m i t a t i o n P r o c e s s ( cpyyy , dsx ) ;<br />

82<br />

Tabella 4.8: Delimitation - [x1,...,xn]p


4.3 Il package cowslite.engine<br />

CowsProcess cpxxx = null ;<br />

cpxxx = new R e p l i c a t i o n P r o c e s s ( nproc , ds , n ) ;<br />

Tabella 4.9: Replication - *[n](p)<br />

CowsProcess cpxxx = null ;<br />

List cplxxx = new ArrayList();<br />

cplxxx . add ( nproc ) ; //2 v o l t e<br />

cpxxx = new P a r a l l e l P r o c e s s ( cplxxx , ds ) ;<br />

Tabella 4.10: Parallel - |(p1,p2)<br />

Per quanto riguarda il processo <strong>di</strong> tipo receive (4.6) la riga commentata deve<br />

essere ripetuta <strong>per</strong> ogni variabile definita come parametro della receive cioè esat-<br />

tamente data.length volte. Allo stesso modo <strong>per</strong> i processi tipo parallel (4.10) e<br />

choiche (4.11) il co<strong>di</strong>ce relativo alla riga commentata con 2 volte sta a significare che<br />

deve essere ripetuta <strong>per</strong> ogn<strong>un</strong>o dei due processi coinvolti nell’o<strong>per</strong>azione. Invece <strong>per</strong><br />

il processo <strong>di</strong> tipo delimitation (4.8) le righe commentate con OR stanno ad in<strong>di</strong>care<br />

che deve essere usato <strong>un</strong>o dei costrutti <strong>per</strong> ogni variabile in<strong>di</strong>cata nella delimitazione<br />

tenendo conto del tipo della variabile (se intero o stringa).<br />

Utilizzare i thread in Java è com<strong>un</strong>que <strong>un</strong>a scelta che porta a fare <strong>di</strong>verse conside-<br />

razioni. Tanto <strong>per</strong> cominciare i thread vengono allocati all’interno della Java Virtual<br />

Machine al momento della creazione e la abbandonano solo dopo la loro terminazione;<br />

in più con le ultime versioni della Virtual Machine sono stati deprecati i meto<strong>di</strong> rela-<br />

tivi alla <strong>di</strong>struzione e alla terminazione forzata <strong>di</strong> <strong>un</strong> thread <strong>per</strong> motivi <strong>di</strong> sicurezza<br />

e <strong>di</strong> stabilità. Questo implica che <strong>un</strong> elevato numero <strong>di</strong> thread, <strong>di</strong> cui molti bloccati<br />

in attesa <strong>di</strong> essere eseguiti o <strong>di</strong> essere terminati, potrà provocare rallentamenti nell’e-<br />

secuzione a causa dell’elevata occupazione <strong>di</strong> risorse. Questo è <strong>un</strong> prezzo da pagare<br />

che può essere ridotto da <strong>un</strong>a gestione oculata del numero <strong>di</strong> thread, facendo sì che<br />

i thread che rappresentano processi non eseguiti (tipo le continuazioni delle scelte<br />

guardate non selezionate) vengano terminati facendoli eseguire come processi vuoti.<br />

Il <strong>di</strong>segno della architettura con <strong>un</strong>a classe <strong>base</strong> derivata da <strong>un</strong> thread comporta<br />

83


CAPITOLO 4 <strong>Implementazione</strong> <strong>di</strong> COWSlite<br />

CowsProcess cpxxx = null ;<br />

List cplxxx = new ArrayList();<br />

cplxxx . add ( nproc ) ; //2 v o l t e<br />

cpxxx = new ChoiceProcess ( cplxxx , ds ) ;<br />

CowsProcess cpxxx = null ;<br />

cpxxx = new Assxxx ( cpyyy , ds ) ;<br />

Tabella 4.11: Choice - +(p1,p2)<br />

Tabella 4.12: Assign - x:=exp<br />

<strong>di</strong>versi aspetti favorevoli. Ogni azione è <strong>un</strong> thread e quin<strong>di</strong> la sua esecuzione è in<strong>di</strong>-<br />

pendente da tutte le altre azioni, inoltre ogni azione è in <strong>un</strong>o stato <strong>di</strong> stand-by fino a<br />

che non viene esplicitamente eseguita. Inoltre essendo tutta inglobata in <strong>un</strong> thread,<br />

deve solo preoccuparsi <strong>di</strong> avviare l’azione successiva che <strong>per</strong> la macchina virtuale è a<br />

sua volta in stand-by. Questo comporta che non deve esserci <strong>un</strong> gestore aggi<strong>un</strong>tivo<br />

che si preoccupi <strong>di</strong> far partire e mettere in attesa i thread nel momento in cui l’azione<br />

che vi è rappresentata deve essere <strong>di</strong>sabilitata. Il co<strong>di</strong>ce che produce l’effetto della<br />

singola azione è com<strong>un</strong>que composto da poche istruzioni, quin<strong>di</strong> ogni thread <strong>per</strong> essere<br />

eseguito completamente non ha bisogno <strong>di</strong> <strong>un</strong> tempo <strong>di</strong> esecuzione molto l<strong>un</strong>go.<br />

Questa elevata modularità facilita la scrittura della logica me<strong>di</strong>ante la semplice<br />

composizione delle azioni, facendo sì che il co<strong>di</strong>ce da scrivere sia molto semplice e<br />

quin<strong>di</strong> si riduce la probabilità <strong>di</strong> produrre co<strong>di</strong>ce Java non f<strong>un</strong>zionante.<br />

Infine il co<strong>di</strong>ce <strong>di</strong> questa <strong>un</strong>ità dell’engine risulta <strong>di</strong> più semplice manutenzione e<br />

<strong>per</strong>mette <strong>di</strong> estendere l’engine semplicemente aggi<strong>un</strong>gendo nuove classi che eseguano<br />

il comportamento <strong>di</strong> azioni finora non definite.<br />

4.3.4 Spazio dei <strong>servizi</strong><br />

Lo spazio dei <strong>servizi</strong> è l’oggetto all’interno del quale viene gestito il <strong>servizi</strong>o. In esso<br />

vengono inserite e confrontate le richieste e le attività <strong>di</strong> ricezione, viene mantenuta<br />

84


4.4 Generazione del compilatore<br />

l’origine del DataSpace principale, quello in cui sono contenute le variabili globali<br />

definite <strong>per</strong> il <strong>servizi</strong>o. Esso sfrutta e maneggia tutte le classi del package principale,<br />

i DataSpace, le variabili, i processi e i <strong>servizi</strong> <strong>di</strong> com<strong>un</strong>icazione. È costituito da due<br />

insiemi <strong>di</strong>sgi<strong>un</strong>ti <strong>di</strong> descrittori <strong>di</strong> <strong>servizi</strong>o: <strong>un</strong>o <strong>per</strong> raccogliere le richieste pendenti in<br />

entrata e <strong>un</strong>o <strong>per</strong> le attività <strong>di</strong> ricezione in attesa. È critico <strong>per</strong>ché da esso <strong>di</strong>pen-<br />

dono le prestazioni dell’intero <strong>servizi</strong>o e in esso possono verificarsi problemi <strong>di</strong> accesi<br />

concorrenti poiché è soggetto ad accessi multipli da parte <strong>di</strong> tutti i thread.<br />

Concorrenza<br />

Alc<strong>un</strong>i aspetti della concorrenza non vengono trattati <strong>per</strong>ché demandati nella loro<br />

gestione allo scheduler del sistema o<strong>per</strong>ativo, della virtual machine e dell’application<br />

server. Questo semplifica enormemente lo sviluppo dell’engine. L’oggetto più critico<br />

nei confronti della concorrenza a questo p<strong>un</strong>to è proprio il ServiceSpace ed in par-<br />

ticolare l’accesso alle due liste contenti i <strong>servizi</strong> pendenti. Anche qui ci si affida al<br />

modello <strong>di</strong> threa<strong>di</strong>ng offerto da Java ed in particolare alle primitive <strong>di</strong> sincronizzazione<br />

definendo i meto<strong>di</strong> e le proprietà interessate come syncronized.<br />

4.4 Generazione del compilatore<br />

Per realizzare il compilatore del co<strong>di</strong>ce COWSlite è stato utilizzato SableCC [16].<br />

SableCC è <strong>un</strong> compilatore <strong>di</strong> compilatori, cioè <strong>un</strong> strumento sviluppato <strong>per</strong> costruire lo<br />

scheletro <strong>di</strong> <strong>un</strong> compilatore, automatizzando la creazione <strong>di</strong> tutti quei componenti che<br />

costituiscono l’infrastruttura <strong>di</strong> analisi del <strong>linguaggio</strong>, i meto<strong>di</strong> <strong>di</strong> verifica del co<strong>di</strong>ce<br />

e la trasformazione in <strong>un</strong> altro <strong>linguaggio</strong> sia esso co<strong>di</strong>ce eseguibile, <strong>un</strong> <strong>linguaggio</strong><br />

interme<strong>di</strong>o (ad es. bytecode o MSIL) o <strong>un</strong>’altro <strong>linguaggio</strong> <strong>di</strong> programmazione.<br />

Partendo dalla descrizione del <strong>linguaggio</strong> me<strong>di</strong>ante <strong>un</strong>a grammatica scritta con<br />

le espressioni regolari e la EBNF, SableCC produce <strong>un</strong>a rappresentazione del pro-<br />

gramma che si vuole compilare generando l’albero sintattico astratto (AST) ottenuto<br />

dal parsing del co<strong>di</strong>ce. L’albero così ottenuto è fortemente tipato e questo assicura<br />

85


CAPITOLO 4 <strong>Implementazione</strong> <strong>di</strong> COWSlite<br />

che l’albero non possa essere corrotto attraverso manipolazioni successive. Inoltre<br />

fornisce gli strumenti <strong>per</strong> implementare le successive fasi che <strong>per</strong>mettano l’analisi e<br />

la compilazione del co<strong>di</strong>ce, producendo delle classi apposite con lo scopo <strong>di</strong> separare<br />

fra loro tutti gli aspetti sia da <strong>un</strong> p<strong>un</strong>to <strong>di</strong> vista <strong>di</strong> co<strong>di</strong>fica delle o<strong>per</strong>azioni che <strong>di</strong><br />

memorizzazione delle informazioni utilizzate da ogni passo <strong>di</strong> analisi.<br />

La Figura 4.7 è <strong>un</strong> esempio <strong>di</strong> AST generato me<strong>di</strong>ante SableCC rappresentante<br />

<strong>un</strong>’espressione matematica data <strong>un</strong>a grammatica <strong>per</strong> il riconoscimento. La gramma-<br />

tica usata nell’esempio è presente in molti esempi in letteratura ed è analoga alla<br />

sezione espressioni descritta <strong>per</strong> COWSlite (Tabella 3.6).<br />

Figura 4.7: AST generato <strong>per</strong> l’espressione (45 + 36/2) ∗ 3 + 5 ∗ 2<br />

Il co<strong>di</strong>ce generato da questo compilatore consiste in <strong>un</strong>a serie <strong>di</strong> classi in linguag-<br />

gio Java che rappresentano le entità sintattiche del <strong>linguaggio</strong> e da altre classi che<br />

86


4.4 Generazione del compilatore<br />

forniscono i meto<strong>di</strong> <strong>per</strong> analizzare il sorgente del <strong>linguaggio</strong> descritto. Il co<strong>di</strong>ce così<br />

ottenuto è già f<strong>un</strong>zionante e <strong>per</strong> lo sviluppatore che utilizza il framework è sufficien-<br />

te specificare le azioni corrispondenti agli elementi lessicali definiti all’interno della<br />

descrizione.<br />

SableCC fa parte <strong>di</strong> <strong>un</strong>a classe <strong>di</strong> programmi molto utilizzata dai programmatori<br />

fra cui possiamo ricordare Lex/YACC [27, 23], PCCTS [36] ed altri specifici del mondo<br />

Java come JavaCC [22].<br />

L’approccio utilizzato da SableCC <strong>di</strong> costruire <strong>un</strong> framework object oriented <strong>per</strong> la<br />

realizzazione del compilatore rende più semplice la manutenibilità del co<strong>di</strong>ce prodotto,<br />

<strong>per</strong>mettendo <strong>di</strong> correggere eventuali errori o effettuare mo<strong>di</strong>fiche sul co<strong>di</strong>ce scritto<br />

dallo sviluppatore, ad esempio nuovi meto<strong>di</strong> <strong>di</strong> analisi e ottimizzazione, senza toccare<br />

il framework a meno che non vengano effettuate mo<strong>di</strong>fiche sul <strong>linguaggio</strong>. Anche in<br />

questo caso è sufficiente mo<strong>di</strong>ficare il file <strong>di</strong> specifica che descrive la grammatica e<br />

rigenerare il framework. Tale struttura <strong>per</strong>mette <strong>di</strong> realizzare facilmente compilatori<br />

multipassata come avviene nella gran parte dei compilatori moderni. Tutto il lavoro <strong>di</strong><br />

verifica e produzione del co<strong>di</strong>ce è reso più semplice dal fatto che il framework produce<br />

<strong>un</strong> AST sul quale lavorano le classi prodotte dallo sviluppatore demandate all’analisi<br />

e alla produzione del co<strong>di</strong>ce.<br />

SableCC si occupa <strong>per</strong>ò solo della definizione lessicale e grammaticale del<br />

<strong>linguaggio</strong> e non della parte semantica.<br />

Il framework fa uso <strong>di</strong> pattern <strong>di</strong> progettazione Object Oriented <strong>per</strong> assicurare la<br />

modularità del co<strong>di</strong>ce, ad esempio l’AST è prodotto sfruttando il pattern visitor [17].<br />

I passi necessari <strong>per</strong> costruire <strong>un</strong> compilatore con SableCC sono:<br />

1. Creare <strong>un</strong> file contenente la specifica SableCC in cui è definita la sintassi e la<br />

grammatica.<br />

2. Lanciare SableCC con il file contenete la specifica <strong>per</strong> generare il framework.<br />

3. Creare <strong>un</strong>a o più working classes, possibilmente estendendo quelle generate da<br />

SableCC.<br />

87


CAPITOLO 4 <strong>Implementazione</strong> <strong>di</strong> COWSlite<br />

4. Creare <strong>un</strong>a classe generale <strong>per</strong> il compilatore in cui vengono attivati il lexer, il<br />

parser e le working classes.<br />

5. Compilare il tutto con Java.<br />

Con il termine working classes si intendono tutte le classi che contengono il nucleo delle<br />

f<strong>un</strong>zionalità del compilatore, queste classi possono essere analizzatori, trasformazioni<br />

dell’AST o semplicemente dei generatori <strong>di</strong> co<strong>di</strong>ce.<br />

Il file <strong>di</strong> specifica è <strong>un</strong> file <strong>di</strong> testo che contiene la definizione lessicale e le produzioni<br />

che descrivono il <strong>linguaggio</strong> che deve essere riconosciuto.<br />

4.4.1 Componenti <strong>di</strong> SableCC<br />

I componenti principali del framework sono:<br />

1. Lexer: è il componente che si occupa del riconoscimento dei token del linguag-<br />

gio e della corretta costruzione sintattica del co<strong>di</strong>ce. La classe prodotta nel<br />

framework che assolve questo compito porta lo stesso nome ed è sufficiente a<br />

svolgere il compito.<br />

2. Nodo: è la classe <strong>base</strong> dalla quale sono costruite tutte le produzioni e i token<br />

del <strong>linguaggio</strong> e che verranno usati come elementi dell’albero sintattico astratto.<br />

3. Parser: sfrutta il lexer, o più precisamente le informazioni in output dal lexer<br />

<strong>per</strong> produrre in <strong>base</strong> alle produzioni, l’AST strutturato me<strong>di</strong>ante le classi figlie<br />

della classe Nodo.<br />

4. Analisys (AST walkers): sono <strong>un</strong>a serie <strong>di</strong> classi che forniscono meto<strong>di</strong> <strong>per</strong> at-<br />

traversare l’albero sintattico prodotto dal parser. Estendendo opport<strong>un</strong>amente<br />

<strong>un</strong>a o più <strong>di</strong> queste classi si costruisce il compilatore.<br />

Ogn<strong>un</strong>o <strong>di</strong> questi elementi è identificato da <strong>un</strong>a o più classi all’interno del<br />

framework e corrispondo agli elementi definiti nel file <strong>di</strong> specifica della grammatica.<br />

Per rendere possibile la produzione e l’analisi del co<strong>di</strong>ce è necessario che i nomi<br />

assegnati agli oggetti rappresentanti gli elementi del <strong>linguaggio</strong> (i no<strong>di</strong> dell’AST)<br />

88


4.4 Generazione del compilatore<br />

siano <strong>un</strong>iformi, <strong>per</strong> questo SableCC definisce delle precise regole <strong>per</strong> l’assegnazione<br />

<strong>di</strong> tali nomi (Name Rules). Tali nomi rappresenteranno i no<strong>di</strong> e determineranno la<br />

nomenclatura dei meto<strong>di</strong> presenti negli AST walkers.<br />

Name Rules<br />

• Ad ogni classe produzione è assegnato il nome della produzione preceduto da<br />

<strong>un</strong>a P maiuscola, e trasformato rendendo maiuscola la prima lettera e tutte<br />

quelle precedute da <strong>un</strong>a sottolineatura e cancellando le sottolineature.<br />

• Se <strong>un</strong>a produzione ha <strong>un</strong>a sola alternativa senza nome, la classe corrispondente<br />

all’alternativa ha lo stesso nome della produzione con <strong>un</strong>a A maiuscola al posto<br />

della P.<br />

• Se le alternative sono più <strong>di</strong> <strong>un</strong>a, solo <strong>un</strong>a può essere senza nome, tutte le altre<br />

devono avere <strong>un</strong> nome e tale nome è inserito come prefisso dopo la A seguendo<br />

le stesse regole usate <strong>per</strong> il nome della produzione.<br />

• Gli elementi vengono in<strong>di</strong>cati con il nome stesso a meno che non compaiano più<br />

<strong>di</strong> <strong>un</strong>a volta all’interno della produzione, in questo caso devono avere <strong>un</strong> nome<br />

e questo nome è usato come prefisso in modo analogo a quanto fatto nei casi<br />

precedenti.<br />

SableCC non da accesso <strong>di</strong>retto agli elementi, ma fornisce dei meto<strong>di</strong> accessori con-<br />

formi allo standard Java (setxxx e getxxx). La presenza <strong>di</strong> tali meto<strong>di</strong> ha lo scopo<br />

<strong>di</strong> impe<strong>di</strong>re che venga corrotta la struttura dell’AST che potrebbe avvenire fornendo<br />

<strong>un</strong> accesso <strong>di</strong>retto alla struttura.<br />

File <strong>di</strong> specifica della grammatica<br />

Il file <strong>di</strong> specifica <strong>di</strong> SableCC è composto da 6 sezioni: package, hel<strong>per</strong>, stati, token,<br />

token ignorati e produzioni. I primi quattro influenzano il lexer, mentre gli ultimi tre e<br />

il package interessano il parser. Alc<strong>un</strong>e sezioni quin<strong>di</strong> hanno a che vedere con entrambi<br />

89


CAPITOLO 4 <strong>Implementazione</strong> <strong>di</strong> COWSlite<br />

i componenti <strong>di</strong> SableCC, ma la cosa non sorprende <strong>per</strong>ché i token, essendo i tasselli<br />

che compongono il <strong>linguaggio</strong>, devono essere tenuti in considerazione da entrambi,<br />

mentre la sezione package non è <strong>di</strong>rettamente collegata al <strong>linguaggio</strong>, ma si riferisce<br />

al co<strong>di</strong>ce Java prodotto (infatti serve <strong>per</strong> dare <strong>un</strong> nome al package che conterrà le classi<br />

generate). Ogni sezione ha <strong>un</strong> proprio insieme <strong>di</strong> regole <strong>per</strong> specificare gli aspetti del<br />

<strong>linguaggio</strong>. Mentre le sezioni token, token ignorati e produzioni si riferiscono agli<br />

elementi <strong>di</strong> <strong>un</strong>a grammatica, è necessario chiarire il significato delle due sezioni non<br />

ancora citate. La sezione hel<strong>per</strong> <strong>per</strong>mette <strong>di</strong> definire degli insiemi <strong>di</strong> caratteri o delle<br />

espressioni regolari. L’uso che se ne fa è simile alle macro definite in molti compilatori<br />

se non <strong>per</strong> la <strong>di</strong>fferenza che la sostituzione degli identificatori definiti è semantica e non<br />

statica. La sezione stati invece <strong>per</strong>mette <strong>di</strong> definire <strong>un</strong>’automa a stati finiti all’interno<br />

dell’insieme dei token, assegnando ad ogni token <strong>un</strong> insieme <strong>di</strong> stati in modo tale che<br />

durante il riconoscimento dei token il lexer possa eseguire altre o<strong>per</strong>azioni sul co<strong>di</strong>ce<br />

analizzato in f<strong>un</strong>zione <strong>di</strong> tali stati.<br />

Una volta scritta la grammatica nel file <strong>di</strong> specifica potrebbe essere sufficien-<br />

te estendere <strong>un</strong>o degli attraversatori inserendo nella nuova classe le o<strong>per</strong>azioni <strong>per</strong><br />

produrre il co<strong>di</strong>ce.<br />

4.4.2 Generazione del co<strong>di</strong>ce<br />

La grammatica completa che implementa COWSlite in formato SableCC è riportata<br />

in appen<strong>di</strong>ce. Le porzioni <strong>di</strong> co<strong>di</strong>ce su cui soffermarsi sono quelle che descrivono le<br />

<strong>di</strong>chiarazioni e i processi. Osservando questi due blocchi possiamo notare che non c’è<br />

molta <strong>di</strong>fferenza con quanto descritto nella Tabella 3.6, infatti sia la notazione usata<br />

nella descrizione che quella <strong>di</strong> cui fa uso SableCC sono tutte derivate dalla EBNF,<br />

con le seguenti <strong>di</strong>fferenze:<br />

90<br />

• Le scelte all’interno <strong>di</strong> <strong>un</strong>a regola devono avere <strong>un</strong> nome che le <strong>di</strong>stingue dalle<br />

altre, questo nome è in<strong>di</strong>cato fra parentesi graffe all’inizio dell’alternativa della<br />

produzione. Ad esempio :<br />

prec_process =


4.4 Generazione del compilatore<br />

{precedence} l_par process r_par |<br />

{normal} process;<br />

• Nel caso <strong>di</strong> termini duplicati all’interno <strong>di</strong> <strong>un</strong>a delle alternative della produzione<br />

anche questi devono essere <strong>di</strong>stinti fra loro me<strong>di</strong>ante <strong>un</strong> nome racchiuso fra<br />

parentesi quadre. Ad esempio:<br />

choice =<br />

{choice} plus r_par [left]:choice comma [right]:choice l_par |<br />

...<br />

• I token del <strong>linguaggio</strong> non sono <strong>di</strong>rettamente scritti nelle produzioni ma sono<br />

in<strong>di</strong>cati tramite alias rispetto a quelli specificati all’interno dell’apposito blocco<br />

<strong>di</strong> definizione.<br />

Da questo file <strong>di</strong> specifica vengono generate <strong>per</strong> mezzo del compilatore <strong>un</strong>a serie<br />

<strong>di</strong> classi che rappresenteranno gli elementi della grammatica e ci <strong>per</strong>metteranno <strong>di</strong><br />

costruire <strong>un</strong> albero raffigurante il co<strong>di</strong>ce che vogliamo interpretare.<br />

Una volta ottenuto l’albero dal parsing del co<strong>di</strong>ce è possibile, con <strong>un</strong>a o più passate<br />

su <strong>di</strong> esso, produrre il co<strong>di</strong>ce voluto come risultato della compilazione. In questo caso<br />

è stato sufficiente implementare <strong>un</strong>’<strong>un</strong>ica classe attraversatrice che scan<strong>di</strong>sce l’albero<br />

con <strong>un</strong> logica depth first e costruisce il co<strong>di</strong>ce durante la scansione.<br />

L’idea con cui si procede nella scansione è la seguente.<br />

La prima receive incontrata all’interno del blocco service sarà quella che darà il<br />

nome al <strong>servizi</strong>o e che verrà considerata come l’endpoint principale con il quale espor-<br />

re il <strong>servizi</strong>o. Tutte le altre receive verranno considerate come o<strong>per</strong>azioni fornite<br />

dallo stesso <strong>servizi</strong>o e saranno considerate esterne solo se si trovano a livello più alto<br />

nell’AST, che è lo stesso livello della prima receive che è stata incontrata. Inoltre<br />

solo le o<strong>per</strong>azioni che vengono considerate esterne devono fare in modo che venga<br />

avviata <strong>un</strong>a nuova istanza del <strong>servizi</strong>o definito. In particolare tutte le o<strong>per</strong>azioni che<br />

devono essere esposte dovranno avere lo stesso partnerName <strong>per</strong> portare a termine<br />

91


CAPITOLO 4 <strong>Implementazione</strong> <strong>di</strong> COWSlite<br />

la compilazione. Questa scelta deriva dal fatto che <strong>un</strong>a volta che <strong>un</strong> <strong>servizi</strong>o viene<br />

compilato in Java, questi deve avere <strong>un</strong> <strong>un</strong>ico nome che viene utilizzato dall’applica-<br />

tion server <strong>per</strong> raggruppare le o<strong>per</strong>azioni da esso fornito all’esterno. Quin<strong>di</strong> quando<br />

il compilatore trova delle receive all’interno del co<strong>di</strong>ce dovrà comportarsi in modo<br />

<strong>di</strong>verso rispetto a tutti gli altri processi trovati durante l’analisi.<br />

Ogni processo viene numerato durante la fase <strong>di</strong>scendente della scansione, in que-<br />

sto modo ogn<strong>un</strong>o <strong>di</strong> essi ha <strong>un</strong> riferimento numerico <strong>di</strong>fferente da tutti gli altri e<br />

questo ci consente <strong>di</strong> identificarlo in maniera <strong>un</strong>ivoca. Durante questa fase vengono<br />

allocate tutte le informazioni ricavate dalla scansione all’interno <strong>di</strong> appositi oggetti<br />

<strong>di</strong> appoggio definiti nel package mcows.compiler ogn<strong>un</strong>o <strong>di</strong> questi oggetti rappresen-<br />

tante gli elementi verrà successivamente interrogato durante la fase ascendente della<br />

scansione.<br />

Il package mcows.compiler contiene la classe che implementa l’attraversatore, che<br />

è il cuore del compilatore, più alc<strong>un</strong>e classi <strong>di</strong> supporto alla compilazione. Tali classi<br />

sono:<br />

CowsTranslator Classe principale del compilatore che esegue la traduzione in Ja-<br />

va me<strong>di</strong>ante l’attraversamento dell’AST, estende la classe DepthFirstAdapter<br />

creata con SableCC.<br />

Dato Contiene le informazioni sui parametri scambiati con i descrittori.<br />

O<strong>per</strong>azione Identifica <strong>un</strong> o<strong>per</strong>azione trovata all’interno del co<strong>di</strong>ce, sia essa <strong>un</strong>a<br />

richiesta o <strong>un</strong>’invocazione.<br />

Servizio Mantiene le informazioni <strong>di</strong> stato <strong>per</strong> il <strong>servizi</strong>o che stiamo compilando.<br />

Processo Mantiene le informazioni sui processi trovati durante la scansione.<br />

Assegnazione Contiene il co<strong>di</strong>ce che dovrà essere generato <strong>per</strong> eseguire la<br />

valutazione dell’espressione e la sua successiva assegnazione.<br />

Tutte queste classi contengono dei meto<strong>di</strong> <strong>per</strong> produrre il co<strong>di</strong>ce Java da inserire nel<br />

listato finale.<br />

92


4.4 Generazione del compilatore<br />

La particolarità della scansione depth first è che ogni ramo viene scan<strong>di</strong>to sempre<br />

fino alla foglia prima <strong>di</strong> cominciare a risalire e questo fa si che al termine della scan-<br />

sione <strong>di</strong> ogni singolo ramo sia possibile scrivere <strong>un</strong>a porzione <strong>di</strong> co<strong>di</strong>ce completo che<br />

rappresenta la logica in<strong>di</strong>rizzata partendo dall’azione terminale fino al principio.<br />

Quin<strong>di</strong> durante la fase ascendente si hanno tutte le informazioni relative alla par-<br />

te terminale del co<strong>di</strong>ce che possono quin<strong>di</strong> essere agganciate al processo che viene<br />

prodotto <strong>per</strong> costruire <strong>un</strong>a porzione <strong>di</strong> descrizione della logica completa fino al p<strong>un</strong>-<br />

to in cui sta avvenendo l’analisi. Il co<strong>di</strong>ce viene costruito con <strong>un</strong> approccio <strong>di</strong> tipo<br />

bottom-up. Per spiegare più chiaramente questo concetto pren<strong>di</strong>amo degli esempi:<br />

Come primo esempio pren<strong>di</strong>amo due azioni <strong>di</strong> invocazione eseguite in parallelo<br />

( | (!(p1, o1, ), !(p2, o2,)) )<br />

con x1, x2 istanziate altrove con <strong>un</strong> valore assegnato e scriviamo il co<strong>di</strong>ce COWSlite<br />

nel modo più semplice possibile, tralasciando ai fini dell’esempio la parte relativa alla<br />

definizione delle variabili. Il co<strong>di</strong>ce da riconoscere <strong>di</strong>venta il seguente:<br />

service{|( !(p1,o1,),!(p2,o2,))}<br />

L’albero AST generato dal parser <strong>per</strong> mezzo delle classi generate con SableCC e<br />

raffigurato in Figura 4.8.<br />

Seguendo <strong>un</strong> or<strong>di</strong>ne depth first <strong>per</strong> l’attraversamento dell’albero si nota che il<br />

primo elemento <strong>di</strong> tipo process incontrato è quello relativo al costrutto parallelo che<br />

quin<strong>di</strong> avrà come progressivo 1, poi l’invoke sul partner p1 che avrà progressivo 2 ed<br />

infine quella sul partner p2 che avrà progressivo 3. Allo stesso modo il primo blocco<br />

process completato sarà quello relativo alla invoke con partner p1, poi quello con<br />

partner p2 e infine il blocco che descrive la composizione parallela dei due processi.<br />

Il co<strong>di</strong>ce da inserire nel metodo ServiceCreator() è riportato in Tabella 4.13.<br />

Osservandolo possiamo notare che partendo dal basso troviamo prima il blocchi <strong>di</strong><br />

co<strong>di</strong>ce generato relativo all’istruzione parallel e poi i due blocchi relativi alle due<br />

istruzioni <strong>di</strong> invoke, in questo modo al momento della definizione alle due istruzioni<br />

invoke viene assegnato <strong>un</strong> identificativo che è passato successivamente al blocco che<br />

93


CAPITOLO 4 <strong>Implementazione</strong> <strong>di</strong> COWSlite<br />

Figura 4.8: Albero AST <strong>per</strong> il costrutto Parallel<br />

le mette in parallelo. Le due righe all’inizio del metodo sono sempre le stesse e servono<br />

<strong>per</strong> inizializzare correttamente il DataSpace <strong>di</strong> lavoro; infatti mainDS è <strong>un</strong> riferimento<br />

al DataSpace principale a cui fa riferimento il <strong>servizi</strong>o.<br />

L’altro costrutto che pren<strong>di</strong>amo in esame è quello relativo all’o<strong>per</strong>atore <strong>di</strong> scelta<br />

con<strong>di</strong>zionata (Choice) del tipo<br />

+(?(p1, o1, < x1 >).nil, ?(p1, o1, < x2 >).nil)<br />

supponiamo che x1 e x2 siano variabili definite in qualche passo precedente e che le<br />

loro istanze abbiano dei valori fissati, tralasciando la parte <strong>di</strong> definizione delle variabili<br />

in COWSlite possiamo ipotizzare <strong>un</strong> co<strong>di</strong>ce <strong>di</strong> questo tipo.<br />

service{ +(?(p1,o1,).nil,?(p1,o1,).nil)}<br />

94


4.4 Generazione del compilatore<br />

private CowsProcess S e r v i c e C r e a t o r ( ) {<br />

DataSpace ds ; /∗ modello d e l ds <strong>per</strong> i l s e r v i z i o ∗/<br />

ds = new DataSpace (mainDS ) ;<br />

/∗ DataSpace D e l i m i t a t i o n ∗/<br />

/∗ Invoke ∗/<br />

CowsProcess cp3 = null ;<br />

WOVect v3 = new WOVect ( 1 ) ;<br />

v3 . insVar ( (WOVar) ds . f i n d V a r i a b i l e ( "x2" ) ) ;<br />

WsDescriptor wd3 = ds . findWsDVar ( "p2" ) ;<br />

cp3 = new InvokeProcess (wd3 , v3 , ds ) ;<br />

/∗ Invoke ∗/<br />

CowsProcess cp2 = null ;<br />

WOVect v2 = new WOVect ( 1 ) ;<br />

v2 . insVar ( (WOVar) ds . f i n d V a r i a b i l e ( "x1" ) ) ;<br />

WsDescriptor wd2 = ds . findWsDVar ( "p1" ) ;<br />

cp2 = new InvokeProcess (wd2 , v2 , ds ) ;<br />

/∗ P a r a l l e l ∗/<br />

CowsProcess cp1 = null ;<br />

List cpl1 = new ArrayList();<br />

cpl1 . add ( cp2 ) ;<br />

cpl1 . add ( cp3 ) ;<br />

cp1 = new P a r a l l e l P r o c e s s ( cpl1 , ds ) ;<br />

return cp1 ;<br />

}<br />

Tabella 4.13: Esempio <strong>di</strong> co<strong>di</strong>ce generato <strong>per</strong> la logica del <strong>servizi</strong>o<br />

Come possiamo vedere dalla Figura 4.9, l’albero AST risultante dal parsing è ana-<br />

logo a quello ottenuto <strong>per</strong> l’esempio precedente e quin<strong>di</strong> anche il co<strong>di</strong>ce da inserire<br />

nel metodo ServiceCreator() sarà analogo. Questa volta, <strong>per</strong>ò, ci sono altri par-<br />

ticolari da evidenziare che non sono <strong>di</strong>rettamente connessi al co<strong>di</strong>ce della logica, ma<br />

che coinvolgono la costruzione del <strong>servizi</strong>o <strong>web</strong> vero e proprio.<br />

In questo caso, oltre alla compilazione del co<strong>di</strong>ce <strong>per</strong> il metodo ServiceCreator(),<br />

devono essere inseriti altri blocchi <strong>di</strong> co<strong>di</strong>ce all’interno della classe che stiamo generan-<br />

do <strong>per</strong> rappresentare il nostro <strong>servizi</strong>o. In particolare dovrà essere controllato che il<br />

nome del partner definito nelle o<strong>per</strong>azioni <strong>di</strong> receive coincida con quello assegnato al<br />

<strong>servizi</strong>o; se il nome dato al <strong>servizi</strong>o corrisponde allora stiamo definendo <strong>un</strong>’o<strong>per</strong>azione<br />

del <strong>servizi</strong>o e quin<strong>di</strong> deve essere verificato se tale o<strong>per</strong>azione è già stata trovata oppure<br />

no, <strong>per</strong> non scrivere più volte la sua definizione; se invece il nome del <strong>servizi</strong>o non è<br />

95


CAPITOLO 4 <strong>Implementazione</strong> <strong>di</strong> COWSlite<br />

Figura 4.9: Albero AST <strong>per</strong> il costrutto Choice<br />

stato definito allora il compilatore prenderà il nome trovato come nome da assegnare<br />

al <strong>servizi</strong>o e quin<strong>di</strong> definirà l’o<strong>per</strong>azione trovata come metodo da esporre.<br />

Il co<strong>di</strong>ce inserito nella classe che definisce <strong>un</strong> nuovo metodo da esporre è del<br />

tipo in<strong>di</strong>cato in Tabella 4.14. In questo caso il co<strong>di</strong>ce corrisponde proprio a quello<br />

generato <strong>per</strong> l’o<strong>per</strong>azione o1 dell’esempio. Se nel co<strong>di</strong>ce fossero state presenti più<br />

azioni <strong>di</strong> receive con in<strong>di</strong>cate o<strong>per</strong>azioni <strong>di</strong>verse il compilatore avrebbe generato più<br />

blocchi <strong>di</strong> questo genere; <strong>un</strong>o <strong>per</strong> ogni o<strong>per</strong>azione trovata.<br />

Le o<strong>per</strong>azioni trovate vengono via via accumulate <strong>per</strong> mezzo della classe <strong>di</strong> ap-<br />

poggio O<strong>per</strong>azione e solo alla fine della scansione <strong>di</strong> tutto l’albero viene generato il<br />

96


4.4 Generazione del compilatore<br />

@WebMethod<br />

@Oneway<br />

public void o1 ( S t r i n g x1 ) {<br />

WOVect v = new WOVect ( 1 ) ;<br />

v . insVar (new WOVar( null , x1 ) ) ;<br />

i f ( ! CS . r e q u e s t (new WsDescriptor ( locPartner , "o1" , v ) ) ) {<br />

S e r v i c e C r e a t o r ( ) . s t a r t ( ) ;<br />

}<br />

}<br />

Tabella 4.14: Esempio <strong>di</strong> co<strong>di</strong>ce generato <strong>per</strong> la scelta con<strong>di</strong>zionata<br />

co<strong>di</strong>ce che crea i meto<strong>di</strong> rappresentanti le o<strong>per</strong>azioni.<br />

La parte <strong>di</strong> listato riguardante le <strong>di</strong>chiarazioni globali genererà <strong>un</strong> blocco <strong>di</strong> co-<br />

<strong>di</strong>ce nel quale viene definito il DataSpace primario, chiamato mainDS con allocate<br />

all’interno tutte le variabili definite nel blocco dec {...}.<br />

97


98<br />

CAPITOLO 4 <strong>Implementazione</strong> <strong>di</strong> COWSlite


Capitolo 5<br />

Uso <strong>di</strong> COWSlite<br />

In questo capitolo descriveremo l’uso degli strumenti realizzati soffermandoci sull’uti-<br />

lizzo e su alc<strong>un</strong>i accorgimenti <strong>di</strong> programmazione del <strong>linguaggio</strong> COWSlite (eviden-<br />

ziando limiti e possibilità dell’implementazione). Infine utilizzeremo <strong>un</strong>o degli esempi<br />

già <strong>di</strong>scussi nei capitoli precedenti come caso <strong>di</strong> stu<strong>di</strong>o <strong>per</strong> mostrare l’utilizzo degli<br />

strumenti software sviluppati ed il f<strong>un</strong>zionamento del supporto a r<strong>un</strong>time.<br />

5.1 Compilatore COWSlite<br />

Il software prodotto contiene alc<strong>un</strong>i file che coa<strong>di</strong>uvano nella compilazione e nella<br />

creazione dei <strong>servizi</strong> COWSlite ed altri programmi <strong>per</strong> la generazione dei pacchetti<br />

<strong>per</strong> la <strong>di</strong>stribuzione su <strong>un</strong> <strong>web</strong> application server.<br />

I principali strumenti realizzati sono tutti programmi a linea <strong>di</strong> comando, da<br />

utilizzare cioè dalla shell del sistema o<strong>per</strong>ativo. Il progetto è stato sviluppato e testato<br />

in ambiente Windows. Non sono state verificate le sue f<strong>un</strong>zionalità in ambiente Linux,<br />

ma la compatibilità dovrebbe essere assicurata dall’ambiente Java stesso. Gli script<br />

<strong>per</strong> aiutare l’utilizzatore nell’esecuzione dei coman<strong>di</strong> sono stati preparati solo <strong>per</strong><br />

Windows, ma non dovrebbe essere <strong>di</strong>fficile realizzarli anche <strong>per</strong> i sistemi o<strong>per</strong>ativi<br />

Linux.<br />

99


CAPITOLO 5 Uso <strong>di</strong> COWSlite<br />

Per i test sono stati utilizzati gli application server SUN Application Server [39]<br />

e Glassfish [21]. Alc<strong>un</strong>e prove sono state effettuate anche su Apache Geronimo [3]<br />

ed hanno evidenziato che in alc<strong>un</strong>i casi il file XML preparato <strong>per</strong> la <strong>di</strong>stribuzione del<br />

pacchetto sul server non è <strong>per</strong>fettamente compatibile con quello generato <strong>per</strong> gli altri<br />

due application server.<br />

Il compilatore è costituito da due pacchetti Java: CowsCompiler e CowsR<strong>un</strong>time,<br />

che contengono rispettivamente il compilatore e l’engine <strong>di</strong> esecuzione <strong>di</strong> COWSlite.<br />

Il programma principale è contenuto nel pacchetto CowsCompiler <strong>di</strong>stribuito come<br />

file JAR. Al suo interno è contenuta <strong>un</strong>a classe main che esegue la compilazione <strong>di</strong> <strong>un</strong><br />

file <strong>di</strong> testo contenete il <strong>servizi</strong>o COWSlite. La classe accetta dei parametri, alc<strong>un</strong>i<br />

opzionali, altri obbligatori. La sintassi del comando è:<br />

CowsCompiler [-a] [-v|-V level] [-o out<strong>di</strong>r] [-p packageName] nomefile<br />

Dal momento che il file è contenuto in <strong>un</strong> archivio Java deve essere eseguito <strong>per</strong> mezzo<br />

dell’interprete del <strong>linguaggio</strong> in modo da poter passare i parametri necessari:<br />

prompt> java -jar CowsCompiler.java .<br />

L’<strong>un</strong>ico parametro obbligatorio è il nome del file da compilare completo <strong>di</strong> <strong>per</strong>corso, gli<br />

altri sono tutti opzionali. Il parametro -o serve <strong>per</strong> in<strong>di</strong>care al compilatore in quale<br />

<strong>per</strong>corso mettere i file generati dalla compilazione, se questo parametro è assente<br />

vengono messi nella <strong>di</strong>rectory corrente. Il parametro -p serve <strong>per</strong> specificare <strong>un</strong> nome<br />

<strong>di</strong> package che sarà assegnato a tutti i file prodotti, in caso <strong>di</strong> assenza <strong>di</strong> questo<br />

parametro il compilatore assegna <strong>un</strong> nome <strong>di</strong> default. Il parametro -a serve <strong>per</strong><br />

visualizzare in <strong>un</strong>a finestra separata l’albero AST ottenuto dal riconoscitore sotto<br />

forma <strong>di</strong> ‘treeview’. I parametri -v e -V level servono <strong>per</strong> impostare il livello <strong>di</strong><br />

visualizzazione delle informazioni da parte del compilatore. In assenza del parametro<br />

il compilatore non visualizzerà alc<strong>un</strong>a informazione ad esclusione degli errori. Se<br />

viene selezionato -V level allora vengono abilitati gli errori e al posto <strong>di</strong> level<br />

deve essere inserito <strong>un</strong> valore fra 6 e 0: con 6 verranno visualizzati solo errori e<br />

warning, con 5 anche le informazioni interme<strong>di</strong>e via via fino ad arrivare a 0 in cui<br />

si hanno informazioni quasi su ogni azione del compilatore. I livelli sotto il 5 hanno<br />

100


5.1 Compilatore COWSlite<br />

mCOWSCompiler ver 0 . 9 . 1 . 3<br />

27−feb−2010 1 1 . 5 4 . 4 7 cows . compiler . Main main<br />

GRAVE: Parametri e r r a t i<br />

S i n t a s s i :<br />

CowsCompiler [ −a ] [ −v |−V l e v e l ] [ −o outDir ] [−p packageName ] fileName<br />

outDir − Percorso <strong>di</strong> output d e i f i l e g e n e r a t i .<br />

packageName − Nome da a s s e g n a r e a l package compilato<br />

fileName − I l nome del f i l e cw da compilare .<br />

−a −> V i s u a l i z z a AST.<br />

−v/−V −> Verboso − l e v e l 0−6 (0 max , 6 min ) .<br />

Tabella 5.1: Messaggio <strong>di</strong> errore del compilatore<br />

principalmente valore <strong>di</strong> debug sulla compilazione. Se viene selezionato -v, questo<br />

equivale all’impostazione <strong>di</strong> <strong>un</strong> livello 5.<br />

In caso <strong>di</strong> assenza dei parametri o <strong>di</strong> errore nei parametri il programma visualizzerà<br />

<strong>un</strong>a serie <strong>di</strong> messaggi a video simili a quelli <strong>di</strong> Tabella 5.1.<br />

Dopo avere generato con il compilatore i file Java questi devono essere compilati<br />

ed assemblati.<br />

Per produrre il file archivio WAR <strong>per</strong> l’installazione del <strong>servizi</strong>o sul server pos-<br />

siamo utilizzare l’utility jar presente nel Development Kit <strong>di</strong> Java. Tramite questa<br />

utility devono essere <strong>un</strong>iti i file compilati, il file <strong>web</strong>.xml ed <strong>un</strong> file xml apposita-<br />

mente prodotto che contiene le informazioni necessarie <strong>per</strong> installare ed instanziare<br />

il <strong>servizi</strong>o. Questo file <strong>per</strong> gli application server della famiglia SUN (Glassfish e S<strong>un</strong><br />

Application Server) deve chiamarsi s<strong>un</strong>-<strong>web</strong>.xml.<br />

Il file generato deve avere la seguente struttura: <strong>un</strong>a <strong>di</strong>rectory principale chia-<br />

mata WEB-INF che contiene al suo interno <strong>un</strong>a cartella classes con i file compilati<br />

corrispondenti ai <strong>servizi</strong> da eseguire, <strong>un</strong>a cartella lib in cui sono inseriti eventua-<br />

li archivi jar contenenti i pacchetti necessari alle classi compilate e i due file XML<br />

precedentemente in<strong>di</strong>cati.<br />

101


CAPITOLO 5 Uso <strong>di</strong> COWSlite<br />

5.1.1 Script <strong>per</strong> automatizzare la compilazione e la build<br />

Per realizzare lo schema <strong>di</strong> compilazione rappresentato in Figura 4.2 sarebbe sufficien-<br />

te usare i programmi realizzati e seguire l’iter in<strong>di</strong>cato. Per agevolare l’intero processo<br />

sono presenti due script <strong>per</strong> la compilazione e la creazione dei pacchetti da <strong>di</strong>stribuire<br />

sull’application server. Lo script cwc.bat serve <strong>per</strong> la compilazione dei file COW-<br />

Slite e lo script build.bat serve <strong>per</strong> compilare i file java ottenuti ed assemblarli<br />

all’interno <strong>di</strong> <strong>un</strong> file archivio.<br />

Questi due script <strong>per</strong> f<strong>un</strong>zionare correttamente devono essere contenuti in <strong>un</strong>a car-<br />

tella del filesystem all’interno della quale deve essere presente <strong>un</strong>a cartella chiamata<br />

mCows contenente il package CowsCompiler e <strong>un</strong>a cartella lib contenente il package<br />

CowsR<strong>un</strong>time. A sua volta i due script produrranno, sempre all’interno della stessa<br />

cartella in cui sono inseriti, <strong>un</strong>a cartella build contenente i file prodotti dal compi-<br />

latore, <strong>un</strong>a cartella classes contenente i file compilati e <strong>un</strong>a cartella WEB-INF nella<br />

quale viene replicata la struttura <strong>di</strong> file e cartelle <strong>per</strong> produrre l’archivio WAR.<br />

102<br />

Per compilare <strong>un</strong> file COWSlite (.cw) sono necessari 2 passi:<br />

1. Compilazione dei file .cw <strong>per</strong> produrre i file .java. Per fare ciò si può usare<br />

cwc.bat. Lo script prende in input alc<strong>un</strong>i dei parametri del compilatore: il<br />

nome del file e il package nel quale inserire i file java. Per definire il package si<br />

usa lo switch -p _nome_del_package_, dove il nome deve essere inserito con la<br />

notazione p<strong>un</strong>tata anziché con i backslash proprio come devono essere scritti in<br />

Java. Ad esempio -p <strong>servizi</strong>o.cows, questo creerà i file .java all’interno della<br />

cartella build riproducendo anche il path in<strong>di</strong>cato dal package.<br />

I due script sono costruiti <strong>per</strong> lavorare insieme<br />

2. Creazione del file WAR. Per questo è necessario utilizzare build.bat. Allo script<br />

sono necessari 2 parametri: il primo è il nome che vogliamo dare al WAR che sarà<br />

anche il nome in cui verrà messo il <strong>servizi</strong>o all’interno del <strong>web</strong> server, il secondo<br />

è il package con cui l’abbiamo compilato (con la notazione con backslash).


5.1 Compilatore COWSlite<br />

Se ad esempio vogliamo che il <strong>servizi</strong>o o i <strong>servizi</strong> siano richiamati con http:<br />

//nome_server:porta_server/TestCows/Test1Service?wsdl (in<strong>di</strong>rizzo del<br />

wsdl del <strong>servizi</strong>o Test1) allora il primo parametro è TestCows. Il carattere ?<br />

serve <strong>per</strong> passare dei parametri alla pagina <strong>web</strong>, in questo caso <strong>un</strong> parametro<br />

senza valore, ma sufficiente <strong>per</strong> richiedere il WSDL del <strong>servizi</strong>o.<br />

Se vogliamo inserire <strong>servizi</strong> definiti in più file COWSlite nello stesso WAR basta<br />

ripetere il passo 1 <strong>per</strong> tutti i file con COWSlite da compilare e poi eseguire <strong>un</strong>’<strong>un</strong>ica<br />

volta il passo 2.<br />

Ad esempio se dobbiamo compilare il file Test1.cw, assegnandolo al package ser-<br />

vizio.cows e costruire il file <strong>per</strong> il deploy <strong>di</strong> nome TestCows, allora devono essere usati<br />

i seguenti coman<strong>di</strong>:<br />

prompt:> cwc -p <strong>servizi</strong>o.cows Test1.cw<br />

prompt:> build TestCows <strong>servizi</strong>o\\cows<br />

Si otterrà così <strong>un</strong> file TestCows.war da caricare sul <strong>web</strong> server con l’apposita<br />

procedura <strong>di</strong> deploy.<br />

È necessario ricordarsi si svuotare la cartella build ogni volta che si vuole fare <strong>un</strong><br />

nuovo file WAR.<br />

5.1.2 Utility <strong>di</strong> supporto<br />

All’interno del package CowsR<strong>un</strong>time sono contenute alc<strong>un</strong>e classi eseguibili che è<br />

possibile richiamare dall’esterno e che forniscono alc<strong>un</strong>e f<strong>un</strong>zioni <strong>di</strong> utilità <strong>per</strong> la<br />

produzione e il test dei <strong>servizi</strong> prodotti.<br />

Per eseguire tali classi è necessario ricorrere ancora <strong>un</strong>a volta all’interpre-<br />

te Java, ma questa volta non è sufficiente in<strong>di</strong>care il file jar, ma è neces-<br />

sario in<strong>di</strong>care con precisione la classe necessaria, con <strong>un</strong>a istruzione del tipo:<br />

java -classpath lib\CowsR<strong>un</strong>time.jar [parametri]. In cui no-<br />

me classe è il <strong>per</strong>corso completo in cui si trova la classe, cioè la concatenazione del<br />

103


CAPITOLO 5 Uso <strong>di</strong> COWSlite<br />

nome del package e del nome della classe. Ad esempio, cows.execution.exec <strong>per</strong><br />

eseguire la classe exec che vedremo successivamente.<br />

Di seguito verranno descritte le f<strong>un</strong>zioni <strong>di</strong> utilità presenti all’interno del package<br />

CowsR<strong>un</strong>time.<br />

exec<br />

Invia <strong>un</strong>a richiesta ad <strong>un</strong> <strong>servizi</strong>o <strong>web</strong>. Questo comando può essere utile <strong>per</strong> eseguire<br />

<strong>un</strong>’o<strong>per</strong>azione esposta da <strong>un</strong> <strong>servizi</strong>o <strong>web</strong> che che vogliamo testare.<br />

dove:<br />

La sintassi del comando è: exec i|e [wsdl] [o<strong>per</strong>azione] [(parametri)].<br />

i|e i <strong>per</strong> informazioni oppure e <strong>per</strong> esecuzione<br />

wsdl in<strong>di</strong>rizzo http del WSDL che descrive il <strong>servizi</strong>o che vogliamo invocare<br />

o<strong>per</strong>azione il nome dell’o<strong>per</strong>azione da eseguire<br />

parametri la lista dei parametri <strong>per</strong> l’o<strong>per</strong>azione richiesta, tali parametri devo essere<br />

racchiusi tra parentesi e separati me<strong>di</strong>ante virgola (...,...)<br />

In caso <strong>di</strong> errore nei parametri viene visualizzato <strong>un</strong> messaggio <strong>di</strong> errore come<br />

quello in Figura 5.2.<br />

COWS − WS executor ver . 0 . 9 . 0<br />

I n s e r i r e Parametri !<br />

SINTASSI: exec o p e r a z i o n e wsdl o p e r a t i o n ( parameter )<br />

o p e r a z i o n e i = i n f o<br />

e = execute<br />

wsdl i n d i r i z z o del f i l e WSDL<br />

o p e r a t i o n nome d e l l ’ o p e r a z i o n e da i n v o c a r e<br />

parameter l i s t a d e i paramteri da p a s s a r e r a c c h i u s i t r a ( ) e<br />

s u d d i v i s a da ,<br />

104<br />

Tabella 5.2: Messaggio <strong>di</strong> errore exec


5.2 Note sul compilatore<br />

makeXmlStub<br />

Crea i file <strong>web</strong>.xml e s<strong>un</strong>-<strong>web</strong>.xml necessari <strong>per</strong> la produzione e la <strong>di</strong>stribuzione del<br />

pacchetto <strong>di</strong> installazione dei <strong>servizi</strong> <strong>web</strong> sull’application server.<br />

dove:<br />

La sintassi del comando è: makeXmlStub tipofile outpath parametro.<br />

tipofile in<strong>di</strong>ca quale dei due file produrre<br />

outpath <strong>di</strong>rectory dove creare il file<br />

parametro nel caso <strong>di</strong> file s<strong>un</strong>-<strong>web</strong> corrisponde al nome del package war da creare<br />

In caso <strong>di</strong> errore nei parametri viene visualizzato <strong>un</strong> messaggio <strong>di</strong> errore come quello<br />

in Figura 5.3.<br />

S i n t a s s i :<br />

makeXmlStub t i p o F i l e outPath Parameter<br />

t i p o f i l e : SUN −> f i l e s<strong>un</strong>−<strong>web</strong> . xml 1 parametro: nome package war<br />

WEB −> f i l e <strong>web</strong> . xml Ness<strong>un</strong> Parametro<br />

Tabella 5.3: Messaggio <strong>di</strong> errore makeXmlStub<br />

5.2 Note sul compilatore<br />

Analizziamo alc<strong>un</strong>e caratteristiche del compilatore che possono essere considerate<br />

p<strong>un</strong>ti <strong>di</strong> forza o limitazioni imposte al <strong>linguaggio</strong> che abbiamo definito.<br />

5.2.1 Linguaggio accettato dal compilatore<br />

Oltre alla sintassi esposta in Tabella 3.6 in <strong>un</strong> file <strong>di</strong> specifica COWSlite è possibile<br />

aggi<strong>un</strong>gere dei commenti che vengono ignorati in fase <strong>di</strong> compilazione. Per fare ciò è<br />

sufficiente racchiudere il commento fra i due delimitatori /* e */, come si fa con altri<br />

linguaggi <strong>di</strong> programmazione ad esempio C++ e Java. Inoltre il compilatore ignora<br />

105


CAPITOLO 5 Uso <strong>di</strong> COWSlite<br />

eventuali spazi aggi<strong>un</strong>tivi, tabulazioni e ritorno a capo che possono essere inseriti <strong>per</strong><br />

migliorare la leggibilità del programma originale.<br />

5.2.2 Linee guida <strong>per</strong> la scrittura e la compilazione dei file<br />

COWSlite<br />

Per scrivere dei programmi eseguibili in COWSlite è necessario seguire alc<strong>un</strong>e linee<br />

guida generali.<br />

Dal momento che non sono definiti meto<strong>di</strong> <strong>di</strong> <strong>di</strong>scovery <strong>di</strong> <strong>un</strong> <strong>servizi</strong>o, <strong>per</strong> poter<br />

ottenere il WSDL <strong>di</strong> <strong>un</strong> <strong>servizi</strong>o che si vuole utilizzare è necessario specificare l’URL<br />

esatto da cui è possibile re<strong>per</strong>ire il WSDL.<br />

Se è necessario scrivere due o più <strong>servizi</strong> che devono com<strong>un</strong>icare tra loro, come ad<br />

esempio dei <strong>servizi</strong> inter<strong>di</strong>pendenti, dei <strong>servizi</strong> correlati oppure dei <strong>servizi</strong> da eseguire<br />

sullo stesso host con la stessa <strong>di</strong>rectory <strong>di</strong> esecuzione, e questi non sono già presenti,<br />

è necessario tener conto <strong>di</strong> dove verrà generato il WSDL dei <strong>servizi</strong> utilizzati in modo<br />

da poter specificare l’URL <strong>per</strong> in<strong>di</strong>viduarli.<br />

Per far questo è necessario tener presente che:<br />

• Deve essere conosciuto il nome, o l’in<strong>di</strong>rizzo IP, dell’host che ospiterà il <strong>servizi</strong>o,<br />

nonché la porta <strong>di</strong> com<strong>un</strong>icazione usata se <strong>di</strong>versa dalla 80 (standard HTTP)<br />

• Deve essere specificata la <strong>di</strong>rectory che conterrà i <strong>servizi</strong> esposti.<br />

• Il nome del <strong>servizi</strong>o che verrà generato sarà il nome che è stato assegnato al<br />

<strong>servizi</strong>o COWSlite da interrogare con l’aggi<strong>un</strong>ta del suffisso Service.<br />

• Il <strong>per</strong>corso esatto in cui risiede il WSDL. Se il server <strong>di</strong> esecuzione è SAS (S<strong>un</strong><br />

Application Server) oppure Glassfish il WSDL si ottiene aggi<strong>un</strong>gendo al nome<br />

del <strong>servizi</strong>o (il partner COWSlite) ‘?wsdl’.<br />

In questo modo l’URL risultante <strong>per</strong> invocare <strong>un</strong> altro <strong>servizi</strong>o COWSlite è del tipo:<br />

http://host:porta/nomeprogetto/nomeServizioSerice?wsdl<br />

106


5.3 Caso <strong>di</strong> stu<strong>di</strong>o<br />

Il nome progetto è importante <strong>per</strong>ché è quello che deve essere fornito al batch <strong>di</strong><br />

generazione del file .war e che verrà utilizzato anche come nome da dare al pacchetto<br />

WAR da creare.<br />

5.3 Caso <strong>di</strong> stu<strong>di</strong>o<br />

Prima <strong>di</strong> addentrarci in <strong>un</strong> esempio vero e proprio dobbiamo fare alc<strong>un</strong>e considerazioni<br />

sulla natura dei <strong>servizi</strong> <strong>web</strong>. Un <strong>servizi</strong>o <strong>web</strong> non ha <strong>un</strong>’interfaccia che possa essere<br />

interrogata <strong>di</strong>rettamente, non è user-friendly, quin<strong>di</strong> non è facile e nemmeno possibile<br />

riuscire a far vedere esattamente come si comporta <strong>un</strong>a volta messo in f<strong>un</strong>zione,<br />

ma possiamo limitarci solo a testarlo come se fosse <strong>un</strong>a scatola nera, cioè dandogli<br />

<strong>un</strong> input <strong>per</strong> poi andare a recu<strong>per</strong>are l’output prodotto, sempre che questo <strong>servizi</strong>o<br />

fornisca <strong>un</strong> qualche tipo <strong>di</strong> output.<br />

Quin<strong>di</strong> analizzeremo in maniera più accurata la parte relativa alla compilazione e<br />

al co<strong>di</strong>ce prodotto, <strong>per</strong>ché questo è <strong>un</strong> output che possiamo verificare e ci limiteremo<br />

a verificare il f<strong>un</strong>zionamento dell’esempio in <strong>base</strong> alla risposta fornitaci.<br />

Per facilitare il compito della verifica del <strong>servizi</strong>o abbiamo realizzato <strong>un</strong>a sempli-<br />

cissima applicazione <strong>web</strong> che consiste in <strong>un</strong> <strong>servizi</strong>o <strong>web</strong> che accetta <strong>un</strong> input e scrive<br />

quello che riceve su <strong>un</strong> file <strong>di</strong> log. Chiameremo il <strong>servizi</strong>o in questione dataLogService<br />

e fra le o<strong>per</strong>azioni esposte utilizzeremo logInfo <strong>per</strong> scrivere l’output voluto sul file<br />

WS_COWS.log all’interno dell’application server. Il <strong>servizi</strong>o <strong>web</strong>, <strong>per</strong> semplicità, è<br />

stato realizzato con l’IDE 1 utilizzato <strong>per</strong> lo sviluppo del progetto.<br />

Ripren<strong>di</strong>amo <strong>un</strong>o degli esempi che abbiamo già trattato nel Paragrafo 3.3, sce-<br />

gliamo quello relativo alle istanze e alla correlazione dei messaggi. Pren<strong>di</strong>amo questo<br />

esempio <strong>per</strong>ché il co<strong>di</strong>ce prodotto non è troppo l<strong>un</strong>go e al tempo stesso è interes-<br />

sante in quanto affronta vari aspetti del <strong>linguaggio</strong>. Infine mo<strong>di</strong>fichiamo l’esempio in<br />

modo da poter mandare <strong>un</strong> messaggio contenente <strong>un</strong>a certa informazione al <strong>servizi</strong>o<br />

<strong>di</strong> log che abbiamo messo in ascolto. Il file che andremo a compilare è riportato in<br />

Tabella 5.4.<br />

1 Integrated Development Environment<br />

107


CAPITOLO 5 Uso <strong>di</strong> COWSlite<br />

dec{<br />

srv : partner srv "o1"<br />

"http://localhost:8080/test/srvService?WSDL";<br />

srv2: partner srv "o2"<br />

"http://localhost:8080/test/srvService?WSDL";<br />

log: partner log "logInfo"<br />

"http://localhost:8080/cowsTest/dataLogService?WSDL";<br />

}<br />

service {<br />

[Xid:var(String);Xp:var(String);Xnum:var(int);<br />

Yp:var(String);Ynum:var(int);res:var(int);]<br />

?("srv","o1",).?("srv","o2",).<br />

res:=Xnum+Ynum.!(log,"logInfo",)<br />

}<br />

once service {<br />

|(<br />

|(!(srv,"o1",),!(srv,"o1",)),<br />

!(srv2,"o2",)<br />

)<br />

}<br />

Tabella 5.4: File COWSlite da compilare<br />

Come si può notare rispetto al co<strong>di</strong>ce del <strong>servizi</strong>o esposto nel Paragrafo 3.3 è stato<br />

aggi<strong>un</strong>ta la definizione <strong>di</strong> <strong>un</strong> partner che corrisponde al sito in cui si trova il <strong>servizi</strong>o<br />

<strong>di</strong> log ed è stata mo<strong>di</strong>ficata la definizione del <strong>servizi</strong>o principale srv aggi<strong>un</strong>gendo al<br />

termine della computazione <strong>un</strong>a assegnazione e l’invocazione del <strong>servizi</strong>o <strong>di</strong> log al<br />

quale viene inviato il risultato della assegnazione.<br />

Si esegue la compilazione del file che chiameremo caseStudy.cw <strong>per</strong> mezzo dello<br />

script cwc con il seguente comando:<br />

cwc -p tesi.cap5 caseStudy.cw<br />

Questo comando generato all’interno delle cartella build, la struttura <strong>di</strong> cartelle in-<br />

<strong>di</strong>cata dal parametro package nella quale sono contenuti i due file Java srv.java e<br />

client1.java contenenti rispettivamente il <strong>servizi</strong>o principale e quello <strong>di</strong> invocazione.<br />

108<br />

Analizziamo adesso il contenuto del file srv.java riportato <strong>di</strong> seguito.


5.3 Caso <strong>di</strong> stu<strong>di</strong>o<br />

package t e s i . cap5 ;<br />

import javax . jws . Oneway ;<br />

import javax . jws . WebMethod ;<br />

import javax . jws . WebParam ;<br />

import javax . jws . WebService ;<br />

import java . u t i l . ∗ ;<br />

import cows . engine . ∗ ;<br />

@WebService<br />

public class srv {<br />

ServiceSpace mainSS ;<br />

DataSpace mainDS ;<br />

Com<strong>un</strong>icationSystem CS ;<br />

Partner l o c P a r t n e r ;<br />

// C o s t r u t t o r e d e l WS<br />

public srv ( ) {<br />

/∗ Crea i l s e r v i z i o i s t a n z i a n d o i l DataSpace P r i n c i p a l e<br />

e i l ServiceSpace ed esegue i l primo processo d e l s e r v i z i o ∗/<br />

/∗ I n i z i a l i z z a g l i s p a z i ∗/<br />

mainSS = new ServiceSpace ( ) ;<br />

CS = new Com<strong>un</strong>icationSystem ( mainSS ) ;<br />

mainDS = new DataSpace (CS ) ;<br />

// I d e n t i f i c a i l Partner f i t t i z i o <strong>per</strong> l o c a l<br />

l o c P a r t n e r = mainSS . getLocalPartner ( ) ;<br />

mainDS . addVariabile (new WsDescriptor ( " srv " , new Partner ( null ,<br />

" http : / / l o c a l h o s t :8080/ t e s t / s r v S e r v i c e ?WSDL" ) , "o1" , null ) ) ;<br />

mainDS . addVariabile (new WsDescriptor ( " srv2 " , new Partner ( null ,<br />

" http : / / l o c a l h o s t :8080/ t e s t / s r v S e r v i c e ?WSDL" ) , "o2" , null ) ) ;<br />

mainDS . addVariabile (new WsDescriptor ( " l o g " , new Partner ( null ,<br />

" http : / / l o c a l h o s t :8080/ cowsTest / dataLogService ?WSDL" ) ,<br />

109


" l o g I n f o " , null ) ) ;<br />

/∗ Crea i p r o c e s s i d e l s e r v i z i o . ∗/<br />

CowsProcess f i r s t P r o c e s s = S e r v i c e C r e a t o r ( ) ;<br />

/∗ Esegue i l primo Processo ∗/<br />

}<br />

f i r s t P r o c e s s . s t a r t ( ) ;<br />

CS . p r i n t S t a t u s ( ) ;<br />

@WebMethod<br />

@Oneway<br />

public void o2 ( S t r i n g Xid , S t r i n g Yp, int Ynum) {<br />

}<br />

try {<br />

WOVect v = new WOVect ( 3 ) ;<br />

v . insVar (new WOVar( null , Xid ) ) ;<br />

v . insVar (new WOVar( null , Yp ) ) ;<br />

v . insVar (new WOVar( null , Ynum ) ) ;<br />

CAPITOLO 5 Uso <strong>di</strong> COWSlite<br />

CS . r e q u e s t (new WsDescriptor ( locPartner , "o2" , v ) ) ;<br />

} catch ( DataCoreException ex ) {<br />

}<br />

@WebMethod<br />

@Oneway<br />

ex . printStackTrace ( ) ;<br />

public void o1 ( S t r i n g Xid , S t r i n g Xp, int Xnum) {<br />

110<br />

try {<br />

WOVect v = new WOVect ( 3 ) ;<br />

v . insVar (new WOVar( null , Xid ) ) ;<br />

v . insVar (new WOVar( null , Xp ) ) ;<br />

v . insVar (new WOVar( null , Xnum ) ) ;<br />

i f ( ! CS . r e q u e s t (new WsDescriptor ( locPartner , "o1" , v ) ) ) {<br />

}<br />

S e r v i c e C r e a t o r ( ) . s t a r t ( ) ;


5.3 Caso <strong>di</strong> stu<strong>di</strong>o<br />

}<br />

} catch ( DataCoreException ex ) {<br />

}<br />

ex . printStackTrace ( ) ;<br />

private CowsProcess S e r v i c e C r e a t o r ( ) {<br />

DataSpace ds ; /∗ modello d e l ds <strong>per</strong> i l s e r v i z i o ∗/<br />

ds = new DataSpace (mainDS ) ;<br />

/∗ DataSpace D e l i m i t a t i o n ∗/<br />

DataSpace ds1 = new DataSpace ( ds ) ;<br />

ds1 . addVariabile (new WOVar( "Xid" , new S t r i n g ( ) . g e t C l a s s ( ) ) ) ;<br />

ds1 . addVariabile (new WOVar( "Xp" , new S t r i n g ( ) . g e t C l a s s ( ) ) ) ;<br />

ds1 . addVariabile (new WOVar( "Xnum" , new I n t e g e r ( 0 ) . g e t C l a s s ( ) ) ) ;<br />

ds1 . addVariabile (new WOVar( "Yp" , new S t r i n g ( ) . g e t C l a s s ( ) ) ) ;<br />

ds1 . addVariabile (new WOVar( "Ynum" , new I n t e g e r ( 0 ) . g e t C l a s s ( ) ) ) ;<br />

ds1 . addVariabile (new WOVar( " r e s " , new I n t e g e r ( 0 ) . g e t C l a s s ( ) ) ) ;<br />

/∗ Invoke ∗/<br />

CowsProcess cp5 = null ;<br />

try {<br />

WOVect v5 = new WOVect ( 1 ) ;<br />

v5 . insVar ( (WOVar) ds1 . f i n d V a r i a b i l e ( " r e s " ) ) ;<br />

WsDescriptor wd5 = ds1 . findWsDVar ( " l o g " ) ;<br />

cp5 = new InvokeProcess (wd5 , v5 , ds1 ) ;<br />

} catch ( DataCoreException dce ) {<br />

}<br />

/∗ Assign ∗/<br />

CowsProcess cp4 = null ;<br />

cp4 = new Assign4 ( cp5 , ds1 ) ;<br />

/∗ Receive ∗/<br />

CowsProcess cp3 = null ;<br />

try {<br />

WOVect v3 = new WOVect ( 3 ) ;<br />

v3 . insVar ( (WOVar) ds1 . f i n d V a r i a b i l e ( "Xid" ) ) ;<br />

111


v3 . insVar ( (WOVar) ds1 . f i n d V a r i a b i l e ( "Yp" ) ) ;<br />

CAPITOLO 5 Uso <strong>di</strong> COWSlite<br />

v3 . insVar ( (WOVar) ds1 . f i n d V a r i a b i l e ( "Ynum" ) ) ;<br />

WsDescriptor wd3 = new WsDescriptor ( locPartner , "o2" , v3 ) ;<br />

wd3 . setContinuazione ( cp4 ) ;<br />

cp3 = new ReceiveProcess (wd3 , ds1 ) ;<br />

} catch ( DataCoreException dce ) {<br />

}<br />

/∗ Receive ∗/<br />

CowsProcess cp2 = null ;<br />

try {<br />

WOVect v2 = new WOVect ( 3 ) ;<br />

v2 . insVar ( (WOVar) ds1 . f i n d V a r i a b i l e ( "Xid" ) ) ;<br />

v2 . insVar ( (WOVar) ds1 . f i n d V a r i a b i l e ( "Xp" ) ) ;<br />

v2 . insVar ( (WOVar) ds1 . f i n d V a r i a b i l e ( "Xnum" ) ) ;<br />

WsDescriptor wd2 = new WsDescriptor ( locPartner , "o1" , v2 ) ;<br />

wd2 . setContinuazione ( cp3 ) ;<br />

cp2 = new ReceiveProcess (wd2 , ds1 ) ;<br />

} catch ( DataCoreException dce ) {<br />

}<br />

/∗ D e l i m i t a t i o n ∗/<br />

}<br />

CowsProcess cp1 = null ;<br />

cp1 = new D e l i m i t a t i o n P r o c e s s ( cp2 , ds1 ) ;<br />

return cp1 ;<br />

}<br />

class Assign4 extends AssignProcess {<br />

public Assign4 ( CowsProcess succ , DataSpace cds ){<br />

}<br />

su<strong>per</strong> ( succ , cds ) ;<br />

public void execute ( ) throws CowsException {<br />

112<br />

WOVar r e s = (WOVar) this . getWds ( ) . f i n d V a r i a b i l e ( " r e s " ) ;<br />

i f ( r e s==null ) {


5.3 Caso <strong>di</strong> stu<strong>di</strong>o<br />

}<br />

r e s = new WOVar( " r e s " ) ;<br />

this . getWds ( ) . a ddVariabile ( r e s ) ;<br />

WOVar Xnum = (WOVar) this . getWds ( ) . f i n d V a r i a b i l e ( "Xnum" ) ;<br />

WOVar Ynum = (WOVar) this . getWds ( ) . f i n d V a r i a b i l e ( "Ynum" ) ;<br />

r e s . setValue (Xnum. add (Ynum ) ) ;<br />

//Come ultimo a v v i a l a c o n t i n u a z i o n e<br />

}<br />

cont . s t a r t ( ) ;<br />

public Object c l o n e ( ) {<br />

}<br />

}<br />

return new Assign4 ( ( CowsProcess ) cont . c l o n e ( ) , this . getWds ( ) ) ;<br />

Innanzitutto il file contiene al suo interno due classi, <strong>un</strong>a pubblica relativa al<br />

<strong>servizi</strong>o ed <strong>un</strong>a privata corrispondente al’istruzione <strong>di</strong> assegnazione definita nel co<strong>di</strong>ce.<br />

La classe principale è sud<strong>di</strong>visibile in tre blocchi, il primo corrisponde al costruttore<br />

della classe, il secondo contiene i meto<strong>di</strong> corrispondenti alle o<strong>per</strong>azioni esposte dal<br />

<strong>servizi</strong>o e l’ultimo è il metodo ServiceCreator() che contiene la descrizione della<br />

logica del <strong>servizi</strong>o.<br />

Nel costruttore, oltre alle istruzioni necessarie <strong>per</strong> inizializzare i componenti del-<br />

l’engine (DataSpace e ServiceSpace), vengono inserite all’interno del DataSpace appe-<br />

na creato le variabili presenti all’interno del blocco <strong>di</strong>chiarazioni del file COWSlite<br />

infatti troviamo tre variabili <strong>di</strong> tipo WsDescriptor che rappresentano le due o<strong>per</strong>a-<br />

zioni del <strong>servizi</strong>o principale srv, che serviranno al <strong>servizi</strong>o client, e l’endpoint del<br />

<strong>servizi</strong>o <strong>di</strong> log.<br />

Le o<strong>per</strong>azioni del <strong>servizi</strong>o sono esposte da due meto<strong>di</strong> contrassegnati con lo stes-<br />

so nome presente nel file e adornati con le keyword @WebMethod e @Oneway come<br />

richiesto dalle specifiche JAX-WS. Il corpo <strong>di</strong> tali meto<strong>di</strong> è molto simile, entrambi<br />

sono composti da <strong>un</strong>a parte iniziale dove sono definiti e richiamati gli oggetti cor-<br />

rispondenti alle variabili che corrispondono ai parametri dell’o<strong>per</strong>azione esposta dal<br />

113


CAPITOLO 5 Uso <strong>di</strong> COWSlite<br />

<strong>servizi</strong>o <strong>web</strong> e che verranno poi inserite come parte della richiesta nel ServiceSpace.<br />

L’<strong>un</strong>ica <strong>di</strong>fferenza fra i due meto<strong>di</strong> è che il metodo o1 ha la facoltà <strong>di</strong> avviare <strong>un</strong><br />

nuovo processo nel caso in cui non ci siano più processi attivi <strong>di</strong>sponibili, mentre il<br />

metodo o2 non può farlo. Questo è coerente con la logica del processo, poiché o1 è<br />

il metodo iniziale e si può com<strong>un</strong>icare con o2 solo se c’è già <strong>un</strong> istanza avviata del<br />

<strong>servizi</strong>o.<br />

Infine il metodo ServiceCreator() contiene all’inizio la definizione del Servi-<br />

ceSpace generato dalla delimitazione e poi esattamente in senso inverso le 5 azioni<br />

definite nel file: invocazione del log, assegnazione <strong>di</strong> res, ricezione dell’o<strong>per</strong>azione o2,<br />

ricezione dell’o<strong>per</strong>azione o1 e delimitazione. Da notare che l’assegnazione non fa altro<br />

che istanziare la classe Assign4 che troviamo all’interno del file e nella quale è definita<br />

l’assegnazione e la valutazione dell’espressione.<br />

A questo p<strong>un</strong>to non resta che provare il co<strong>di</strong>ce generato dal compilatore CO-<br />

WSlite. Per testare il <strong>servizi</strong>o creiamo il pacchetto <strong>di</strong> <strong>di</strong>stribuzione con lo script<br />

build:<br />

build test tesi\\cap5<br />

Otteniamo così il file test.war contenente i <strong>servizi</strong> da <strong>di</strong>stribuire sull’application<br />

server.<br />

Una volta <strong>di</strong>stribuito il <strong>servizi</strong>o sull’application server è sufficiente chiamare<br />

<strong>un</strong>’o<strong>per</strong>azione del <strong>servizi</strong>o oppure il file WSDL <strong>per</strong> avviarne l’esecuzione.<br />

Quello che ci aspettiamo <strong>di</strong> trovare nel file <strong>di</strong> log è il contenuto della variabile res<br />

dopo l’assegnazione cioè Xnum+Ynum che nel caso dell’esempio deve essere uguale a<br />

2 + 1 = 3. Guardando il file <strong>di</strong> log generato, che è in formato XML, troviamo infatti:<br />

<br />

<br />

<br />

<br />

114<br />

2010−03−20 T10:26:52<br />

1269077212140


5.3 Caso <strong>di</strong> stu<strong>di</strong>o<br />

298<br />

cows . t e s t<br />

INFO<br />

cows . cowstest . dataLog<br />

&l t ; i n i t&gt ;<br />

11<br />

Log Avviato !<br />

<br />

<br />

2010−03−20 T10:27:27<br />

1269077247140<br />

350<br />

cows . t e s t<br />

INFO<br />

cows . cowstest . dataLog<br />

l o g I n f o<br />

20<br />

3<br />

<br />

Dove notiamo che il primo record è l’avvio del logger e il secondo è stato inserito con<br />

il metodo logInfo che ha scritto come messaggio 3 all’interno del log, proprio come<br />

ci aspettavamo.<br />

Possiamo quin<strong>di</strong> dedurre che il <strong>servizi</strong>o COWSlite ha eseguito correttamente<br />

il suo compito. Naturalmente ripetendo il test si ottiene sempre lo stesso risultato.<br />

L’<strong>un</strong>ica incognita è l’or<strong>di</strong>ne con cui sono eseguite le tre richieste <strong>di</strong> <strong>servizi</strong>o fatte dal-<br />

l’istanza <strong>di</strong> client1, <strong>per</strong>ché tale or<strong>di</strong>ne <strong>di</strong>pende da come le richieste vengono eseguite<br />

dal gestore dei thread.<br />

Volendo potremmo simulare <strong>un</strong> or<strong>di</strong>ne specifico sfruttando <strong>un</strong>a caratteristica dei<br />

<strong>servizi</strong> compilati sugli application server Java. Con SAS e Glassfish <strong>un</strong>a volta installa-<br />

to <strong>un</strong> <strong>servizi</strong>o è possibile, solo sulla macchina che esegue l’application server, accedere<br />

ad <strong>un</strong>a particolare pagina <strong>web</strong> che <strong>per</strong>mette il test del <strong>servizi</strong>o <strong>web</strong>. Questo si può<br />

115


CAPITOLO 5 Uso <strong>di</strong> COWSlite<br />

Figura 5.1: Test dell’o<strong>per</strong>azione con S<strong>un</strong> Applicatioin Server<br />

fare semplicemente con <strong>un</strong> browser, richiamando il <strong>servizi</strong>o <strong>web</strong> tramite l’URL che<br />

lo in<strong>di</strong>vidua e aggi<strong>un</strong>gendo il parametro tester. Nel nostro caso accedendo all’URL<br />

http://localhost:8080/test/srvService?Tester si ottiene la pagina mostrata in<br />

Figura 5.1.<br />

Dalla pagina <strong>web</strong> ottenuta possiamo invocare <strong>un</strong>a qual<strong>un</strong>que o<strong>per</strong>azione esposta<br />

dal <strong>servizi</strong>o passando i parametri necessari. In questo modo richiamando più volte<br />

la pagina e inserendo i parametri che vogliamo inviare possiamo scegliere noi l’or<strong>di</strong>ne<br />

con cui mandare le richieste al <strong>servizi</strong>o. Questa f<strong>un</strong>zione è molto utile <strong>per</strong> testare il<br />

f<strong>un</strong>zionamento e la corretta istallazione <strong>di</strong> <strong>un</strong> <strong>servizi</strong>o.<br />

116


Capitolo 6<br />

Conclusioni<br />

In questa tesi abbiamo introdotto COWSlite <strong>un</strong> <strong>linguaggio</strong> <strong>di</strong> programmazione <strong>per</strong><br />

<strong>servizi</strong> <strong>web</strong> derivato da <strong>un</strong> <strong>linguaggio</strong> formale, tale da scrivere <strong>servizi</strong> che sod<strong>di</strong>sfi-<br />

no certe proprietà desiderate che sono state precedentemente verificate sul model-<br />

lo del <strong>servizi</strong>o scritto nel formalismo originario, utilizzando meto<strong>di</strong> analitici tramite<br />

strumenti automatici o manuali.<br />

Dopo aver descritto i calcoli <strong>di</strong> processo da cui abbiamo preso sp<strong>un</strong>to (COWS<br />

e µCOWS m ) ed il <strong>linguaggio</strong> che abbiamo implementato, abbiamo osservato che la<br />

sintassi adottata <strong>per</strong> COWSlite presenta numerosi p<strong>un</strong>ti in com<strong>un</strong>e con quella dei<br />

calcoli presi a modello; la notazione utilizzata è rimasta la stessa ed è stato mantenuto<br />

l’approccio algebrico alle istruzioni presente nei calcoli. Questa scelta evidenzia la<br />

somiglianza dei formalismi a scapito della semplicità <strong>di</strong> scrittura <strong>di</strong> <strong>un</strong> programma<br />

usando COWSlite. Le <strong>di</strong>fferenze dal p<strong>un</strong>to <strong>di</strong> vista semantico fra il <strong>linguaggio</strong> e i<br />

calcoli non sono molte e sono soprattutto ristrette alla gestione della valutazione delle<br />

espressioni e all’utilizzo dei partner link. Abbiamo anche motivato le scelte fatte <strong>per</strong><br />

la definizione del <strong>linguaggio</strong> e la sua successiva realizzazione.<br />

Per poter procedere con l’implementazione abbiamo definito <strong>un</strong> insieme <strong>di</strong> tipi <strong>di</strong><br />

dato ed <strong>un</strong> <strong>linguaggio</strong> <strong>di</strong> <strong>base</strong> <strong>per</strong> le espressioni sui valori che né in COWS, né in<br />

µCOWS m sono specificati.<br />

Ma lo sforzo maggiore è stato la progettazione e lo sviluppo dell’infrastruttura<br />

117


CAPITOLO 6 Conclusioni<br />

<strong>per</strong> la gestione delle com<strong>un</strong>icazioni e la descrizione dei processi che ha portato alla<br />

creazione <strong>di</strong> <strong>un</strong> motore <strong>per</strong> coa<strong>di</strong>uvare l’esecuzione delle istruzioni.<br />

Poiché COWSlite deve esporre e colloquiare con <strong>servizi</strong> <strong>web</strong> reali, mentre i <strong>servizi</strong><br />

<strong>web</strong> descritti me<strong>di</strong>ante COWS sono <strong>servizi</strong> astratti, in fase <strong>di</strong> progettazione abbiamo<br />

dovuto tenere conto <strong>di</strong> numerosi vincoli che si ri<strong>per</strong>cuotono nell’implementazione e<br />

nell’utilizzo. Inoltre, <strong>per</strong> poter realizzare <strong>un</strong> <strong>linguaggio</strong> <strong>di</strong> programmazione che collo-<br />

qui con <strong>servizi</strong> scritti nei linguaggi più vari è stato importante cercare <strong>di</strong> mantenere la<br />

compatibilità con gli standard (XML,WSDL, XSD, ...), ricordando che <strong>per</strong> ottenere<br />

tale compatibilità è spesso necessario utilizzare meto<strong>di</strong> che siano più semplici possi-<br />

bili e ricondursi ad <strong>un</strong> insieme minimo <strong>di</strong> dati che siano com<strong>un</strong>i a tutti. Anche se le<br />

caratteristiche e le numerose API che Java possiede sono state <strong>di</strong> notevole aiuto in<br />

questo processo, ci sono volute molte ore <strong>di</strong> lavoro <strong>per</strong> implementare e testare le varie<br />

parti.<br />

Il compilatore che deve produrre la descrizione in Java del file <strong>di</strong> specifica CO-<br />

WSlite è a sua volta scritto in Java ed è stato sfruttato il framework SableCC <strong>per</strong><br />

la produzione del riconoscitore grammaticale in modo da semplificare lo sviluppo del<br />

software e ottenere del co<strong>di</strong>ce che garantisca il corretto riconoscimento del linguag-<br />

gio. SableCC oltre a velocizzare la scrittura del compilatore, ne semplifica anche la<br />

manutenzione; <strong>per</strong> ogni aggi<strong>un</strong>ta o mo<strong>di</strong>fica della grammatica sarà quin<strong>di</strong> sufficiente<br />

ricompilarne il progetto <strong>per</strong> ottenere <strong>un</strong>a nuova serie <strong>di</strong> classi; il nome della classe che<br />

rappresenta l’attraversatore dell’albero AST è sempre lo stesso; quin<strong>di</strong>, a meno che<br />

non ci siano state mo<strong>di</strong>fiche sostanziali alla grammatica (eliminazione <strong>di</strong> produzioni<br />

o parte <strong>di</strong> esse), la parte già scritta non dovrebbe generare errori.<br />

Una prerogativa del nostro lavoro è stata <strong>di</strong> non usare alc<strong>un</strong>a libreria o API che<br />

non sia <strong>di</strong>stribuita con Java. Infatti <strong>per</strong> il f<strong>un</strong>zionamento dei <strong>servizi</strong> creati non è<br />

necessario installare alc<strong>un</strong> plug-in sull’application server, ma è sufficiente ri<strong>di</strong>stribuire<br />

insieme alle classi ottenute solo il motore <strong>di</strong> esecuzione, che occupa poche centinaia<br />

<strong>di</strong> kb.<br />

118<br />

Come abbiamo già evidenziato precedentemente in questi ultimi anni è molto


sentita la necessità <strong>di</strong> formulare calcoli <strong>per</strong> i <strong>servizi</strong> <strong>web</strong> che abbiano delle implemen-<br />

tazioni reali tali da <strong>per</strong>mettere <strong>di</strong> eseguire prove e misure sul co<strong>di</strong>ce scritto. Ci sono<br />

<strong>di</strong>versi esempi <strong>di</strong> altre <strong>un</strong>iversità italiane che si muovono in questa <strong>di</strong>rezione e tra<br />

i tanti progetti realizzati possiamo citare Pi-Duce [11], Jolie [32], JSCL [15], jCa-<br />

SPiS [7]. Ogn<strong>un</strong>o <strong>di</strong> questi linguaggi implementa <strong>un</strong> calcolo <strong>per</strong> l’orchestrazione <strong>di</strong><br />

<strong>servizi</strong>. Pi-Duce e JSCL, che sono entrambi derivati da π-calculus, non sono nati con<br />

il chiaro intento <strong>di</strong> <strong>di</strong>alogare con <strong>servizi</strong> <strong>web</strong>, ma questa caratteristica è stata inse-<br />

rita nelle implementazioni, mentre Jolie e jCaSPiS sono stati progettati tenendo in<br />

considerazione questo aspetto. Ad esclusione <strong>di</strong> Pi-Duce che è scritto in C#, gli altri<br />

linguaggi sono tutti implementati in Java. Molti sono i concetti com<strong>un</strong>i fra questi<br />

linguaggi, ad esempio tutti sono stati costruiti prendono in considerazione lo stesso<br />

insieme <strong>di</strong> primitive <strong>di</strong> com<strong>un</strong>icazione, ma le <strong>di</strong>verse scelte fatte li portano ad essere<br />

tutti <strong>di</strong>fferenti fra loro e orientati a modellare e stu<strong>di</strong>are aspetti <strong>di</strong>versi dell’interazio-<br />

ne fra <strong>servizi</strong> e della loro orchestrazione. È interessante notare che JSCL, jCaSPiS e<br />

Jolie sono linguaggi interpretati, mentre Pi-Duce è più simile a COWSlite poiché<br />

viene prodotto del co<strong>di</strong>ce compilabile.<br />

Il compilatore presentato in questo lavoro è solo <strong>un</strong> prototipo che potrebbe evol-<br />

vere in modo da ottenere <strong>un</strong> implementazione <strong>di</strong> COWS completa sotto tutti gli<br />

aspetti. Il motore <strong>di</strong> esecuzione può essere esteso in modo da implementare i costrutti<br />

mancanti rispetto a COWS, semplicemente aggi<strong>un</strong>gendo due classi che implementino<br />

il comportamento dei due o<strong>per</strong>atori mancanti in µCOWS m (kill e protection). Allo<br />

stesso tempo sarebbe opport<strong>un</strong>o aggi<strong>un</strong>gere nuovi tipi <strong>di</strong> dato, ad esempio i booleani,<br />

rendendo così più semplice simulare il costrutto if tipico dei linguaggi <strong>di</strong> program-<br />

mazione. Poiché la classe <strong>di</strong> <strong>base</strong> delle variabili è costruita tramite generics, non sarà<br />

<strong>di</strong>fficile aggi<strong>un</strong>gere nuovi tipi <strong>di</strong> dato; le parti principali su cui intervenire saranno la<br />

generazione <strong>di</strong> <strong>un</strong>a nuova grammatica, estendendo il blocco espressione con le nuove<br />

produzioni, e la mo<strong>di</strong>fica delle f<strong>un</strong>zioni che producono il co<strong>di</strong>ce delle classi Assign.<br />

Un altro aspetto che potrebbe essere oggetto <strong>di</strong> mo<strong>di</strong>fica <strong>per</strong> ottenere <strong>un</strong> comporta-<br />

mento più vicino a COWS riguarda la modalità <strong>di</strong> selezione delle attività <strong>di</strong> ricezione;<br />

119


CAPITOLO 6 Conclusioni<br />

cioè selezionare fra tutte le attività <strong>di</strong> ricezione coerenti con la richiesta quella più<br />

compatibile e non <strong>un</strong>a qual<strong>un</strong>que in modo non deterministico; <strong>per</strong> fare ciò sarà neces-<br />

sario agire sulle f<strong>un</strong>zioni <strong>di</strong> match in modo da definire <strong>un</strong>a priorità fra le alternative<br />

al fine <strong>di</strong> scegliere la migliore fra tutte quelle possibili. Infine il compilatore potrebbe<br />

essere mo<strong>di</strong>ficato in modo da non rendere obbligatoria la definizione dei partner <strong>per</strong><br />

quei <strong>servizi</strong> che sono definiti all’interno dello stesso file facendo in modo che sia il<br />

compilatore stesso a risolvere il nome.<br />

120


Appen<strong>di</strong>ce A<br />

Grammatica<br />

A.1 Grammatica COWSlite <strong>per</strong> SableCC<br />

Di seguito è riportata le definizione secondo SableCC della grammatica che è stata<br />

costruita <strong>per</strong> implemetare il <strong>linguaggio</strong> COWSlite.<br />

// Grammatica <strong>per</strong> COWSlite. Ver. 1.0.0<br />

// Grammatica ridotta <strong>per</strong> il <strong>linguaggio</strong> COWS<br />

// usando la sintassi <strong>per</strong> SableCC.<br />

Package mcows.grammar;<br />

Hel<strong>per</strong>s<br />

all = [0 .. 127];<br />

<strong>di</strong>git = [’0’ .. ’9’];<br />

nonzero<strong>di</strong>git = [<strong>di</strong>git -’0’];<br />

non<strong>di</strong>git = [’_’ + [[’a’ .. ’z’]+[’A’ .. ’Z’]]];<br />

cr = 13; //Carriage return<br />

lf = 10; //Line feed<br />

tab = 9; //Tab char<br />

not_star = [all - ’*’];<br />

121


not_star_slash = [not_star - ’/’];<br />

s_char = [all - [’"’ + [’\’ + [10 + 13]]]];<br />

s_char_seq = s_char+;<br />

// Definizione dei Token appartenenti al <strong>linguaggio</strong>.<br />

Tokens<br />

dot = ’.’;<br />

comma = ’,’;<br />

l_par = ’(’;<br />

r_par = ’)’;<br />

l_qpar = ’[’;<br />

r_qpar = ’]’;<br />

l_gpar = ’{’;<br />

r_gpar = ’}’;<br />

plus = ’+’;<br />

minus = ’-’;<br />

mult = ’*’;<br />

<strong>di</strong>v = ’/’;<br />

semicolon = ’;’;<br />

colon = ’:’;<br />

equal = ’=’;<br />

lesser = ’’;<br />

mod = ’mod’;<br />

elev =’^’;<br />

non = ’not’;<br />

and = ’and’;<br />

or = ’or’;<br />

122<br />

CAPITOLO A Grammatica


A.1 Grammatica COWSlite <strong>per</strong> SableCC<br />

// Keyword non appartenenti originariamente al <strong>linguaggio</strong><br />

dec = ’dec’;<br />

service = ’service’;<br />

once = ’once’;<br />

var = ’var’;<br />

killerlabel = ’killer’;<br />

label = ’lab’;<br />

partner = ’partner’;<br />

// Keyword <strong>per</strong> i tipi <strong>di</strong> dato.<br />

string= ’String’;<br />

int=’int’;<br />

vect=’vect’;<br />

// Keyword delle azioni COWS<br />

receive = ’?’;<br />

parallel = ’|’;<br />

invoke = ’!’;<br />

kill = ’kill’;<br />

assign = ’:=’;<br />

nil = ’nil’;<br />

// identificatori, stringhe, numeri, spazi e comenti.<br />

ide = non<strong>di</strong>git (<strong>di</strong>git | non<strong>di</strong>git)*;<br />

string_literal = ’"’ s_char_seq? ’"’;<br />

number = nonzero<strong>di</strong>git <strong>di</strong>git*;<br />

blank = ( cr | lf | tab | ’ ’)+;<br />

comment = ’/*’ not_star* ’*’+<br />

(not_star_slash not_star* ’*’+)* ’/’;<br />

123


Insieme dei token da ignorare durante il parsing.<br />

Ignored Tokens<br />

blank,<br />

comment;<br />

// Insieme delle produzioni che rappresentano<br />

// il <strong>linguaggio</strong> COWS.<br />

Productions<br />

//Programma<br />

cows = declaration? cows_service+;<br />

//Dichiarazioni - Blocco <strong>di</strong>chiarativo iniziale del<br />

declaration = dec l_gpar variable* r_gpar;<br />

variable = variable_end semicolon;<br />

variable_end = ide colon lab_type;<br />

lab_type = {var} var l_par var_type r_par|<br />

{kill} killerlabel |<br />

{label} label |<br />

CAPITOLO A Grammatica<br />

{partner} partner partner_name o<strong>per</strong>ation_name wsdl_link;<br />

var_type = {string} string |<br />

{int} int |<br />

{vect} vect l_par number r_par;<br />

delimdec = variable; //Alias <strong>per</strong> le <strong>di</strong>chiarazioni<br />

// <strong>di</strong> variabili all’interno della delimitazione<br />

replication = mult; //Alias <strong>per</strong> il prodotto.<br />

//Processi<br />

cows_service = once? service l_gpar prec_process r_gpar;<br />

prec_process = {precedence} l_par process r_par |<br />

124


A.1 Grammatica COWSlite <strong>per</strong> SableCC<br />

{normal} process;<br />

process = {parallel} parallel l_par [left]:prec_process comma<br />

[right]:prec_process r_par |<br />

{replication} replication repetition_time? prec_process |<br />

{delimitation} l_qpar delimdec* r_qpar prec_process |<br />

{invoke} invoke l_par partner_name<br />

[first]:comma o<strong>per</strong>ation_name<br />

[second]:comma invoke_param r_par |<br />

{choice} choice |<br />

{assign} ide assign assignable dot prec_process;<br />

assignable = {expression} expr | {const} const;<br />

choice = {choice} plus r_par [left]:choice comma<br />

[right]:choice l_par|<br />

{nil} nil |<br />

{receive} receive l_par partner_value<br />

[first]:comma o<strong>per</strong>ation_name<br />

[second]:comma receive_param r_par dot prec_process;<br />

//Parametri<br />

repetition_time = l_qpar number r_qpar;<br />

partner_value = value;<br />

partner_name = ide;<br />

o<strong>per</strong>ation_name= string_literal;<br />

receive_param = lesser list_value? greater;<br />

invoke_param = lesser list_value? greater;<br />

list_value = value list_cont*;<br />

list_cont =comma value;<br />

value = {ide} ide | {const} const | {number} number;<br />

const = string_literal;<br />

wsdl_link = string_literal;<br />

125


Espressioni<br />

expr =<br />

{term} term |<br />

{negterm} minus term | {posterm} plus term |<br />

{sum} expr plus term |<br />

{<strong>di</strong>ff} expr minus term ;<br />

term = {fact} fact |<br />

{mult} term mult fact |<br />

{<strong>di</strong>v} term <strong>di</strong>v fact ;<br />

fact = {number} number |<br />

126<br />

{ide} ide |<br />

{precexpr} l_par expr r_par;<br />

CAPITOLO A Grammatica


Appen<strong>di</strong>ce B<br />

Deploy su application server<br />

Gli application server <strong>di</strong> ultima generazione forniscono delle interfacce <strong>di</strong> amministra-<br />

zione molto evolute, non è quin<strong>di</strong> più necessario andare a stu<strong>di</strong>arsi te<strong>di</strong>osi manuali<br />

pieni <strong>di</strong> coman<strong>di</strong>, oppure scorrere riga <strong>per</strong> riga degli interminabili file <strong>di</strong> configurazione.<br />

Per poter mo<strong>di</strong>ficare la configurazione basta accedere alla console <strong>di</strong> amministrazione.<br />

SUN Application Server e Glassfish hanno <strong>un</strong>a console <strong>web</strong> <strong>per</strong> la configurazione.<br />

Basta accede con <strong>un</strong> qual<strong>un</strong>que browser alla pagina http://localhost:4848, immet-<br />

tere le credenziali <strong>di</strong> amministratore <strong>per</strong> accedere alla pagina principale <strong>di</strong> gestione<br />

del server (Figura B.1).<br />

Dalla console <strong>di</strong> amministrazione è possibile gestire tutte le componenti dell’appli-<br />

cation server e controllare lo stato dei componenti: avviarli, arrestarli, riavviarli, ecc.<br />

Da questa console è possibile installare nuovi <strong>servizi</strong> in modo semplice e soprattutto<br />

veloce.<br />

Sulla parte sinistra della finestra troviamo <strong>un</strong>a rappresentazione ad albero <strong>di</strong> tutti<br />

i componenti dell’application server. Delle 5 sezioni in cui sono organizzati tutti i<br />

parametri, quelle che ci interessano <strong>per</strong> la gestione dei <strong>servizi</strong> e la loro <strong>di</strong>stribuzione<br />

sono solo due, le altre servono <strong>per</strong> la configurazione del server, <strong>per</strong> il monitoraggio dello<br />

stato del server e <strong>per</strong> la gestione <strong>di</strong> altri componenti. La prima voce da selezionare è<br />

la sottosezione Web Application nel nodo Applications, come si vede dalla Figura B.2,<br />

dalla quale è possibile gestire il carico e lo scarico delle applicazioni e l’altra è sotto<br />

127


CAPITOLO B Deploy su application server<br />

Figura B.1: Pagina <strong>di</strong> amministrazione dell’application server<br />

la sezione Web Services dalla quale è possibile controllare lo stato <strong>di</strong> f<strong>un</strong>zionamento<br />

<strong>di</strong> ogni <strong>servizi</strong>o <strong>web</strong> installato all’interno dell’appication server.<br />

Per installare <strong>un</strong>a applicazione <strong>web</strong> (come i file WAR generati <strong>per</strong> il nostro pro-<br />

getto) è necessario selezionare il pulsante Deploy... all’interno della pagina <strong>di</strong> ammi-<br />

nistrazione delle applicazioni <strong>web</strong> (visibile in Figura B.2) e seguire il semplice wizard,<br />

composto da due pagine, che ci viene proposto <strong>per</strong> l’installazione dell’applicazione.<br />

Nella prima delle due pagine deve essere inserito il <strong>per</strong>corso dal quale caricare il file<br />

archivio oppure la posizione in cui si trovano i file sorgenti, nella pagina successiva<br />

devono essere inseriti i parametri che verranno utilizzati <strong>per</strong> avviare l’applicazione;<br />

fra questi quelli essenziali sono il nome dell’applicazione e il contesto che corrispon-<br />

dono al nome con cui verrà in<strong>di</strong>cata l’applicazione nel pannello <strong>di</strong> amministrazione e<br />

il <strong>per</strong>corso in cui dovranno essere cercati i <strong>servizi</strong> <strong>web</strong> <strong>un</strong>a volta installati; è possibile<br />

anche in<strong>di</strong>care <strong>un</strong> server <strong>di</strong>verso da quello <strong>di</strong> default nel caso in cui nell’application<br />

server siano definiti più server virtuali. Il resto dei parametri riguardano l’attivazione,<br />

128


Figura B.2: Pagina <strong>di</strong> amministrazione dei <strong>servizi</strong> in esecuzione<br />

alc<strong>un</strong>i controlli da eseguire precedentemente alla fase <strong>di</strong> esecuzione e se precompilare<br />

il co<strong>di</strong>ce oppure no. Terminati questi passi se l’installazione è andata a buon fine la<br />

nuova applicazione sarà presente all’interno della lista delle applicazioni.<br />

L’interfaccia e la modalità da utilizzare <strong>per</strong> il server Glassfish è del tutto analoga.<br />

129


130<br />

CAPITOLO B Deploy su application server


Bibliografia<br />

[1] Simple API for XML (SAX) project site. 2003. http://www.saxproject.org/.<br />

[2] A. Alves, A. Arkin, S. Askary, C. Barreto, B. Bloch, F. Curbera, M. Ford, Y. Go-<br />

land, A. Guízar, N. Kartha, C. Kevin Liu, R. Khalaf, D. König, M. Marin, V. Me-<br />

hta, S. Thatte, D. van der Rijn, P. Yendluri e A. Yiu. Web Services Business<br />

Process Execution Language Version 2.0. Relazione tecnica, 2007. Disponibile<br />

su http://docs.oasis-open.org/wsbpel/2.0/wsbpel-v2.0.html.<br />

[3] Apache Software Fo<strong>un</strong>dation. Apache Geronimo. Disponibile su http://<br />

geronimo.apache.org/.<br />

[4] C. Barreto, V. Bullard, T. Erl, J. Evdemon, D. Jordan, K. Kand, D. König,<br />

S. Moser, R. Stout, R. Ten-Hove, I. Trickovic, D. van der Rijn e A. Yiu. Web<br />

Services Business Process Execution Language Version 2.0 primer. Relazione tec-<br />

nica, 2007. Disponibile su http://docs.oasis-open.org/wsbpel/2.0/Primer/<br />

wsbpel-v2.0-Primer.html.<br />

[5] L. Bettini. Progetto e Realizzazione <strong>di</strong> <strong>un</strong> Linguaggio <strong>di</strong> Programmazione <strong>per</strong><br />

Co<strong>di</strong>ce Mobile. Tesi <strong>di</strong> Laurea, Dipartimento <strong>di</strong> Sistemi e Informatica, Uni-<br />

versità <strong>di</strong> Firenze, 1998. Disponibile su http://music.dsi.<strong>un</strong>ifi.it/thesis/<br />

xklaimthesis.ps.gz.<br />

[6] L. Bettini, V. Bono, R. De Nicola, G. Ferrari, D. Gorla, M. Loreti, E. Moggi,<br />

R. Pugliese, E. Tuosto e B. Venneri. The Klaim Project: Theory and Practice.<br />

131


BIBLIOGRAFIA<br />

In Global Computing: Programming Environments,Languages, Security and Ana-<br />

lysis of Systems, volume 2874 <strong>di</strong> Lecture Notes in Computer Science. Springer,<br />

2003.<br />

[7] L. Bettini, R. De Nicola e M. Loreti. Implementing Session Centered Calculi.<br />

In COORDINATION, volume 5052 <strong>di</strong> Lecture Notes in Computer Science, pp.<br />

17–32. Springer, 2008.<br />

[8] L. Bettini, R. De Nicola e R. Pugliese. KLAVA: a Java package for <strong>di</strong>stributed<br />

and mobile applications. Softw. Pract. Ex<strong>per</strong>., 32(14):1365–1394, 2002.<br />

[9] M. Boreale, R. Br<strong>un</strong>i, L. Caires, R. De Nicola, I. Lanese, M. Loreti, F. Mar-<br />

tins, U. Montanari, A. Ravara, D. Sangiorgi, V. T. Vasconcelos e G. Zavattaro.<br />

SCC: A Service Centered Calculus. In WS-FM, volume 4184 <strong>di</strong> Lecture Notes in<br />

Computer Science, pp. 38–57. Springer, 2006.<br />

[10] G. Br<strong>un</strong>o. Linguaggi formali e compilatori. UTET Libreria, 1992.<br />

[11] S. Carpineti, C. Laneve e L. Padovani. PiDuce - A project for ex<strong>per</strong>imenting<br />

Web services technologies. Sci. Comput. Program., 74(10):777–811, 2009.<br />

[12] E. Christensen, F. Curbera, G. Mere<strong>di</strong>th e S. Weerawarana. Web Services<br />

Description Language (WSDL) 1.1. Relazione tecnica, 2001. Disponibile su<br />

http://www.w3.org/TR/2001/NOTE-wsdl-20010315.<br />

[13] B. Eckel. Thinking in Java (3rd E<strong>di</strong>tion). Prentice Hall Professional Technical<br />

Reference, 2002.<br />

[14] A. Fantechi, S. Gnesi, A. Lapadula, F. Mazzanti, R. Pugliese e F. Tiezzi. A model<br />

132<br />

checking approach for verifying COWS specifications. In Proc. of F<strong>un</strong>damental<br />

Approaches to Software Engineering (FASE’08), volume 4961 <strong>di</strong> Lecture Notes<br />

in Computer Science, pp. 230–245. Springer, 2008.


BIBLIOGRAFIA<br />

[15] G. Ferrari, R. Guanciale e D. Strollo. JSCL: A Middleware for Service Coor<strong>di</strong>na-<br />

tion. In FORTE, volume 4229 <strong>di</strong> Lecture Notes in Computer Science, pp. 46–60.<br />

Springer, 2006.<br />

[16] E. Gagnon. SableCC, An Object-Oriented Compiler Framework. Master’s The-<br />

sis, McGill University, Montreal, Quebec, 1998. Disponilile su http://www.dcs.<br />

gla.ac.uk/~wpc/hi/sablecc-thesis.pdf.<br />

[17] E. Gamma, R. Helm, R. Johnson e J. Vlissides. Design Patterns. Ad<strong>di</strong>son-Wesley<br />

Professional, 1995.<br />

[18] C. Gui<strong>di</strong>, R. Lucchi, R. Gorrieri, N. Busi e G. Zavattaro. SOCK: a calculus for<br />

service oriented computing. In ISOC, volume 4294 <strong>di</strong> Lecture Notes in Computer<br />

Science, pp. 327–338. Springer, 2006.<br />

[19] K. Heather. Web Services Conceptual Architecture (WSCA 1.0). IBM, 2001.<br />

Disponibile su http://www-306.ibm.com/software/solutions/<strong>web</strong>services/<br />

pdf/WSCA.pdf.<br />

[20] A. Le Hors, P. Le Hégaret, L. Wood, G. Nicol, J. Robie, M. Champion<br />

e S. Byrne. The Document Object Model(DOM) Level 2 Core Specifica-<br />

tion. Relazione tecnica, 2000. Disponibile su http://www.w3.org/TR/2000/<br />

REC-DOM-Level-2-Core-20001113/.<br />

[21] java.net. Glassfish. Disponibile su https://glassfish.dev.java.net/.<br />

[22] java.net. JavaCC Home Page. https://javacc.dev.java.net/.<br />

[23] S. C. Johnson. Yacc: Yet Another Compiler-Compiler. Tech. Rep. Computing<br />

Science 32, Bell Laboratories, 1975.<br />

[24] D. Kohlert e A. Gupta. JSR-000224 Java API for XML-Based Web Services<br />

(JAX-WS). Relazione tecnica, 2007. Disponibile su http://jcp.org/en/jsr/<br />

detail?id=224.<br />

133


BIBLIOGRAFIA<br />

[25] A. Lapadula, R. Pugliese e F. Tiezzi. A Calculus for Orchestration of Web<br />

Services. In Proc. of 16th European Symposium on Programming (ESOP’07),<br />

volume 4421 <strong>di</strong> Lecture Notes in Computer Science, pp. 33–47. Springer, 2007.<br />

[26] A. Lapadula, R. Pugliese e F. Tiezzi. Regulating data exchange in service oriented<br />

applications. In Proc. of IPM International Symposium on F<strong>un</strong>damentals of<br />

Software Engineering (FSEN’07), volume 4767 <strong>di</strong> Lecture Notes in Computer<br />

Science, pp. 223–239. Springer, 2007.<br />

[27] M. E. Lesk. Lex - a lexical analyzer generator. Tech. Rep. Computing Science 39,<br />

Bell Laboratories, 1975.<br />

[28] F. Leymann. Web Services Flow Language (WSFL 1.0). Relazione tecnica. Dispo-<br />

nibile su http://www.itee.uq.edu.au/~infs7201/Assessments/Assignment\<br />

%201\%20Material/WSFL.pdf.<br />

[29] R. Milner. Comm<strong>un</strong>ication and Concurrency. Prentice Hall, 1989.<br />

[30] R. Milner. Comm<strong>un</strong>icating and mobile systems: the π-calculus. Cambridge<br />

University Press, New York, NY, USA, 1999.<br />

[31] N. Mitra e Y. Lafon. SOAP Version 1.2 Part 0: Primer (Second<br />

E<strong>di</strong>tion). W3C, 2007. Disponibile su http://www.w3.org/TR/2007/<br />

REC-soap12-part0-20070427/.<br />

[32] F. Montesi, C. Gui<strong>di</strong>, R. Lucchi e G. Zavattaro. JOLIE: a Java Orchestration<br />

Language Interpreter Engine. Electronic Notes in Theoretical Computer Science,<br />

181:19 – 33, 2007.<br />

[33] W. Nagy, F. Curbera e S. Weerawarana. The Advertisement and Discovery of<br />

Services (ADS) protocol for Web services. Relazione tecnica. Disponibile su<br />

http://www.ibm.com/develo<strong>per</strong>works/library/ws-ads.html.<br />

[34] OASIS. UDDI Reference Site. http://ud<strong>di</strong>.xml.org/.<br />

134


BIBLIOGRAFIA<br />

[35] M. Page-Jones. Progettazione a oggetti UML. Apogeo, 2002.<br />

[36] T. J. Parr, H. D. Dietz e W. E. Cohen. PCCTS Reference Manual - Version 1.00.<br />

SIGPLAN Notices, 27:88–165, 1991.<br />

[37] D. Pran<strong>di</strong> e P. Quaglia. Stochastic COWS. In Proc. 5th International Conference<br />

on Service Oriented Computing (ICSOC’07), volume 4749 <strong>di</strong> Lecture Notes in<br />

Computer Science. Springer, 2007.<br />

[38] A. Skonnard. The XML File: Publishing and Discovering Web Services wi-<br />

th DISCO and UDDI. Relazione tecnica, 2002. Disponibile su http://msdn.<br />

microsoft.com/en-us/magazine/cc302073.aspx.<br />

[39] SUN. S<strong>un</strong> Application Server. http://develo<strong>per</strong>s.s<strong>un</strong>.com/appserver/.<br />

[40] SUN. JDK 6 Documentation. 2006. Disponibille su http://java.s<strong>un</strong>.com/<br />

javase/6/docs/.<br />

[41] SUN. The Java Web Services Tutorial. Relazione tecnica, 2006. Disponibile su<br />

http://java.s<strong>un</strong>.com/<strong>web</strong>services/docs/2.0/tutorial/doc/.<br />

[42] S. Thatte. XLANG: Web Services for Business Process Design. Relazione tecnica,<br />

2001. Disponibile su http://www.gotdotnet.com/team/xml_wsspecs/xlang-c/<br />

default.htm.<br />

135

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!