Telerefertazione medica su TCP/IP: progetto e

UNIVERSITÀ POLITECNICA DELLE MARCHE
FACOLTÀ DI INGEGNERIA
Corso di Laurea in Ingegneria Informatica e dell’Automazione
Telerefertazione medica su TCP/IP:
progetto e realizzazione degli opportuni
Web-Service
Tesi di laurea di:
Marco Induti
Correlatori:
Relatore:
Prof.
Prof. Ing.
Aldo Franco Dragoni
Paolo Puliti
Guido Tascini
Anno Accademico 2006-2007
SOMMARIO
Capitolo 1. Telemedicina
1.1
1.2
1.2.1
1.2.2
1.3
Introduzione…………………………………………………………………..
Applicazioni…………………………………………………………………….
Vantaggi…………………………………………………………………………
Problemi…………………………………………………………………………
Stato dell’arte………………………………………………………………….
pag.
pag.
pag.
pag.
pag.
6
7
7
8
9
pag.
pag.
pag.
pag.
pag.
pag.
pag.
pag.
15
16
18
19
20
22
22
23
pag.
pag.
pag.
pag.
pag.
pag.
pag.
pag.
25
32
34
35
37
38
40
42
pag.
pag.
pag.
pag.
pag.
pag.
pag.
46
47
47
47
53
54
57
pag.
pag.
pag.
pag.
pag.
pag.
61
75
94
98
108
111
Capitolo 2. Progetto JTelemed
2.1
2.2
2.2.1
2.2.2
2.2.3
2.3
2.3.1
2.3.2
Finalità……………………………………………………………………………
Architettura generale.………………………………………………………
Repository………………………………………………………………………
Ente richiedente……………………………………………………………..
Ente refertante.………………………………………………………………
Soluzioni tecniche……………………………………………………………
Middleware Client-Server….……………………………………………..
Messaggi SOAP.………………………………………………………………
Capitolo 3. I Web-Service
3.1
3.2
3.3
3.3.1
3.3.2
3.3.3
3.3.4
3.4
L’architettura Client-Server……………………………………………….
Introduzione ai Web-Service…………………………………………….
Cosa sono i Web-Service e come funzionano.…………………….
XML Schema…………………………………………………………………..
UDDI……………………………………………………………………………..
WSDL…………………………………………………………………………….
SOAP……………………………………………………………………………..
Cenni su Apache Axis………………………………………………………
Capitolo 4. Progettazione del database
4.1
4.2
4.2.1
4.2.2
4.2.3
4.3
4.4
Specifica delle operazioni……………………………………………......
Progettazione concettuale della base di dati………………………
Un primo schema scheletro………………………………………………
Sviluppo delle componenti dello scheletro………………………….
Schema E-R completo……………………………………………………..
Traduzione verso il modello relazionale……………………………..
Codifica SQL……………………………………………………………………
Capitolo 5. Implementazione del progetto JTelemed
5.1
5.2
5.3
5.4
5.5
5.6
Preparazione dell’ambiente di sviluppo………………………………
Servizi offerti dal Web-Service………..………………………………..
Fase di deploy…………………………………………………………………
Una possibile e particolare implementazione del client…….….
Axis Attachments…………………………………………………………….
Comunicazione Client-Server…………………………………………….
SOMMARIO
Capitolo 6. Tecnologie software
6.1
6.1.1
6.2
6.2.1
6.2.2
6.3
6.3.1
6.4
6.4.1
6.5
6.5.1
6.5.2
Java Platform………………………………………………………………….
Le Servlet………………………………………………………………………
Service-Oriented Architecture…………………………………………..
Web-Services………………………………………………………………….
Protocollo SOAP……………………………………………………………..
Application Server…………………………………………………………..
Apache Tomcat………………………………………………………………
Strumenti di sviluppo………………………………………………………
Apache Axis……………………………………………………………………
Database Relazionale………………………………………………………
Oracle……………………………………………………………………………
FreeTOAD………………………………………………………………………
pag.
pag.
pag.
pag.
pag.
pag.
pag.
pag.
pag.
pag.
pag.
pag.
119
129
133
137
141
156
156
163
163
167
167
173
Capitolo 7. Problematiche e miglioramenti
7.1
7.2
7.3
Il server Linux……………………………………………………………….. pag. 176
Gestioni critiche……………………………………………………………… pag. 180
Un database Open Source: MySQL…………………………………… pag. 182
Capitolo 8. Pubblicazione
8.1
8.2
Il firewall di Linux…………………………………………………………… pag. 187
Il comando iptables………………………………………………………… pag. 189
Bibliografia………………..………………………………………………………………. pag. 193
INTRODUZIONE
La tecnologia dei calcolatori elettronici negli ultimi decenni si è evoluta
notevolmente, tanto da rendere il computer un elemento quasi indispensabile in tutti
gli ambiti della vita quotidiana.
Dal lavoro al tempo libero, dai trasporti alle comunicazioni, dal settore
industriale al commerciale, l’uso di hardware e software specifici hanno permesso
all’uomo di migliorare il proprio stile di vita ed ottimizzare la gestione delle
informazioni e dei dati in suo possesso.
In tutto il mondo tale evoluzione si è inevitabilmente estesa anche al campo
medico, dove velocità, organizzazione e precisione sono fondamentali e, spesso,
consentono di salvare vite umane.
In questo panorama globale, anche l’Italia sente forte la necessità di
ristrutturare l’intero sistema sanitario nazionale spingendosi verso nuove frontiere, e
sviluppando un settore innovativo come quello della Telemedicina.
La presente tesi di laurea ha come obiettivo la realizzazione del progetto
JTelemed, nato dalla collaborazione tra Nbs srl ed Università Politecnica delle Marche.
Nella prima fase è stato analizzato il concetto di Telemedicina ed il ruolo da
essa attualmente ricoperto, facendo particolare riferimento alle problematiche delle
aziende sanitarie locali e realizzando uno stato dell’arte del sistema sanitario
nazionale. Tra gli argomenti trattati spicca uno dei settori di maggior interesse, la
telerefetazione, per la quale è stata sviluppata un’architettura software “flessibile” e
completa per il teleconsulto e la teleassistenza.
Particolare attenzione è stata, infine, dedicata alla descrizione dettagliata del
progetto JTelemed e del suo funzionamento, soprattutto della sua implementazione
dal punto di vista server in un’ottica di un’architettura client-server, non tralasciando
comunque tecnologie e paradigmi di comunicazione caratteristici dell’ambiente client.
Tale descrizione è stata sviluppata analizzando ogni singolo passo di
progettazione, programmazione e sviluppo del progetto e richiamando alcuni dei
software utilizzati per la sua realizzazione.
4
CAP. 1 - TELEMEDICINA
Introduzione al concetto di telemedicina e stato dell’arte nella sanità
italiana.
INDICE ARGOMENTI:
1.1 Introduzione
1.2 Applicazioni
1.2.1 Vantaggi
1.2.2 Problemi
1.3 Stato dell’Arte
5
CAP. 1 - TELEMEDICINA
1.1 Introduzione
Il concetto di telerefertazione non è un principio a sé stante, ma nasce in un
contesto molto più ampio, nasce come un aspetto particolare, come una branchia,
della Telemedicina. In questo capitolo affronteremo una breve descrizione della
Telemedicina per chiarire di cosa essa si occupa e quali sono i vantaggi legati al suo
impiego nel mondo della sanità, nonché alcune delle sue possibili implementazioni a
livello applicativo.
Una definizione della Telemedicina che ha riscosso un notevole successo è la
seguente: “La Telemedicina rappresenta l’erogazione di servizi sanitari, laddove la
distanza rappresenti un fattore critico da parte di professionisti nell’assistenza
sanitaria che utilizzino tecnologie dell’informazione e della comunicazione per lo
scambio di informazioni rilevanti, per la diagnosi, il trattamento e la prevenzione delle
patologie e per l’educazione continuativa degli operatori sanitari, nell’interesse del
miglioramento della salute e delle comunità assistite”.
La Telemedicina utilizza le tecnologie della telecomunicazione per erogare
assistenza sanitaria specialistica, spesso a notevoli distanze, con la possibilità di
contenere i costi delle prestazioni. Questo avviene in special modo quando l’Assistenza
Sanitaria è rivolta ad aree isolate o comunque dove non sia disponibile direttamente la
prestazione specialistica del medico.
La Telemedicina consente di conseguire notevoli benefici sia per erogatori di
assistenza remota, sia naturalmente, per gli utenti dei servizi, siano essi pazienti o
operatori sanitari.
Fig. 1.1 – Telemedicina come servizio sanitario delocalizzato
6
CAP. 1 - TELEMEDICINA
Lo sviluppo e l’applicazione della Telemedicina richiede significativi expertise nei
settori delle telecomunicazioni, delle erogazioni dei servizi sanitari e dell’information
tecnology and comunications.
L’applicazione della Telemedicina ben si presta ad un opera di cooperazione fra
i paesi dotati di maggiori tecnologie e quelli ancora in via di sviluppo.
1.2 Applicazioni
Il concetto di telemedicina non significa dunque soltanto “medicina praticata a
distanza”, ma include tutti quegli aspetti legati all’assistenza sanitaria in senso lato.
Una serie di nuovi concetti sono ora riferiti alla telemedicina; due di questi sono ehealth e tele-health (tele-assistenza).
La telemedicina teleassistenza può essere applicata in vari modi in tutti i servizi
sanitari; può facilitare e razionalizzare la comunicazione e lo scambio di informazioni,
tra servizi di primaria assistenza e gli ospedali, tra ospedali diversi, tra ospedali e i
laboratori, tra i servizi di riabilitazione e le organizzazioni paramediche. La
telemedicina riguarda anche la direzione e l’amministrazione dell’unità sanitarie locali,
i pazienti e i loro familiari.
1.2.1 Vantaggi
L’avvento dell’informatica medica e la conseguente introduzione di nuove
tecnologie nell’ambito sanitario hanno portato e porteranno notevoli vantaggi sia per i
pazienti che per il personale medico.
L’introduzione della telemedicina permette :
Diagnosi e cure più rapide;
Minor numero di spostamenti sia del personale medico che dei pazienti;
7
CAP. 1 - TELEMEDICINA
Riduzione dei costi per personale, compreso quello di emergenza;
Comunicazioni più veloci;
Aggiornamento più semplice e rapido delle informazioni riguardanti
diagnosi e metodi di cura;
Miglior sostegno allo staff medico per la formazione sia teorica che pratica.
1.2.2 Problemi
In passato i costi per l’attrezzatura e le telecomunicazioni erano troppo alti da
permetterne un’introduzione su larga scala, oggi tuttavia la situazione sotto questo
punto di vista è notevolmente migliorata; il vero ostacolo da affrontare è cercare di
introdurre metodi che favoriscano l’accettazione e la comprensione da parte del
personale interessato, delle applicazioni di telemedicina e teleassistenza nei servizi
sanitari.
Tuttavia anche quest’ultimo aspetto si sta via via superando, grazie
all’impegno dell’azienda sanitaria locale e nazionale per una informatizzazione del
personale sanitario attraverso la creazione di corsi di aggiornamento.
Bisogna però sottolineare che l’introduzione della telemedicina influenza i
tradizionali metodi di lavoro, si vanno a modificare i modelli di cooperazione, si creano
nuove figure lavorative e molto spesso sorgono problemi di distribuzione dei costi e di
investimenti delle risorse. Alcuni progetti di telemedicina sono partiti proprio da
un’analisi preliminare dell’impatto che possono avere nelle procedure ospedaliere,
nella ridistribuzione dei compiti e delle risorse. Dato l’impiego di tecnologie avanzate
sia come digitalizzazione che come diffusione dell’informazione, quindi nei settori
dell’informatica e della telecomunicazione, è necessaria anche la formazione del
personale e l’addestramento dello stesso all’utilizzo corretto delle infrastrutture e alla
manutenzione di questo nuovi sistemi. A livello internazionale, ad oggi, si registra una
mancanza di uniformità sull’applicazione del concetto di telemedicina, dato che vanno
a sovrapporsi due differenti sfere di interesse, quella medica e quella ingegneristica;
tutto ciò rende difficile la creazione di standard riconosciuti che possano
regolamentare tale disciplina.
8
CAP. 1 - TELEMEDICINA
Questo rappresenta un limite alla diffusione e all’impiego su larga scala delle
soluzioni che in questi anni sono state elaborate.
1.3 Stato dell’arte
Oggigiorno i sistemi sanitari mondiali stanno facendo passi da gigante
nell’utilizzo massiccio della telemedicina, grazie soprattutto allo sviluppo di nuove
tecnologie. In ambito nazionale ogni regione si sta attrezzando allo sviluppo di sistemi
di informatica medica.
Uno dei principali progetti a livello nazionale è rappresentato da As.ter: un
sistema informativo-informatico per la gestione di tutte le attività del territorio
sviluppato dalla USL 11 di Empoli. As.Ter integra, con l’ausilio di una piattaforma
tecnologica innovativa, tutti gli applicativi ed i database delle attività sanitarie e sociali
svolte sul territorio, consentendo la rilevazione dei bisogni complessivi dei cittadini,
l’individuazione delle modalità e dei tempi di risposta ai loro bisogni, la rilevazione dei
costi; tutto ciò al fine di pianificare e gestire le attività sociosanitarie sul territorio in
un ottica manageriale di costi/benefici.
Un altro progetto è stato proposto dal servizio sanitario regionale EmiliaRomagna con il nome di SOLE. Esso è finalizzato a realizzare una rete telematica,
basata su una serie di hub (centri di archiviazione) e spoke (centri di acquisizione), di
collegamento tra i servizi ospedalieri e i servizi territoriali per agevolare la
comunicazione tra operatori sanitari e, di conseguenza, agevolare l'erogazione dei
servizi con importanti e positive ricadute sulla continuità assistenziale e sulla
semplificazione dell’accesso ai servizi per il cittadino. Un’interessante applicazione
sviluppata da un’equipe guidata da Ennio Amori, all’interno di questo progetto è
“Neurosurgery Teleconsulting”, un servizio di teleconsultazione tra i centri di
neurochirurgia collegati attraverso la rete hub&spoke, nella nuova logica distribuita e
digitale, in modo da poter trattare ogni trauma e lesione in modo appropriato
sfruttando il livello avanzato che ha raggiunto l’IT.
Molti sono i progetti pilota che puntano a creare tra i nostri ospedali e centri
d’eccellenza un collegamento con i paesi dell’Europa dell’est, che sono da poco entrati
9
CAP. 1 - TELEMEDICINA
nella comunità europea, per fornire servizi di teleconsulto e telediagnosi, come per
esempio tra Padova o Milano e la Romania. Nello sviluppo di questo tipo di progetti è
possibile usufruire anche dei finanziamenti della comunità europea che ovviamente
danno maggiore spinta alla ricerca e permettono di pagare la consulenza di software
house, esterne alle aziende sanitarie, che possono dare un forte supporto tecnico e
far ottenere un prodotto software più completo ed evoluto.
In tutto questo panorama di progetti non emerge nessun sistema simile a
quello sviluppato in questa tesi, si tratta sempre di servizi ad hoc per applicazioni
specifiche, senza una vera ottica di integrazione e supporto globale di servizi sanitari
delocalizzati.
Avvicinandoci a realtà più vicine a noi, l’ASUR della regione Marche zona 7 ha
sviluppato una serie di progetti che riguardano l’ambito medico tra i quali troviamo:
1. Sistema di Teleconsulto ospedale di Osimo con stazioni fisse e stazioni mobili;
2. Assistente Virtuale;
3. Delocalizzazione della refertazione diagnostica.
Il Sistema di Teleconsulto è composto da un server e da un client entrambi
situati presso l’Ospedale di Osimo e da tre stazioni fisse composte da tre
elettrocardiografi. Ogni elettrocardiografo è provvisto di varie uscite esterne, tra cui
quattro seriali RS 232, una rete Ethernet per trasmissione e ricezione di tracciati ecg
con relativo referto e stampante Archimed 4240 termica formato A4. Inoltre ogni
stazione è dotata di memoria interna per l’archiviazione di quaranta ecg (10 secondi
12
derivazioni)
fornita
di
cellulare
Gsm
Dual
Band
con
interfaccia
per
elettrocardiografo e cavi di connessione per la trasmissione digitale dell’ecg alla
Centrale di Ascolto, funzione di viva voce per comunicare con la Centrale di Ascolto.
Il Client è posto nella zona di controllo della Unità di Terapia Critica del
Dipartimento di Medicina Interna dove un operatore è costantemente presente
durante le ore del giorno e della notte. Le tre stazioni fisse sono al momento situate
presso le Unità di degenza mediche del Presidio Ospedaliero di Osimo ed una presso i
Poliambulatori di Camerano situati all’interno di una struttura residenziale per anziani
con circa 80 degenti.
10
CAP. 1 - TELEMEDICINA
La stazione mobile viene al momento affidata agli operatori della Emergenza
Urgenza Territoriale che fanno capo al Distretto Ancona Sud.
Fig. 1.2 – Applicazione di telemedicina con elettrocardiografo
L’Assistente Virtuale è un progetto, già in parte sviluppato e funzionante,
che ha come obiettivo quello di creare un assistente personale virtuale che sia in
grado di offrire ad ogni singolo utente un valido appoggio.
Si possono connettere a questo sistema tre tipi di client: l’assisto che potrà
consultare i propri dati clinici oltre che avere in modo automatico un promemoria degli
eventuali esami da svolgere o dei referti pronti alla consultazione, un motore di ricerca
personalizzato e potenziato e un forum.
Gli altri due utenti, il medico di base e il medico specialista, sono tuttavia
ancora in fase di realizzazione. Gli utenti avranno a disposizione un alter-ego virtuale
che attraverso un’interfaccia user-friendly sarà in grado di rispondere attraverso una
voce sintetica alle domande scritte dagli utenti stessi, quindi un sistema con
interfaccia amichevole per accedere ai propri dati clinici che funga anche da archivio e
agenda sanitaria.
11
CAP. 1 - TELEMEDICINA
Per quanto riguarda invece la Delocalizzazione della Refertazione
Diagnostica, nell’ottica di capillarizzare l’offerta sanitaria così come negli obiettivi
della sanità regionale, può essere importante pensare ad una struttura informatica
che renda indipendenti le due fasi della diagnostica: l’esecuzione dell’esame e la sua
refertazione.
Infatti mentre è possibile pensare di localizzare alcuni macchinari (di basso
costo) anche nei poliambulatori più piccoli, può risultare sconveniente portare in
questi poliambulatori personale di alta specializzazione.
Quello che ci si propone è di potenziare la rete di acquisizione dell’esame
digitale, aumentando il numero delle macchine e dei tecnici di laboratorio,
concentrando invece il personale medico che deve compilare il referto; il personale di
laboratorio ha un costo inferiore rispetto ai dottori, quindi si aumentano capacità,
capillarità e efficienza del servizio limitando gli investimenti.
La struttura informatica che ci si propone di realizzare in questa fase, poi potrà
anche servire per altri scopi come consulti medici oppure per fornire servizi (a
pagamento) di refertazione per altri enti.
L’architettura di massima proposta è quindi la seguente:
Fig. 1.4 – Schema a blocchi delocalizzazione diagnostica
12
CAP. 1 - TELEMEDICINA
Sostanzialmente un sistema per la refertazione a distanza altro non è che un
repository di eventi sanitari con relativo output dell’esame (per esempio radiografia,
elettrocardiogramma, etc).
In questo repository gli enti periferici (poliambulatori, etc.) depositano gli
output degli esami e prelevano i referti mentre il centro di refertazione preleva gli
output degli esami ed inserisce i referti relativi.
Per mettere in piedi la procedura appena descritta è indispensabile che tutti i
partecipanti siano collegati, attraverso una infrastruttura PKI funzionante, ad una rete
intranet o internet utilizzando un metodo di trasferimento sicuro (SSL).
Il progetto Jtelemed nasce proprio come ricerca di una soluzione ingegneristica
a livello software per rispondere ad un’esigenza sanitaria di delocalizzazione. Requisiti
fondamentali di tale sistema, data la varietà di dati da trattare e di ambienti in cui
operare, sono la semplicità e la flessibilità; tenendo presenti questi due punti il
sistema può raggiungere un livello di efficienza adeguato al supporto di servizi di
teleconsulto e la telerefertazione e non solo, in generale per qualsiasi servizio
sanitario delocalizzato.
13
CAP. 2 – PROGETTO JTELEMED
Descrizione dell’architettura del Progetto JTelemed, spiegazione del
funzionamento delle varie componenti del sistema: repository,
richiedente e refertante. Panoramica delle soluzioni tecniche adottate.
INDICE ARGOMENTI:
2.1 Finalità
2.2 Architettura generale
2.2.1 Repository
2.2.2 Ente richiedente
2.2.3 Ente refertante
2.3 Soluzioni tecniche
2.3.1 Middleware Client-Server
2.3.2 Messaggi SOAP
14
CAP. 2 – PROGETTO JTELEMED
2.1 Finalità
Il progetto JTelemed nasce dalla collaborazione tra l’Università Politecnica delle
Marche e l’N.b.s s.r.l, come soluzione software, all’esigenza di poter delocalizzare la
refertazione diagnostica.
L’obiettivo del progetto è quello di fornire, un prodotto flessibile che
implementasse un servizio di refertazione asincrono, cioè in grado di separare non
solo da un punto di vista temporale, ma anche da quello spaziale, l’esecuzione
dell’esame dalla refertazione dello stesso. Per asincrono intendiamo che non ci si
aspetta che l’esame venga refertato in tempo reale, ma in un tempo accettabile
concordato tra i fornitori del servizio e gli utenti.
Fig. 2.1 – Contesto del progetto
La figura mostra che la nostra architettura fornisce un supporto per lo sviluppo
di servizi sanitari, ovvero non si pone l’obiettivo di sostituire i sistemi informativi già
esistenti che sono molteplici e variegati, ma li vuole integrare in una rete di
comunicazione sicura che faciliti e razionalizzi lo scambio di informazioni. Nello
specifico si tratta di servizi di teleconsulto in ambiente Intranet e/o Internet, quindi
basati su TCP/IP, come la refertazione e la “second opinion”.
15
CAP. 2 – PROGETTO JTELEMED
Visto che l’ambiente in cui opera il nostro sistema è intrinsecamente non sicuro,
uno dei requisiti fondamentali da rispettare è il livello di sicurezza e di affidabilità, del
trattamento del dato clinico, cioè consentire uno scambio di informazioni sicuro in un
ambiente,internet, che non lo è per definizione.
Lo scopo di JTelemed è creare un’applicazione software completa in grado di gestire
l’intero processo di telerefertazione, più in generale supportare in modo sicuro un
servizio sanitario delocalizzato.
2.2 Architettura generale
Il primo passo fatto per progettare JTelemed (il nome è ottenuto dall’unione
delle parole Java e Telemedicina) è stato capire come si doveva integrare con il
sistema informativo sanitario già esistente; la prima ipotesi semplificativa adottata è
stata quella di creare una piattaforma flessibile per lo sviluppo di servizi sanitari.
Si è pensato di creare una struttura semplice, basata su standard diffusi e
riconosciuti in modo da sviluppare una piattaforma che potesse facilmente essere
applicata in ambito sanitario sia a livello del personale medico che in un prossimo
futuro direttamente ai cittadini.
JTelemed si basa sul concetto di evento: questo aspetto rappresenta il punto
focale dell’intero sistema. L’effettuazione di un esame presso una qualsiasi struttura
clinica e la conseguente archiviazione del dato in forma digitale genera ciò che viene
chiamato evento.
L’evento non è il dato clinico vero e proprio ma rappresenta una sorta di metadato-clinico del dato digitale generato dai laboratori. E’ composto da una serie di
informazioni che riguardano il dato digitale prodotto dall’evento come ad esempio:
l’unità che ha erogato la prestazione, la data e l’ora dell’esame, la struttura che l’ha
prodotto, il dottore richiedente ed il codice dell’impegnativa, lo stato della fase di
refertazione, e, cosa molto importante il link che consente di scaricare il dato. Ogni
evento quindi viene immagazzinato all’interno di un apposito raccoglitore, definito
repository, che costituisce il nucleo del sistema e che funziona da collegamento tra
colui che referta e l’esame.
16
CAP. 2 – PROGETTO JTELEMED
Questo legame è contenuto nell’evento e il repository è una sorta di sofisticato
gestore di eventi clinici.
Qualsiasi esame che può essere memorizzato in forma digitale può essere
associato ad un evento, con questa soluzione ingegneristica si è riusciti ad ottenere
quella flessibilità ed adattabilità che venivano richieste in fase di progettazione. Una
soluzione semplice, ma molto efficace, che è il cardine fondamentale dei progetti di
sistemi informativi in ambito sanitario.
L’architettura, di conseguenza, mostra un’analoga flessibilità e semplicità,
infatti è prevista la presenza solamente di tre attori principali che interagiscono tra
loro e che rappresentano un’astrazione delle funzioni principali: da un lato
l’esecuzione dell’esame, dall’altro la generazione del referto, con al centro un nodo di
gestione del sistema.
Fig. 2.2 – Architettura generale dell’applicativo JTelemed
Il cuore del sistema è rappresentato dal Repository centrale, che altro non è
che un server relazionale, cioè un server che gestisce un DataBase. Il Repository può
essere ospitato da un azienda o da un ente erogante, il quale si impegna a certificare
l’identità di coloro che usufruiscono del servizio (medici e laboratori) e a garantire il
corretto funzionamento e la manutenzione dell’intero sistema.
17
CAP. 2 – PROGETTO JTELEMED
Nella parte destra della figura sono rappresentate le strutture che producono i
dati digitali di un esame clinico e che si interfacciano nel sistema come dei client di
laboratorio: sono quelli che attivano il processo di refertazione e attendono i risultati.
Dall’altra parte si trova il personale che fornisce il servizio di refertazione, una
clinica specializzata, un semplice medico o una equipe di medici; attraverso
l’interfaccia del medico possono interagire nel nostro sistema e pubblicare il proprio
referto autenticandolo con la propria firma.
Oltre alla figura del Repository possiamo dunque identificare le altre due entità
fondamentali che costituiscono il nostro sistema:
ENTE RICHIEDENTE
ENTE REFERTANTE
Vediamo brevemente in cosa consistono queste entità.
2.2.1 Repository
La struttura del sistema prevede la presenza di un repository centrale,
costituito da un server che ospita un database relazionale nel quale vengono
memorizzati le informazioni relative ai dati digitali prodotti nei laboratori.
Ogni registrazione all’interno del database di questo repository costituisce
quello che noi chiamiamo “evento”; l’evento rappresenta una sorta di meta-dato
informativo riguardante il dato digitale prodotto nei laboratori.
Le informazioni che vengono registrate sono data e ora dell’inserimento nella
base dati, il tipo di esame eseguito, informazioni sulla provenienza della richiesta di
prestazione sanitaria, l’esame o meglio il dato digitale riguardante l’esame vero e
proprio e alcune informazioni personali dei pazienti, quali età, peso, altezza che sono
di fondamentale importanza per la fase di diagnosi.
Da notare che non vengono mai registrate le informazioni anagrafiche del
paziente: infatti il primo obiettivo è quello di fornire un servizio di refertazione che
abbia la possibilità di concedere “second opinion”.
18
CAP. 2 – PROGETTO JTELEMED
Tutto ciò rende molto flessibile la struttura eliminando i problemi riguardanti la
privacy. Nel caso di applicazioni future per telediagnosi, o per la consultazione della
cartella clinica dei pazienti, avremmo l’obbligo legale di strutturare in modo più
robusto, dal punto di vista della sicurezza, il server che ospita il repository, oltre
all’utilizzo di tecniche di criptazione per la memorizzazione dei dati.
2.2.2 Ente richiedente
La seconda figura che viene presa in esame è l’utente (o ente) richiedente; con
questo termine si indica una qualsiasi entità che abbia la necessità di farsi refertare un
esame; potrebbe essere un laboratorio radiologico, analisi, epidemiologico oppure un
autoambulanza con apposita apparecchiatura, una piattaforma petrolifera (anche essa
con la giusta strumentazione), un medico di base che chiede opinioni ad un medico
specialistico, un infermiere ecc…. Quindi nella descrizione del sistema si parlerà
sempre di richiedente come interfaccia comune che identifica in modo univoco ognuna
di queste unità.
L’ente richiedente crea un nuovo evento, cioè una volta effettuato un esame e
ottenuto il dato digitale sia in maniera diretta o tramite passaggi di discretizzazione,
entra nel portale web con username e password e tramite un opportuna interfaccia
inserisce i dati relativi all’esame eseguito all’interno del database centrale.
Grazie al repository che pubblica l’evento, il dato digitale presente nel
laboratorio diventa accessibile e pronto per essere refertato da parte degli altri attori
di questo sistema, i dottori o meglio il personale specializzato per la refertazione.
Una volta generato l’evento il richiedente può monitorare l’evento, ossia
controllare tutte le varie fasi di refertazione che l’evento da lui generato subisce, fino
a che non ritiene soddisfatta la sua richiesta.
A questo punto dichiara chiuso l’evento e termina la fase di refertazione;
ovviamente solo chi ha generato la richiesta può dichiarare terminato il processo di
refertazione: infatti ogni utente richiedente potrà visionare solo gli eventi da lui stesso
creati.
19
CAP. 2 – PROGETTO JTELEMED
Fig. 2.3 – Funzionalità lato del laboratorio.
2.2.3 Ente refertante
Una volta che un utente richiedente apre un evento e quindi va ad aggiungere
un record al Repository centrale, effettua una richiesta di refertazione all’altra figura
che compare nell’architettura di JTelemed: l’ente refertante costituito da un insieme di
medici, o per non generalizzare, da un insieme di personale specializzato.
Ogni utente refertante effettuando l’accesso tramite un semplice web browser
(per esempio Internet Explorer o Mozilla) accede al sistema dove tramite opportune
interfacce user-friendly vengono mostrati tutti gli eventi che il medico è in grado di
refertare: questo perché uno degli scopi del presente lavoro è quello di creare un
portale per servizi di “second-opinion”.
Inoltre ognuno di essi potrà visualizzare un elenco di tutti gli eventi che può
refertare, dove sono presenti data e ora di inserimento nel database, lo stato
dell’esame (aperto, refertato, chiuso) e infine il link per effettuare il download sul
proprio pc del dato clinico per visualizzarlo in modalità offline e quindi refertarlo in
modo asincrono.
20
CAP. 2 – PROGETTO JTELEMED
Fig. 2.4 – Funzionalità lato refertante.
Quando un medico decide di refertare un esame, gli verrà presentata una form
dove può effettuare l’upload del suo referto che deve essere scritto e salvato in un file
di qualsiasi formato, ad esempio testo (*.txt).
In questo modo si viene a creare il meccanismo di “second opinion” (uno degli
obiettivi di partenza del progetto). Inoltre egli può anche dichiarare il referto appena
inviato al repository centrale non definitivo, cioè può riservarsi il privilegio di inviare
un referto non ancora completo, ovviamente prendendosi l’onere di completarlo in
breve tempo.
Il sistema provvederà a memorizzare nel database la data e l’ora della
refertazione, garantendo quindi in modo inequivocabile l’istante temporale in cui il
dottore ha effettuato il referto.
L’attendibilità del medico che può effettuare referti è verificata in fase di
accesso da parte del medico al browser dal sistema attraverso un’identificazione con
username e password.
In questo modo si offrono le garanzie necessarie alla fase di refertazione.
21
CAP. 2 – PROGETTO JTELEMED
2.3 Soluzioni tecniche
JTelemed è un applicazione “object-oriented” basata su internet che fa uso di
un database relazionale per memorizzare i dati.
L’architettura prescelta è quella delineata da Java 2 Enterprise Edition della Sun e gli
strumenti di sviluppo sono:
Eclipse 3.2.0 WTPAll-in-one, JDK 1.5.0 e Apache Tomcat 5.5 – come
piattaforma di sviluppo;
Classi Java – per la realizzazione della parte server;
SitePainter e PortalStudio – per le interfacce web lato client (non
verranno approfondite)
Apache Axis – per la realizzazione del web service;
I database supportati sono tutti quelli con interfacce JDBC, in questo caso
Oracle, ma senza particolare sforzo potrà, in futuro, essere estesa ad altri tipi di
database, di tipo free, come ad esempio MySQL.
I client possono accedere in qualsiasi momento per consultazione o inserimento
dati utilizzando un comune Web Browser. Ogni operatore accederà a funzionalità
diverse
del
sistema sulla
base
del
proprio profilo professionale
certificato
dall’amministratore del sistema stesso: ciò significa che solo chi è stato autenticato
come personale autorizzato potrà entrare, attraverso la pagina del login, nel portale
web e usufruire dei suoi servizi.
2.3.1 Middleware Client-Server
JTelemed è un middleware client-server cioè un una piattaforma software che
è interposta tra l'utente finale e il database. Esso è composto da un server web
relazionale scritto in Java e quindi perfettamente adattabile a qualsiasi piattaforma
grazie all’impiego della Java Virtual Machine e da un unico client sia per l’utente
refertante che per il richiedente.
22
CAP. 2 – PROGETTO JTELEMED
Il client si collega al sistema direttamente tramite web browser, senza necessità
di avere installato componenti particolari, come per esempio la virtual machine stessa
che risiede solo sul server: infatti sono il PortalStudio e il Tomcat che traducono il
codice Java lato server e lo trasformano in codice HTML per il client. Il requisito della
compatibilità è fondamentale specialmente in ambiente remoto che può essere il più
vario possibile.
2.3.2 Messaggi SOAP
La comunicazione all’interno del sistema, avviene con scambio di messaggi
SOAP (cosa sono e come funzionano verrà spiegato nei prossimi capitoli).
I dati si inviano come allegati ai messaggi SOAP, è stata scelta questa tecnica
per lo scambio di informazione perché avendo come obbiettivo quello di creare una
struttura in grado di adattarsi a qualsiasi tipo di esame, era importante avere la
possibilità di scambiare messaggi di dimensioni variabili, in questo modo abbiamo
raggiunto tale obbiettivo.
Ad esempio, un dato proveniente da un laboratorio radiologico produce dei file
Dicom di dimensioni che si aggirano attorno ai 30 Mb (dipende dall’esame), con
questo sistema non si sono verificati problemi di trasmissione dei pacchetti.
Una cosa importante da notare è che per implementare questa struttura si ha
bisogno di una rete a larga banda che consenta le transizioni di file di dimensione
variabile.
23
CAP. 3 – I WEB-SERVICE
Prima di procedere con la descrizione dell’implementazione del
progetto JTelemed occorre avere una panoramica essenziale su alcune
delle tecnologie software su cui si basa il progetto stesso, tecnologie e
nozioni fondamentali per una comprensione più efficace delle varie fasi
di realizzazione. In particolare verrà introdotto un concetto cardine del
mondo del web: il Web-Service.
Alcune terminologie e gli altri strumenti software verranno poi
approfonditi e descritti in seguito nei prossimi capitoli.
INDICE ARGOMENTI:
3.1 L’architettura Client-Server
3.2 Introduzione ai Web-Service
3.3 Cosa sono i Web-Service e come funzionano
3.3.1 XML Schema
3.3.2 UDDI
3.3.3 WSDL
3.3.4 SOAP
3.4 Cenni su Apache Axis
24
CAP. 3 – I WEB-SERVICE
3.1 Architettura Client-Server
Il modello Client-Server è il paradigma di Distributed Computing che allo stato
attuale viene utilizzato maggiormente. Tale modello permette a processi situati su
differenti calcolatori di cooperare in tempo reale attraverso lo scambio di messaggi,
ottenendo così un notevole miglioramento rispetto, ad esempio, al modello File-
Transfer, che richiede il trasferimento di interi file e in cui le computazioni sui dati
sono eseguite off-line. Il modello Client/Server viene tipicamente implementato
attraverso le chiamate di procedura remota (RPC), che estende lo scopo di una
chiamata locale, oppure attraverso il paradigma degli oggetti distribuiti che estende lo
scopo del modello degli oggetti locali.
Il modello di calcolo Client/Server nasce con l’obiettivo di poter utilizzare più
efficacemente le possibilità offerte dalla distribuzione delle risorse di quanto non fosse
ottenibile impiegando il modello File sharing. Infatti le limitazioni che questo schema
impone sono piuttosto stringenti e non permettono un proficuo uso delle capacità
della distribuzione, imponendo di fatto la coesistenza di un limitato numero di processi
nel sistema. Le caratteristiche del modello Client/Server, tra le quali la struttura
modulare e l’utilizzo dello scambio di messaggi nella cooperazione tra processi,
permette al contrario di ottenere buone prestazioni per quel che riguarda requisiti
importanti quali l’utilizzabilità, la flessibilità, l’interoperabilità, e la scalabilità.
Fig. 3.1 - Relazione tra i modelli di calcolo
25
CAP. 3 – I WEB-SERVICE
Innanzitutto è opportuno chiarire che, in questo ambito, quando si parla di
modello Client/Server, ci si riferisce ad un’architettura software, vale a dire ad uno
schema dove esistono processi che forniscono servizi (server) e processi che
usufruiscono dei servizi (client), ciò però, non è necessariamente legato al fatto che i
due tipi di processi siano bipartiti su macchine distinte, una detta Client e l’altra
Server.
Questa precisazione è importante poiché in generale si tende a considerare
Client la macchina sulla quale si lavora, e Server la macchina alla quale ci si può
collegare per usufruire di un servizio. Purtroppo la coincidenza dei nomi può generare
confusione. Tipicamente molte applicazioni possono essere logicamente viste come se
composte da tre componenti. Nella prima componente troviamo l’interfaccia verso
l’utente, cioè tutti quei meccanismi che si occupano di manipolare gli input dalla
tastiera, dal mouse e dai vari dispositivi d’ingresso, nonché di fornire l’output verso
l’utente.
Nella seconda troviamo l’applicazione in senso più stretto, vale a dire
quell’insieme di funzionalità, specifiche del problema da risolvere. L’insieme di tali
funzionalità viene tipicamente riferito con il nome di “business logic”. Infine la terza
componente fornisce alle altre due quei servizi generali necessari e che si riferiscono,
ad esempio, alla comunicazione ed alla gestione dei dati. In un’architettura
Client/Server le componenti logiche di cui si è parlato possono essere poste su due o
tre differenti strati. Ciò porta a distinguere due diverse forme di architettura
Client/Server:
two-tier Client/Server architecture;
three-tier Client/Server architecture;
Nei due sottoparagrafi che seguono verranno brevemente illustrate queste due
differenti architetture ed al fine di rendere il discorso più concreto ci si riferirà, come
esempio, ad una applicazione che richiede servizi per la gestione di dati (database
service).
26
CAP. 3 – I WEB-SERVICE
Two-tier Client/Server architecture
In uno schema two-tier le tre componenti vengono implementate su due
differenti strati. Nel primo strato vengono poste le funzionalità relative all’interfaccia
ed una parte di quelle relative alla “business logic”, mentre nel secondo strato sono
poste le funzionalità di servizio (nel nostro esempio le funzioni di gestione della base
di dati) e quelle rimanenti della “business logic”.
I due strati corrispondono rispettivamente ad un processo Client e ad un
processo Server che comunicano tra di loro; il primo richiedendo servizi e l’altro
fornendo i servizi corrispondenti. Tipicamente la comunicazione viene realizzata
attraverso l’invocazione di procedure remote (RPC) oppure, nel caso di “database
server”, attraverso il linguaggio SQL.
Nel nostro esempio il costrutto SQL è inviato al processo Server che esegue nel
suo ambiente le computazioni corrispondenti e restituisce al Client i risultati della
richiesta. La comunicazione tra il Client ed il Server richiederà dunque il trasferimento
dei soli dati rilevanti per la query risparmiando evidentemente banda rispetto al
modello file sharing che avrebbe richiesto il trasferimento di più file.
Three-tier Client/Server architecture
Lo schema three-tier si sviluppa come evoluzione dello schema two-tier poiché
quest’ultimo risulta inadeguato per la soluzione di alcuni problemi complessi, ed
inoltre
presenta
alcuni
inefficenze
riguardanti
ad
esempio
la
scalabilità,
l’interoperabilità e la portabilità. Secondo il modello three-tier le tre componenti della
struttura logica di un’applicazione vengono implementate da altrettanti strati. La
realizzazione dell’applicazione risulta allora più complessa ma permette di rimediare
alle caratteristiche negative dell’architettura two-tier. Per illustrare, con un esempio,
questo tipo di architettura, consideriamo un sistema in cui siano presenti più database
server e supponiamo di dover eseguire una transazione che richieda l’accesso a dati
residenti su server distinti. Come è noto le caratteristiche di una transazione, che
devono essere garantite da un sistema che permetta l’esecuzione di tali operazioni su
basi di dati, sono: atomicità, serializzabilità e persistenza.
27
CAP. 3 – I WEB-SERVICE
L’utilizzo di un’architettura di tipo two-tier, si rivela in questo caso inefficente,
richiedendo una complessa coordinazione (sarebbe questa la parte della business
logic presente nel server) delle basi di dati presenti. Infatti, ogni database server
prevede
supporti
soltanto
per
l’esecuzione
di
transazioni
che
interessino
esclusivamente dati locali. La soluzione del problema passa attraverso l’introduzione di
un terzo strato che contenga tutta la business logic e si occupi di coordinare le diverse
basi di dati. Questo strato intermedio è riferito in letteratura con il nome di
Transaction Processing monitor.
I vantaggi più evidenti portati da una tale soluzione sono l’affrancamento del
Client dalle caratteristiche dei singoli database server e la realizzazione di una
architettura software in cui la modularità risulta enfatizzata.
Riassumendo possiamo dire che il modello Client-Server è “un modello di
interazione tra una coppia di processi uno dei quali richiede un servizio (Client) ad un
altro che lo fornisce (Server)”.
Fig. 3.2 – Il modello Client/Server nel World Wide Web
I Client e i Server sono dei moduli funzionali con interfacce ben definite (le
informazioni interne sono invisibili all’esterno). Le funzioni possono essere realizzate
da moduli hardware, software o da una combinazione dei due e l’interazione ClientServer (C/S) si attiva tra due moduli funzionali quando uno di essi (Client) richiede un
servizio e un altro (Server) decide di rispondere alla richiesta.
28
CAP. 3 – I WEB-SERVICE
Durante un’interazione i ruoli del Client e del Server rimangono immutati,
mentre possono variare per interazioni diverse.
Lo scambio di informazioni tra i moduli avviene attraverso messaggi (non
attraverso l’uso di variabili globali) ed il messaggio scambiato è una “capsula”
all’interno della quale vengono inseriti i dati oggetto della comunicazione e che viene
inviato al modulo corrispondente.
I messaggi scambiati sono tipicamente interattivi e generano l’attivazione di
processi all’interno dei moduli (eseguiti on-line). Esistono tuttavia rare eccezioni, come
i sistemi di gestione dei messaggi (posta elettronica), nei quali il server memorizza i
messaggi in una coda e li recupera in modo asincrono successivamente per inoltrarli.
Il World Wide Web introduce una nuova dimensione nell’architettura delle
applicazioni C/S: le interfacce utente sono sostituite dai Web Browsers (Clients) che
accedono direttamente ai documenti HTML gestiti dai Web Servers o da altre
applicazioni attrvarso i Gateways.
Fig. 3.3 – Il modello Client/Server nel World Wide Web (W3)
29
CAP. 3 – I WEB-SERVICE
Un server W3 può:
Fornire pagine statiche:
Alla richiesta di un client, che specifica tramite un URL il documento a cui è
interessato, recupera il file corrispondente e lo invia al richiedente.
Fig. 3.4 – Server come fornitore di servizi statici
Fornire pagine dinamiche:
In questo caso il server crea dinamicamente la pagina in base alle
richieste del client e la invia al richiedente.
Esistono vari strumenti per la realizzazione di questa funzione, quali ad
esempio PHP, CGI, Java Servlets
Fig. 3.5 – Server come fornitore di servizi dinamici
30
CAP. 3 – I WEB-SERVICE
Il client più diffuso nel W3 è invece un browser che tramite un’interfaccia
grafica permette di visualizzare i documenti contenuti nei siti W3. Essi sono costituiti
da un nucleo software principale che implementa le funzioni di base (interazione http,
interpretazione codice HTML, XML, JavaScript, esecuzione di programmi Java…).
Chiarita cosa sia un architettura C/S e i ruoli che svolgono il client e il server
all’interno di questa architettura è possibile fare un passo in avanti e introdurre il
concetto di Web-Service.
31
CAP. 3 – I WEB-SERVICE
3.2 Introduzione al Web-Service
Il paradigma del Service Oriented Computing è visto come una rivoluzione nella
comunità informatica e i Web services una sua realizzazione. La possibilità di vedere il
Web come un grande sistema informativo in cui sono forniti innumerevoli servizi offre
agli utenti finali un potentissimo strumento che va al di là del vero scambio di
informazioni che al momento rappresenta il Web.
I servizi web, meglio noti come Web services, sono diventanti uno degli
argomenti più attuali nel panorama dello sviluppo in ambiente Internet. Posti al centro
delle più recenti strategie di aziende del calibro di IBM, Microsoft e Sun, vengono
spesso descritti come una vera e propria rivoluzione nel mondo del Web ed in
particolare per tutto quanto attiene allo sviluppo di applicazioni distribuite ed
all'integrazione di applicazioni.
Focalizzando l’attenzione sul concetto di servizio è ovvio immaginare, anche alla
luce di quanto detto finora, come gli attori in causa siano necessariamente il fornitore
e il richiedente.
Questo tipo di paradigma è il medesimo che si riscontra nella tipica interazione
di tipo Client-Server. Attraverso la SOA (Service-Oriented Architecture) questa
interazione viene arricchita con un ulteriore attore detto Service Directory o Service
Broker che, come mostrato in figura 3.6, si inserisce all’interno della comunicazione
tra fornitore e fruitore del servizio.
Fig. 3.6 – Service Oriented Architecture
32
CAP. 3 – I WEB-SERVICE
Service Provider
Chi realizza e mette a disposizione un servizio. Tramite l’operazione di publish il
servizio viene “pubblicizzato”, in quanto le caratteristiche del servizio realizzato
vengono memorizzate all’interno di un registry accessibile pubblicamente. Il Service
Provider rimane, quindi, in attesa che un utente richieda tale servizio.
Service Directory o Service Broker
Questo componente si occupa della gestione del registry, permettendo, a chi
ha necessità, di ricercare un servizio sulla base delle caratteristiche con le quali è
stato definito e memorizzato. Naturalmente, il Service Directory può seguire politiche
di controllo degli accessi sulle interrogazioni in modo da limitare la visibilità sui servizi
inseriti. Nel presente lavoro il registry, viene considerato parzialmente accessibile.
Service Requestor
Rappresenta un potenziale utente che richiede un servizio. A tale scopo,
tramite la primitiva di find l’utente interagisce con il Service Directory per ottenere il
servizio più adatto ai propri obiettivi. Una volta individuato si collega al Service
Provider corrispondente (bind) e inizia a fruire del particolare servizio (use).
Partendo da questa considerazione si può dire che una architettura per e-
Service è un’istanza di una SOA dove il mezzo di comunicazione è di tipo elettronico,
mentre una architettura per Web service è un’istanza di una SOA dove il mezzo di
comunicazione considerato è il Web.
33
CAP. 3 – I WEB-SERVICE
3.3 Cosa sono i Web services e come funzionano
Un Web-Service è un componente applicativo. Possiamo definirlo come un
sistema software in grado di mettersi al servizio di un applicazione comunicando su di
una medesima rete tramite il protocollo HTTP.
Un Web-Service consente quindi alle applicazioni che vi si collegano di usufruire
delle funzioni che mette a disposizione. Esso comunica tramite protocolli e standard
definiti "aperti" e quindi sempre a disposizione degli sviluppatori ed ha una
caratteristica molto particolare ed utile al suo scopo: è auto-contenuto ed autodescrittivo, cioè è in grado di farci sapere che funzioni mette a disposizione (senza
bisogno di conoscerle a priori) e ci permette inoltre di capire come vanno utilizzate.
Il protocollo HTTP si occupa di mettere in comunicazione il servizio web con
l'applicazione che intende usufruire delle sue funzioni. Oltre ad HTTP però, i servizi
web utilizzano molti altri standard web, tutti basati su XML, tra cui:
•
XML Schema
•
UDDI (Universal Description, Discovery and Integration)
•
WSDL (Web Services Description Language)
•
SOAP (Simple Object Access Protocol)
È importante sottolineare che XML può essere utilizzato correttamente tra
piattaforme
differenti
(Linux,
Windows,
Mac)
e
differenti
linguaggi
di
programmazione. XML è inoltre in grado di esprimere messaggi e funzioni anche
molto complesse e garantisce che tutti i dati scambiati possano essere utilizzati ad
entrambi i capi della connessione. Si può quindi dire che i Web services sono basati su
XML ed HTTP e che possono essere utilizzati su ogni piattaforma e con ogni tipo di
software.
34
CAP. 3 – I WEB-SERVICE
3.3.1 XML Schema
Abbiamo detto che un Web service è auto-descrittivo. Con XML Schema
cominceremo a capire come fa un servizio web a disporre di questa caratteristica. XML
Schema serve per definire qual è la costruzione legale di un documento XML, come
fanno per esempio i DTD con le pagine web.
Vediamo una lista delle principali funzioni di XML Schema:
•
Definire gli elementi (tag) che possono apparire in un documento;
•
Definire gli attributi che possono apparire in un elemento;
•
Definire quali elementi devono essere inseriti in altri elementi (child);
•
Definire il numero degli elementi child;
•
Definire quando un elemento deve essere vuoto o può contenere testo,
elementi, oppure entrambi;
•
Definire il tipo per ogni elemento e per gli attributi (intero, stringa, ecc, ma
anche tipi personalizzati);
•
Definire i valori di default o fissi per elementi ed attributi;
Ecco un esempio di XML Schema in grado di descriverlo:
<?xml version="1.0"?>
<!-- iniziamo lo schema -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.XXXX.it/Guida_ai_Webservice"
xmlns="http://www.XXXX.it/Guida_ai_Webservice" elementFormDefault="qualified">
<!-- definiamo l'elemento libro -->
<xs:element name="libro">
<xs:complexType>
<xs:all>
<!-- definiamo i vari elementi child di libro -->
<xs:element name="titolo" type="xs:string" />
<xs:element name="autore" type="xs:string" />
<xs:element name="numeroDiPagine" type="xs:integer" />
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
35
CAP. 3 – I WEB-SERVICE
Per ora concentriamoci sul primo elemento: schema. Questo è l'elemento che
racchiude tutti i tipi di dato che andiamo a descrivere. Il tag <schema> può avere
diversi attributi.
•
xmlns:xs="..." stabilisce che gli elementi che iniziano con 'xs' provengono dal
namespace http://www.w3.org/2001/XMLSchema .
•
targetNamespace="..." definisce a quale namespace appartengono gli
elementi definiti con questo schema .
•
xmlns="..." definisce il namespace di default (quello applicato se non ne
escplicitiamo uno)
•
elementFromDefault="qualified" indica che ogni elemento usato nel
documento XML che utilizzerà questo schema dovrà essere qualificato.
Una volta aperto il tag <schema> bisogna inserire al suo interno tutti gli
elementi che vogliamo definire per il nostro documento. Esistono sostanzialmente due
tipi di elementi:
•
gli elementi semplici non possono contenere altri elementi e avere attributi.
Possono contenere solo testo.
•
gli elementi complessi possono contenere testo, altri elementi e attributi in
qualsiasi combinazione.
36
CAP. 3 – I WEB-SERVICE
3.3.2 UDDI
L'UDDI (acronimo di Universal Description Discovery and Integration) è
un registry (ovvero una base dati ordinata ed indicizzata), basato su XML ed
indipendente dalla piattaforma hardware, che permette alle aziende la pubblicazione
dei propri dati e dei servizi offerti su internet.
L ‘UDDI permette quindi la scoperta e l'interrogazione dei servizi offerti sul
web, delle aziende che li offrono e della maniera per usufruirne. Una "registrazione"
UDDI consiste, infatti, di tre diverse componenti:
•
Pagine bianche (White Pages): indirizzo, contatti (dell'azienda che offre uno o
più servizi) e identificativi;
•
Pagine gialle (Yellow Pages): categorizzazione dei servizi basata su tassonomie
standardizzate;
•
Pagine verdi (Green Pages): informazioni (tecniche) dei servizi fornite
dall'azienda
L'UDDI è uno degli standard alla base del funzionamento dei Web services: è
stato progettato per essere interrogato da messaggi in SOAP e per fornire il
collegamento ai documenti WSDL che descrivono i vincoli protocollari ed i formati dei
messaggi necessari per l'interazione con i Web services elencati nella propria
directory.
37
CAP. 3 – I WEB-SERVICE
3.3.3 WSDL
Il WSDL serve a specificare dove si trovano i servizi e le operazioni esposte dal
servizio web.
Cominciamo subito a vedere come un documento WSDL definisce un Web
service. All'interno del documento esistono quattro elementi principali:
•
<types>
•
<message>
•
<portType>
•
<binding>
<definitions>
<types>
<!-- definizione dei tipi di dato utilizzati... -->
</types>
<message>
<!-- definizione di uno dei messaggi impiegati dal web service per comunicare con
l'applicazione client -->
</message>
<!-- naturalmente può esistere più di un elemento message all'interno del documento -->
<portType>
<!-- definisce una "porta" e le operazioni che possono essere eseguite dal web service.
Definisce inoltre i messaggi coinvolti nelle operazioni elencate -->
</portType>
<binding>
<!-- definisce il formato del messaggio ed i
dettagli di protocollo per ogni porta -->
</binding>
</definitions>
38
CAP. 3 – I WEB-SERVICE
I types, message e portType sono elementi del messaggio WSDL all’interno di
definitions e sono usati per definire le operazioni:
• <types>
è usato per definire i tipi base necessari allo scambio
dell’informazione.
• <message>
è usato per definire il messaggio spedito e ricevuto ed utilizza i tipi
definiti in types.
• <portTypes> è usato per definire il funzionamento delle porte allocate dal
servizio come i messaggi da utilizzare in input e output.
Gli elementi binding e service sono usati per definire il protocollo associato
all’operazione:
• <binding> è usato per definire il protocollo da utilizzare per comunicare con la
porta su cui è allocata l’operazione (HTTP, SOAP,…).
• <service>
è usato per definire una porta come URL attraverso la quale si trova il
servizio.
Il WSDL inoltre definisce quattro tipi di operazioni attraverso il tag <operations>:
– One-way: è una chiamata asincrona al servizio.
– Request-responce: chiamata sincrona al servizio.
– Sollicit-responce: invia una risposta dopo un sollecito.
– Notification: ricevere una notifica.
39
CAP. 3 – I WEB-SERVICE
3.3.4 SOAP
E’ utile sapere che tutte le informazioni che
vengono definite da WSDL, è
grazie a SOAP (Simple Object Access Protocol) se vengono scambiate tra il Web
service è l'applicazione che vi accede. Questo protocollo fornisce una via per
comunicare tra applicazioni eseguite su sistemi operativi diversi, con diverse
tecnologie e linguaggi di programmazione, tramite HTTP ed XML.
Un messaggio SOAP è un documento XML che contiene i seguenti elementi:
•
Envelope, identifica il documento come un messaggio SOAP;
•
Un elemento Header opzionale, contenete informazioni specifiche per
l'applicazione, che non sarà approfondito in questa sede ma che permette di
definire alcuni messaggi, anche con diversi destinatari nel caso il messaggio
dovesse attraversare più punti di arrivo;
•
Body è un elemento indispensabile che contiene le informazioni scambiate
dalle richieste/risposte;
•
Fault è un elemento opzionale che fornisce informazioni riguardo ad eventuali
errori manifestati durante la lettura del messaggio.
Le regole principali per realizzare un messaggio SOAP sono le seguenti:
•
Deve essere ovviamente codificato con XML
•
Deve
utilizzare
il
SOAP
Evenelope
namespace
Encoding
namespace
(http://www.w3.org/2001/12/soap-envelope)
•
Deve
utilizzare
il
SOAP
(http://www.w3.org/2001/12/soap-encoding)
•
Non deve contenere il collegamento ad un DTD e non deve contenere
istruzioni per processare XML
Lo "scheletro" di un messaggio SOAP:
40
CAP. 3 – I WEB-SERVICE
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope
(http://www.w3.org/2001/12/soap-envelope)"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Header>
...
</soap:Header>
<soap:Body>
...
<soap:Fault>
...
</soap:Fault>
</soap:Body>
</soap:Envelope>
All'interno dell'elemento Envelope abbiamo definito i namespace soap evelope
ed encoding che come abbiamo visto sono richiesti per questo tipo di documento. Se
non vengono definiti o si definiscono diversamente le applicazioni coinvolte nella
comunicazione potrebbero generare un errore o scartare il messaggio.
41
CAP. 3 – I WEB-SERVICE
3.4 Apache Axis
Axis è il motore opensource più famoso per la creazione di Web services in
Java. Axis è un progetto dell'Apache Software Fondation e deriva da SOAP4J, un
progetto regalato dall'IBM ad Apache. Brevemente, si tratta di un’API di
programmazione e deployment di Web services che permette di lavorare ad un livello
di astrazione elevato, evitando così di dover maneggiare direttamente l’envelope
SOAP. Con Axis è possibile, dunque, implementare Web services e anche sviluppare
client di servizi di terzi. Per semplicità, viene esposto solo l’aspetto di funzionalità RPC
e non quello relativo ai vari approcci di messaging supportati da Axis. Ciò è comunque
in linea con la maggior parte della casistica Web services che si basa su meccanismi
request/response a dispetto del modello asincrono.
Axis 1.4 disponibile all’URL http://ws.apache.org/axis/ è composto da:
•
una web application che si occupa di gestire l'ambiente di esecuzione dei
servizi (routing, istance pooling, serializzazione e deserializzazione dei
messaggi SOAP, ecc...);
•
una API composta da classi di utilità per la scrittura di servizi web e da classi
necessarie al funzionamento della web application e dei tool;
•
una serie di tool, tra cui WSDL2Java per generare scheletri lato server e stub
lato client dei servizi web a partire dalla descrizione WSDL;
•
Java2WSDL per generare la descrizione come servizio web di una classe Java;
•
diversi tool per l'amministrazione e la gestione dei servizi installati;
•
un TCP monitor stand-alone ed un SOAP monitor integrato nella web
application per controllare la forma dei messaggi scambiati tra i servizi nelle
fasi di debug e test.
Tra le caratteristiche più interessanti di Axis c'è la possibilità di creare Web
service in maniera immediata a partire da classi Java molto semplici con estensione
.jws (Java Web Service).
42
CAP. 3 – I WEB-SERVICE
Axis può essere quindi utilizzato in una serie di scenari anche molto diversi tra
loro, ad esempio può servire per:
•
la creazione di applicazioni client di servizi web già esistenti per i quali è
disponibile il WSDL: utilizzando WSDL2Java si possono creare in maniera
automatica gli stub per l'accesso a servizi esistenti implementati con qualsiasi
piattaforma. Le applicazioni client che utilizzano gli stub non necessitano di
ambienti di esecuzione particolari ma soltanto della presenza della libreria
axis.jar nel proprio classpath;
•
la comunicazione via JAX-RPC tra processi Java: le API di Axis implementano
una versione di JAX-RPC, rendendo possibile lo sviluppo di applicazioni
distribuite Java con protocollo di trasporto SOAP;
•
la creazione di servizi web a partire da classi Java: Axis offre diversi
meccanismi per l'implementazione dei servizi. Quello più semplice e
completamente trasparente per il programmatore è JWS, ma sono disponibili
anche modelli di servizi più complicati dove è possibile personalizzare, ad
esempio, le modalità di serializzazione dei messaggi, la struttura dei package
ed il formato dei parametri, senza mai occuparsi della descrizione WSDL o del
formato SOAP dei messaggi, grazie all'integrazione tra l'ambiente di
esecuzione e Java2WSDL;
•
l'implementazione di servizi web a partire da descrizioni WSDL: il tool
WSDL2Java è particolarmente utile quando, come nel caso di Zlatan, si parte
dalla descrizione dei servizi per la realizzazione di un sistema piuttosto che
dalla loro implementazione.
I problemi principali di Axis riguardano lo stretto legame con il web application
container Tomcat (anche se è possibile con qualche sforzo installare l'ambiente in altri
server, come fatto con SJSAS8 in Zlatan) e la conformità soltanto parziale alle
specifiche del WS-I.
43
CAP. 3 – I WEB-SERVICE
Riassumendo possiamo dire che Axis non è che un SOAP engine: questo
significa che è un framework che si concentra unicamente sulle problematiche della
creazione di client e server e per la gestione di messaggi SOAP; in pratica consiste in
un insieme di tool per la generazione automatica di classi e in una libreria che
“incapsula” in classi Java l’accesso alle tecnologie connesse ai Web-Service.
L’architettura generale di Axis appare nella seguente figura nei suoi componenti
principali:
Fig. 3.7- Architettura generale di Axis.
Il requestor è un client che effettua una richiesta su alcuni dei protocolli
supportati da Axis. Generalmente è usato HTTP. Il requestor può essere una desktop
application, una web application, o un altro web service.
Il motore Axis agisce agevolando la comunicazione tra client e web service
maneggiando la traduzione ad e da web service standard.
Axis permette allo sviluppatore di definire una serie di handlers, allacciati alla
richiesta o alla risposta. Questi handlers sono simili a filtri servlet; ogni handler svolge
uno specifico compito adando avanti fino al prossimo handler in linea.
44
CAP. 4 – PROGETTAZIONE DEL DATABASE
Un ultimo passo prima di descrivere la realizzazione del progetto:
progettazione
fisica
del
database.
Specifica
delle
operazioni,
progettazione concettuale della base di dati, schema di progettazione
e script per la creazione del database.
INDICE ARGOMENTI:
4.1 Specifica delle operazioni
4.2 Progettazione concettuale
4.2.1 Un primo schema scheletro
4.2.2 Sviluppo delle componenti dello scheletro
4.2.3 Schema E-R completo
4.3 Traduzione verso il modello relazionale
4.4 Codifica SQL
45
CAP. 4 – PROGETTAZIONE DEL DATABASE
4.1 Specifica delle operazioni
Il modello base impostato ha come concetti di riferimento l’Utente
Richiedente, oggetto del servizio di assistenza e l’Utente Erogante, soggetti che
erogano il servizio di refertazione. Il richiedente (accreditato) che si interfaccia con
questo applicativo deve avere la possibilità di fare una richiesta “generica” (senza un
destinatario definito) pubblicando il risultato di una indagine clinica. A questo punto
un qualunque refertante accreditato può interagire con il nostro applicativo e fornire
una risposta al richiedente.
Se il richiedente è soddisfatto della refertazione ottenuta può chiudere il
processo di pubblicazione, altrimenti lasciare pubblicata la richiesta in attesa di
refertazione da parte di refertanti diversi.
Fig. 4.1 – Architettura del progetto JTelemed.
46
CAP. 4 – PROGETTAZIONE DEL DATABASE
4.2 Progettazione concettuale
Per quanto riguarda la Progettazione Concettuale del nostro DataBase,
abbiamo seguito una strategia mista come andremo a descrivere.
4.2.1 Un primo schema scheletro (top-down)
Sono state identificate inizialmente le seguenti entità (che hanno vita propria e
indipendente l’una delle altre): Utente Richiedente e Utente Refertante.
Ad un primo livello di astrazione è concepito il seguente schema scheletro:
4.2.2 Sviluppo delle componenti dello scheletro (inside-out)
Sia l’Utente Richiedente che l’Utente Refertante appartengono a delle strutture
cliniche accreditate e si differenziano tra di loro solo per il ruolo che ricoprono
nell’interfacciarsi con l’applicativo. Si può pensare, quindi, di accorpare queste due
entità in una sola entità e sfruttare una relazione ricorsiva.
Ogni UTENTE è caratterizzato da:
•
un identificativo univoco dell’utente all’interno del sistema, ID;
•
un CommonName che deve essere presente anche all’interno del certificato
digitale, CN;
•
un tipo di utente (R= utente richiedente, E= utente erogante), TYPE;
•
un codice identificativo dell’utente, CODENTE;
47
CAP. 4 – PROGETTAZIONE DEL DATABASE
•
un codice identificativo della struttura, CODSTRUTTURA;
•
un codice della specialità della struttura, CODSPECIALITA;
•
un codice identificativo dell’unità erogante, CODUNITAEROGANTE;
•
una username dell’utente per l’accesso al Repository, USERNAME;
•
una password dell’utente per l’accesso al Repository, PASSWORD.
La chiave primaria per questa entità è l’ID (univoco). Un utente richiedente può
emettere una o più richieste di refertazione [cardinalità (1,N)], mentre un utente
erogante può rispondere alle richieste di nessuno o più richiedenti [cardinalità (0,N)].
Ogni utente (richiedente o refertante) appartiene ad una UNITA’ EROGANTE
che è caratterizzata da:
•
un identificativo dell’ente, CODENTE;
•
un identificativo della struttura, CODSTRUTTURA;
•
un identificativo della specialità, CODSPECIALITA;
•
un codice dell’unità erogante, CODUNITAEROGANTE;
•
una descrizione dell’unità erogante, DESCR;
Le chiavi primarie sono: CODENTE, CODSTRUTTURA, CODSPECIALITA e
CODUNITAEROGANTE.
48
CAP. 4 – PROGETTAZIONE DEL DATABASE
A questo punto, è possibile definire un’entità TIPO ESAME che permetterà di
tener traccia di tutte le possibili patologie.
Ogni patologia è individuata da:
•
un codice identificativo della patologia dell’esame, CODICE;
•
una descrizione della patologia dell’esame, DESCR.
Ogni laboratorio accreditato che richiede una refertazione ad un altro laboratorio
genera un EVENTO.
Le informazioni necessarie per un qualsiasi evento risultano essere:
•
identificativo univoco dell’evento all’interno del sistema, ID;
•
identificativo univoco del richiedente, UTN_ID;
•
tipologia dell’esame collegato all’evento, TRF_CODICE;
•
data e ora di creazione dell’evento, DATE_OPEN;
•
data e ora di chiusura dell’evento, DATE_CLOSE;
•
il file allegato all’evento, ALLEGATO;
•
nome del file allegato, NOMEALLEGATO;
•
codice di ricerca esterna, CODICE_ESTERNO;
•
dati
aggiuntivi
del
paziente
quali
RAZZA,
SESSO, ETA,
ALTEZZA,
UM_ALTEZZA, PESO, UM_PESO, MEMO.
49
CAP. 4 – PROGETTAZIONE DEL DATABASE
Un utente può generare uno o più eventi (richiesta di refertazione) mentre un
evento è legato ad uno ed un solo utente [cardinalità: (1,N) ; (1,1)]. Ad ogni evento,
invece, è associata un’unica patologia.
Il richiedente deve essere un utente accreditato e quindi già registrato nella
tabella UTENTI: per questo motivo UTN_ID è chiave esterna con l’ ID della tabella
UTENTI.
La tipologia di esame deve essere una di quelle previste dalla tabella
TIPO_ESAMI, perciò TRF_CODICE è chiave esterna con il CODICE della tabella
TIPO_ESAMI.
dateclose
Quando un utente refertante fornisce una risposta ad un utente richiedente
genera un REFERTO.
Le informazioni necessarie per un qualsiasi referto risultano essere:
•
indice progressivo del referto dell’evento, IND;
•
identificativo univoco dell’evento all’interno del sistema, EVT_ID;
•
identificativo dell’utente che ha scritto il referto, UTN_ID;
•
file che contiene il referto in formato testo, ALLEGATO_REFERTO;
•
nome del file del referto, NOMEALLEGATO_REFERTO;
•
data e ora di inserimento del referto, DATEREFERTO.
50
CAP. 4 – PROGETTAZIONE DEL DATABASE
Un referto è la risposta ad un determinato evento: perciò EVT_ID è chiave
esterna con l’ID dell’evento. L’utente che ha effettuato il referto deve essere un ente
accreditato e già registrato nella tabella UTENTI: per questo motivo UTN_ID è chiave
esterna con l’ID della tabella UTENTI. Si noti che ad un evento possono essere
associati più referti (in generale potranno essere forniti referti ad un evento finché
l’evento non viene chiuso).
Ogni utente refertante potrà eseguire refertazioni solo ed esclusivamente sulle
patologie di competenza, ovvero solo per le patologie a lui accreditate; per questo
motivo si inserisce un’entità PERMISSIONI.
Tale entità è composta da due campi:
•
identificatore dell’utente, IDUTE (chiave primaria e chiave esterna con ID
della tabella UTENTI);
•
identificatore della patologia di competenza, CODESAME.
51
CAP. 4 – PROGETTAZIONE DEL DATABASE
52
CAP. 4 – PROGETTAZIONE DEL DATABASE
4.2.3 Schema E-R completo
dateclose
CAP. 4 – PROGETTAZIONE DEL DATABASE
4.3 Traduzione verso il modello relazionale
Tabella TM_UTENTI
Nome del campo
Tipo
Dim.
Identificat.
Chiave esterna
UTN_ID (Autonumber)
Number
10
UTN_CN
Varchar
128
UTN_TYPE
Varchar
1
UTN_CODENTE
Varchar
10
TM_UNITAEROGANTI.
UER_CODENTE
UTN_CODSTRUTTURA
Varchar
10
TM_UNITAEROGANTI.
UER_CODSTRUTTURA
UTN_CODSPECIALITA
Varchar
10
UTN_CODUNITAEROGANTE
Varchar
10
UTN_USERNAME
Varchar
20
UTN_PASSWORD
Varchar
20
Primary Key
TM_UNITAEROGANTI.
UER_CODSPECIALITA
TM_UNITAEROGANTI.
UER_CODUNITAEROGA
NTE
Tabella TM_ UNITAEROGANTI
Nome del campo
Tipo
Dim.
Identificatore
Varchar
10
Primary Key
UER_CODSTRUTTURA
Varchar
10
Primary Key
UER_CODSPECIALITA
Varchar
10
Primary Key
UER_CODUNITAEROGANTE
Varchar
10
Primary Key
UER_DESC
Varchar
50
UER_CODENTE
Chiave esterna
54
CAP. 4 – PROGETTAZIONE DEL DATABASE
Tabella TM_TIPOESAMI
Nome del campo
TES_CODICE
TES_DESCR
Tipo
Dim.
Identificatore
Varchar
10
Primary Key
Varchar
255
Chiave esterna
Tabella TM_EVENTI
Nome del campo
Tipo
Dim.
Identificatore
Chiave esterna
EVT_ID (Autonumber)
Number
10
Primary Key
EVT_UTN_ID
Number
10
TM_UTENTI.UTN_ID
EVT_TRF_CODICE
Varchar
10
TM_TIPOESAMI.TES_CODICE
EVT_DATEOPEN
Date
EVT_DATECLOSE
Date
EVT_ALLEGATO
Blob
EVT_NOMEALLEGATO
Varchar
25
EVT_CODICE_ESTERNO
Varchar
10
EVT_RAZZA
Varchar
25
EVT_SESSO
Varchar
1
EVT_ETA
Number
3
EVT_ALTEZZA
Number
(8,4)
EVT_UM_ALTEZZA
Varchar
10
EVT_PESO
Number
(8,4)
EVT_UM_PESO
Varchar
10
EVT_MEMO
Varchar
255
55
CAP. 4 – PROGETTAZIONE DEL DATABASE
Tabella TM_REFERTI
Nome del campo
Tipo
Dim.
Identificatore
Chiave esterna
REF_IND (Autonumber)
Number
10
Primary Key
REF_EVT_ID
Number
10
TM_EVENTI.EVT_ID
REF_UTN_ID
Number
10
TM_UTENTI.UTN_ID
REF_ALLEGATO_REFERTO
Blob
REF_NOMEALLEGATO_REFERT
O
Varchar
REF_DATEREFERTO
Date
REF_MEMO
Varchar
REF_DEFINITIVO
Char
25
255
1
Tabella TM_PERMISSIONI
Nome del campo
Tipo
Dim.
Identificatore
Chiave esterna
PER_UTN_ID
Number
10
Primary Key
TM_UTENTI.UTN_ID
PER_TES_CODICE
Varchar
10
Primary Key
TM_TIPOESAMI.TES_CODICE
56
CAP. 4 – PROGETTAZIONE DEL DATABASE
4.4 Codifica SQL
CREATE TABLE TM_UNITAEROGANTI (
uer_codente VARCHAR(10) DEFAULT '' NOT NULL,
uer_codstruttura VARCHAR(10) DEFAULT '' NOT NULL,
uer_codspecialita VARCHAR(10) DEFAULT '' NOT NULL,
uer_codunitaerogante VARCHAR(10) DEFAULT '' NOT NULL,
uer_descr VARCHAR(50) DEFAULT NULL,
PRIMARY KEY
(uer_codente,uer_codstruttura,uer_codspecialita,uer_codunitaerogan
te)
);
CREATE TABLE TM_TIPOESAMI (
tes_codice VARCHAR(10) DEFAULT '',
tes_descr VARCHAR(255) DEFAULT '' NOT NULL,
PRIMARY KEY (tes_codice)
);
CREATE TABLE tm_utenti (
utn_id NUMBER(10) PRIMARY KEY,
utn_cn VARCHAR(128) DEFAULT NULL UNIQUE,
utn_type VARCHAR(1) DEFAULT 'M' NOT NULL,
utn_codente VARCHAR(10) DEFAULT NULL,
utn_codstruttura VARCHAR(10) DEFAULT NULL,
utn_codspecialita VARCHAR(10) DEFAULT NULL,
utn_codunitaerogante VARCHAR(10) DEFAULT NULL,
utn_username VARCHAR(20),
utn_password VARCHAR(20),
FOREIGN KEY (utn_codente, utn_codstruttura, utn_codspecialita,
utn_codunitaerogante)
REFERENCES TM_UNITAEROGANTI(UER_CODENTE, UER_CODSTRUTTURA,
UER_CODSPECIALITA, UER_CODUNITAEROGANTE)
);
CREATE SEQUENCE TM_UTENTI_SEQ
START WITH 1
INCREMENT BY 1
NOMAXVALUE;
57
CAP. 4 – PROGETTAZIONE DEL DATABASE
CREATE TRIGGER TM_UTENTI_TRIGGER
BEFORE INSERT ON TM_UTENTI
FOR EACH ROW
BEGIN
SELECT TM_UTENTI_SEQ.NEXTVAL INTO :NEW.UTN_ID FROM DUAL;
END;
CREATE TABLE tm_eventi (
evt_id NUMBER(10) NOT NULL,
evt_utn_id NUMBER(10) DEFAULT NULL,
evt_trf_codice VARCHAR(10) DEFAULT NULL,
evt_dateopen DATE DEFAULT NULL,
evt_dateclose DATE DEFAULT NULL,
evt_allegato BLOB,
evt_nomeallegato VARCHAR(25) DEFAULT '--',
evt_codice_esterno VARCHAR(10) DEFAULT '--',
evt_razza VARCHAR(25) DEFAULT '--',
evt_sesso VARCHAR(1) DEFAULT '--',
evt_eta NUMBER(3) DEFAULT 0,
evt_altezza NUMBER(8,4),
evt_um_altezza VARCHAR(10),
evt_peso NUMBER(8,4),
evt_um_peso VARCHAR(10),
evt_memo VARCHAR(255) DEFAULT '-',
PRIMARY KEY (evt_id),
FOREIGN KEY (evt_trf_codice) REFERENCES
TM_TIPOESAMI(tes_codice),
FOREIGN KEY (evt_utn_id) REFERENCES TM_UTENTI(utn_id)
);
CREATE SEQUENCE TM_EVENTI_SEQ
START WITH 1
INCREMENT BY 1
NOMAXVALUE;
CREATE TRIGGER TM_EVENTI_TRIGGER
BEFORE INSERT ON TM_EVENTI
FOR EACH ROW
BEGIN
SELECT TM_EVENTI_SEQ.NEXTVAL INTO :NEW.EVT_ID FROM DUAL;
END;
58
CAP. 4 – PROGETTAZIONE DEL DATABASE
CREATE TABLE tm_referti (
ref_ind NUMBER(10) NOT NULL,
ref_evt_id NUMBER(10) DEFAULT '0' NOT NULL,
ref_utn_id NUMBER(10) DEFAULT '0' NOT NULL,
ref_allegato_referto BLOB,
ref_nomeallegato_referto VARCHAR(25),
ref_datereferto DATE,
PRIMARY KEY (ref_ind),
FOREIGN KEY (ref_evt_id) REFERENCES TM_EVENTI (evt_id),
FOREIGN KEY (ref_utn_id) REFERENCES TM_UTENTI (utn_id)
);
CREATE SEQUENCE TM_REFERTI_SEQ
START WITH 1
INCREMENT BY 1
NOMAXVALUE;
CREATE TRIGGER TM_REFERTI_TRIGGER
BEFORE INSERT ON TM_REFERTI
FOR EACH ROW
BEGIN
SELECT TM_REFERTI_SEQ.NEXTVAL INTO :NEW.REF_IND FROM DUAL;
END;
CREATE TABLE TM_PERMISSIONI (
per_utn_id NUMBER(10) DEFAULT '0' NOT NULL,
per_tes_codice VARCHAR(10) DEFAULT '' NOT NULL,
PRIMARY KEY (per_utn_id, per_tes_codice),
FOREIGN KEY (per_utn_id) REFERENCES TM_UTENTI(utn_id),
FOREIGN KEY (per_tes_codice) REFERENCES TM_TIPOESAMI
(tes_codice)
);
59
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
Descrizione dell’ambiente con cui è stato sviluppato il Web-Service e
dei servizi da esso messi a disposizione. Dettagli su aspetto critico
della comunicazione Client-Server: gli attachments.
INDICE ARGOMENTI:
5.1 Preparazione dell’ambiente di sviluppo
5.3 Servizi offerti dal Web-Service
5.2 Fase di deploy
5.4 Una possibile e particolare implementazione del client
5.5 Attachments
5.6 Comunicazione Client-Server
60
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
5.1 Preparazione dell’ambiente di sviluppo
Per la creazione dell’ambiente di sviluppo si è proceduto come segue:
•
Installazione della JDK 1.5 e della JRE 1.5 mediante l’utilizzo del kit J2SE
Development Kit 5.0; in tal modo si è creata la cartella C/Programmi/Java
contenente le sottodirectory jdk1.5.0 e jre1.5.0.;
•
Installazione dell’Application Server JAKARTA TOMCAT (vedremo più avanti
cosa sia) attraverso l’eseguibile jakarta-tomcat-5.5.4.exe; nella fase di
installazione, per prima cosa, è stata selezionata l’opzione per l’aggiunta del
componente
opzionale
Webapps ed infine si è
selezionato
Destination
cartella
per
come
folder
la
C:/TOMCAT554;
verificare
l’effettivo
funzionamento
del
Tomcat si è visualizzata la
home page del medesimo
attraverso
l’URL
http://localhost:8080;
•
Come IDE di sviluppo è stato scelto Eclipse: la versione a cui faremo
riferimento è la WTP 1.5 AllInOne. Tale sigla sta per Web Tools Project, e
contiene, fra l'altro, Eclipse 3.2. In questa versione ci sono già molte
funzionalità rivolte al Web, come suggerisce il nome. L'installazione è
semplicissima, anzi, non necessita neanche di una installazione. Una volta
scaricato il file compresso è sufficiente scompattarlo ed Eclipse è già pronto.
La prima volta che avviamo Eclipse viene chiesta la directory dove salvare i
nostri progetti. Una volta scelta, ci troveremo di fronte all'ambiente grafico di
sviluppo.
61
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
•
Istallazione di APACHE AXIS che consiste nei due seguenti passi:
Fig. 5.1 - Cartella scompattata di Axis.
1) Scompattare Axis, prendere la cartella lib e copiarla all'interno della
installazione di Eclipse.
2) Prendere la cartella axis dentro webapps e incollarla sull'omonima cartella di
Tomcat.
A questo punto abbiamo tutti gli strumenti necessari per creare il nostro
Web service, ma prima di iniziare vediamo la disposizione delle varie librerie:
•
per un corretto funzionamento dell’applicativo lato server sono necessarie le
seguenti librerie nella directory della JDK (nel nostro caso versione 1.5)
C:/Programmi/Java/jdk1.5.0/jre/lib/ext.:
dnsns.jar
sunjce_provider.jar
localedata.jar
sunpkcs11.ja
62
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
•
•
le librerie necessarie sotto C:/TOMCAT554/common/lib sono:
activation.jar
mail.jar
commons-el.jar
naming-factory-dbcp.jar
jasper-compiler jdt.jar
naming-factory.jar
jasper-compiler.jar
naming-resources.jar
jasper-runtime.jar
ojdbc14.jar
jsp-api.jar
servlet-api.jar
le librerie necessarie sotto C:/TOMCAT554/webapps/axis/WEB-INF/lib sono:
activation.jar
jaxrpc.jar
axis-ant.jar
log4j-1.2.8.jar
axis.jar
mail.jar
commons-discovery-0.2.jar
saaj.jar
commons-logging-1.0.4.jar
wsdl4j-1.5.1.jar
Chiarite le posizioni delle varie librerie cominciamo a costruire il nostro Web
service a partire dalla IDE di sviluppo Eclipse:
•
Innanzitutto selezionare dalla toolbar la voce File->New->Project (figura 5.2).
Nella successiva finestra indicare il tipo di progetto che si vuole realizzare, nel
nostro caso un Dinamic Web Project (figura 5.3).
63
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
Fig. 5.2 – Creazione del Web Service
Il primo passo per la costruzione di un Web-Service è rappresentato dalla
scelta del tipo di progetto tra quelli che l’IDE Eclipse mette a disposizione. Nella
figura successiva si può notare che esistono varie tipologie di progetti, una delle
quali dedicata al mondo del Web.
64
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
Fig. 5.3 – Creazione del Web service
Non è difficile riconoscere quale sia effettivamente il tipo di progetto da
selezionare per la creazione di un web service: aprire la directory Web e
selezionare la voce Dynamic Web Project
•
Successivamente verrà chiesto di dare un nome al nuovo progetto e di lavorare
con delle impostazioni. Per il nostro scopo è possibile utilizzare le impostazioni di
default e una volta completata la procedura l’interfaccia di eclipse appare nel
seguente modo (figura 5.4):
65
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
Figura 5.4 - L’interfaccia di Eclipse
•
Come ultimo passo non rimane altro che testare il prototipo di applicazione
costruito; per fare ciò basta lanciare l’applicazione stessa all’interno di Eclipse
attraverso il comando Run.
Poiché abbiamo però costruito una web application, occorre definire il server su
cui far girare il progetto: Eclipse a questo scopo ci permette di impostare una
sorta di server interno che si appoggia all’Application Server istallato sulla
macchina di sviluppo, nel nostro caso JAKARTA TOMCAT.
Vediamo brevemente come funziona il tutto. Con il tasto destro del mouse
cliccare sull’icona del progetto che appare nella Resource Navigator view e
scegliere Run As -> Run On Server (figura 5.5).
66
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
Successivamente
selezionare
dall’elenco
messo
a
disposizione il server desiderato,
in questo caso Apache Tomcat
v.5.5 (figura 5.6). Anche in
questo
caso
è
possibile
modificare delle impostazioni,
ma
non
è
controidicativo
utilizzare quelle di default.
Concludendo tale procedimento
guidato l’istallazione del nostro
server interno è completata e
l’applicazione
Fig. 5.5 – Impostare il server di Eclipse (1)
è
pronta
per
essere utilizzata (figura 5.7).
Figura 5.6
Impostare
il
server
di
Eclipse (2).
E’ necessario selezionare
dall’elenco
di
figura
lo
stesso Application Server
che si è istallato sulla
macchina di lavoro.
Come
sempre
facciamo
riferimento a questo caso
che
utilizza
un
Tomcat
versione 5.5
67
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
Fig. 5.7 – Impostare il server di Eclipse (3)
Come ulteriore verifica della funzionalità del server possiamo utilizzare la Console:
Figura 5.8 – La Console di Eclipse
Come vedremo più avanti Eclipse mette inoltre a disposizione un ulteriore
strumento di controllo in fase di utilizzo dei servizi, il TCP/IP Monitor.
68
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
•
Ora tutto il nostro sistema è funzionante, ma prima di ultimare il lavoro occorre
fare un piccolo passo indietro. Conclusa la fase di editing con la creazione delle
classi che implementano i servizi occorre costruire il descrittore dei servizi, il
WSDL. Ricordiamo che il WSDL serve a specificare dove si trovano i servizi e le
operazioni esposte dal servizio web.
L’Eclipse mette a disposizione
un meccanismo rapido ed
efficiente per la creazione
automatica di tale descrittore
che fisicamente non è altro
che un file xml. Cliccare con il
tasto destro del mouse sulla
classe
nella
quale
sono
definiti i servizi che il nostro
progetto
vuole
realizzare.
Selezionando la voce Web
Service -> Create Web
Service (figura 5.9) si apre
una finestra di impostazioni
(figura 5.10): “spuntare” le
due voci Publish the Web
service e Monitor the Web
service;
inoltre
se
è
necessario il TCP/IP Monitor
Fig. 5.9 – Generazione del WSDL (1)
spostare
la
completamente
barra
in
(1)
alto.
Successivamente apparirà un’ulteriore finestra nella quale è possibile selezionare
tutti i servizi da inserire nel wsdl e scegliere il cosiddetto “Style and use”
impostandolo a RPC/Encoded.
Questa caratteristica rappresenta la scelta del formato di un messaggio SOAP.
69
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
Le possibili scelte di SOAP:Body di un messaggio SOAP sono:
-
document: il SOAP Body del documento contiene una o più "parts" che dal
punto di vista di XML sono childNodes di SOAP:Body. Non ci sono particolari
regole sulla struttura di questi nodi figli.
- RPC: il SOAP:Body contiene un elemento il cui nome corrisponde al nome
della procedura remota da invocare e un elemento per ogni parametro da
fornire alla procedura.
La serializzazione del SOAP:Body prevede:
-
encoded: le regole di serializzazione sono dettate dalla sezione 5 della
specifica SOAP 1.1 .
-
literal: i dati sono serializzati nel rispetto di una specifica XML che ad oggi è
XML Schema Definition 1.0, domani potrebbe essere altro.
In .NET tutto questo si trasforma nell'utilizzare, come decorazione dei nostri
WebMethod, uno dei due seguenti attributi:
-
SoapRpcMethod: il SOAP:Body sarà RPC/encoded.
-
SoapDocumentMethod: SOAP:Body in formato document. Se la proprietà
Use vale SoapBindingUse.Literal il body sarà document/literal, se invece Use
vale SoapBindingUse.Encoded avremo un body document/encoded. Se la
proprietà
ParameterStyle
vale
SoapParameterStyle.Bare
avremo
i
parametri inviati tra i SOAP Node posizionati direttamente all'interno del
SOAP:Body.
Se
invece
la
proprietà
ParameterStyle
vale
SoapParameterStyle.Wrapped i parametri saranno inviati tra i due SOAP
node, racchiusi all'interno di un solo elemento, figlio di SOAP:Body. Il default
di ASP.NET è Literal, Wrapped.
70
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
Barra (1).
Spostare la barra
completamente in
alto per avere il
TCP/IP Monitor
Opzioni da
selezionare
Figura 5.10.
Generazione del
WSDL (2)
Risultato di tutta questa procedura è un file .wsdl di cui riportiamo un piccolo
frammento:
INTESTAZIONE
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://services.jtelemed.it"
xmlns:apachesoap="http://xml.apache.org/xml-soap"
xmlns:impl="http://services.jtelemed.it" xmlns:intf="http://services.jtelemed.it"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!--WSDL created by Apache Axis version: 1.3
Built on Oct 05, 2005 (05:23:37 EDT)-->
71
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
DEFINIZIONE DEI METODI
<wsdl:message name="openeventResponse">
<wsdl:part name="openeventReturn" type="xsd:int"/>
</wsdl:message>
<wsdl:message name="userinfoResponse">
<wsdl:part name="userinfoReturn" type="xsd:string"/>
</wsdl:message>
<wsdl:message name="listeventsResponse">
<wsdl:part name="listeventsReturn" type="xsd:string"/>
</wsdl:message>
PORT TYPE
<wsdl:portType name="WSRepository">
<wsdl:operation name="echo" parameterOrder="value">
<wsdl:input message="impl:echoRequest" name="echoRequest"/>
<wsdl:output message="impl:echoResponse" name="echoResponse"/>
</wsdl:operation>
<wsdl:operation name="userinfo" parameterOrder="utn_cn username password">
<wsdl:input message="impl:userinfoRequest" name="userinfoRequest"/>
<wsdl:output message="impl:userinfoResponse" name="userinfoResponse"/>
</wsdl:operation>
72
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
BINDING
<wsdl:binding name="WSRepositorySoapBinding" type="impl:WSRepository">
<wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="echo">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="echoRequest">
<wsdlsoap:body encodingStyle=http://schemas.xmlsoap.org/soap/encoding/
namespace="http://services.jtelemed.it" use="encoded"/>
</wsdl:input>
<wsdl:output name="echoResponse">
<wsdlsoap:body encodingStyle=http://schemas.xmlsoap.org/soap/encoding/
namespace="http://services.jtelemed.it" use="encoded"/>
</wsdl:output>
</wsdl:operation>
SERVIZI
<wsdl:service name="WSRepositoryService">
<wsdl:port binding="impl:WSRepositorySoapBinding" name="WSRepository">
<wsdlsoap:address
location="http://localhost:8080/jtelemed/services/WSRepository"/>
</wsdl:port>
</wsdl:service>
Infine per testare l’effettivo funzionamento del Web-Service occorre creare un
client che si interfacci con i servizi messi a disposizione. Anche in questo caso l’Eclipse
ha una via veloce ed efficiente: riprendendo lo schema di figura 5.9, basta selezionare
Generate Sample JSPs.
73
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
Nel Resource Navigator view di Eclipse apparirà una nuova directory:
Lanciando
l’applicazione
server appare
sul
una Directory
Listing For sampleWSRepository
dove WSRepository è la classe
con la quale è costruito il Web
service.
La lista è composta da quatto
link ai file .jsp evidenziati in
figura.
Selezionando “TestClient.jsp” si
accede alla fase di testing dei
servizi.
Fig. 5.11 – Creazione del client di test
74
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
5.2 Servizi offerti dal Web-Service
Come ormai più volte detto, un Web-Service è un’entità in grado di soddisfare
delle richieste da parte di un generico client, ovvero uno strumento software che
mette a disposizione dei suoi utilizzatori determinati servizi. Dunque descrivere
l’implementazione del Web-Service significa descrivere i servizi da esso messi a
disposizione, i meccanismi per invocare tali servizi e il criterio di elaborazione e
produzione dei risultati.
La struttura è molto semplice:
WSRepository
Application
DateTime
FileUtil
String Util
wsApp
WSRepository()
echo(…)
userinfo(…)
listevents(…)
openEvent(….)
closeEvent(…)
downloadEvent(…)
referta(…)
listEventsReferted(…)
listEventsRefertedByEvtId(…)
downloadRefert(…)
showStoric(…)
listRefertForErogants(…)
refertToEvent(…)
updateRefert(…)
75
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
Il cuore del sistema è rappresentato dalla classe WSRepository che,
appoggiandosi alle classi Application, DateTime, FileUtil e StringUtil (blocchi verdi),
offre una serie di funzioni che permettono la gestione del repository. In figura è
evidenziata la struttura della classe con i metodi esposti (quelli nel riquadro di colore
fucsia), cioè quei metodi che costituiscono l’interfaccia con cui è possibile comunicare
con l’oggetto.
Sarà poi questa interfaccia ad essere tradotta da codice Java in un file WSDL,
ovvero il documento xml che descrive i metodi forniti da un Web-Service. Questo file
viene poi pubblicato e reso disponibile a chiunque voglia fruire di uno dei servizi web
forniti, per visualizzarlo basta richiamare l’URL WSRepository?wsdl a partire dal
percorso che contiene il Web-Service.
Questo file è fondamentale nell’architettura distribuita, perchè rappresenta
come è possibile comunicare e interagire con il server e quindi anche come costruire
un client che lo possa sfruttare.
In ambiente Java è presente un tool, Java2WSDL, che automatizza questo
processo e si carica del tedioso lavoro di creazione del file descrittore WSDL a partire
da una classe Java.
Ad ogni metodo pubblico della classe corrisponderà un metodo del web service,
richiamabile
attraverso
una
URL
in
un
formato
particolare:
WSRepository?method=”nome del metodo”&”nome del parametro”=”valore del
parametro”&...
Dall’altra parte, è presente un tool che compie il lavoro inverso: WSDL2Java, a
partire dal descrittore WSDL crea le classi per una minima implementazione del client.
Per maggiori informazioni su questi tool è possibile consultare la documentazione
della Sun. Vediamo ora una panoramica dei metodi esposti dalla classe WSRepository.
Anche se il cuore del sistema è costituito dalla classe WSRepository,
quest’ultima
sgrava
i
suoi
compiti
alla
classe
Application
che
contiene
l’implementazione effettiva dei servizi messi a disposizione del Web-Service.
Per cui di seguito verrà trattata l’implementazione dei metodi di Application.
76
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
All’interno di essa, una qualsiasi applicazione JDBC deve:
1. Creare una connessione con il DataBase
2. Creare un oggetto Statement per interrogare il database.
3. Interagire con il database.
4. Gestire i risultati ottenuti.
Come detto ogni servizio richiede inizialmente di creare una connessione al
DataBase, che viene realizzata tramite il metodo setConnection().
setConnection():
L'API JDBC, racchiusa nel package java.sql.*, fornisce un'interfaccia unificata
per l'accesso ad un qualunque database, "mascherando" le peculiarità di ogni singolo
DBMS introducendo il concetto di driver.
Per capire meglio cosa questo significhi basta dare un'occhiata alla
documentazione del pacchetto java.sql: ci si accorge immediatamente che la maggior
parte delle funzionalità vengono fornite tramite interfacce (cioè tipi puramente
astratti), mentre le classi vere e proprie sono davvero poche. Cosa implica tutto ciò?
Semplicemente, l'API JDBC si limita in gran parte a dichiarare le funzionalità che
un'interfaccia generalizzata per l'accesso ad un database dovrebbe avere, delegando
l'implementazione delle interfacce ai driver che devono fornire l'accesso ai singoli
DBMS. Quindi, compito di un driver JDBC è fornire un insieme di classi che
implementino tutte le interfacce dichiarate nel pacchetto java.sql.
I parametri di connessione vengono recuperati da un file di Properties tramite
l’istruzione di load(…). Il file DBConfig2 contenente tutti i parametri di connessione ed
è situato nella cartella di installazione del TOMCAT, mentre per recuperare
informazioni scritte sul file viene usato il comando getProperty(…).
Quindi
in
tal
modo
è
possibile
(props.getPropery(“JDBCConnectionURL.1”)
recuperare
e
il
driver
l’URL
di
connessione
necessario
per
la
connessione(props.getPropery(“JDBCConnectionURL.1”).
77
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
L’istruzione successiva carica in memoria il driver JDBC per l’accesso al DBMS,
infatti le specifiche JDBC redatte dalla Sun prevedono che, per poter essere utilizzato,
un driver JDBC deve essere caricato in memoria, e una volta che ciò è avvenuto, il
driver stesso ha il compito di registrarsi presso il Driver Manager, il quale ha quindi il
compito di tenere traccia dei driver JDBC disponibili, in modo da poter costruire
correttamente
le
istanze
delle
classi
che
implementano
l'interfaccia
java.sql.Connection quando queste vengono richieste dalle applicazioni.
Successivamente vengono recuperate dal file di Property la Username per
accedere
al
DB
(props.getProperty("UserName.1"))
e
la
password
(props.getProperty("UserName.1")). Tramite l’istruzione setPropery() assegno alla
stringa jdbc.driver il valore di driver_class, ovvero il driver per la connessione al DB.
E’ molto importante settare il Driver in quanto converte chiamate JDBC in
chiamate di rete dirette utilizzando protocolli di rete specifici del database (socket),
inoltre è semplice da utilizzare in quanto non richiede di avere librerie o software
speciali.
Ottenere una connessione al database tramite JDBC è abbastanza semplice ed
indipendente da quale tipo di DBMS si stia utilizzando. E’ necessario solamente
indicare all’applicazione, tramite il DriverManager, quale driver utilizzare e farsi
rilasciare un oggetto Connection che servirà per dialogare con la base dati. E’ da
notare che per identificare il database è necessario specificare l’URL, ossia l’indirizzo
verso il quale tentare la connessione. Questa stringa può variare in base al tipo di
driver utilizzato, e, alcune volte, può richiedere anche la specificazione di login e
password dell’utente, come nel nostro caso.
La classe DriverManager non è l'unica che permette la connessione con un DB,
ma è possibile utilizzare anche l'interfaccia Driver che permette di accedere a tutte le
informazioni che riguardano il db. JDBC permette di sfruttare una delle caratteristiche
piu' importanti dei Database ovvero la gestione delle transazioni. Tale gestione si
effettua attraverso due semplici metodi della classe Connection: commit e rollback. Il
significato dei due metodi e' quello che ci si aspetta: il metodo commit rende
definitive tutte le modifiche apportate usando la connessione fino al precedente
commit o rollback, viceversa il metodo rollback le annulla fino al precedente commit.
78
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
All'apertura di una connessione la connessione stessa puo' rendere definitiva
ogni singola modifica senza bisogno di chiamare esplicitamente il metodo commit
(Auto Commit). Per fare in modo che la semantica dei metodi commit e rollback sia
quella descritta prima dobbiamo togliere l'Auto Commit nella connessione usando il
metodo setAutoCommit(false). E' chiaro che i metodi per la gestione delle transazioni
hanno effetto su tutte e sole le operazioni effettuate sul DB tramite la connessione su
cui vengono invocati i metodi stessi.
public void setConnection()
throws
IllegalAccessException
, InstantiationException
, ClassNotFoundException
, SQLException
, FileNotFoundException
, IOException{
try {
Properties props= new Properties();
FileInputStream in = new
FileInputStream(System.getProperty("catalina.home")+
File.separator+"DBConfig2");
props.load(in);
in.close();
String connectionURL=props.getProperty("JDBCConnectionURL.1");
String driver_class= props.getProperty("JDBCDriver.1");
Class.forName (driver_class).newInstance();
String dbUser= props.getProperty("UserName.1");
String dbPassword= props.getProperty("Password.1");
System.setProperty("jdbc.drivers", driver_class);
conn = DriverManager.getConnection(connectionURL, dbUser,
dbPassword);
conn.setAutoCommit(false);
System.out.println("Connected.\n");
}
catch (IllegalAccessException e) {
System.out.println("Illegal Access Exception: (Open
Connection).");
e.printStackTrace();
throw e;
}
catch (InstantiationException e) {
System.out.println("Instantiation Exception: (Open
Connection).");
e.printStackTrace();
throw e;
}
catch (ClassNotFoundException e) {
System.out.println("Class Not Found Exception: (Open
Connection).");
e.printStackTrace();
throw e;
}
catch (SQLException e) {
System.out.println("Caught SQL Exception: (Open
Connection).");
e.printStackTrace();
throw e;
}
catch (FileNotFoundException e) {
System.out.println("Caught : FileNotFoundException (Open
connection).");
e.printStackTrace();
throw e;
}
}
79
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
Come file di Properties è stato utilizzato un semplice file di testo all’interno del
quale sono settati i valori assegnati alle variabili per la connessione, ovvero il driver,
l’URL di connessione, la Username e la Password.
String driver_class
= "oracle.jdbc.driver.OracleDriver";
String connectionURL =
"jdbc:oracle:thin:@172.18.11.201:1521:ora920";
String dbUser="STAGE04";
String dbPassword="STAGE04";
authentication():
Ogni servizio per implementare un maggior livello di sicurezza richiede come
parametro username e password. Tramite la funzione authentication() il Web-Service
va a controllare nel proprio database l’esistenza effettiva dell’utente che ha richiesto di
essere loggato. Ciò equivale a realizzare la seguente query:
SELECT count(*) from tm_utenti,tm_unitaeroganti
WHERE utn_username='"+username+"'
AND utn_password='"+password+"'
AND utn_codente=uer_codente
AND utn_codstruttura=uer_codstruttura
AND utn_codspecialita=uer_codspecialita
AND utn_codunitaerogante=uer_codunitaerogante
Se il risultato è diverso da zero (dovrebbe essere al massimo uguale ad uno),
significa che il Web-Service ha riconosciuto l’utente come utente autorizzato e gli
permette l’accesso all’interno dell’applicazione.
80
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
userInfo():
Tale metodo restituisce tutte le informazioni relative ad un dato utente.
setConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT utn_id, utn_type, utn_codente,
utn_codstruttura, utn_codspecialita FROM tm_utenti WHERE utn_cn = " +
StringUtil.quoteString(utn_cn));
if (rs.next()) {
info = rs.getInt(1) + ";" + rs.getString(2) + ";" + rs.getString(3)
+ ";" + rs.getString(4)+";"+rs.getString(5);
}
rs.close();
stmt.close();
conn.close();
Come visto precedentemente la connessione al database viene effettuata
tramite il metodo setConnection(), successivamente viene creato lo Statement e il
ResultSet a cui viene assegnato il risultato della query.
I comandi di scrittura come INSERT, UPDATE e DELETE restituiscono un valore
che indica quante righe sono state affette (inserite, modificate, cancellate)
dall'istruzione. Essi non restituiscono altre informazioni.
Le interrogazioni (query) restituiscono un result set (classe ResultSet). È
possibile spostarsi nel result set riga per riga (tramite il metodo next()). Si può
accedere alle colonne di ogni singola riga chiamandole per nome o per numero. Il
ResultSet può essere costituito da un numero qualsiasi di righe. Esso comprende dei
metadati che indicano il nome, il tipo e le dimensioni delle colonne.
Per le stringhe viene utilizzato il metodo quoteString() della classe StringUtil
contenente funzioni di utilità per la loro gestione, soprattutto in fase di
interfacciamento con i data base (query e insert).
81
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
listEvents(double utn_id, double days):
Metodo usato dal refertante, che ritorna l’elenco degli eventi che il dottore è in
grado di refertare/visualizzare. Essendo un metodo utilizzato dal refertante
inizialmente vi è una select che controlla se l’utente è un erogante. In caso positivo
viene fatto un controllo sul tipo di esami che l’erogante è in grado di refertare, tramite
la seguente query:
SELECT per_tes_codice FROM TM_PERMISSIONI WHERE per_utn_id = "+utn_id+"
cioè restituisce il codice che identifica il tipo di esame di possibile refertazione.
I valori ottenuti dall’interrogazione devono essere inviati al client per alimentare
una griglia, quindi viene creato un file xml contenente il risultato della query.
fileName=FileUtil.createXML("SELECT evt_id, evt_dateopen, evt_utn_id,
utn_cn, evt_trf_codice, tes_descr,
evt_sesso, evt_razza, evt_eta,
evt_altezza,evt_um_altezza, evt_peso,
evt_um_peso, evt_memo,COUNT(REF_IND)
REFERTI
FROM TM_EVENTI, TM_TIPOESAMI, TM_UTENTI,
TM_REFERTI
WHERE evt_utn_id=utn_id
AND evt_trf_codice=tes_codice
AND evt_trf_codice IN (" +sql_viewexams+ ")
AND evt_dateclose IS NULL
AND EVT_ID=REF_EVT_ID(+)
AND evt_dateopen>=SYSDATE-"+days+"
GROUP BY evt_id, evt_dateopen, evt_utn_id,
utn_cn, evt_trf_codice, tes_descr,
evt_sesso, evt_razza, evt_eta,
evt_altezza, evt_um_altezza,
evt_peso, evt_um_peso, evt_memo
ORDER BY REFERTI","ListEventE",(int)utn_id)
Ma come è possibile creare un file XML a partire da una query?
Il linguaggio di programmazione java, mette a disposizione tramite la libreria
javax.xml delle funzioni che permettono di fare ciò, ovvero di incapsulare i risultati
della query all’interno di tag XML. Il codice utilizzato per realizzare tale scopo è il
seguente:
82
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
DocumentBuilder db=dbf.newDocumentBuilder();
Document doc=db.newDocument();
Element root=doc.createElement("root_element");
//connect to database
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(querySQL);
ResultSetMetaData rsmd = rs.getMetaData();
while(rs.next()){
Element row=doc.createElement("row");
for(int j=1;j<=rsmd.getColumnCount();j++){
String colName=rsmd.getColumnName(j);
String colValue=rs.getString(j);
Element e=doc.createElement(colName);
e.appendChild(doc.createTextNode(colValue));
row.appendChild(e);
}
root.appendChild(row);
}
doc.appendChild(root);
TransformerFactory tmf=TransformerFactory.newInstance();
Transformer tf=tmf.newTransformer();
DOMSource source=new DOMSource(doc);
//write to the stream
StreamResult result=new StreamResult(fileFullName);
tf.transform(source,result);
Creato il file Xml contenente il risultato della query, esso viene inviato come allegato
tramite il seguente frammento di codice:
message=(org.apache.axis.MessageContext.getCurrentContext()).getRes
ponseMessage();
message.addAttachmentPart(message.createAttachmentPart(newDataHandl
er(new URL("file:"+File.separator+fileNamePath+fileName))));
Essendo un argomento particolarmente delicato quello inerente agli allegati vi
torneremo in un secondo momento.
Inoltre, poichè molti degli altri servizi implementati, utilizzano la tecnica appena
vista (creazione del file XML e invio come allegato), non ci soffermeremo
dettagliatamente sulla loro descrizione.
83
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
openEvent(…):
Il metodo OpenEvent permette ad un richiedente di inserire un nuovo evento
che poi sarà soggetto a refertazione.
E’ uno dei pochi casi in cui non c’è la creazione del file xml e il suo
funzionamento è semplicissimo:
•
Ha come parametri le informazioni necessarie al nuovo evento
•
Prende tali parametri e fa un “INSERT” all’interno del database
Ora poiché la tabella oggetto dell’insert ha un campo BLOB (Binary Large
OBject) destinato a ricevere la codifica binaria dell’allegato (la documentazione
relativa ad un esame, eg. immagine di una radiografia o di una tac ecc…) abbiamo la
necessità di una particolare gestione:
•
Occorre dapprima inserire un “EMPTY_BLOB” nel campo BLOB della tabella
(FASE 1)
•
Selezionare tramite una query l’EMPTY_BLOB appena inserito (FASE 2)
•
Recuperare il vero BLOB come attachment (FASE 3)
•
Sovrascrivere l’EMPTY_BLOB con l’effettivo BLOB (FASE 4)
Vediamo come tutto questo viene realizzato:
FASE 1:
setConnection();
stmt = conn.createStatement();
stmt.execute("INSERT INTO tm_eventi (evt_utn_id, evt_trf_codice,
evt_dateopen, evt_codice_esterno, evt_sesso,
evt_eta, evt_altezza, evt_um_altezza, evt_peso,
evt_um_peso, evt_memo, evt_nomeallegato,
evt_allegato)
VALUES ("+utn_id+","+StringUtil.quoteString(evt_trf_codice)+
",TO_DATE('"+DateTime.getCurrentDateTime()+"','YYYYMM-DD HH24:MI:SS'),"+
StringUtil.quoteString(evt_codice_esterno) + "," +
StringUtil.quoteString(evt_sesso) + "," +
evt_eta + "," + evt_altezza + "," +
StringUtil.quoteString(evt_um_altezza) + "," +
evt_peso + ","+ StringUtil.quoteString(evt_um_peso) +
"," + StringUtil.quoteString(evt_memo)+","+
StringUtil.quoteString(evt_nomeallegato.trim())+
",EMPTY_BLOB())");
stmt.close();
84
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
FASE 2:
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT MAX(EVT_ID) FROM TM_EVENTI
WHERE EVT_UTN_ID="+ utn_id);
if (rs.next()) evt_id=Integer.parseInt(rs.getString(1));
stmt.close();
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT EVT_ALLEGATO FROM TM_EVENTI
WHERE EVT_ID="+evt_id+" FOR UPDATE NOWAIT");
FASE 3:
if (rs.next()) {
oracle.sql.BLOB bcol = ((OracleResultSet)rs).getBLOB(1);
OutputStream blobOutputStream = bcol.getBinaryOutputStream();
//Recupera allegato dal messaggio di richiesta del client
message=(org.apache.axis.MessageContext.getCurrentContext()).getRequestMess
age();
Iterator attachments = message.getAttachments();
//Se non ci sono attachment ritorna -5
if(!attachments.hasNext())return -5;
//Prendo solo il primo allegato
att = (AttachmentPart) attachments.next();
DataHandler dh = att.getActivationDataHandler();
//Ottengo la codifica in byte dell'allegato
BufferedInputStream bis = new BufferedInputStream(dh.getInputStream());
byte[] bs = new byte[bis.available()];
bis.read(bs, 0, bs.length);
bis.close();
FASE 4:
//Inserisco la codifica in byte dell'allegato nel campo BLOB del DB
blobOutputStream.write(bs, 0, bs.length);
blobOutputStream.flush();
blobOutputStream.close();
System.out.println("Generato nuovo evento con id "+(int)evt_id+".");
stmt.close();
conn.close();
85
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
closeEvent(int evt_id):
Tale metodo aggiorna lo stato dell’evento a chiuso, ovvero l’utente richiedente
ha deciso che non ha più bisogno di ulteriori refertazioni.
Per fare ciò va a valorizzare il campo evt_dateclose della tabella eventi con la
data corrente:
setConnection();
Statement stmt = conn.createStatement();
stmt.execute("UPDATE tm_eventi
SET evt_dateclose = TO_DATE('" +
DateTime.getCurrentDateTime()+"','YYYY-MM-DD HH24:MI:SS')
WHERE EVT_ID= "+evt_id);
System.out.println("Evento "+(int)evt_id+" chiuso con successo.");
stmt.close();
conn.close();
downloadEvent(double evt_id):
Permette ad un client (refertante) di scaricare la documentazione relativa ad un
dato evento che egli intende refertare.
La procedura consta di 4 passi:
•
Recupero dal database del nome del file relativo all’evento richiesto dal client
•
Lettura dal database del BLOB corrispondente all’evento richiesto
•
Scrittura del BLOB in un file fisico
•
Invio del file appena creato come attachment
setConnection();
//Recupero nome del file
Statement stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT TRIM(EVT_NOMEALLEGATO) EVT_NOMEALLEGATO FROM
TM_EVENTI WHERE EVT_ID= "+evt_id);
if (rs.next())
fileName=rs.getString(1);
stmt.close();
String fileFullName=fileNamePath+fileName.trim();
86
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
//Recupero del BLOB
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT EVT_ALLEGATO FROM TM_EVENTI WHERE EVT_ID=
"+evt_id);
if (rs.next()) {
oracle.sql.BLOB bcol =((OracleResultSet)rs).getBLOB(1);
//Scrittura del blob su un file fisico
long inizio=1;
dati = bcol.getBytes(inizio,(int)bcol.length());
FileOutputStream inn=new FileOutputStream(fileFullName);
for(int i=0;i<dati.length;i++)
inn.write(dati[i]);
inn.close();
//Invio del file come attachment
message=(org.apache.axis.MessageContext.getCurrentContext()).getResp
onseMessage();
/*LINUX*/
message.addAttachmentPart(message.createAttachmentPart(new
DataHandler(new
URL("file:"+File.separator+File.separator+fileNamePath+fileName))));
/*WINDOWS*/
//message.addAttachmentPart(message.createAttachmentPart(new
DataHandler(new
URL("file:"+File.separator+fileNamePath+fileName))));
//Cancellazione del file dalla cartella temp del Tomcat
FileUtil.deleteFiles();
System.out.print("Download documentazione evento "+(int)evt_id+"
scaricata con successo.");
}
stmt.close();
conn.close();
referta(…):
Analogo ad openEvent(), esso inserisce nella tabella dei referti l’evento
appena refertato.
Anche in tal caso è presente un attachment, quindi un campo BLOB
(documentazione del referto) che deve essere gestito allo stesso modo a quanto fatto
precedentemente.
87
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
Vediamo com’è stata strutturata la query d’inserimento:
setConnection();
stmt = conn.createStatement();
String query="INSERT INTO tm_referti (ref_evt_id, ref_utn_id,
ref_datereferto,
ref_nomeallegato_referto,
ref_allegato_referto, ref_memo,
ref_definitivo)
VALUES ("+ ref_evt_id + "," + ref_utn_id + ",TO_DATE('" +
DateTime.getCurrentDateTime()+"','YYYY-MM-DD
HH24:MI:SS'),"+
StringUtil.quoteString(ref_nomeallegato_referto.trim())
+",EMPTY_BLOB()," +
StringUtil.quoteString(ref_memo)+","+
StringUtil.quoteString(ref_definitivo)+")";
stmt.execute(query);
stmt.close();
listEventReferted(double utn_id):
Visualizza gli eventi refertati relativi ad un specificato utente.
E’ costituito dalla solita struttura:
Creazione xml
Invio come attachment
Ci soffermiamo alla query con la quale viene creato l’xml:
fileName=
FileUtil.createXML("SELECT evt_id, evt_trf_codice, tes_descr,
evt_dateopen,evt_codice_esterno, COUNT(REF_IND)
REFERTI
FROM TM_EVENTI, TM_TIPOESAMI, TM_UTENTI, TM_REFERTI
WHERE evt_utn_id=utn_id AND evt_trf_codice=tes_codice
AND evt_dateclose IS NULL AND EVT_ID=REF_EVT_ID(+)
AND utn_id="+utn_id+"
GROUP BY evt_id, evt_trf_codice, tes_descr,
evt_dateopen,evt_codice_esterno
ORDER BY REFERTI DESC","ListEventR",(int)utn_id);
88
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
listEventRefertedByEvtId(double ref_evt_id):
Permette di visualizzare tutte le refertazioni relative ad un dato evento (ogni
evento può avere più di una refertazione).
Anch’esso si basa sul binomio creazione xml e invio come attachment:
fileName=
FileUtil.createXML("SELECT REF_IND, REF_UTN_ID, UTN_CN,REF_DATEREFERTO,
TES_DESCR,REF_NOMEALLEGATO_REFERTO,
REF_MEMO,REF_DEFINITIVO
FROM TM_EVENTI,TM_REFERTI, TM_UTENTI, TM_TIPOESAMI
WHERE EVT_TRF_CODICE=TES_CODICE AND UTN_ID=REF_UTN_ID
AND REF_EVT_ID="+ref_evt_id+"
AND EVT_ID=REF_EVT_ID","ListRefertByEvtId",
(int)ref_evt_id);
downloadRefert(double ref_ind):
Così come un refertante scarica la documentazione relativa all’evento che egli
vuole refertare, allora alla stessa maniera un utente richiedente a refertazione
ultimata chiede di scaricare il referto relativo alla sua richiesta.
setConnection();
//Recupero nome del file
Statement stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT TRIM(REF_NOMEALLEGATO_REFERTO)
REF_NOMEALLEGATO_REFERTO
FROM TM_REFERTI WHERE REF_IND= "+ref_ind);
if (rs.next())
fileName=rs.getString(1);
stmt.close();
String fileFullName=fileNamePath+fileName.trim();
stmt = conn.createStatement();
89
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
//Recupero del BLOB
rs = stmt.executeQuery("SELECT REF_ALLEGATO_REFERTO FROM TM_REFERTI WHERE
REF_IND= "+ref_ind);
if (rs.next()) {
oracle.sql.BLOB bcol =((OracleResultSet)rs).getBLOB(1);
//Scrittura del blob su un file fisico
long inizio=1;
dati = bcol.getBytes(inizio,(int)bcol.length());
FileOutputStream inn=new FileOutputStream(fileFullName);
for(int i=0;i<dati.length;i++){
inn.write(dati[i]);
}
inn.close();
//Invio del file come attachment
message=(org.apache.axis.MessageContext.getCurrentContext()).getResp
onseMessage();
/*LINUX*/
message.addAttachmentPart(message.createAttachmentPart(new
DataHandler(new
URL("file:"+File.separator+File.separator+fileNamePath+fileName))));
/*WINDOWS*/
//message.addAttachmentPart(message.createAttachmentPart(new
DataHandler(new
URL("file:"+File.separator+fileNamePath+fileName))));
System.out.print("Download referto "+(int)ref_ind+" effettuato con
successo.");
//Cancellazione del file dalla cartella temp del Tomcat
FileUtil.deleteFiles();
}
stmt.close();
conn.close();
showStoric(double utn_id):
Permette di visualizzare lo storico degli eventi di un determinato utente, ovvero
gli eventi che l’utente stesso ha deciso di chiudere. Anch’esso a partire da una query
genera un file xml che poi verrà inviato come attachment.
La query è la seguente:
SELECT evt_id, evt_trf_codice, tes_descr, evt_dateopen,evt_dateclose,
evt_nomeallegato, evt_codice_esterno, evt_memo,COUNT(REF_IND) REFERTI
FROM
TM_EVENTI, TM_TIPOESAMI, TM_UTENTI, TM_REFERTI
WHERE evt_utn_id=utn_id AND evt_trf_codice=tes_codice AND evt_dateclose IS NOT
NULL AND EVT_ID=REF_EVT_ID(+) AND utn_id="+utn_id+" GROUP BY evt_id,
evt_trf_codice, tes_descr, evt_dateopen,evt_dateclose, evt_nomeallegato,
evt_codice_esterno, evt_memo ORDER BY REFERTI
Il filtro fondamentale è la presenza di una data di chiusura non nulla.
90
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
listRefertForErogants(double utn_id, double days):
E’ un servizio destinato ad un utente refertante e permette di visualizzare i
referti da egli effettuati che sono ancora aperti, ovvero che non sono stati dichiarati,
sempre dallo stesso refertante, definitivi. Inoltre tali referti sono filtrati secondo una
specifica data, cioè il refertante può consultare solamente quei referti che hanno una
data di refertazione che rientri in un range stabilito dalla data corrente e dai giorni
selezionati da lui stesso nell’interfaccia di visualizzazione.
Tramite una query viene creato un file xml che poi viene inviato al client come
allegato.
Query:
SELECT ref_ind, ref_evt_id, evt_utn_id, utn_cn, evt_trf_codice, tes_descr,
ref_datereferto, ref_definitivo
FROM TM_EVENTI, TM_TIPOESAMI, TM_UTENTI, TM_REFERTI
WHERE evt_utn_id=utn_id AND evt_trf_codice=tes_codice
AND evt_trf_codice IN (SELECT per_tes_codice FROM TM_PERMISSIONI WHERE
per_utn_id = ref_utn_id)
AND evt_dateclose IS NULL AND EVT_ID=REF_EVT_ID(+)
AND ref_datereferto>=SYSDATE-"+days+" AND ref_utn_id="+utn_id+"
ORDER BY REF_DEFINITIVO
refertToEvent(double ref_ind):
Permette di visualizzare le informazioni di interesse relative alla richiesta di un
evento che è stato gia refertato, ad esempio tipo e codice esame, caratteristiche
fisiche del richiedente, informazioni sul referto.
Tale servizio viene invocato nel momento in cui un utente erogante (refertante)
decide di consultare la refertazione di un evento che ha già subito delle refertazioni da
parte dell’utente stesso o da altri utenti autorizzati. In tal caso vedrà visualizzate oltre
alle informazioni dell’evento anche la diagnosi con tanto di referto allegato.
Tutte le informazioni verranno visualizzate lato client in una griglia alimentata
tramite un file xml creato attraverso la seguente query:
91
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
SELECT ref_evt_id, evt_trf_codice, tes_descr, ref_definitivo, ref_memo,
evt_sesso, evt_eta, evt_peso, evt_um_peso, evt_altezza,
evt_um_altezza, evt_memo, ref_nomeallegato_referto
FROM TM_EVENTI, TM_TIPOESAMI, TM_UTENTI, TM_REFERTI
WHERE evt_utn_id=utn_id AND ref_evt_id=evt_id AND evt_trf_codice=tes_codice
AND evt_trf_codice IN (SELECT per_tes_codice FROM TM_PERMISSIONI WHERE
per_utn_id = ref_utn_id)
AND evt_dateclose IS NULL AND EVT_ID=REF_EVT_ID(+)
AND ref_ind="+ref_ind
updateRefert(double ref_ind, ….):
Consente ad un utente refertante di poter modificare un qualsiasi suo referto
dichiarato non definitivo. E’ analogo al servizio “referta”, l’unica differenza sta nella
query: si usa un UPDATE anziché INSERT.
setConnection();
stmt = conn.createStatement();
String query="UPDATE tm_referti SET REF_NOMEALLEGATO_REFERTO="+
StringUtil.quoteString(ref_nomeallegato_referto.trim()) + ","
+ " REF_MEMO="+StringUtil.quoteString(ref_memo)+ "," +
" REF_DEFINITIVO="+StringUtil.quoteString(ref_definitivo)+ ","
+" REF_DATEREFERTO=TO_DATE('"+DateTime.getCurrentDateTime()+
"','YYYY-MM-DD HH24:MI:SS')"+" WHERE REF_IND="+ref_ind;
stmt.execute(query);
stmt.close();
Per il campo BLOB viene utilizzata la stessa procedura ampliamente descritta in alcuni
dei servizi precedenti.
updateRefertWithoutBLOB(double ref_ind, ….):
E’ il servizio precedente senza però l’update del campo BLOB.
92
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
login(String user, String pswd):
Il servizio di login è molto simile al servizio “authentication”, ma leggermente
più completo. Infatti oltre ad andare a verificare l’esistenza dell’utente che ha richiesto
l’accesso all’applicazione sul database, esso, in caso affermativo, invia al client un file
xml contenete le informazioni principali dell’utente appena loggato, cosicché queste
possano essere visualizzate nell’interfaccia migliorando l’estetica e la leggibilità.
Tramite una query si reperiscono le informazioni dell’utente che vengono poi
incapsulate in un file xml e inviate come allegato al client.
Query:
String query="SELECT utn_id, utn_cn, utn_type, utn_codente,
utn_codstruttura, utn_codspecialita, utn_codunitaerogante,
uer_descr
FROM tm_utenti,tm_unitaeroganti
WHERE utn_username='"+user+"'
AND utn_password='"+pswd+"'
AND utn_codente=uer_codente
AND utn_codstruttura=uer_codstruttura
AND utn_codspecialita=uer_codspecialita
AND utn_codunitaerogante=uer_codunitaerogante";
93
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
5.3 Fase di deploy
Lo schema proposto dalla Sun Microsystem in quanto a Web Applications
propone un modello descrittivo dell'alberatura del progetto in modo da separare e
descrivere meglio tutta l'applicazione.
Questo
approccio
ha,
come
sappiamo,
gli
indubbi
vantaggi
della
standardizzazione. Da una parte consente a chi produce i tool di sviluppo e gli
application server di rendersi compatibili (e magari certificati da Sun) con le nuove
specifiche, dall'altra permette a chi sviluppa applicazioni Web di sapere che la
struttura dell'applicazione deve essere fatta in un certo modo e che un qualunque
application server, se certificato, tratterà l'applicazione allo stesso modo, garantendo
quindi la portabilità assoluta.
Il nodo centrale della standardizzazione è dato da una definizione precisa
dell'alberatura dell'applicazione. Come sappiamo la root della Web Application dovrà
contenere le pagine HTML o JSP. In alcuni casi le pagine JSP possono essere anche
nella cartella JSP, in "css" ci sono i fogli di stile, in "js" i file contenenti codice
Javascript e dentro "WEB-INF" c'è una determinata alberatura.
In particolare a partire dalla cartella "classes" vengono espansi i package Java
dell'applicazione, in "conf" ci sono i file deputati alla configurazione applicativa, in "lib"
tutte le librerie esterne sotto forma di JAR o ZIP, in "tld" eventuali tag libraries, in
"log" i log dell'applicazione.
Supponiamo di aver creato la nostra applicazione utilizzando questo schema,
ad un certo punto sarà necessario effettuare il deploy su una macchina differente da
quella di sviluppo. La macchine di sviluppo, soprattutto se si utilizzano ambienti di
sviluppo molto sofisticati, sono configurate diversamente da quelle di test, pertanto il
passaggio da un ambiente all'altro potrebbe non essere indolore.
94
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
Deploy - modo tradizionale
Per eseguire il deploy di questa Web Application in modo tradizionale, se si
utilizza Tomcat come application server, è necessario copiare l'alberatura così com'è
sul file system della macchina server ed editare il file
TOMCAT_HOME/conf/server.xml
aggiungendovi la sezione relativa al nuovo context da creare per poter utilizzare la
nuova Web Application attraverso HTTP.
La sezione che ci serve è di questo genere:
<ContextManager>
<Context path="/nomeApplicazione"
docBase="c:\nomeApplicazione"
crossContext="true"
debug="0"
reloadable="true"
trusted="false" >
</Context>
</ContextManager>
Sarà nostra cura inoltre modificare il CLASSPATH di sistema in modo da
includere tutte le librerie esterne che debbano essere utilizzate dalle componenti della
nostra applicazione.
Questo metodo funziona indipendentemente da come sia organizzata la Web
Applicaton. Al termine potremo raggiungere la nostra applicazione attraverso l'url:
http://localhost:8080/nomeApplicazione/
95
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
Cosa accade però in fase di manutenzione? In altre parole, cosa succede
quando dobbiamo riportare in ambiente di test delle modifiche che coinvolgono alcune
parti della Web Application? Ci sono solitamente due alternative:
•
si sovrascrive l'intera alberatura con la versione aggiornata
•
si sovrascrivono selettivamente soltanto i file modificati
In ogni caso gli interventi da effettuare manualmente sono molti e la procedura
non troppo semplice, soprattutto se siamo di fronte ad applicazioni con un certo grado
di complessità.
Deploy - il file WAR
La specifica proposta da Sun non si limita a descrivere l'alberatura per la
costruzione dell'applicazione, ma ci consente anche di avere un buon sistema per
effettuare il deploy dell'applicazione utilizzando un singolo file, il file WAR.
Un file WAR, come sappiamo, viene generato attraverso il tool jar.exe
contenuto nel JDK ed è pertanto un semplice file JAR rinominato. Il fatto che sia un
WAR e non un JAR, indipendentemente dal contenuto, gli permette di essere
automaticamente riconosciuto come una vera e propria Web Application completa e
dotata di vita propria, in questo modo l'application server sarà in grado di
autoconfigurarsi sapendo che il WAR contiene esattamente quel tipo di struttura.
Per effettuare il deploy su Tomcat di un file WAR è sufficiente crearlo, dopo
essersi posizionati all'interno della cartella contenente l’applicazione, attraverso il
comando:
jar cvf nomeApplicazione.war .
Dopo aver ottenuto il file nomeApplicazione.war l'operazione di deploy si limita
allo spostamento del file WAR all'interno della cartella webapps di Tomcat.
96
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
Subito dopo il restart dell'Application Server potremo vedere la nostra
applicazione utilizzando il solito url:
http://localhost:8080/nomeApplicazione/
Quando l'Application Server parte, si scompatta automaticamente il file WAR e
si crea il context per poter raggiungere l'applicazione via http.
Utilizzando questo metodo di deploy la manutenzione si riduce ai tre passi seguenti:
•
creazione del nuovo file WAR
•
copia del nuovo WAR sulla macchina di test
•
eliminazione della vecchia alberatura estratta dal WAR precedente
Eclipse mette a disposizione un comando per la crazione del file WAR senza
dover andare a ricorrere al prompt dei comandi:
Figura 5.12.
Creazione del WAR file.
Cliccare con il tasto destro del
mouse sull’icona del progetto e
selezionare
la
voce
Export->WAR file.
Successivamente verrà richiesta
la path di destinazione del file e
il nostro WAR è pronto per il
deploy.
Ora occorre spostare il file WAR appena creato all'interno della cartella
webapps di Tomcat.
A tal proposito possiamo utilizzare due alternative:
•
Spostare fisicamente il file nella macchina di sviluppo
•
Utilizzare il manager del tomcat
97
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
Indirizzo del server
Path del WAR file
Figura 5.13 – Deploy con il manager del Tomcat.
Conclusioni
I vantaggi della seconda soluzione sono evidenti, è possibile effettuare un
deploy su qualsiasi Application server compatibile con le specifiche di Sun
semplicemente copiando il file nella posizione giusta ed effettuando il restart.
Utilizzando il metodo tradizionale, invece, dovremmo verificare caso per caso
qual è la procedura di creazione del context e specificando manualmente il
CLASSPATH.
La scelta del WAR è indubbiamente la più interessante. Il vero problema è la
migrazione di applicazioni scritte utilizzando strutture differenti e molto spesso questa
non è un'operazione per niente banale.
98
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
5.4 Una possibile e particolare implementazione del client
Il progetto JTelemed descrive le architetture software e hardware per la
realizzazione di un modello client-server per la telerefertazione on-line. Anche se
questo elaborato presenta solamente gli aspetti legati allo sviluppo lato server è bene
chiarire che esso è stato creato in un aspetto molto più ampio e integrato da un
applicativo client.
Per capire meglio come client e server possano effettivamente comunicare tra
loro è bene dunque fornire qualche breve cenno sulla realizzazione del client.
Il client è stato sviluppato grazie ad un tool di sviluppo proprietario della
Zucchetti che comprende PortalStudio e SitePainter. Essi sono strumenti potentissimi
che facilitano il lavoro di creazione delle classi Java indispensabili nella comunicazione
client-server. Uno dei loro aspetti più importanti, che è stato ampiemente utilizzato, è
la creazione di griglie di dati alimentate da una query SQL o da un file XML.
Infatti nel capitolo 5.2 abbiamo visto che il server forniva quasi sempre come
risultato di una generica richiesta da parte di un client un file XML che poi inviava
come allegato (attachment) al messaggio SOAP di risposta. Ecco questo file XML non
faceva altro che andare ad alimentare la griglia realizzata dai tool del client.
Senza perdere troppo tempo andiamo ad analizzare qualche piccolo aspetto del
client.
La home page dell’applicativo corrisponde alla PAGELET (di SitePainter PortalStudio)
pg_inizio_jtelemed.jsp. Tale pagelet prevede 3 frame distinti:
-
nel frame in alto è caricata la portlet jtelemed_alto_portlet.jsp;
-
nel frame laterale sinistro è caricata la portlet jtelemed_left_login_portlet.jsp;
-
nel frame centrale è caricata la portlet di presentazione jtelemed3_portlet.jsp.
99
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
Figura 5.14 – Home page di un possibile client.
Portlet: jtelemed_alto_portlet
Non è altro che una semplice portlet con un’immagine: il banner dell’applicativo.
Portlet: jtelemed_left_login_portlet
La portlet
jtelemed_left_login_portlet.jsp
permette all’utente di effettuare il
login attraverso gli identificativi
username e password.
sp_global_var
sp_login
xmlLogin
100
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
Action code
function bt_entra_Click()
{
this.username.Value(this.txt_user.Value())
this.password.Value(this.txt_psw.Value())
var a = this.sp_login.Link()
if(a=="true"){
this.xmlLogin.Query()
this.sp_global_var.Link()
window.open('jtelemed_left_portlet.jsp','frame_left')
}
else alert(a);
}
Al click del mouse sul bottone “Entra” vengono presi i valori delle textbox
txt_user e txt_psw e passati alle rispettive variabili username e password. A questo
punto viene attivato l’SPLinker sp_login che richiama la servlet (Function)
../servlet/fn_login passandogli come parametri le variabili username e password.
String home_catalina=System.getProperty("catalina.home");
try{
WSRepositoryServiceLocator wsrl = new WSRepositoryServiceLocator();
WSRepository wsr= wsrl.getWSRepository();
nome_file = wsr.login(username,password);
//Recupera l’allegato dal messaggio di risposta del server.
Object[] attachments=((WSRepositorySoapBindingStub)wsr).getAttachments();
AttachmentPart att = (AttachmentPart) attachments[0];
DataHandler dh = att.getActivationDataHandler();
FileOutputStream fos = new
FileOutputStream(home_catalina+File.separator+"webapps"
+File.separator+"jtelemed"+File.separator+"temp"+File.s
eparator+nome_file);
BufferedInputStream bis=new BufferedInputStream( dh.getInputStream());
byte[] bs = new byte[bis.available()];
bis.read( bs, 0, bs.length );
fos.write( bs );
bis.close();
fos.close();
}
catch(Exception e) {
File f = new
File(home_catalina+File.separator+"webapps"+File.separator+"jtelemed
"+File.separator+"temp"+File.separator+nome_file);
f.delete();
System.out.println(e);
nome_file="Errore nel recupero allegato";
}
101
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
La parte evidenziata in rosso è quella che ci interessa maggiormente in quanto
rappresenta la chiamata esplicita a un servizio messo a disposizione dal server: in
particolare tale funzione java del client invoca il servizio login del server che, come
abbiamo visto nel capitolo 5.2, esegue una query sul database in corrispondenza dei
valori passati dal client (username e password relativi all’utente che ha richiesto di
loggarsi), crea un file XML con le informazioni (se l’utente è registrato) dell’utente,
ritorna come risposta un messaggio SOAP contenente il nome del file appena creato e
invia come allegato al messaggio tale file.
Tale funzione ha dunque il compito di controllare se l’utente è accreditato ad
accedere all’applicativo. Se il ritorno di tale funzione è un valore “true”, viene attivato
l’XMLObject xmlLogin che va a leggere un file .xml creato attraverso la precedente
funzione e che si trova nella cartella (Source) ../temp/XmlLogin.xml. La struttura del
file .xml prevede una intestazione (prima di accedere alla informazioni vere e proprie)
del
tipo
/root_element/row da dichiarare nel campo Root delle proprietà
dell’XMLObject. Se la lettura al file .xml è andata a buon fine, vengono
automaticamente valorizzate le variabili utn_id, utn_cn, utn_type, utn_codente,
utn_codstruttura, utn_codspecialita, utn_codunitaerogante, utn_descr ovvero tutte le
informazioni dell’utente appena loggato. Tali variabili infatti sono dichiarate indicando
tra le rispettive proprietà il DataObject associato (Dataobj: xmlLogin) ed il campo da
utilizzare per il valore dell'elemento (ad esempio per la variabile utn_id si associa
Field:
UTN_ID).
A
../servlet/fn_set_global
questo
(che
punto
non
viene
richiamata
affrontiamo)
la
attraverso
funzione
il
link
(Function)
all’SPLinker
sp_global_var. Tale funzione prende come parametri tutte le informazioni
dell’utente ricavate precedentemente dall’XMLObject e li imposta come variabili
globali. Attraverso il comando javascript window.open(…) viene caricata la portlet
jtelemed_left_portlet.jsp nel frame laterale sinistro frame_left.
Se l’utente fosse risultato non accreditato ad accedere all’applicativo viene
fornito in output un messaggio di notifica dell’errore. In questo caso non è permesso
l’accesso all’applicativo.
102
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
Portlet: jtelemed_left_portlet
La
portlet
jtelemed_left_portlet.jsp
fornisce all’utente appena loggato un
menù di accesso ai servizi. In particolare:
a) se l’utente è un RICHIEDENTE
sp_logout
vengono attivati i bottoni NUOVO
EVENTO, EVENTI REFERTATI ed
lb_utente
lb_tipo
image15
EVENTI CHIUSI
b) se
l’utente
è
un
EROGANTE
vengono attivati i bottoni EVENTI
APERTI e REFERTI APERTI
Nella portlet vengono richiamate le variabili globali g_utn_cn e g_utn_type
(impostando tra le proprietà il campo Init par a “global string) che recuperano
rispettivamente il CommonName (nome) e il tipo (richiedente/erogante) di utente. In
base al valore (R: richiedente , E:erogante) della variabile g_utn_type vengono
mostrati (Show()) o nascosti (Hide()) i vari bottoni . Le label lb_utente e lb_tipo
vengono valorizzate con il CommonName dell’utente e con l’indicazione del tipo
utente.
Action code 1
// Codice sicurezza portlet
this.lb_utente.Value(this.g_utn_cn.Value())
if(this.g_utn_type.Value()=="R") this.lb_tipo.Value("RICHIEDENTE")
else this.lb_tipo.Value("EROGANTE")
if(this.g_utn_type.Value()=="R"){
this.image5.Show() // Nuovo evento
this.image6.Show() // Eventi refertati
this.image7.Show() // Eventi chiusi
this.image4.Hide()
this.image8.Hide()
}
else{
this.image4.Show() // Eventi aperti
this.image8.Show() // Referti aperti
this.image5.Hide()
this.image6.Hide()
this.image7.Hide()
}
103
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
Al click dei diversi bottoni vengono caricate diverse portlet attraverso il
comando javascript window.open(‘nome_portlet’,’frame_destinazione’). Nel nostro
caso le portlet vengono caricate nel frame_centro (ovvero il frame centrale
dell’applicativo). In ogni caso è previsto un bottone per effettuare il logout
dall’applicativo. Al click di questo bottone (image15) viene richiamata una funzione di
SitePainter (Servlet: ../servlet/fn_logout) che resetta le variabili globali e reindirizza
l’utente alla home page. Tale funzione è richiamata attraverso l’SPLinker sp_logout
che non necessita di alcun parametro.
//----Funzioni-----
Action code 2
function image6_Click(){
window.open('eventi_refertati_frame_portlet.jsp','frame_centro');
}
function image4_Click(){
window.open('eventi_aperti_frame_portlet.jsp','frame_centro');
}
function image5_Click(){
window.open('scelta_lingua_portlet.jsp','frame_centro');
}
function image7_Click(){
window.open('eventi_chiusi_frame_portlet.jsp','frame_centro');
}
function image8_Click(){
window.open('referti_aperti_frame_portlet.jsp','frame_centro');
}
function image15_Click(){
this.sp_logout.Link()
}
Delle numerose portlet che costituiscono il client prenderemo adesso in esame
una portlet che realizza un aspetto molto importante accennato in precedenza:
alimentare una griglia attraverso un file XML proveniente dal server.
104
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
Portlet: eventi_aperti_frame_portlet.jsp (Erogante – Eventi aperti)
frame_listevent
Attraverso questa portlet un utente EROGANTE potrà avere la lista degli eventi
aperti che egli potrà refertare. In particolare, la lista comprenderà solamente gli
eventi di sua “competenza”, ovvero gli eventi legati ad una disciplina sulla quale
l’erogante ha la permissione. L’utente potrà visionare gli eventi aperti negli ultimi 3
giorni, ultimi 7 giorni, ultimi 15 giorni, ultimi 30 giorni, ultimi 60 giorni.
Cliccando sul bottone “Visualizza” viene caricata la portlet listevent_portlet.jsp
nel frame frame_listevent. Se l’utente non seleziona un periodo di riferimento per la
query, viene settato il valore massimo di 60 giorni.
//-----Funzioni----
Action code
function bt_download_Click()
{
if(this.combo_periodo.Text()=='-') this.combo_periodo.Value('60')
window.open('../jsp/listevent_portlet.jsp?utn_id='+this.utn_id.Valu
e()+'&periodo='+this.combo_periodo.Value(),'frame_listevent');
}
105
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
Portlet: listevent_portlet.jsp
splinker27
xmlobj7
Quella che si vede in figura è una griglia che riepiloga gli eventi aperti che
l’utente può refertare perché di sua competenza. Per ottenere ciò si richiama la
funzione del SitePainter ../servlet/fn_listevent (simile per principio di funzionamento
alla funzione fn_login) attraverso l’splinker27. A tale funzione è necessario passare
l’ID dell’utente refertante (per controllare le discipline di sua competenza) e il periodo
richiesto (utn_id,periodo). Questa funzione recupera un file XML creato lato server
contenete tutte le informazioni richieste. Questo file XML (../temp/ListaEvent.xml) è
letto dall’XMLDataobj xmlobj7 che poi alimenterà la griglia.
Action code 1
parent.ZtVWeb.getPortlet('evnti_aperti_frame').nome_file.Value('');
var a=this.splinker27.Link();
parent.ZtVWeb.getPortlet('evnti_aperti_frame').nome_file.Value(a);
if(parent.ZtVWeb.getPortlet('evnti_aperti_frame').nome_file.Value()
=="-2") {
this.Box10.Show()
alert("Utente non erogante:accesso negato")
}
else{
this.Box10.Hide();
this.xmlobj7.Query();
}
this.colora();
La griglia permetterà di visualizzare le seguenti informazioni (Columntitles):
Evento, Data Apertura, Id Utente, Nome, Codice esame, Descrizione, Referti .
106
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
In particolare, cliccando sul campo Evento si richiama una funzione dell’Action
Code(Columnlinks:javascript:ZtVWeb.getPortlet(\'listevent\').download(\'%EVT_ID%\'
|\'%EVT_ETA%\'|\'%EVT_SESSO%\'|\'%EVT_ALTEZZA%\'|\'%EVT_UM_ALTEZZA%\'|
\'%EVT_UM_PESO%\'|\'%EVT_PESO%\'|\'%EVT_MEMO%\'|\'%TES_DESCR%\'|\'%E
VT_RAZZA%\'|'\%REFERTI%\'),,,,,,,).
Action code 2
function download(evt_id,eta,sesso,altezza, um_altezza,um_peso,
peso, memo, descr,razza,referti)
{
window.open('../jsp/downloadevent_portlet.jsp?evt_id='+evt_id+'&ra
zza='+razza+'&sesso='+sesso+'&eta='+eta+'&peso='+peso+'&altezza='+
altezza+'&memo='+memo+'&esame='+descr+'&um_peso='+um_peso+'&um_alt
ezza='+um_altezza+'&referti='+referti+'&utn_ref='+this.utn_id.Valu
e(),'frame_listevent','toolbar=no,location=no,scrollbars=no,width=
785,height=560');
}
Questa funzione aprirà una portlet che permetterà all’utente di:
-
visionare maggiori informazioni sull’evento selezionato,
-
visionare referti di altri eroganti sul medesimo evento
-
effettuare successivamente una refertazione
Figura 5.15 – Griglia del client
107
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
5.5 Axis Attachments
a) Aggiungere un allegato al messaggio SOAP di risposta al client (upload)
Codice
import
import
import
import
import
java.io.*;
java.net.URL;
javax.activation.DataHandler;
javax.xml.soap.SOAPMessage;
org.apache.axis.attachments.AttachmentPart;
// ……Servizio del Web Services……
SOAPMessage message=null;
message=(org.apache.axis.MessageContext.getCurrentContext()).getRe
sponseMessage();
URL url= new URL("file:"+File.separator+fileNamePath+fileName)
message.addAttachmentPart(message.createAttachmentPart(new
DataHandler(url));
Poiché si vuole allegare un file al messaggio di risposta del server verso il
client, si deve recuperare il Context (contesto) corrente e quindi il relativo messaggio
di risposta (getResponseMessage()). Per realizzare ciò si utilizza la classe di Axis
org.apache.axis.MessageContext e, in ordine, i metodi getCurrentContext() e
getResponseMessage().
La
classe
SOAPMessage
implementa
il
metodo
addAttachmentPart che permette, individuato l’URL del file e creata la classe
DataHandler , di creare una sezione del messaggio SOAP in cui posizionare
effettivamente l’allegato.
108
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
b) Recuperare un allegato dal messaggio SOAP di richiesta dal client
(download)
Codice
import
import
import
import
import
java.io.*;
java.net.URL;
javax.activation.DataHandler;
javax.xml.soap.SOAPMessage;
org.apache.axis.attachments.AttachmentPart;
//……Servizio del Web Services……
message=(org.apache.axis.MessageContext.getCurrentContext()).getRe
questMessage();
Iterator attachments = message.getAttachments();
if(!attachments.hasNext())return -5;
//Se non ci sono attachment
ritorna -5
att = (AttachmentPart) attachments.next(); //Prendo solo il primo
allegato
DataHandler dh = att.getDataHandler();
BufferedInputStream bis = new
BufferedInputStream(dh.getInputStream());
byte[] bs = new byte[bis.available()];
bis.read(bs, 0, bs.length);
bis.close();
Poiché si vuole recuperare un allegato dal messaggio di richiesta del client
verso il server, si deve recuperare il Context (contesto) corrente e quindi il relativo
messaggi di richiesta (getRequestMessage()). La classe SOAPMessage mette a
disposizione il metodo getAttachments() che restituisce un iterator degli allegati. Si
recupera, quindi, il primo allegato (primo elemento dell’iterator) ed il relativo
DataHandler attraverso il metodo getDataHandler(). A questo punto si attivano i
canali di stream per la successiva scrittura del file sul file system.
109
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
TCP/IP Monitor
Abbiamo più volte parlato del TCP/IP Monitor come uno strumento per il controllo dello
scambio di messaggi tra client e server. Vediamo come appare la sua interfaccia:
Ora di invio della richiesta, tempo di
risposta, protocollo utilizzato
Figura 5.16 – Il TCP/IP Monitor di Eclipse
Richiesta del
client
Struttura del messaggio SOAP
contenente la richiesta da parte del
client di un determinato servizio.
Risposta del server
Struttura del messaggio SOAP
contenente la risposta da parte del
server al servizio richiesto dal client.
La presenza di un attachement si nota dalla parola chiave _Part_ seguita da
un numero di serie. In questo caso il server ha risposto al client inviando un
determinato file (nella maggioranza dei casi xml) come allegato.
110
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
5.6 Comunicazione Client-Server
Finora ci siamo occupati della realizzazione software di un server e di un client
che permettono lo scambio di esami e referti. Quello che però è stato descritto è ciò
che sta alla base del progetto, ciò che sta sotto al progetto e che nessun utente finale
è in grado di vedere. Allora in questo paragrafo verrà illustrato come questo
applicativo appare agli occhi di un utente, ovvero le interfacce grafiche con le quali un
qualsiasi utente autorizzato può ad esempio creare nuovi eventi (nel caso di un utente
richiedente) oppure refertare un evento (utente erogante).
Figura 5.17 – Home page dell’applicativo JTelemed
Innanzitutto nella pagina iniziale è presente un area di accesso riservato in cui
vi è l’identificazione dell’utente richiedente o dell’utente che emette il referto. In base
all’utente che si autentica si avrà un’interfaccia diversa.
111
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
Nella maschera
relativa all’ utente RICHIEDENTE
è presente una sorta di
menù contenente la gestione delle varie richieste, ossia le informazioni relative alla
nuova richiesta, lo stato delle richieste non chiuse ovvero il messaggio di
consulta delle richieste non chiuse e uno storico delle richieste chiuse entro due
mesi dalla data in cui la richiesta viene chiusa.
Operazioni possibili di un utente richiedente
Informazioni utente: nome e tipo
Figura 5.18 – Home page di un utente richiedente
Per inserire un nuovo evento il richiedente deve compilare un modulo in cui
inizialmente seleziona la lingua (Italiano/Inglese).
Successivamente inserisce tutte le informazioni
personali quali sesso, età,
altezza e peso. Altre informazioni necessarie per identificare la richiesta sono:
Riferimento della richiesta, il tipo di riferimento, un campo note (per eventuali
chiarimenti) e un campo Allegati in cui è possibile inserire degli allegati, ovvero
documenti digitali relativi agli esami effettuati.
112
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
Figura 5.19 – Maschera di inserimento di un nuovo evento
Cliccando sulla voce “Eventi refertati” vengono visualizzati tutti gli eventi per cui
l’utente richiedente apena loggato ha richiesto una refertazione.
Numero di referti per un dato evento
Link ai dettagli di un dato evento
Possibilità di chiudere un evento
Figura 5.20 – Maschera di visualizzazione degli eventi aperti e refertati
113
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
Selezionando invece “Eventi chiusi” appare una maschera simile alla precedente
nella quale sono elencati tutti gli eventi generati da un dato utente che per qualche
motivo sono stati chiusi, ovvero l’utente ha deciso che non è più interessato ad alcuna
refertazione o ad alcuna ulteriore refertazione.
Figura 5.21 – Maschera di visualizzazione degli eventi chiusi
Un evento chiuso non è più visibile da un refertante. Nella maschera relativa
all’utente che effettua il referto è presente un menù contenente un link ad una lista
degli eventi aperti ed uno ai referti non definitivi. Quando parliamo di lista di referti o
lista di eventi aperti bisogna specificare che essi sono tutti quelli del tipo per cui un
utente erogante è specializzato, ovvero, per esempio, se l’utente è un radiologo egli
potrà refertare solo esami di radiologia (e non ad esempio quelli di virologia).Tali liste
potranno essere consultate dai refertanti i quali in seguito potranno dare un loro
parere.
Operazioni possibili di un utente erogante
Informazioni utente: nome e tipo
Figura 5.22 – Maschera di visualizzazione degli eventi aperti per un refertante
114
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
Filtro per data
Figura 5.23 – Maschera di visualizzazione degli eventi aperti per un refertante
Per inserire un referto è necessario cliccare sull’evento (nell’esempio il 469); si
aprirà una finestra con tutti i dettagli e con la possibilità di scaricare la
documentazione relativa all’evento.
Figura 5.24 – Dettagli di un evento
115
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
Successivamente occorre compilare un modulo che ha la seguente forma:
Figura 5.25 – Modulo per la refertazione
Compilato il modulo e inserito il referto come allegato per inoltrarlo al servar basta
premere il pulsante “Invia referto”.
Infine, selezionando dal menù la voce “Referti aperti”, l’utente erogante può
consultare le refertazioni che lui stesso ha emesso o che sono in fase di emissione
(refertazione non definitiva).
Figura 5.26 – Elenco dei referti
Sempre dal menù sulla sinistra è possibile disconnettersi e tornare alla pagina iniziale:
116
CAP. 5 – IMPLEMENTAZIONE DEL PROGETTO JTELEMED
Figura 5.27 – Menù di un utente erogante
117
CAP. 6 – TECNOLOGIE SOFTWARE
Panoramica delle tecnologie software impiegate nella realizzazione del
progetto. Maggiori dettagli su aspetti già introdotti nei capitoli
precedenti
INDICE ARGOMENTI:
6.1 Java Platform
6.1.1 Le Servlet
6.2 Service-Oriented-Architecture
6.2.1 Web-Services
6.2.2 Protocollo SOAP
6.3 Application Server
6.3.1 Apache Tomcat
6.4 Strumenti di sviluppo
6.4.1 Apache Axis
6.5 Database Relazionale
6.5.1 Oracle
6.5.2 FreeTOAD
118
CAP. 6 – TECNOLOGIE SOFTWARE
6.1 Java Platform
Fig. 6.1 – Architetture della piattaforma Java
Java appena è uscito è stato accolto con molto entusiasmo dalla comunità
mondiale dei progettisti di software e dei provider di servizi Internet, questo perché
Java permetteva agli utenti di Internet di utilizzare applicazioni sicure e indipendenti
dalla piattaforma, che si possono trovare in qualsiasi punto della rete.
Java è quindi nato come linguaggio per la rete, per affiancare l'Hyper Text
Markup Language (HTML), il quale non è un linguaggio di programmazione vero e
proprio, e per dargli quella sicurezza che l'HTML non ha. Da quando è nato Java sulla
rete si è iniziato a poter parlare di numeri di carte di credito e di informazioni sicure,
notizia che ha molto affascinato le grosse società mondiali, le quali hanno trasformato
la vecchia Internet, rete ad appannaggio delle sole università e centri di ricerca,
nell'attuale mezzo di comunicazione aperto a tutti.
Il linguaggio di programmazione Java è stato creato verso la metà degli anni
novanta, è il più recente tra i suoi cugini, e per questo è ancora in fase evolutiva,
tanto che ogni anno circa ne viene rilasciata una nuova relase.
119
CAP. 6 – TECNOLOGIE SOFTWARE
Da linguaggio nato solo per la rete è divenuto un vero e proprio linguaggio di
programmazione, paragonabile, dal punto di vista delle funzionalità, al più blasonato
C++. Java e la maggior parte degli altri linguaggi possono essere paragonati solo dal
punto di vista delle funzionalità, perché sono fondamentalmente molto diversi, infatti
Java compila i sorgenti dei suoi programmi in un codice detto Bytecode, diverso dal
linguaggio della macchina su cui è compilato, mentre linguaggi come il C++
compilano i sorgenti dei programmi in un codice che è il codice della macchina ( per
macchina intendo computer + sistema operativo ) su cui è eseguito. Quindi per
eseguire un programma Java occorre avere uno strumento che è chiamato Java
Virtual Machine, la quale interpreta il bytecode generato dal compilatore Java e lo
esegue sulla macchina su cui è installato. Grazie alla Java Virtual Machine Java è
indipendente dalla piattaforma, infatti il programma compilato Java è legato alla JVM
e non al sistema operativo, sarà quindi possibile eseguire lo stesso programma Java,
compilato una sola volta su una qualche macchina con un compilatore Java versione
X, su una piattaforma Windows e su una piattaforma Linux, per fare questo però c'è
bisogno che sia Windows che Linux abbiano installato una Java Virtual Machine che
supporti la versione X di Java. Le due JVM installate sulle due piattaforme diverse
sono lo stesso programma compilato una volta per Windows ed una volta per Linux,
come avveniva con i programmi scritti in linguaggi come il C/C++.
Una Java Virtual Machine è implementata anche nei vari Browser (Come
Netscape e Explorer) per poter eseguire i programmi Java incontrati nella rete, i
cosidetti Applet. Questo però, unito al fatto che Java ancora si evolve, causa degli
ovvi problemi di incompatibilità: capita sempre che il più moderno Browser supporti
una versione precedente di Java rispetto all'ultima versione rilasciata dalla Sun
Microsystem, inoltre bisogna tener presente che non tutti gli utenti di Internet
navigano usando l'ultima versione di Netscape o di Explorer. Quindi volendo creare un
applet ed inserirlo in un nostro documento HTML, dobbiamo tenere presente questi
problemi, e cercare di scrivere un programma che sia compatibile con la maggior
parte delle JVM inplementate nei vari browser.
120
CAP. 6 – TECNOLOGIE SOFTWARE
Un altro problema da affrontare è quello della scelta del compilatore Java da
utilizzare, infatti esistono vari ambienti integrati per editare, compilare, debuggare ed
eseguire programmi Java, come quelli della Borland, della Microsoft, della Symantec.
Tutti questi ambienti offrono dei tool di sviluppo eccellenti, come editori grafici di
finestre, debugger molto interessanti, però hanno due problemi, il primo è che si
pagano, anche molto, il secondo è sempre lo stesso della compatibilità, infatti essi
spesso si trovano indietro alla relase della sun, ed inoltre aggiungono delle classi che
poi le JVM implementate nei browser non hanno.
Il consiglio è quello di usare le JDK (Java Development Kit) della Sun, le quali
comprendono sia il compilatore che la Java Virtual Machine per eseguire i programmi
da noi compilati, inoltre sono freeware (non costano niente) e sono scaricabili dalla
rete ed i browser si adeguano pian piano a questa versione di Java. Se volete scrivere
applet per i vecchi browser dovete scaricarvi la versione 1.1 di Java. Comunque ad
oggi le ultime versioni dei programmi di navigazione più diffusi supportano la più
recente release di Java, cioè la 1.5, quella che è stata utilizzata nello sviluppo del
progetto.
Un ultimo problema che ha Java è la lentezza, infatti, come già detto, esso è
interpretato, quindi le istruzioni Java prima di essere eseguite dalla macchina vengono
interpretate dalla JVM, ovvero per eseguire ogni istruzione il computer eseguirà un
numero di istruzioni macchina che è più del doppio delle istruzioni che eseguirebbe se
la stessa istruzione fosse stata scritta in C, quindi avrete bisogno di computer veloci
per eseguire bene programmi Java, e di questo vi sarete sicuramente accorti anche
navigando sulla rete.
Per finire ritorniamo al Java Development Kit della Sun Microsystem, con
questo è possibile produrre tutto il software che si vuole senza dover pagare diritti di
uso del prodotto come avviene con il Borland Jbuilder, il Symantec Cafe, e il Microsoft
Visual Java, vi consigliamo di leggere la licenza d'uso che troverete quando andrete a
scaricare il JDK prima di cominciare a produrre software.
La principale differenza tra Java e gli altri linguaggi di programmazione ad
oggetti è che mentre con questi ultimi è possibile anche programmare ad oggetti con
Java si deve assolutamente programmare ad oggetti. Quindi punto fondamentale è
spiegare cosa vuol dire programmare ad oggetti.
121
CAP. 6 – TECNOLOGIE SOFTWARE
Sostanzialmente la programmazione avviene allo stesso modo dei linguaggi
"normali", solo che sia i dati che le funzioni che li manipolano sono racchiusi in delle
strutture dette classi. Le classi sono dei prototipi di oggetti, ovvero sono delle
strutture astratte che possono essere istanziate e quindi creare un oggetto (ma anche
più di uno). La classe definisce tutte le proprietà degli oggetti appartenenti a quella
classe, detti attributi, e le funzioni che verranno usate per agire su di essi, detti
metodi. Ad esempio è possibile definire una classe delle persone, come segue:
La classe delle persone così definita ha un attributo che è annodinascita che
sarà sicuramente un numero intero ed un metodo che in base all'anno attuale
passatogli calcola l'età della persona. Usando il formalismo di Java,per definire la
classe persone scriveremo:
Come si vede abbiamo dichiarato sia il metodo che l'attributo come public,
vedremo tra poco cosa significa, vediamo anche che la classe comincia con { e finisce
con }, così anche i metodi.
122
CAP. 6 – TECNOLOGIE SOFTWARE
Questo ricorda molto il C, e devo dire che la sintassi di Java è molto simile, anzi
quasi uguale a quella del C, mentre per chi non conosce il C, le parentesi graffe
rappresentano il begin e l'end del pascal. La classe avrà un cosiddetto costruttore (o
più di uno), che è un metodo particolare che di solito viene utilizzato per inizializzare
gli attributi quando viene instanziata la classe in un oggetto, esso è una funzione che
non ha nessun tipo di ritorno ed il nome uguale al nome della classe. Ho detto che i
costruttori possono essere più di uno, però il nome del costruttore deve essere lo
stesso di quello della classe. Chi è abituato a programmare con linguaggi non orientati
agli oggetti troverà tutto questo strano, però è possibile perché Java fa il cosidetto
overloading di funzioni, ovvero funzioni con lo stesso nome che hanno parametri
diversi (detti in informatica parametri formali) sono diverse, e al momento
dell'invocazione viene scelta la funzione in base al parametro (detto parametro
attuale).
Questo vale per ogni metodo, non solo per i costruttori.
123
CAP. 6 – TECNOLOGIE SOFTWARE
Nell'esempio vediamo che ci sono tre costruttori, diversi per i parametri formali,
che hanno lo stesso nome, vediamo inoltre un nuovo attributo che è Cognome, esso è
una Stringa, definita come public String Cognome=new String(); la parte prima
dell'uguale è chiara, lo è meno quella a destra, quel new String() crea un nuovo
oggetto della classe String, e ne invoca il costruttore che non ha parametri, questo è il
modo standard usato da Java per instanziare gli oggetti di una classe. Non deve
sorprendere che il tipo di dato stringa sia una classe, in Java è possibile usare oggetti
che rappresentano tutti i tipi di dato del linguaggio, inseriti per completezza del
linguaggio, detti involucri che a volte sono molto utili, è però possibile anche usare i
valori.
Quindi ad esempio ci troveremo a lavorare sia con interi che con oggetti che
rappresentano interi.
Un’ultima cosa che salta all'occhio dall'esempio è che i costruttori hanno
volutamente dei parametri che hanno lo stesso nome degli attributi, anche questo è
possibile in Java, il quale stabilisce che quando c'è un assegnamento alla sinistra
dell'uguale ci deve essere l'attributo, e alla destra il parametro, comunque se non
vogliamo confonderci possiamo usare il riferimento this, scrivendo ad esempio
this.annodinascita intendiamo l'attributo.
124
CAP. 6 – TECNOLOGIE SOFTWARE
This è un riferimento all'oggetto, e nell'esempio lo troviamo anche come
invocazione di funzione this(0), in questo caso esso è un riferimento ad un costruttore
dell'oggetto, in questo caso chiama il costruttore persone (int annodinascita), con il
valore 0. È quindi possibile in un costruttore chiamare un costruttore diverso della
classe stessa, a patto che l'invocazione sia la prima istruzione del costruttore e che il
costruttore sia diverso da quello attuale.
A questo punto siamo pronti a creare oggetti appartenenti alla classe da noi
appena definita, abbiamo tre modi per farlo, perché abbiamo creato tre costruttori,
essi sono:
Introduciamo adesso degli attributi e dei metodi particolari, i cosidetti membri
statici. Per come abbiamo definito i membri della classe non ci è possibile referenziare
direttamente dalla classe attributi e metodi (persone.annodinascita è un errore),
questo perché essi lavorano su una istanza della classe, ovvero su un oggetto, però a
volte può essere utile scrivere metodi e attributi che possano essere invocati senza
dover istanziare l'oggetto, ma direttamente dalla classe, per fare questo occorre
dichiararli static, ad esempio:
125
CAP. 6 – TECNOLOGIE SOFTWARE
Introduciamo adesso la relazione is_a tra classi, data una classe è possibile
creare una nuova classe da questa facendo come si dice in gergo una specializzazione
della prima classe. La nuova classe creata è in relazione is_a con la prima. Creata una
classe studente dalla classe (detta superclasse) persone, la nuova classe eredita dalla
prima tutti i metodi e gli attributi, con la possibilità di definirne dei nuovo o di
ridefinirne alcuni, in Java l'estensione di una classe si esplicita con la parola chiave
extends.
126
CAP. 6 – TECNOLOGIE SOFTWARE
Come si vede dall'esempio la classe studente eredita tutti i metodi e gli
attrubuti della classe persone, definisce un nuovo attributo matricola e nei suoi
costruttori chiama i costruttori della classe persone, con super().
super() può essere, come this(), una invocazione di un altro costruttore (tra
parentesi vanno i parametri eventuali) o un riferimento alla classe (alla superclasse in
questo caso), quindi super.annodinascita rappresenta l'attributo annodinascita della
superclasse persone. Le relazioni is_a e instance_of sono le due relazioni più
importanti dei modelli ad oggetti.
I package sono delle collezioni di classi, racchiuse in una collezione che le
accomuna. Sono in pratica delle librerie a cui l'utente può accedere e che offrono
varie funzionalità.
I package possono anche essere creati dall'utente, ad esempio racchiudendovi
tutte le classi che ha definito per svolgere alcune funzioni che poi userà in vari
programmi, ma questo a noi non interessa, perché ci interesserà vedere i package
sicuramente più interessanti definiti in Java.
È questa la vera potenza odierna di Java, il numero di classi già definite che
svolgono i più svariati compiti, ed è anche la parte che continua sempre di più a
crescere e ad aggiornarsi con le nuove versioni di Java (JDK 1.3 ne ha ben 18Mb).
Il nucleo del linguaggio Java contiene solo le parole chiave per la costruzione
delle classi, i commenti, i normali costrutti if, switch, while, do-while, for, etichette,
break, continue e return (manca il goto), tutto il resto è implementato nei package del
linguaggio, comprese le normali primitive di Input e di Output. In questo paragrafo
vedremo la lista dei packages di Java e ne vedremo uno in particolare, quello che ci
interessa vedere per scrivere la nostra prima applicazione Java ancor prima di avere
visto i costrutti, ovvero quello in cui possiamo trovare le istruzioni di input e output.
Sembrano pochini in effetti, sembra quasi che io abbia detto un stupidaggine in
riferimento alla potenza di Java, ma se pensate che solo il package java.io comprende
50 classi e 10 interfacce capite bene che quelli di sopra sono una collezione di classi
corposa. A questo punto vorremmo fare l'input e output da console, per fare questo
dobbiamo usare il package java.lang .
127
CAP. 6 – TECNOLOGIE SOFTWARE
Per usare un package in una nostra classe, prima della definizione della classe
dobbiamo inserire l'istruzione import, ad esempio volendo usare il package java.awt
dobbiamo inserire all'inizio del nostro file:
import java.awt.*;
La * sta ad indicare che vogliamo usarne tutte le classi, se invece vogliamo usarne
solo una classe possiamo specificarlo, ad esempio, import java.awt.Frame; potremo
usare solo la classe Frame dell'awt. Nel caso nostro, in cui vogliamo fare una
operazione di output, dovremmo dichiarare all'inizio import java.lang.*;
oppure, sapendo che la classe del package java.lang che contiene i metodi per fare
questo è System potremmo scrivere :
import java.lang.System;
La classe System a sua volta avrà al suo interno una import java.io (che è il
package per l'input e l'output) per accedere alle classi dell'input e dell'output, e le
userà per mandare quello che vogliamo su schermo.
Abbiamo visto un esempio di package che al suo interno invoca un altro
package per fargli svolgere dei compiti, in queste librerie Java accade spesso questo,
ed è proprio questo fenomeno che a molti fa apparire Java un linguaggio ostico, però
superato questo blocco psicologico di fronte a quest'aspetto del linguaggio, la
programmazione diviene semplice ed immediata.
Abbiamo introdotto il package java.lang, vi dico anche che questo è il più
importante di Java, in questo sono racchiuse le classi fondamentali del linguaggio,
tanto che non serve dichiarare l'import, perché java lo importa automaticamente.
Inoltre bisogna soffermarci su un aspetto fondamentale dell'importare i package, se
noi importiamo nel mio file il package java.lang, anche se esso importerà il package
java.io, io dal mio file non potremmo usare le classi di java.io, per farlo devo
importarlo esplicitamente. Questo succede anche se programmiamo una applicazione
in più file (con più classi), in ogni file dobbiamo importare i package che ci occorrono
per la classe che stiamo definendo, non basta importarli in una sola.
128
CAP. 6 – TECNOLOGIE SOFTWARE
6.1.1 Le Servlet
La crescente richiesta di pagine web con contenuti dinamici e di servizi su web,
ha portato allo sviluppo di una particolare tipologia di software che collabora con il
server web per estenderne le funzionalità e poter interagire con basi di dati. Le
tecniche per realizzare questo tipo di software, sono tante, tra cui le più conosciute
sono sicuramente le estensioni CGI (Common Gateway Interface), realizzate
principalmente in C o in Perl. Anche Java mette a disposizione una API, le Servlet,
appunto, che permette di sviluppare applicazioni lato server. Daremo una descrizione
di tipo generale su questa tecnologia che si è rivelata molto migliore delle tecniche
precedenti sotto molti aspetti quali la portabilità e l'efficienza.
Fig. 6.2 – Java based Web Application Technology.
Che cos'è una Servlet?
Le Servlet sono moduli software scritti in Java che vengono eseguiti in
applicazioni lato server per esaudire le richieste dei client.
129
CAP. 6 – TECNOLOGIE SOFTWARE
Esse non sono legate ad un particolare protocollo per la comunicazione tra
client e server, anche se più comunemente si utilizza il protocollo HTTP ed infatti si
parla di http Servlet. Per scrivere una Servlet si fa uso delle classi del package
javax.servlet che è il framework di base per la scrittura delle servlet e del package
javax.servlet.http che è l'estensione del framework di base, per la comunicazione via
http. Utilizzando un linguaggio portabile come Java, le Servlet consentono di realizzare
soluzioni per estendere le funzionalità dei server web, indipendenti dal sistema
operativo su cui esse vengono eseguite.
Per cosa vengono utilizzate?
Le Servlet vengono più comunemente utilizzate per:
elaborare e salvare dati provenienti da form HTML;
provvedere alla creazione di pagine HTML dinamiche, ad esempio
utilizzando i dati contenuti in un database, in seguito ad una richiesta di un
client;
gestire informazioni con stato, ad esempio la gestione di un sistema di
commercio elettronico, dove un certo numero di clienti fa degli acquisti
contemporaneamente e dove occorre quindi mantenere in modo corretto le
informazioni sui clienti e sui loro acquisti (il classico carrello della spesa);
Servlet vs CGI
Le Servlet hanno diversi vantaggi rispetto al tradizionale CGI e precisamente
sono più efficienti, più facili da utilizzare, più potenti, più portabili e più economici.
Vediamo più in dettaglio ciascun punto:
Efficienza: Con una tradizionale applicazione CGI, viene generato un processo
(istanza del programma o script CGI) per ogni richiesta che arriva al server, questo
tipo di operazione può risultare abbastanza pesante in termini di risorse. Con le
Servlet invece, la JVM (Java Virtual Machine) genera, per ogni richiesta da esaudire,
un Thread Java, molto più leggero (lightweight) di un processo generato dal sistema
operativo: con il CGI se ci sono N richieste contemporanee, esistono N immagini in
memoria del programma CGI.
130
CAP. 6 – TECNOLOGIE SOFTWARE
Con le Servlet invece, ci sono N Thread ma una sola copia della classe Servlet
in memoria. Inoltre c'è da dire che l'efficienza è ancora superiore se si pensa che, ad
esempio, un'applicazione CGI che si interfaccia con un database si connette ad esso
ad ogni richiesta che arriva e si disconnette al termine: operazioni queste molto
pesanti. Con le Servlet invece è possibile mantenere aperte una o più connessioni al
database, utilizzando ad esempio una Connection Pool, e riutilizzarle da richiesta a
richiesta.
Facilità d'uso: Java mette a disposizione una API per la scrittura delle servlet che
facilità molto le varie operazioni coinvolte nell'utilizzo di una Servlet e cioè:
manipolazione dei dati provenienti dai form HTML, lettura e gestione delle intestazioni
(headers) delle richieste http, gestione dei Cookie e delle sessioni e molte altre cose
utili.
Potenza: Con le servlet si possono fare tante cose che con i programmi CGI sono
difficili o addirittura impossibili da realizzare: le servlet possono dialogare direttamente
con il server web facilitando l'utilizzo e la condivisione di dati (testi, immagini ecc.) .
Inoltre le servlet facilitano operazioni come la session tracking, permettendo il
mantenimento di informazioni tra una richiesta e un'altra, e di caching delle operazioni
già eseguite in una richiesta precedente.
Portabilità: Essendo scritte in Java mediate un'apposita API standard, le Servlet
possono girare su qualsiasi piattaforma. Oggi le servlet sono supportate, direttamente
o mediante plug-ins (servlet engines), dalla maggior parte dei server web in
circolazione, commerciali e free.
Convenienza. Molti server web che supportano le servlet sono free o comunque
hanno un basso costo. Se si dispone già di un server web commerciale (di quelli cari!)
che non supporta le servlet l'aggiornamento con appositi plug-ins per il supporto delle
servlet è normalmente free.
131
CAP. 6 – TECNOLOGIE SOFTWARE
Architettura di base e ciclo di vita di una Servlet
Una Servlet, nella sua forma più generale, è un'istanza della classe che
implementa l'interfaccia javax.servlet.Servlet, e cioè javax.servlet.GenericServlet; ma
come abbiamo già detto quella più utilizzata è quella che usa il protocollo HTTP e che
si costruisce estendendo la classe javax.servlet.http.HttpServlet. Vediamo adesso il
tipico ciclo di vita di una Servlet. All'avvio, il server carica in memoria la classe Servlet
ed eventualmente le classi utilizzate da questa, e crea un'istanza chiamando il
costruttore senza argomenti. Subito dopo viene chiamato il metodo init(ServletConfig
config). Qui avvengono le inizializzazioni delle variabili globali, procedura che viene
fatta una sola volta durante l'intero ciclo di vita della Servlet, e viene caricato l'oggetto
ServletConfigche potrà poi essere recuperato più tardi mediante il metodo
getServletConfig(). Quest'ultima operazione viene eseguita nel metodo init della classe
GenericServlet ed è per questo che in ogni classe che la estende, come lo è
HttpServlet, all'inizio del metodo init c'è una chiamata al metodo della superclasse e
cioè super.init(config). L'oggetto ServletConfig contiene i parametri della Servlet e il
riferimento a ServletContext che rappresenta il contesto in cui gira la Servlet. Una
volta inizializzata la Servlet, viene chiamato il metodo service (ServletRequest req,
ServletResponse res) per ogni richiesta che arriva dai client; questo metodo viene
chiamato in modo concorrente cioè più Thread possono invocarlo nello stesso
momento. In casi particolari e cioè quando si lavora con risorse non condivisibili, è
possibile implementare Servlet non concorrenti. Quando una Servlet deve essere
arrestata, ad esempio se deve essere aggiornata o bisogna riavviare il server, viene
chiamato il metodo destroy() nel quale vengono rilasciate le risorse allocate nel
metodo init. Anche questo metodo viene chiamato una sola volta durante il ciclo di
vita della Servlet.
Conclusioni
Possiamo concludere dicendo che, le Servlet sono uno strumento tra i più validi
per le applicazioni che richiedono contenuti web dinamici; sono abbastanza semplici
da sviluppare e consentono di eseguire operazioni che con le tecniche precedenti
risultavano difficili, questo grazie alla possibilità di utilizzare tutte le API che Java
mette a disposizione, che sappiamo essere numerose e varie.
132
CAP. 6 – TECNOLOGIE SOFTWARE
6.2 Service-Oriented Architecture
Durante l’evoluzione della tecnologia dei Web service, abbiamo notato un
pattern. Ogni volta che applichiamo le tecnologie degli Web service ad un problema di
integrazione di applicazioni, emerge un pattern. Chiamiamo questo pattern,
Architettura Orientata al Servizio, service-oriented architecture (SOA). SOA è un
semplice concetto, che lo rende applicabile ad un ampia varietà di situazioni di Web
service.
Fig 6.3 - Service-oriented architecture (SOA).
In ogni service-oriented architecture si individuano tre ruoli: un richiedente del
servizio, un fornitore del servizio, e un registro del servizio:
1. un service provider è responsabile della creazione della descrizione del
servizio, della pubblicazione della descrizione del servizio su uno o più service
registry, and receiving Web service invocation messages from one or more
service requestors.
133
CAP. 6 – TECNOLOGIE SOFTWARE
Un service provider, quindi, può essere una qualsiasi società che mantiene un
Web service rendendolo accessibili su un qualche rete. Si può pensare ad un
service provider come al "lato server" di una relazione client-server tra un
service requestor e il service provider.
2. un service requestor è responsabile della ricerca di una descrizione di un
servizio pubblicato su uno o più service registry ed è responsabile dell’usare la
descrizione di un servizio per collegare o invocare i Web service mantenuti
dagli service provider. Qualsiasi utente di un Web service può essere
considerato un service requestor. Si può pensare ad un service requestor come
al "client side" di una relazione client-server tra un service requestor e il
service provider.
3. il service registry è responsabile di mostrare le descrizione dei Web service
pubblicate dai service provider e di permettere ai service requestor di ricercare
la collezione di descrizioni dei servizi contenuti all’interno del service registry. Il
ruolo del service registry è semplice: essere l’intermediario tra service
requestor e service provider. Una volta che il service registry crea il
collegamento, non è più necessario; il resto dell’interazione avviene
direttamente tra il service requestor e il service provider con l’invocazione del
Web service.
Ciascuno di questi ruoli può essere svolto da un qualsiasi programma o nodo
della rete. In alcune circostanze, un singolo programma potrebbe svolgere più ruoli;
per esempio, un programma può essere un service provider, che fornisce un Web
service a degli utenti come pure un service requestor, che usa Web service forniti da
altri.
Una SOA include inoltre tre operazioni: publish, find, and bind. Queste
operazioni definiscono dei contratti tra i ruoli nella SOA:
134
CAP. 6 – TECNOLOGIE SOFTWARE
1. l’operazione di publish è un atto di registrazione del servizio o di avviso di
servizio. Costituisce il contratto tra il service registry e l service provider.
Quando un service provider pubblica le descrizioni dei suoi Web service sul
service registry, rende noti i dettagli di quel Web service ad una comunità di
service requestor. I dettagli attuali della API di publish dipendono da come è
stato implementato il service registry. In alcuni semplici scenari o nel "direct
publish", il ruolo service registry è svolto dalla rete stessa, l’operazione publish
è semplicemente l’azione di spostare la descrizione del servizio nella struttura a
cartelle di un Web application server. Altre implementazioni di service registry,
come l’UDDI, definisce una implementazione molto sofisticata dell’operazione
di publish.
2. L’operazione di find è il logico duale dell’operazione di pubblicazione.
L’operazione di ricerca è il contratto tra un service requestor e un service
registry. Con l’operazione di ricerca, il service requestor dichiara un criterio di
ricerca, come il tipo di servizio, molti altri aspetti del servizio come le garanzie
di qualità del servizio, e così via. Il service registry confronta il criterio di
ricerca con la collezione di descrizioni di Web service pubblicati. Il risultato
dell’operazione di ricerca è una lista di descrizioni di servizi che soddisfano il
criterio di ricerca. Ovviamente, la sofisticatezza dell’operazione di ricerca varia
con l’implementazione del ruolo di service registry. I Semplici service registry
possono fornire un’operazione di ricerca niente di più complesso di una HTTP
GET senza parametri. In questo caso l’operazione di ricerca ritorna sempre tutti
gli Web service pubblicati sul service registry ed è compito del service
requestor di stabilire quale descrizione di Web service corrisponde alle proprie
esigenze. L’UDDI, ovviamente, fornisce delle capacità di ricerca estremamente
potenti.
3. l’operazione di bind racchiude la relazione client-server tra il service requestor
e il service provider. L’operazione di bind può essere abbastanza sofisticata e
dinamica, come la generazione on-the-fly del proxy lato-client basato sulla
descrizione del servizio, usato per invocare il Web service; o può essere un
135
CAP. 6 – TECNOLOGIE SOFTWARE
modello molto statico, dove uno sviluppatore scrive a mano come l’applicazione
client richiama un Web service.
La chiave del SOA è la descrizione del servizio. È la descrizione del servizio che
è pubblicata dal service provider sul service registry. È la descrizione del servizio che
viene recuperata dal service requestor come risultato di un’operazione di ricerca. È la
descrizione del servizio che dice al service requestor tutto quello che deve conoscere
in modo da collegare o invocare il Web service fornito dal service provider. La
descrizione del servizio indica quale informazione (se presente) è ritornata al service
requestor come risultato di un’invocazione di uno Web service.
136
CAP. 6 – TECNOLOGIE SOFTWARE
6.2.1 Web-Services
Fig 6.4 - Flusso procedurale di una chiamata ad un servizio web.
Un Web Services è un insieme di standard di comunicazione che permettono a
diverse applicazioni di scambiarsi dati e servizi applicative.
Lo scenario ipotizzato è quello di un’applicazione che necessita, per espletare le
sue funzioni, di una serie di servizi . Si vogliono reperire altrove questi servizi invece di
svilupparli all’interno dell’applicazione stessa.
137
CAP. 6 – TECNOLOGIE SOFTWARE
I Web Services non sono stati la prima formalizzazione di architettura
distribuita ma rispetto alle precedenti questa architettura offre dei vantaggi che
l’hanno fatta preferire alle altre:
semplicità della specifica;
utilizzo di tecnologie standard;
ampio consenso da parte di diverse aziende (Microsof, Sun, IBM….), la
presenza di tool che aiutano enormemente la creazione di nuovi servizi e la
fruizione dei servizi esistenti.
Tutto ciò ha portato all’adozione dei Web Services in diversi contesti. Come
accade spesso, avere numerose implementazioni, sia di servizi che di strumenti per
realizzarli, porta la specifica a diventare uno “standard di fatto”. Questo grazie a:
1. Semplicità della specifica. Più una specifica è semplice, minore è il tempo
che trascorre tra il suo studio e la realizzazione di progetti concreti. Le
tecnologie che stanno alla base dei Web Services sono molto semplici, intuitive
e con poche regole di base.
2. Utilizzo di tecnologie standard. Tutte le tecnologie alla base dei Web
Services sono standard (essenzialmente XML per la rappresentazione, XML
schema per la validazione e Http per il trasporto anche se esso si può basare
su qualsiasi altro protocollo. L’XML come scelta di base permette, inoltre,
anche ad una persona di “guardare” i messaggi ed di intuirne il significato.
3. Ampio consenso da parte di diverse aziende. Microsoft è stata la prima
azienda a proporre modalità di comunicazione basate su XML. Però ha avuto la
lungimiranza di non mantenere proprietarie le specifiche ma di renderle
pubbliche. Questo ha portato ad un crescente interesse all’affermarsi dei primi
standard.
4. Presenza di tool. La loro presenza è una conseguenza dei punti precedenti ma
è l’unico vero motivo che riesce a catalizzare una quantità sempre crescente di
sviluppatori.
138
CAP. 6 – TECNOLOGIE SOFTWARE
I Web Services sono un ottimo strumento dove l’interoperabilità è un requisito
essenziale. Per altri contesti e soprattutto in quelli in cui si ha un completo controllo
sulle tecnologie adottabili nelle applicazioni coinvolte, i Web Services non sono una
scelta ottimale: la loro generalità implica un volume di traffico notevole e non
ottimizzato e un carico computazionale significativo sia per la codifica che la decodifica
dei dati.
Fig. 6.5 - Stack di collegamento tra messaggio SOAP e protocollo di rete HTTP.
Lo stack di collegamento rappresenta le tecnologie che determinano come un
messaggio viene spedito dal richiedente del servizio al fornitore del servizio. La base
dello stack è un protocollo di rete (Network Protocol). I Web Service possono essere
basati su una varietà di standard, i protocolli di collegamento di Internet come HTTP o
HTTPS, SMTP, FTP, e via dicendo, come pure sofisticati protocolli di livello enterprise
come RMI/IIOP e MQSeries.
Per la codifica dei dati (Data Encoding), i Web service usano l’XML. In aggiunta, un
contenuto non XML può essere referenziato da Web service con messaggio invocato,
permettendo la massima flessibilità nei tipi di dati usati nel messaggio. Per le
specifiche dei dati, i Web service usano l’XML Schema. Questo include sia gli schemi
nel contesto del messaging XML sia gli schemi conformi ad un set di regole
predefinite, come le regole della codifica SOAP.
139
CAP. 6 – TECNOLOGIE SOFTWARE
Costruito sopra gli strati di networking protocol e data-encoding sono gli strati
di messaging XML. Per l’XML Messaging, i Web service usano il SOAP nel data
encoding, nello stile di interazione e nelle variazioni di binding dei protocolli. SOAP è
usato come un semplice approccio per inserire un messaggio XML in una busta. Il
risultato è una base solida di standard per i Web service.
Concettualmente al di sopra il meccanismo di SOAP enveloping è un
meccanismo per estensioni dell’envelope chiamati SOAP header. Con i SOAP header,
le estensioni ortogonali come una firma digitale possono essere associati con il corpo
del messaggio contenuto all’interno del SOAP envelope.
Gli strati di questo stack sono ben definiti, sia come protocolli di rete standard
che come specifiche SOAP stesse. Lo stack è il più diffuso e più ampiamente
supportato set di tecnologie per i Web service.
A destra nella figura ci sono tre colonne verticali che rappresentano le
tecnologie associate che coinvolgono più livelli dello stack di collegamento. La
sicurezza, per esempio, può intervenire ad ogni livello (l’SSL a livello di protocollo di
rete e le firme digitale a livello delle estensioni dell’envelope). È fuori di ogni dubbio
che non avremmo mai un singolo standard che copra tutti gli aspetti della sicurezza di
cui hanno bisogno i Web service. Le altre colonne verticali elencate includono la
qualità del servizio e la manutenzione. Questi sono solo alcuni degli aspetti degli Web
service che possono intervenire in più levelli dello stack di collegamento, ma non ci
sono standard universalmente accettati.
140
CAP. 6 – TECNOLOGIE SOFTWARE
6.2.2 Protocollo SOAP
SOAP nasce come uno standard aziendale, progettato per migliorare
l'interoperabilità della multipiattaforma, frutto del lavoro congiunto di colossi quali
Microsoft, DevelopMentor, IBM, Lotus Development, UserLand e Sun Microsystems.
La comunicazione da applicazione ad applicazione su Internet e/o su Intranet
ha impegnato tantissimo il popolo degli sviluppatori. La maggior parte delle soluzioni
individuate tendono ad essere specifiche della piattaforma, non scalano molto bene,
spesso richiedono molti round-trip tra il Client e il Server. Altre soluzioni a questo tipo
di problemi sono DCOM, CORBA, ecc. Le stesse comunque, incontrano non pochi
problemi nel passare attraverso i FireWall. Il protocollo SOAP riduce molti di questi
problemi, la specifica completa di SOAP è disponibile sul Web site di Microsoft. Il
protocollo SOAP fornisce un modo consistente e strutturato di trasporto dei dati e di
chiamata dei metodi fra le potenziali applicazioni distribuite. L'esecuzione di questi
servizi basati sul WEB necessita di numerosi componenti posti sui vari computer.
Poiché questi sistemi comprendono molti computer, inclusi client, server di
medio livello e DBMS, sono denominati sistemi distribuiti.
Sistemi distribuiti
Solitamente i sistemi distribuiti utilizzano due modelli di comunicazione:
1. Trasferimento di messaggi,
2. Richiesta/risposta.
Il primo modello consente la comunicazione tra gli attori mediante lo scambio
di messaggi che possono essere spediti in ogni momento, questo provoca un'azione
da parte del destinatario del messaggio, che a sua volta viene "risvegliato" per
eseguire l'azione associata.
141
CAP. 6 – TECNOLOGIE SOFTWARE
L'elaborazione dei messaggi può essere:
• Sincrona
• Asincrona
Sincrona quando, a fronte della spedizione del messaggio, il destinatario
immediatamente inizia l'esecuzione dell'azione associata. Asincrona quando, tra
trasmettitore/ricevitore è interposta una coda di messaggi, e solo quando il ricevitore
richiede di riceverli in coda li elabora. Ciò può essere fatto anche dopo molto tempo
rispetto all'invio del messaggio. Nel modello richiesta/risposta, la richiesta e la risposta
sono unite e quindi si parla di sistema sincrono. La richiesta viene inoltrata da
un'applicazione e questa, prima di continuare con l'elaborazione, attende i risultati. Il
modello richiesta/risposta è utilizzato per consentire la comunicazione tra i
componenti sui diversi computer attraverso le RPC (Remote Procedure Call).
Attualmente i due standard più diffusi per l'attivazione remota di procedure
sono DCOM (Distributed Component Object Model) e IIOP (Internet Inter-Orb
Protocol). Sono entrambi efficaci, anche se non progettati appositamente per
l'interoperabilità, quindi non è possibile richiamare da un client un componente su un
server prima di conoscere lo standard utilizzato dal server e prima di avere impostato
la security. Su intranet è possibile limitare il sistema all'utilizzo di una piattaforma di
riferimento, non appena si opera su internet, di solito non è possibile utilizzare una
piattaforma uniforme nell'intero sistema.
A questo punto DCOM e IIOP non consentono più la comunicazione tra due
componenti all'interno del sistema né consentono agli utenti di transitare all'interno di
domini affidabili. Per politiche di security, viene bloccato dai Firewall il passaggio di
stream binari da porte TCP/IP. SOAP rappresenta una soluzione a questi problemi,
sfruttando la tecnologia WEB e la flessibilità e l'estensibilità di XML, permette inoltre di
transitare all'esterno delle reti intranet, non procurando problemi ai Firewall.
Lo standard SOAP non introduce nuovi concetti in quanto si basa su tecnologia
già esistente. Attualmente utilizza il protocollo HTTP come protocollo di trasporto di
messaggi richiesta/risposta ed è indipendente dalla piattaforma ponendosi inoltre ad
uno strato indipendente dal protocollo di trasporto.
142
CAP. 6 – TECNOLOGIE SOFTWARE
Teoricamente è possibile effettuare la richiesta utilizzando qualsiasi protocollo
di trasporto ed avere la risposta con qualsiasi protocollo di trasporto.
Un Package SOAP contiene informazioni che consentono di richiamare un
metodo anche se nella specifica SOAP il nome del metodo stesso non viene definito.
SOAP, inoltre, non gestisce il garbage-collector distribuito, il boxcarring dei messaggi,
la protezione del tipo e HTTP bidirezionale. SOAP consente il passaggio dei parametri
e dei comandi tra i client e i server HTTP indipendentemente dalle piattaforme e dalle
applicazioni sul client e sul server. I parametri e i comandi sono codificati mediante
XML.
URI, URL
Prima di iniziare a parlare di protocollo HTTP, SOAP ecc. è importantissimo
introdurre il significato di alcuni termini, quali URL, URI, URN. Un URI (Uniform
Resource Identifier) è semplicemente una stringa formattata che identifica
univocamente una risorsa.
Un URIs può essere espresso in due diversi modi, uno è URLs (Uniform
Resource Locators) e URNs (Uniform Resource Names). Una URL codifica il protocollo
necessario per localizzare la risorsa specificata. Una URN è indipendente dalla
posizione e non implica alcun protocollo o meccanismo per localizzare la risorsa
specificata. Una URL inizia con il prefisso che identifica il protocollo, lo scheletro di
una URL è ( [] indica opzionale ):
<host> indica l'indirizzo IP del server, <port> è il numero di porta TCP su cui è in
attesa il server, se non è specificato nessuna porta per default si assume la porta 80,
e il <path> è l'URI assoluto passato con Request-URI nell'intestazione della richiesta
HTTP, se non viene specificato nessun path per default si assume "\" (root).
143
CAP. 6 – TECNOLOGIE SOFTWARE
Una URN a differenza della URL è poco comprensibile, una URN è una stringa
univoca (molto simile ad UUID). Non esiste un modo generico per deferenziare una
URN per cercare la risorsa che identifica, la sintassi utilizzata per definire una URN è:
<NID> è l'indentificatore del namespace, e <NSS> è la stringa che specifica il
namespace, ad esempio una interfaccia di un componente COM può essere
rappresentata dalla seguente URN:
Le URN è il meccanismo preferito per riferirsi a risorse mantenendosi
indipendenti dalla locazione della risorsa stessa, questo meccanismo è pesantemente
utilizzato in XML, SOAP.
HTTP come protocollo di trasporto
È pratica comune usare DCOM o CORBA all'interno di un server farm ed usare
http per entrare nel farm da una macchina client. HTTP è un protocollo RPC-like molto
semplice da installare, ed è molto più semplice farlo "passare" attraverso i Firewall
rispetto ad altri protocolli. Una richiesta http è tipicamente inviata ad un WebServer
(ad esempio IIS, Apache, Tomcat) anche se un numero sempre più crescente di
applicazioni supporta direttamente HTTP come protocollo nativo in aggiunta a DCOM
e IIOP. Come DCOM e IIOP, lo strato HTTP comunica con il protocollo TCP/IP, la
porta standard utilizzata è la 80, ma qualunque altra porta può essere utilizzata allo
stesso scopo. Dopo aver stabilito una connessione TCP, il client spedisce un
messaggio di richiesta HTTP al server,che gli risponde con un messaggio di risposta
HTTP dopo aver elaborato la richiesta stessa.
144
CAP. 6 – TECNOLOGIE SOFTWARE
Sia richiesta che risposta contengono un'arbitraria informazione PAYLOAD,
tipicamente rappresetanta dalle intestazioni Content-Length e Content-Type. Di
seguito è riportato un esempio di richiesta HTTP valida:
Esempio di richiesta http
Come si può notare, l'intestazione HTTP è rappresentata da testo, è molto
semplice trovare eventuali problemi HTTP utilizzando uno sniffer o un tool testuale, ad
esempio TELNET. La natura testuale di HTTP lo rende adattabile a qualsiasi ambiente
di sviluppo Web-Based. La prima linea della richiesta HTTP contiene tre componenti: il
metodo HTTP , la richiesta URI e la versione del protocollo. La IETF (Internet
Engineering Task Force) ha standardizzato il numero dei possibili metodi HTTP, questi
sono GET e POST. Il Metodo GET è utilizzato per la navigazione nel WEB, il metodo
POST è comunemente utilizzato per lo sviluppo di applicazioni. I metodi GET/POST
possono essere utilizzati indifferentemente per inviare informazioni dal client al server.
La richiesta URI (Uniform Resource Identifier) è un token usato dai server HTTP per
identificare il destinatario della richiesta (RFC2616). Il server HTTP dopo aver
elaborato la richiesta, rimanda indietro al client una risposta. La risposta contiene lo
stato che indica la buona o cattiva elaborazione della richiesta stessa. Un esempio di
risposta HTTP è:
145
CAP. 6 – TECNOLOGIE SOFTWARE
In questo caso, il server ritorna il codice 200. Con questo codice, si indica in
modo standard HTTP la corretta elaborazione della richiesta. Nel caso in cui il server
non è stato in grado di elaborare la richiesta, la risposta del server può essere ad
esempio:
Il server HTTP decide che la richiesta inviata al destinatario definita nella URI
deve essere temporaneamente rediretta su una differente URI, la risposta ritornata
dal server è:
Questa risposta avverte il client che per essere soddisfatta la richiesta, questa
deve essere reinoltrata alla nuova URI definita in Location. Per eventuali
approfondimenti sui codici dello stato standard, si rimanda alla RFC2616.
SOAP
Fig 6.6 – Struttura di un messaggio SOAP.
146
CAP. 6 – TECNOLOGIE SOFTWARE
SOAP
viene
codificato
mediante
l'utilizzo
di
XML
tramite
il
modello
richiesta/risposta usando come protocollo di trasporto HTTP. Un metodo SOAP è
semplicemente una richiesta HTTP e una risposta alle specifiche di decodifica SOAP.
Come CORBA /IIOP, SOAP non richiede che un oggetto specifico sia legato ad un dato
end-point ma spetta allo sviluppatore decidere come mappare l'oggetto end-point su
un oggetto presente sul server. L'end-point SOAP è una URL http che identifica il
metodo destinatario dell'invocazione. Una richiesta SOAP è una richiesta HTTP- POST.
Per indicare il metodo da invocare si usa l'intestazione HTTP SOAPMethodName, un
esempio:
In questa intestazione il nome del metodo è indicato dopo il segno # ed è add.
Il payload HTTP di una richiesta SOAP è un documento di XML che contiene i valori
[in] e [in,out] dei parametri del metodo. Questi valori sono codificati come elementi
figli di un elemento distinguibile di chiamata, condiviso con il nome, l'URI del
namespace e dell'interstazione HTTP di SOAPMethodName. L'elemento della chiamata
deve comparire all'interno del messaggio standard SOAP composto da <Envelope> e
<Body>, un esempio di richiesta minima di un metodo SOAP è riportata di seguito:
147
CAP. 6 – TECNOLOGIE SOFTWARE
Nell'intestazione SOAPMethodName è inserito un elemento figlio dell'elemento
<Body>, altrimenti la chiamata viene rifiutata. Ciò permette agli amministratori del
firewall di realizzare filtri di chiamata a particolari metodi senza passare dal parser
XML. Il formato di risposta di SOAP è simile a quello della richiesta. Il payload di
risposta conterrà i parametri [out] e [in,out] del metodo messi come elementi figli di
un elemento distinguibile della risposta. Il nome di questo elemento è lo stesso
dell'elemento di chiamata della richiesta concatenato con il suffisso Response. Di
seguito è riportato un esempio minimo di risposta:
In questo caso l'elemento di risposta è chiamato methodResponse, che è il
nome di metodo seguito dal suffisso di Response. Inoltre c'è da notare che
l'intestazione del HTTP SOAPMethodName è assente. L'intestazione è richiesta
soltanto nel messaggio di richiesta, non nella risposta.
148
CAP. 6 – TECNOLOGIE SOFTWARE
DataType
Ogni elemento di un messaggio SOAP è un elemento strutturale di SOAP, un
elemento della root, un accessor, o un elemento indipendente. I soap:Envelope,
soap:Body e soap:Header sono gli unici tre elementi strutturali di SOAP. La relazione
base è descritta dal seguente frammento dello schema di XML:
Dei quattro tipi di elementi di SOAP, gli elementi strutturali sono utilizzati per
rappresentare le istanze dei tipi, o riferimenti a istanze di tipi. Un elemento root è un
elemento
distinto,
discende
direttamente
dall'elemento
<soap:Body>
oppure
dall'elemento <soap:Header>. L'elemento <soap: Body> ha esattamente un
elemento root, questo può rappresentare sia la chiamata, sia la risposta che eventuali
elementi di fault. Questo elemento root deve essere il primo elemento child di
<soap:Body> e deve essere corredato del URI del namespace che deve corrispondere
all'intestazione HTTP SOAPMethodName, o soap:Fault nel caso di un messaggio di
fallimento dell'invocazione del servizio. L'elemento di <soap:Header> può avere più
elementi root, di cui uno per l'estensione dell'intestazione connessa con il messaggio.
Questi elementi root devono essere discendenti diretti di <soap:Header> ed i loro URI
del namespace indicano l'estensione del tipo di dati utilizzati.
149
CAP. 6 – TECNOLOGIE SOFTWARE
Gli elementi accessor sono usati per rappresentare i campi, le proprietà, o i
membri del tipo di dati. Ogni campo tipo di dato avrà esattamente un elemento
accessor nella relativa rappresentazione di SOAP.
Per capire bene come si utilizzato gli elementi accessor, consideriamo la
seguente definizione di classe Java:
Serializzando mediante SOAP questa classe, abbiamo:
Gli elementi accessor ivalue e lvalue sono chiamati semplici accessor perché
corrispondono a tipi primitivi, e sono definiti nella 2°parte del W3X XML Schema (per
ulteriori
informazioni
clicca
qui).
Questa
specifica
formalizza
i
nomi
e
le
rappresentazioni dei tipi numerici, tipo data, tipo stringa, inoltre è un meccanismo per
la definizione dei tipi primitivi nuovi usando il costrutto <datatype> all'interno di
nuova definizione dello schema. La soluzione più semplice per inserire strutture
complesse all'interno di una struttura, è quello di incapsulare il valore della struttura
all'interno dell'elemento accessor, ad esempio consideriamo la seguente definizione di
classe Java:
150
CAP. 6 – TECNOLOGIE SOFTWARE
Come
possiamo
notare,
all'interno
della
classe
sono
inseriti
due
oggetti
precedentemente specificati, quindi, serializzando la classe avremo:
In questo caso, i valori degli oggetti sono inseriti direttamente sotto i loro elementi
accessor.
Elementi Indipendenti
In SOAP, un elemento indipendente, rappresenta una istanza di un tipo che si
riferisce ad almeno un elemento accessor multireference. Tutti gli elementi
indipendenti sono etichettati dall'attributo di <soap:id> ed il valore di questo attributo
deve essere unico in tutto l'Envelope di SOAP.
151
CAP. 6 – TECNOLOGIE SOFTWARE
SOAP definisce un attributo (soap:Package) che può essere applicato ad un
elemento. L'attributo è usato per controllare dove gli elementi indipendenti possono
essere codificati. Le regole di serializzazione di SOAP impongono che un elemento
indipendente deve essere codificato come un discendente diretto di un elemento
<soap:Header>,
<soap:Body>
oppure
un
elemento
che
è
marcato
come
<soap:Package='true'>.
Annotando un elemento come Package, si garantisce che l'elemento XML che
codifica l'istanza è completamente self-contained e non ha multireference accessori ad
elementi che sono esterni al package.
Array
Gli array in SOAP sono trattati come caso speciale compound type. Un array
SOAP deve avere un Rank (dimensione) e una capienza. Un array viene trattato come
un compound type, ogni elemento di array ha come subelement il nome e il tipo
definito nel namespace-qualified. Consideriamo ad esempio la seguente definizione di
un tipo COM IDL:
una istanza di questo tipo viene serializzata come:
152
CAP. 6 – TECNOLOGIE SOFTWARE
se gli oggetti sono marcati con l'attributo [ptr], la codifica sarà fatta mediante l'utilizzo
dei multireference accessor, un esempio di questa codifica è di seguito riportata:
Elemento FAULT
Un elemento FAULT può contenere quattro elementi figli: faultcode, faultstring,
faultactor e detail.
I valori di codice attualmente disponibili sono:
VersionMismatch: questo errore viene restituito quando la chiamata ha
utilizzato uno spazio non valido
MustUnderstand: quando il destinatario non ha riconosciuto un
elemento XML ricevuto, che contiene un elemento con un tag
mustUnderstand="true".
153
CAP. 6 – TECNOLOGIE SOFTWARE
Client: classi di errore causate da informazioni improprie nel messaggio
SOAP effettivo, questi errori rappresentano un problema che riguarda il
contenuto del messaggio effettivo e indicano che il messaggio non deve
essere inviato nuovamente senza modifica.
Server: tali errori riguardano i problemi con il server e di solito non
rappresentano problemi con il messaggio SOAP.
L'elemento faultstring è una stringa non utilizzata dalle applicazioni ma
utilizzata solo come Struttura richiesta SOAP.
L'elemento faultfactor può fornire informazioni sugli elementi che hanno
provocato l'errore nel percorso del messaggio SOAP, è una URI che identifica l'origine:
se l'errore si verifica in un'applicazione che non è la destinazione finale del messaggio,
l'elemento faultactor deve essere incluso, altrimenti non è necessario. L'elemento
detail è necessario se i contenuti dell'elemento Body (SOAP) non possono essere
elaborati, questo viene utilizzato per fornire informazioni sugli errori specifici
dell'applicazione.
Un esempio di risposta SOAP contenente un fault è proposto qui di seguito:
154
CAP. 6 – TECNOLOGIE SOFTWARE
155
CAP. 6 – TECNOLOGIE SOFTWARE
6.3 Application Server
6.3.1 Apache Tomcat
Struttura di una applicazione web
La nozione di applicazione web è stata formalizzata per la prima volta nelle
specifiche delle servlet Java. Sebbene il concetto di applicazione web sia piuttosto
ampio e dipendente dal contesto in cui viene esaminato, la definizione fornita nelle
suddette specifiche risulta di portata sufficientemente generale.
Dal punto di vista dello sviluppatore di applicazioni web basate su Java risulta
particolarmente importante la standardizzazione della struttura di tali applicazioni e
l'introduzione degli archivi WAR come strumento per il deployment delle applicazioni
web. Una applicazione web è una gerarchia di file e directory disposti secondo uno
schema standard.
/webapp. Una applicazione web ha una propria directory radice (root). Il nome della
cartella corrisponde a ciò che nella terminologia delle servlet viene chiamato context
path (nel seguito supporremo che tale nome di tale cartella sia webapp). La directory
radice contiene tutti gli altri elementi che compongono l'applicazione web.
File HTML, JSP, ... La directory /webapp contiene i documenti HTML, le pagine JSP, le
immagini e le altre risorse che compongono l'applicazione web. Tali file possono
essere strutturati in directory esattamente come si farebbe per un sito web statico.
/webapp/WEB-INF. All'interno della cartella root si trova una directory speciale,
denominata WEB-INF. La funzione di questa cartella è quella di contenere file
riservati, come ad esempio il file di configurazione dell'applicazione, web.xml. Per
questo motivo le specifiche impongono che la cartella ed il suo contenuto debbano
risultare inaccessibili per gli utenti dell'applicazione.
156
CAP. 6 – TECNOLOGIE SOFTWARE
/webapp/WEB-INF/web.xml. Il file web.xml viene comunemente denominato
deployment descriptor. Si tratta del file di configurazione dell'applicazione web; in
esso, ad esempio, si definiscono gli alias delle servlet, i parametri di inizializzazione, le
mappature dei percorsi e così via.
/webapp/WEB-INF/classes e /webapp/WEB-INF/lib. Queste due directory
sono destinate a contenere le classi e gli archivi Jar di cui la nostra applicazione web
necessita. Se dobbiamo utilizzare delle classi Java compilate (file con estensione .class
andremo a copiarle all'interno di /webapp/WEB-INF/classes, secondo l'usuale struttura
di directory Java (così se abbiamo una classe MiaServlet contenuta nel package
sito.servlet.
il
percorso
del
file
compilato
sarà
/webapp/WEB-
INF/classes/sito/servlet/MiaServlet.class). Se dobbiamo utilizzare classi contenute in
archivi Jar, invece, sarà sufficiente copiarli in /webapp/WEB-INF/lib.
Archivi WAR
Una volta sviluppata una applicazione web possiamo "impacchettarla" in un
archivio WAR (Web Application Archive). Un archivio WAR non è altro che un archivio
Jar, una vecchia conoscenza dei programmatori Java, la cui estensione viene
modificata in .war semplicemente per indicare che il contenuto dell'archivio è una
applicazione web.
Gli archivi WAR hanno una duplice funzione: oltre a quella ovvia di comprimere
tutte le componenti di una applicazione in un unico archivio, costituiscono il formato di
deployment dell'applicazione stessa. Il termine inglese deployment indica la messa in
opera dell'applicazione. Uno scenario tipico è quello in cui l'applicazione viene
sviluppata localmente per poi essere trasferita, ad ultimazione, sul server vero e
proprio (detto anche di produzione). In questo caso è sufficiente creare il file WAR,
copiarlo sul server di produzione e seguire le istruzioni per l'installazione del WAR
relative al servlet container che si sta utilizzando. Nel caso di Tomcat, l'installazione di
un WAR è estremamente semplice: è sufficiente copiare il file nella directory webapps
e avviare (o riavviare) il server, che provvederà da solo a decomprimere l'archivio e
ad avviare l'applicazione.
157
CAP. 6 – TECNOLOGIE SOFTWARE
Un esempio di comando per la creazione di un archivio WAR (da digitare dopo
essersi spostati all'interno della cartella webapp) è il seguente:
jar cvf webapp.war
È consigliabile, in ogni caso, fare riferimento alla documentazione ufficiale del
tool jar per una spiegazione esaustiva delle opzioni disponibili.
In questa breve nota abbiamo preso dimestichezza con la strutturazione di una
applicazione web, così come definita nelle specifiche Servlet.
Organizzando le nostre applicazioni in tal modo otterremo diversi vantaggi:
• aumenteremo la portabilità dell'applicazione, rendendone più semplice la messa
in opera;
•
renderemo l'applicazione più comprensibile ad altre persone, in quanto sarà
molto più semplice sapere dove si trovano le classi, gli archivi Jar e le altre
componenti dell'applicazione stessa;
•
potremo racchiudere l'intera applicazione in un archivio WAR, rendendone
semplice l'installazione su tutti i servlet container conformi alle specifiche Sun.
Abbiamo così compiuto il primo passo per la realizzazione di una applicazione
web in ambiente Java, che abbiamo imparato a strutturare in modo standard. Il
prossimo argomento da affrontare sarà la configurazione dell'applicazione attraverso il
già citato file web.xml.
L'ambiente di Tomcat
Tomcat contiene al suo interno tutte le funzionalità tipiche di un web server,
ovvero - in sintesi - ha la capacità di interpretare una richiesta di una risorsa veicolata
su protocollo HTTP, indirizzarla ad un opportuno gestore (o prenderla dal filesystem)
e restituire poi il risultato (codice HTML o contenuto multimediale che sia).
158
CAP. 6 – TECNOLOGIE SOFTWARE
In questo aspetto non differisce molto da altri web server, come Apache, se
non che spesso si rivela meno prestante. La caratteristica innovativa di Tomcat non è
quindi quella di essere un veloce web server, ma piuttosto quella di fornire allo
sviluppatore un vero e proprio ambiente nel quale girano applicazioni Java (le servlet).
Adesso cercheremo di comprendere meglio come sia strutturato questo ambiente Java
nel quale prenderanno vita le nostre applicazioni latoserver.
Contenitori in Tomcat
Come nelle normali applicazioni, anche nella programmazione lato server gli
oggetti creati devono avere uno scopo, ovvero essere definiti ed accessibili in un
determinato contesto. Utilizzare Tomcat equivale a suddividere lo spazio delle risorse
in contenitori sostanzialmente indipendenti nei quali possono essere depositati oggetti
Java, secondo una logica orientata al web. Per comprendere appieno questo concetto
analizziamo nel dettaglio i singoli contenitori che sono tra loro strutturati in maniera
abbastanza gerarchica.
Tomcat
Chiaramente il primo livello corrisponde al web server stesso che avrà un
insieme di variabili ad esso associate. Ad esempio qui dentro vi sarà indicazione del
numero di thread attualmente in esecuzione, della versione di Tomcat o altre
proprietà globali generalmente di poco interesse nella programmazione.
Contesto
Quando un utente accede al web server accede in realtà ad una sezione
specifica del web server (a un certo dominio virtuale o directory, ad esempio)
identificata sostanzialmente dalla URL. Nel gergo di Tomcat la sezione viene chiamata
contesto (context). All'interno di questo contenitore si troveranno quindi oggetti
comuni a tutta la sezione, che saranno gli stessi per tutti gli utenti e tutte le
applicazioni del contesto.
159
CAP. 6 – TECNOLOGIE SOFTWARE
Questo contenitore viene generato all'avvio di Tomcat e rimane attivo
indipendentemente dal fatto che qualcuno lo stia interrogando in quel momento.
Questo non vuol dire che rimanga invariato, anzi, il suo contenuto cambierà in
funzione delle richieste ricevute ed ogni elemento contribuirà a definire l'ambiente di
tutta la sezione.
Sessione
Il primo contenitore con caratteristiche fortemente orientate al web è quello
associato alla sessione (Session). Come dice il nome questo contenitore viene
associato ad un utente (o, meglio, ad un client) per tutto il tempo per il quale rimane
connesso ad un contesto specifico. Al suo interno verranno memorizzati oggetti che
saranno accessibili solo a quell'utente e ne personalizzeranno l'ambiente rispetto ad
altri client che utilizzino risorse dello stesso contesto nello stesso momento.
Richiesta
Il contenitore con la vita più breve è la richiesta (Request) che nasce e muore
nell'ambito della singola transazione web. Raramente questo contenitore viene
riempito da applicazioni anche se svolge un ruolo fondamentale nel flusso dei dati che
attraversano Tomcat.
Il flusso di dati
Abbiamo visto che l'oggetto Context viene creato all'avvio di Tomcat mentre
l'oggetto Request nasce muore ad ogni richiesta. Andiamo ad analizzare un po' più in
dettaglio il flusso logico che segue Tomcat nel processare le singole richieste web che
riceve.
Richiesta di una risorsa
Supponiamo che un client acceda a una risorsa su di un server su cui gira Tomcat.
Innanzi tutto viene instanziato un oggetto Request, Req, in Tomcat nel quale vengono
160
CAP. 6 – TECNOLOGIE SOFTWARE
inserite tutte le informazioni ricevute tramite HTTP (dalla url richiesta sino ai cookies)
e "al suo fianco" viene instanziato un oggetto risposta (Response, Res) nel quale
costruire pian piano la risposta da restituire al client. Leggendo la url all'interno della
richiesta Tomcat è quindi in grado di comprendere a quale dei contesti residenti in
memoria debbano essere consegnati questi due oggetti Req e Res.
Contesto e sessione
Il contesto invocato da Tomcat provvederà a vedere se esiste già una sessione
attiva per quel tipo di client leggendone la "firma" nella richiesta (sotto forma di
cookie o nella url, a seconda del metodo usato). Se la sessione, Ses, esiste già tra
quelle immagazzinate nel context, il contesto la riprende e la affianca agli oggetti Req
e Res. A questo punto l'ambiente è stato completamente definito e il web server può
passare il controllo all'applicazione associata alla risorsa in questione.
Le Servlet
A questo punto del percorso logico, il contesto è in grado di decidere (sulla
base del suo file di configurazione) a quale applicazione passare il controllo all'interno
dell'ambiente di lavoro definito in tutto il percorso (la più semplice delle applicazioni è
chiaramente quella che si occupa di restituire un file presente sul disco del server).
L'applicazione Java (la servlet) potrà quindi svolgere tutte le sue funzioni
attingendo agli oggetti già presenti nei vari contenitori (nella sessione, ad esempio) o
mettendocene di nuovi.
Risposta
Al termine del proprio lavoro la Servlet deve dare un esito al proprio lavoro
tramite la risposta Res. Le uniche due modalità per farlo sono o riempirla con dei
contenuti che il client sia in grado di comprendere (codice HTML, ad esempio) oppure
inserire un ordine per il contesto di redirigere il controllo ad un'altra risorsa (forward).
161
CAP. 6 – TECNOLOGIE SOFTWARE
Nel primo caso il contesto ripasserà tutto l'oggetto a Tomcat che si occuperà di
generare l'output per il client.
Nel secondo caso, se la risorsa è esterna al contesto il controllo verrà restituito
a Tomcat che ricomincerà il percorso logico con questa nuova risorsa. Se invece la
risorsa è interna al contesto un'operazione di forward equivale a fare un passo
indietro nel percorso logico per poi tornare avanti su un altro sentiero o, in altri
termini, chiamare la Servlet associata alla risorsa indicata nell'istruzione di forward,
passandole nuovamente tutto l'ambiente.
162
CAP. 6 – TECNOLOGIE SOFTWARE
6.4 Strumenti di sviluppo
6.4.1 Apache Axis
Axis è un progetto della Apache Software Foundation e prende origine dal
progetto Apache SOAP: durante lo sviluppo di quest’ultimo è nata l’esigenza di una
riscrittura dell’intero progetto per farlo evolvere ad una architettura maggiormente
modulare e con un meccanismo di parsing XML di tipo SAX.
Axis è un SOAP engine: questo significa che è un framework che si concentra
unicamente sulle problematiche della creazione di client e server e per la gestione di
messaggi SOAP; in pratica consiste in un insieme di tool per la generazione
automatica di classi e in una libreria che “incapsula” in classi Java l’accesso alle
tecnologie connesse ai Web Services.
L’architettura generale di Axis appare nella seguente figura nei suoi componenti
principali.
Fig. 6.7 – Architettura generale di Axis.
Il requestor è un client che effettua una richiesta su alcuni dei protocolli
supportati da Axis. Generalmente è usato HTTP. Il requestor può essere una desktop
application, una web application, o un altro web service.
Il motore Axis agisce agevolando la comunicazione tra client e web service
maneggiando la traduzione ad e da web service standard.
163
CAP. 6 – TECNOLOGIE SOFTWARE
Axis permette allo sviluppatore di definire una serie di handlers, allacciati alla
richiesta o alla risposta. Questi handlers sono simili a filtri servlet; ogni handler svolge
uno specifico compito adando avanti fino al prossimo handler in linea.
Gli handlers si adattano insieme in una catena , la quale comprende un set
specifico di handlers che corrispondono e richieste o risposte ad un web service.
Questo processo è mostrato in figura.
Fig. 6.8 – Catena degli handler per le risposte e le richieste.
Esempi di handlers sono componenti di sicurezza, sistemi di jogging, e
trasformazioni. Un speciale handler , conosciuto come il pivot point handler, esiste per
ogni web service. Questo handler elabora le chiamate attuali dei metodi del web
service . In altre parole , questo si ha dove il contenuto definito dalla chiamata del
metodo come un servizio web è spedito indietro al client richiedente.
Le catene di handler sono definite in documento di configurazione usato dal
motore di Axis chiamato server.config. Questo file è un documento XML che definisce i
parametri di configurazione per Axis.
Axis è composto da:
Una web application che si occupa di gestire l’ambiente di esecuzione dei
servizi (routine, istance poooling, serializzazione e deseralizzazione dei
messaggi SOAP, ecc….);
Una API composta da classi di utilità per la scrittura di servizi web e da
classi necessarie al funzionamento della web application e dei tool;
164
CAP. 6 – TECNOLOGIE SOFTWARE
Una seri di tool, tra cui WSDL2Java per generare scheletri lato server e
stub lato client dei servizi web a partire dalla descrizione WSDL;
Java2WSDL per generare la descrizione come servizio web di una classe
Java;
Diversi tool per l’amministrazione e la gestione dei servizi installati;
Un TCP monitor stand-alone ed un SOAP monitor integrato nella web
application per controllare la forma dei messaggi scambiati tra i servizi nelle
fasi di debug e test.
Tra le caratteristiche più interessanti di Axis c’è la possibilità di creare web
service in maniera immediata a partire da classi Java molto semplici con estensione
.jws(Java Web Service). Axis può essere quindi utilizzato in una serie di scenari anche
molto diversi tra loro, ad esempio può servire per:
la creazione di applicazioni client di servizi web già esistenti per i quali è
disponibile il WSDL: utilizzando WSDL2Java si possono creare in maniera
automatica gli stub per l’accesso a servizi esistenti implementati con
qualsiasi piattaforma . Le applicazioni client che utilizzano gli stub non
necessitano di ambienti di esecuzione particolari ma soltanto della presenza
della libreria axis.jar nel classpath;
la comunicazione via JAX-RPC tra processi Java: le API di Axis
implementano una versione JAX-RPC, rendendo possibile lo sviluppo di
applicazioni distribuite Java con protocollo di trasporto SOAP;
la creazione di servizi web a partire da classi java: Axis offre diversi
meccanismi per l’implementazione dei servizi. Quello più semplice e
completamente trasparente per il programmatore è JWS , ma sono
disponibili anche con modelli di servizi più complicati dove è possibile
personalizzare , ad esmpio , le modalità di serializzazione dei messaggi , la
struttura dei package ed il formato dei parametri , senza mai occuparsi
della descrizione WSDL o del formato SOAP dei messaggi , grazie
all’integrazione tra l’ambiente di esecuzione e Java2WSDL;
165
CAP. 6 – TECNOLOGIE SOFTWARE
l’implementazione di servizi web a partire da descrizioni WSDL: il tool
WSDL2Java è particolarmente utile quando si parte dalla descrizione dei
servizi per la realizzazione di un sistema piuttosto che della loro
implementazione.
166
CAP. 6 – TECNOLOGIE SOFTWARE
6.5 Database Relazionale
6.5.1 Oracle
⇒ L' architettura di Oracle
Un server Oracle è rappresentato fondamentalmente da due strutture, il
database e l'istanza. Con il termine database (d'ora in poi DB) si indicano i file fisici
in cui sono memorizzati i dati, mentre per istanza si intende l'insieme delle aree di
memoria e dei processi di background necessari ad accedere ai dati, ovvero al DB.
L'architettura del server è complessa: ogni area di memoria nell'istanza
contiene dati che non sono contenuti in altre e i processi di background hanno compiti
ben precisi, tutti diversi fra loro. Ogni DB deve obbligatoriamente fare riferimento
almeno ad un'istanza, è anche possibile avere più di un'istanza per database, ma in
realtà faremo sempre riferimento a database a singola istanza. Ciascun DB consiste di
strutture logiche di memorizzazione, per immagazzinare e gestire i dati, (tabelle,
indici, etc.) e di strutture fisiche di memorizzazione che contengono le strutture
logiche.I servizi offerti dalle strutture logiche del server sono indipendenti dalle
strutture fisiche che le contengono. Questo perché le strutture logiche possano essere
progettate nello stesso modo indipendentemente dall'hardware e dal sistema
operativo impiegati.Quindi sia che abbiamo un'installazione di server Oracle su
sistema operativo Microsoft, Linux o Solaris non troveremmo alcuna differenza nella
progettazione delle strutture logiche di memorizzazione.
⇒ Strutture logiche di memorizzazione
Tablespace
Al vertice della scala gerarchica troviamo i Tablespace, strutture che
raggruppano, a loro volta, quelle di livello più basso. È ammissibile suddividere i dati
in differenti tablespace in base ad uno specifico significato logico dettato dalla nostra
167
CAP. 6 – TECNOLOGIE SOFTWARE
applicazione che interagirà con il database. Per esempio si può creare un tablespace
per ciascun utente che andrà a memorizzare propri dati nel database.
Questa
suddivisione
logica
ha
l'enorme
vantaggio
di
consentire
l'amministrazione di una porzione limitata del DB, ovvero di un tablespace, senza
intaccare la funzionalità delle parti rimanenti. Ogni database deve avere uno o più
tablespace. Come requisito minimo per la creazione di un DB Oracle crea sempre un
tablespace di sistema, denominato SYSTEM.
Block
Un blocco dati è la più piccola unità di memorizzazione in Oracle, pertanto
indivisibile, e corrisponde ad un numero di byte scelto dal DBA durante la creazione
del database. È sempre multiplo della capacità del blocco usato dal sistema operativo
su cui si opera. Per approfondire è consultare la documentazione di Oracle alla voce
DB_BLOCK_SIZE.
Extent
È composto di un numero specifico di blocchi contigui di dati (block).
Segment
È formato da un insieme di extent. Ne sono un esempio le tabelle o gli indici.
Ogni qualvolta si crea un segment Oracle alloca al suo interno almeno un extent che,
a sua volta, contiene almeno un block. Tutto questo è sempre deciso dal DBA. Un
segment può essere associato esclusivamente ad un tablespace.
168
CAP. 6 – TECNOLOGIE SOFTWARE
Figura 6.9 - Relazioni tra tablespace, segment, extent e block
⇒ Strutture fisiche di memorizzazione
Data file
File che contengono tutti i dati del DB. Ogni database Oracle deve avere uno o
più data file. Ciascun data file è associato esclusivamente ad un tablespace, ma un
tablespace può essere formato anche da più di un data file. Ne esiste sicuramente
almeno uno per il tablespace SYSTEM.
Redo log file
Registrano tutte le modifiche occorse ai dati. Ogni DB possiede almeno due file
di redo log, perché Oracle scrive in questi file in maniera circolare: quando un file di
redo log è pieno allora Oracle scrive in quello successivo, quando l'ultimo file di redo
log è pieno allora Oracle ricomincia dal primo, assicurandosi però di memorizzare le
informazioni nei data file prima di sovrascriverle.
169
CAP. 6 – TECNOLOGIE SOFTWARE
Se una qualsiasi anomalia non permette la scrittura delle modifiche occorse al
database nei rispettivi data file, allora possiamo tranquillamente ottenere tali
modifiche dai redo log file. Le modifiche ai dati, pertanto, non sono mai perse.
I redo log file rappresentano la cronologia delle modifiche ai dati e sono di
vitale importanza per l'integrità del DB. Oracle permette di avere più di una copia per
ciascun redo log file: questa importante caratteristica è denominata multiplexing
dei redo log file.
Control file
Ogni database ha almeno un control file che contiene informazioni circa la
struttura fisica del DB, ovvero il nome, la data e l'ora di creazione e il percorso
completo di ciascun data file e redo log file. È di vitale importanza e si consiglia di
configurarne più di una copia: anche in questo caso parleremo di multiplexing di
control file.
Figura 6.10. Relazioni fra le strutture fisiche e logiche di un DB
170
CAP. 6 – TECNOLOGIE SOFTWARE
⇒ Aree di memoria in Oracle
Le aree di memoria di un server Oracle sono usate per contenere i dati, le
informazioni del dizionario dei dati, i comandi SQL, il codice PL/SQL e tanto altro
ancora. Tali aree sono allocate nell'istanza Oracle ogni qualvolta questa è fatta partire
e deallocata, vale a dire rilasciata, quando la stessa è "terminata".
Le due maggiori strutture di memoria sono la System Global Area (SGA) e la
Program Global Area (PGA).
Figura 6.11 - Componenti della SGA e della PGA
System Global Area
È un'area di memoria condivisa, il che significa che tutti gli utenti del DB ne
condividono le informazioni. È composta a sua volta di più aree di memoria ed ha uno
spazio allocato all'avvio di un'istanza definito dal parametro SGA_MAX_SIZE.
L'SGA e i processi di background formano l'istanza Oracle. Come si può vedere
in figura 3 quest'area è formata dal Database Buffer Cache, dal Redo Log Buffer, dallo
171
CAP. 6 – TECNOLOGIE SOFTWARE
Shared Pool, dal Large Pool e dal Java Pool. Le ultime due sono opzionali mentre le
altre sono obbligatorie per ciascuna istanza.
⇒ I processi di background di Oracle
Un processo è un meccanismo usato dal sistema operativo per eseguire alcune
attività. Oracle inizializza diversi processi di background per ogni istanza. Ogni
processo di background è responsabile nel portare a termine specifici compiti.
Non tutti i processi sono presenti in un'istanza Oracle: la maggior parte di essi
sono obbligatori, la presenza di altri dipende dal tipo di architettura Oracle desiderata.
Sono processi di background il Database Writer (DBWn), il Log Writer (LGWR), il
Checkpoint (CKPT), il System Monitor (SMON), il Process Monitor (PMON), l'Archiver
(ARCn), il Recoverer (RECO), il Dispatcher (Dnnn) e lo Shared Server (Snnn).
Per la realizzazione del progetto è stato utilizzato un database Oracle 10G
Express.
172
CAP. 6 – TECNOLOGIE SOFTWARE
6.5.2 FreeTOAD
FreeToad è un tool software free che permette di visualizzare e modificare
attraverso un interfaccia grafica il contenuto informativo di un database.
Esso mette a disposizione diversi strumenti grafici per la manipolazione di
database, tabelle, campi e dati e un prompt dei comandi con il quale, attraverso del
codice SQL, è possibile interrogare una base di dati.
Per prendere confidenza con esso, parallelamente al progetto JTelemed, è
stato realizzato un semplice database di tutti i comuni italiani.
Di seguito alcune immagini del software freeTOAD.
Elenco Tabelle di un determinato DB.
Ho selezionato la tabella A_ITTCOMUNI_TUTTI
Records della tabella
A_ITTCOMUNI_TUTTI
Figura 6.12 – Records di una tabella visualizzati attraverso freeTOAD
173
CAP. 6 – TECNOLOGIE SOFTWARE
Figura 6.13 – Campi della tabella A_ITTCOMUNI_TUTTI
Figura 6.14 – Risultati di una query SQL
174
CAP. 7 – PROBLEMATICHE E MIGLIORAMENTI
Illustrazione delle problematiche più critiche incontrate durante la
realizzazione del progetto e dei possibili miglioramenti da apportare
per sviluppi futuri.
INDICE ARGOMENTI:
7.1 Il server Linux
7.2 Gestioni critiche
7.3 Un database Open Source: MySQL
175
CAP. 7 – PROBLEMATICHE E MIGLIORAMENTI
7.1 Il server Linux
Come detto nel capitolo 5.3 nella descrizione della fase di deploy, “le macchine
di sviluppo, soprattutto se si utilizzano ambienti di sviluppo molto sofisticati, sono
configurate diversamente da quelle di test, pertanto il passaggio da un ambiente
all'altro potrebbe non essere indolore”.
Nel nostro caso il server di sviluppo è una semplicissima macchina con
piattaforma Windows nella quale abbiamo istallato tutti gli strumenti per la
realizzazione del Web service (tomcat, axis, eclipse) mentre la macchina di test, quella
che effettivamente è il server e che permette la pubblicazione sul web, gira su un
sistema operativo Linux.
Nonostante siano state prese tutte le dovute precauzioni in fase di
programmazione, soprattutto nella gestione delle path di file e di directory, qualche
piccolo, ma fondamentale
aspetto rendeva le due fasi (di sviluppo e di test) non
completamente dipendenti e perciò nel passaggio alla fase di test ogni volta bisogna
avere l’accortezza e la pazienza di tornare sul codice.
Vediamo brevemente di cosa si tratta.
PRECAUZIONI:
La disponibilità di implementazioni della JVM (Java Virtual Machine) per diversi
ambienti operativi è la chiave della portabilità di Java, proclamata nello slogan write
once, run everywhere ("scrivi una volta, esegui dappertutto"). La macchina virtuale
realizza infatti un ambiente di esecuzione omogeneo, che nasconde al software Java
(e quindi al programmatore) qualsiasi specificità del sistema operativo sottostante. Ciò
ha permesso di non dover andare a modificare metodi e funzioni specifiche e
soprattutto di poter definire univocamente una delle questioni più delicate nella
gestione di files: le path. La grande maggioranza dei servizi implementati si basa sui
due seguenti passi:
•
Creazione di un file .xml tramite una query SQL;
•
Invio del file appena creato;
176
CAP. 7 – PROBLEMATICHE E MIGLIORAMENTI
Il file xml viene salvato fisicamente sul file system nella cartella temp
dell’Application Server (il tomcat). Onde evitare incompatibilità tra i vari sistemi
operativi definiamo tale percorso come:
Path=System.getProperty("catalina.home")+File.separator+"temp"+File.separator;
Che corrisponde:
WINDOWS
LINUX
C:/TOMCAT554/temp/
/var/jakarta-tomcat-5.5.4/temp/
System.getProperty("catalina.home") restituisce il valore della variabile
di ambiente CATALINA HOME impostata in fase di istallazione dell’Apllication Server
mentre il File.separator inserisce il carattere di separazione della path assoluta di un
file (slash per Linux, back-slash per windows).
Questo è stato un semplice esempio di portabilità di java in quanto siamo
riusciti a passare da windows a linux senza dover effettuare nessun cambiamento.
Purtroppo però le cose non vanno sempre così, infatti in fase di attachment:
//Invio del file xml ottenuto dalla query come allegato
message=(org.apache.axis.MessageContext.getCurrentContext()).getResponseMes
sage();
/*VERSIONE PER LINUX*/
message.addAttachmentPart(message.createAttachmentPart(new DataHandler(new
URL("file:"+File.separator+File.separator+fileNamePath+fileName))));
/*VERSIONE PER WINDOWS*/
message.addAttachmentPart(message.createAttachmentPart(new DataHandler(new
URL("file:"+File.separator+fileNamePath+fileName))));
Come si può notare dal frammento di codice i due sistemi operativi si
comportano in modo differente nella gestione dell’oggetto URL. La sintassi in
questione è:
177
CAP. 7 – PROBLEMATICHE E MIGLIORAMENTI
file:
Protocollo
// FilePath+FileName
Doppio File.separator
Nome del file
L’ingruenza tra i due sistemi sta nel fatto che windows accetta una sintassi con
un solo file separator, mentre linux una sintassi con due file separator.
Risultato di ciò è che se non si accetta questa predisposizione si ha un errore in
compilazione.
Un altro aspetto di fondamentale importanza sempre riguardo all’utilizzo di due
sistemi operativi differenti è la gestione degli attachments.
Dopo un lungo studio e una lunga fase di test abbiamo imparato che quando la
dimensione dell’allegato al messaggio SOAP supera una certa soglia il sistema
operativo si fa carico di prendere tale allegato e salvarlo temporaneamente sotto una
sua ben specificata directory per poi poterlo inviare al destinatario.
Il percorso di questa directory è specificato in un file di configurazione,
server-config.wsdd che viene creato, lato server, automaticamente dall’eclipse in
fase di generazione del Web service.
Leggendo le righe di codice di questo file, ad un certo punto si incontra il
seguente frammento:
<globalConfiguration>
<parameter name="sendMultiRefs" value="true"/>
<parameter name="disablePrettyXML" value="true"/>
<parameter name="adminPassword" value="admin"/>
<parameter name="attachments.Directory"
value="C:\workspace\.metadata\.plugins\org.eclipse.wst.server.
core\tmp0\webapps\jtelemed\WEB-INF\attachments"/>
<parameter name="dotNetSoapEncFix" value="true"/>
178
CAP. 7 – PROBLEMATICHE E MIGLIORAMENTI
Facendo un deploy dell’intero progetto come war sul server linux anche il file
server-config.wsdd viene importato con tutte le sue caratteristiche e soprattutto con
la sua attachments.Directory impostata con una path valida sotto windows ma non
sotto linux: occorre definire una nuova path:
<globalConfiguration>
<parameter name="sendMultiRefs" value="true"/>
<parameter name="disablePrettyXML" value="true"/>
<parameter name="adminPassword" value="admin"/>
<parameter name="attachments.Directory"
value="/var/jakarta-tomcat5.5.4/webapps/jtelemed_server/
WEBINF/attachment"/>
<parameter name="dotNetSoapEncFix" value="true"/>
179
CAP. 7 – PROBLEMATICHE E MIGLIORAMENTI
7.2 Gestioni critiche
Un’aspetto che merita di essere citato come gestione critica è il processo di
cancellazione dei files creati sia lato server che lato client, files che sono parte
integrante della comunicazione all’interno del nostro Web Service.
Come ormai ben saprete, il nostro server risponde alla richiesta di un servizio
quasi esclusivamente generando un file che poi invierà come allegato al messaggio
SOAP ovvero al messaggio di risposta.
Questi files prima di poter essere spediti vengono salvati fisicamente sul file
system nelle directory temp sotto tomcat (per il server) e nella directory temp sotto
webapps/jtelemed (per il client).
Per poter avere un’accurata gestione delle risorse è necessario prevedere un
meccanismo di cancellazione di questi files.
Attualmente è stato implementato una semplicissimo metodo all’interno della
classe FileUtil che cerca di soddisfare le nostre necessità, ma con un elevato numero
di files il sistema va in crisi.
Non appena un file viene inviato al destinatario non si ha più bisogno di esso e
deve essere eliminato; quindi alla fine di ogni servizio in cui sono interessati i files
deve essere prevista una piccola gestione di questa procedura di cancellazione.
Questo approccio però non è funzionante in quanto il sistema, per ancora
oscuri motivi, non riesce fisicamente a cancellare il file appena creato e appena
inviato.
Un’alternativa a questo è stata rappresentatata dall’idea di cancellare, al
momento della creazione di un nuovo file, il file precedente.
Idea fantasiosa, ma dubbiamente realizzabile in quanto, oltre ai problemi
appena citati, nasceva la necessità di tener traccia da qualche parte del file da
cancellare.
Dunque è stata fatta la seguente scelta:
1. Si imposta un valore di soglia del numero di files che si desiderano all’interno
della cartella temporanea
2. Se si è raggiunto il valore di soglia inizia la cancellazione di un numero di file
tale che il numero totale rientri nel valore di soglia
3. Se non si è raggiunto il valore di soglia non succede nulla
180
CAP. 7 – PROBLEMATICHE E MIGLIORAMENTI
Molti si chiederanno il perché di tutto questo, ma è stato inevitabile e
soprattutto è molto semplice da spiegare.
Alcuni dei file creati non possono essere cancellati perché nonostante tutti gli
stream fossero stati chiusi c’è qualcosa da qualche parte che tiene ancora attivo il loro
stato e se si cerca di intervenire manualmente alla loro cancellazione viene restituito
un messaggio d’errore.
Anche con l’ultima soluzione proposta, a lungo, si avranno dei problemi e
quando si verificheranno basterà semplicemente cancellare il contenuto delle cartelle
temp di cui si è parlato all’inizio del paragrafo.
Un progetto concluso, per coloro che lo hanno realizzato è un punto d’arrivo,
ma per chiunque lo voglia migliorare non è altro che un punto di partenza: questo
aspetto è ciò da cui ricominciare.
181
CAP. 7 – PROBLEMATICHE E MIGLIORAMENTI
7.3 Un database Open Source: MySQL
Fig. 7.1 – Struttura di memorizzazione dei database.
MySQL è un RDBMS veloce e semplice, usato per i database di molti siti Web.
La velocità è stato sin dall’inizio l’obiettivo principale degli sviluppatori. Per ottenere
maggiore velocità, presero la decisione di offire meno funzionalità rispetto ai maggiori
concorrenti (per esempio, Oracle e Sybase). Comunque, anche se MySQL non fornisce
funzionalità complete come i suoi concorrenti commerciali, ha tutte le funzionalità
necessaria alla maggior parte degli sviluppatori di database.
182
CAP. 7 – PROBLEMATICHE E MIGLIORAMENTI
È più facile da installare e da usare rispetto ai suoi concorrenti commerciali, e
la differenza nel costo favorisce fortemente MySQL.
MySQL è sviluppato, distribuito, e supportato da MySQL AB, che è una
compagnia Svedese. Questa fornisce due tipi di licenze:
•
Open source software: MySQL è disponibile con licenza GNU GPL (General
Public License) per scopi non commerciali. Chiunque soddisfi le richieste della
GPL può usare il software liberamente. Se si usa MySQL per un database in un
sito Web, MySQL può essere usato gratuitamente, anche se il sito Web è di
tipo commerciale.
•
Commercial license: MySQL è disponibile con licenza commerciale per quelli
che la preferiscono al GPL. Se uno sviluppatore vuole usare MySQL come parte
di un nuovo prodotto software e vuole vendere questo prodotto, invece di
rilasciarlo sotto licenza GPL, lo sviluppatore deve acquistare una licenza
commerciale, ad un costo ragionevole.
Trovare il supporto tecnico per MySQL non è un problema. Ci si può iscrivere
ad una degli innumerovoli forum di discussione offerti anche sul sito web di MySQL,
www.mysql.com. È possibile consultare anche uno degli archivi di e-mail, che
contengono una ampia base di conoscenza su MySQL con domande e risposte
comuni. Se si vuole un supporto di tipo commerciale, MySQL AB offrer contratti di
supporto tecnico — cinque livelli di supporto, dal supporto diretto con e-mail a quello
telefonico, a cinque livelli di prezzo.
Vantaggi di MySQL
MySQL è un database popolare tra gli sviluppatori Web. La sua velocità e
leggerezza lo rendono ideale per un sito Web. Aggiungendo a questo il fatto che è
open source, il che significa gratis, si ha la spiegazione della sua popularità. Vediamo
alcuni dei principali vantaggi:
Velocità. Il principale obiettivo delle persone che hanno sviluppato MySQL
era la velocità. Conseguentemente, il software, sin dall’inizio, è stato
progettato con la velocità in mente.
183
CAP. 7 – PROBLEMATICHE E MIGLIORAMENTI
Basso costo. MySQL è gratuito sotto la licenza open source GPL, e il costo
di una licenza commerciale è ragionevole.
Facilità d'uso. È possibile costruire un database MySQL ed interagire con
esso usando poche semplici istruzioni nel linguaggio SQL, che è lo standard
per la comunicazione con i RDBMS.
Supporto sistemi operativi. MySQL gira su una gran numero di sistemi
operavi — Windows, Linux, Mac OS, molte varianti di Unix (incluse Solaris,
AIX, e DEC Unix), FreeBSD, OS/2, Irix, e altri.
Supporto Tecnico. Il supporto tecnico è disponibile. Un gran numero di
utenti offre un supporto gratuito attraverso forum di discussione. Gli stessi
sviluppatori di MySQL partecipano a questi forum e sono contattabili via email. È possibile ottenere anche il supporto tecnico diretto da MySQL AB ad
un prezzo contenuto.
Sicurezza. Il sistema flessibile di autorizzazioni di MySQL permette di
concedere diversi privilegi sul database (per esempio, il diritto di creare un
database o cancellare dati) agli specifici utenti o gruppi di utenti. Le
password sono criptate.
Supporto grandi databasi. MySQL può gestire fino a 50 milioni di record
e più. Il limite predefinito di dimensione per una tabella è 4GB, ma è
possibile aumentarlo (se il sistema operativo lo consente) ad un limite
teorico di 8 milioni di terabyte (TB).
Personalizzabilità.
La
licenza
open
source
GPL
permette
ai
programmatori di modificare il software di MySQL per adattarlo alle proprie
esigenze.
Come lavora MySQL
Il software di MySQL è composto dal server MySQL, svariati programmi di
utilità che aiutano nell'amministrazione dei database MySQL ed alcuni che software di
supporto del quale il server MySQL ha bisogno (ma che non è necessario conoscere).
Il nucleo del sistema è il server MySQL.
184
CAP. 7 – PROBLEMATICHE E MIGLIORAMENTI
Il server MySQL è il gestore del sistema di database. Gestisce tutte le istruzioni
riguardanti i database. Per esempio, se si vuole creare un database nuovo, basta
inviare un messaggio al server MySQL che dice “crea un nuovo database e chiamalo
newdata.” Il server MySQL quindi crea una sottocartella nella sua cartella dati, e la
chiama newdata, e vi mette i file necessari nei formati corretti. Allo stesso modo, per
aggiungere dati a quel database, basta inviare un messaggio al server MySQL,
fornendogli i dati e dicendo dove questi vanno aggiunti.
Prima di poter passare le istruzioni al server MySQL , questo deve essere
operativo ed in attesa di richieste. Il server MySQL è solitamente impostato in modo
da avviarsi all’avvio del computer e rimanere in esecuzione fino al suo spegnimento.
Questa è la configurazione comune per un sito Web. Comunque, non è
necessario impostare l’avvio in questo modo. Se necessario, è possibile avviarlo
manualmente ogni qualvolta sia richiesto accedere ad un database. Quando è in
esecuzione, il server MySQL resta in ascolto ed attende che gli arrivino dei messaggi
contenenti richieste.
Comunicazione con il server MySQL
Tutte le interazioni con il database vengono effettuate passando i messaggi al
server MySQL. Si possono mandare messaggi al server MySQL in svariati modi, a
seconda del linguaggio e della piattaforma utilizzata. Ogni linguaggio ha delle
dichiarazioni specifiche che vengono usate per inviare istruzioni al server MySQL.
Il server MySQL deve essere in grado di comprendere le istruzioni che gli
vengono inviate. Si comunica utilizzando l’SQL (Structured Query Language), che è un
linguaggio standard utilizzato dalla maggior parte dei RDBMS. Il server MySQL
comprende l’SQL. Dalla parte Java, il driver JDBC non conosce l’SQL, si limita a
stabilire la connessione con il server MySQL e invia il messaggio SQL sulla
connessione. Il server MySQL interpreta il messaggio SQL ed esegue le istruzioni, a
questo punto risponde con un messaggio di ritorno, notificando il suo stato e che cosa
ha fatto (o ritornando un errore se non è in grado di capire o eseguire il le istruzioni).
Per una descrizione più approfondita della sintassi del linguaggio SQL basta consultare
uno dei manuali in materia.
185
CAP. 8 – PUBBLICAZIONE
Descrizione degli aspetti fondamentali della pubblicazione di un WebService
INDICE ARGOMENTI:
8.1 Il firewall di Linux
8.2 Il comando iptables
186
CAP. 8 – PUBBLICAZIONE
8.1 Il Firewall di Linux
Un Firewall linux non è altro che un semplice personal computer normalmente
collegato fisicamente (con dei cavi) a più di una rete.
Un firewall avrà quindi installata una scheda di rete (interfaccia) per ogni rete
cui sarà collegato. Inoltre, dovrà costituire l'unico punto di contatto tra le reti cui è
connesso, ovvero dovrà costituire l'unico punto di collegamento tra due o più reti. Un
po' come un ponte che collega due o più isole. Senza entrare nei dettagli del
protocollo ip, tutte le comunicazioni tra queste reti saranno quindi costrette a passare
da questo computer.
Questo computer, una volta configurato come firewall, sarà in grado di
decidere cosa far passare, cosa scartare o come reagire a determinati eventi.
Tornando all'esempio del nostro ponte, configurare il computer come firewall può
essere considerato equivalente a mettere una stanga e 2 finanzieri che controllano
tutti i veicoli e le persone in transito.
Questi 2 finanzieri saranno quindi in grado di agire secondo le istruzioni che gli
verranno date dal ministero, bloccando veicoli, arrestando i contrabbandieri o
sparando a vista ai ricercati.
In linux, la stanga e i finanzieri sono messi a disposizione direttamente dal
kernel. Per controllare il kernel, per dare cioè le direttive ai finanzieri, vengono messi
a disposizione diversi comandi: con il kernel 2.4, i principali e più avanzati sono
comunque il comando ip, tc e iptables, i primi due inclusi nel pacchetto iproute mentre
il terzo distribuito indipendentemente.
Procedendo con ordine, in linea di principio il comando ip consente di creare
nuove isole e nuovi ponti, di gestire quindi le tabelle di routing e le interfacce di rete,
il comando iptables di istruire i finanzieri dicendo cosa far passare e cosa non far
passare o come reagire a determinate condizioni, consente cioè di creare dei filtri.
Infine, il comando tc, consente di stabilire delle priorità e dei limiti sul traffico in
ingresso ed in uscita. Ad esempio, un compito che esula dal filtraggio e che quindi
riguarda tc potrebbe essere quello di riservare alcune corsie al passaggio di veicoli di
emergenza o di servizio, limitando magari il traffico automobilistico, di riservare cioè
determinate quantità di banda a determinate tipologie di traffico.
187
CAP. 8 – PUBBLICAZIONE
Riassumendo, quindi, si parlerà del comando:
•
ip per configurare, attivare, disattivare o creare interfacce di rete, nonché per
gestire le tabelle di routing (da solo rimpiazza i comandi ifconfig, route e arp).
•
iptables per bloccare, consentire o registrare il traffico, per effettuare cioè
firewalling, ovvero per modificare alcune caratteristiche dei pacchetti in
transito, per effettuare cioè NAT (Network Address Translation).
•
tc per assegnare delle priorità, imporre delle precedenze o dei limiti di banda
(tc sta per traffic classifier.), in poche parole, per effettuare dello shaping.
Quello che più ci interessa è il comando iptables.
188
CAP. 8 – PUBBLICAZIONE
8.2 Il comando iptables
Dovendo parlare di iptables, è indispensabile una piccola introduzione. Il
parente più stretto di iptables è sicuramente ipchains il quale aveva introdotto il
concetto di catena.
iptables ha ripreso il concetto di catena per estenderlo tramite l'introduzione di
tabelle. Prima di parlare di tabelle però, ci conviene chiarire il concetto di catena.
L'idea di base è abbastanza semplice: un computer collegato in rete con una o
più interfacce ha a che vedere con tre tipi di pacchetti:
•
Pacchetti destinati al firewall stesso
•
Pacchetti che devono transitare dal firewall ma destinati a qualcun altro
•
Pacchetti originati dal firewall stesso
Di default ipchains ed iptables mettono quindi a disposizioni rispettivamente 3 catene:
•
La catena di input
•
La catena di forward
•
La catena di output
In un computer normale (o in un server) verrebbero principalmente utilizzate le
catene di input e di output per filtrare il traffico ricevuto e generato dalla macchina
presa in considerazione.
In un firewall invece, i pacchetti transiterebbero da una scheda di rete all'altra,
passando quindi attraverso la catena di forward.
Ogni catena è poi costituita da un insieme di regole. Ad ogni regola, è
associata un'azione (target). Ogni volta che un pacchetto transita per una catena,
tutte le regole vengono controllate in ordine, dalla prima inserita fino all'ultima.
Quando una regola risulta applicabile al pacchetto (viene trovato un match)
viene applicata al pacchetto l'azione specificata e viene interrotto il processo di
ricerca.
Se non viene trovata una regola applicabile al pacchetto, la sua sorte (l'azione
d'applicare) viene scelta in base alla politica (policy) della catena stessa. In pratica, la
policy indica cosa fare di tutti i pacchetti che non rientrano in nessuna regola.
189
CAP. 8 – PUBBLICAZIONE
Sia ipchains che iptables poi, consentono di creare o rimuovere catene e di
specificare come azione quella di percorrere un'altra catena.
Definizione delle policy
Iniziamo quindi a parlare di iptables, ed iniziamo proprio definendo la politica di
default delle catene di base, cioè l'azione che deve essere presa nel caso in cui
nessuna regola si possa applicare al particolare pacchetto. Per fare questo, basta
dare:
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
Qui vediamo proprio che se un match non viene trovato, i pacchetti devono
essere buttati via (DROP), proprio come se non fossero mai stati ricevuti (o richiesto
l'invio, a secondo della catena).
Oltre a DROP, esistono molte altre azioni che è possibile specificare, dove le principali
sono:
•
ACCEPT , lascia passare il pacchetto
•
QUEUE, passa il pacchetto ad un programma in userspace
Spesso però capita di usare delle target extensions, ossia dei particolari target
che sono forniti tramite dei moduli esterni. E' buona abitudine mettere come politica
di default quella di buttare via i pacchetti, dopodichè consentire esplicitamente tutto
ciò che vogliamo fare passare. Questo principalmente per due motivi:
•
è facile rendersi conto di cosa si è dimenticato chiuso (molti degli utenti
telefoneranno fino alla saturazione delle linee telefoniche pur di vedere il loro
client preferito funzionare), mentre è molto più difficile vedere cosa si è
dimenticato aperto.
190
CAP. 8 – PUBBLICAZIONE
•
non è facile riconoscere tutto ciò che c'è da bloccare. Per esempio, usando una
politica di ACCEPT, è estremamente difficile prevedere ciò che potrà essere
utilizzato per aggirare le restrizioni, contando che spesso non è obbligatorio
seguire gli standard e una persona un po’ sveglia potrebbe modificare il kernel
di due macchine linux per utilizzare un protocollo che nulla ha a che vedere col
tcp e che mai noi ci saremmo immaginati di dover bloccare (trattandosi,
magari, di un protocollo inventato di sana pianta).
Un comando che può essere utile nello scrivere le regole si chiama nstreams:
questo stamperà a video l'elenco di tutte le connessioni in corso su una rete.
Modifiche on the fly - iptables da riga di comando
Sebbene sia veramente poco piacevole, è possibile utilizzare iptables
direttamente da riga di comando.
Nonostante questo, alcune di queste funzioni possono risultare molto utili in
fase di testing. Ad esempio, dovendo fare delle misure di banda può essere utile
consentire temporaneamente solo il traffico tra determinate macchine, e non è il caso
di perdere tempo a modificare file di configurazione o script dalla provata affidabilità.
Iniziamo quindi col vedere le regole attive sul kernel, col comando:
iptables -nL
dove n dice di non risolvere i nomi (passando da indirizzi ip a nomi di domini) e L di
listare o elencare (in italiano) tutte le regole.
Vediamo alcuni esempi:
[root@jtelemed ~]# iptables –nL
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
REJECT tcp -- 0.0.0.0/0 0.0.0.0/0 reject-with tcp-reset
Chain FORWARD (policy DROP)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
191
CAP. 8 – PUBBLICAZIONE
-n viene usato principalmente perché altrimenti ci vorrebbe molto tempo a generare
l'output (tentando di connettersi al database). Un problema di iptables -nL (rispetto ad
usare un file di configurazione) è che molti dettagli non vengono mostrati e comunque
la leggibilità è molto minore.
Per avere più dettagli, comunque, è possibile utilizzare l'opzione -v o -vv, con
un comando simile a
iptables –v -nL
[root@jtelemed ~]# iptables –L -v
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target
prot opt in out source
1062 124K RH-Firewall-1-INPUT all -- any any anywhere
destination
anywhere
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target
prot opt in out source
0
0
RH-Firewall-1-INPUT all -- any any anywhere
destination
anywhere
Chain OUTPUT (policy ACCEPT 1337 packets, 1311K bytes)
pkts bytes target
prot opt in out source
destination
Chain RH-Firewall-1-INPUT (2 references)
pkts bytes target prot
opt in
37
6707 ACCEPT all
-- lo
43
2630 ACCEPT icmp
-- any
any
0
0
ACCEPT ipv6-crypt -- any
0
0
ACCEPT ipv6-auth
-- any
0
0
ACCEPT udp
-- any
dpt:5353
0
0
ACCEPT udp
-- any
dpt :ipp
880
100
ACCEPT all
-- any
RELATED, ESTABLISHED
0
0
ACCEPT tcp
-- any
NEW tcp dpt :http
0
0
ACCEPT tcp
-- any
NEW tcp dpt :https
3
144
ACCEPT tcp
-- any
NEW tcp dpt :8085
99
13912 REJECT all
-- any
with icmp-hosts-proibited
out
any
any
source
anywhere
anywhere
destination
anywhere
anywhere icmp
any
any
any
anywhere
anywhere
anywhere
anywhere
anywhere
224.0.0.251 udp
any
anywhere
anywhere
any
anywhere
anywhere state
any
anywhere
anywhere state
any
anywhere
anywhere state
any
anywhere
anywhere state
any
anywhere
anywhere reject-
udp
Se si è interessati ad un'unica catena, si può specificarne il nome dopo il -nL.
Con qualcosa di simile a iptables –vv -nL INPUT si vedrà solo la catena di INPUT ed
un dump delle informazioni del kernel. Come altre opzioni generiche, si possono
utilizzare -x, che mostrerà i valori esatti dei contatori, mentre -Z li azzererà, oppure -t
nometabella per visualizzare altre tabelle.
192
BIBLIOGRAFIA
Riferimenti telemedicina
Molino G., La cartella clinica va on line, Il sole 24 ore Sanità – Management.
Dicembre 2002
Nonis M., Braga M., Guzzanti E. Cartella, Clinica e qualità dell’assistenza.
Passato, presente e futuro, Il Pensiero Scientifico Editore. Roma 1998.
Salvadori P., Informatizzazione e Distretto Socio Sanitario, Panorama della
Sanità, anno XV N° 39, ottobre 2002.
Hakansson S., Gavelin C., What do we really know about the cost
effectiveness of telemedicine?, Journal of Telemedicine and Telcare
2000;6(S1):S133
M.Ciulla, R.Paliotti, F.Magrini, Archivio ecocardiografico multimediale,
Cardiologia 1998: 43 n 2: 195-2006
M. Ciulla, R. Paliotti, M.V. Barelli, P.Valentini, F. Magrini Internet: cosa offre la rete
informatica al medico, XCVIII Congresso Naz Soc It di Medicina Interna,
1997 Roma
193
BIBLIOGRAFIA
Riferimenti tecnologia
Feghhi J., Digital Certificates – Applied Internet Security, Addison-Wesley 2000
Jayson Falkner e Kevin Jones, Servlets and JavaServer Pages™: The J2EE™
Technology Web Tier, Addison-Wesley 2003
James Turner, MySQL™ and JSP™ Web Applications: Data-Driven
Programming Using Tomcat and MySQL, Sams 2002
James Goodwill, Apache Axis Live, SourceBeat LLC 2004
James R. Groff,Paul N. Weinberg, SQL - The Complete Reference, McGraw-Hill
2003
Elliotte Rusty Harold, Java Network Programming, Second Edition, O’Reilly 2000
Jason Hunter, Java Servlet Programming, Second Edition, O’Reilly 2001
Steve Graham, Simeon Simeonov, Toufic Boubez, Doug Davis, Glen Daniels, Yuichi
Nakamura, Ryo Neyama, Building Web Services with Java™: Making
Sense of XML, SOAP, WSDL, and UDDI, Sams Publishing 2001
[WSCA10] Heather Kreger, 2001, IBM, Web Services Conceptual Architecture
1.0
194
BIBLIOGRAFIA
[SOAP11] W3C, Simple Object Access Protocol (SOAP) 1.1
[WSDL11] W3C, Web Services Description Language (WSDL) 1.1
[UDDI-TWP] Uddi.org, UDDI Technical White Paper
Riferimenti web
1. Articoli su http://www.latoserver.it
Struttura di una applicazione web - Luca Balzerani 18/04/2002
L'ambiente di Tomcat - Massimo Vassalli 26/02/2002
Installazione di Apache Tomcat - Giuseppe Capodieci 13/03/2001
Java lato server: le Servlet - Giuseppe Capodieci 24/11/2001
2. Articoli su http://www.itportal.it
SOAP: l'ultima frontiera per lo scambio dei dati-Francesco Zumpano 02-05-01
3. Ajax e Javascript:
http://www.zapatec.com/website/main/products/suite/
http://www.webmasterpoint.org/ajax/home.asp
4. Apache Tomcat, Axis, Soap attachment:
http://ws.apache.org/axis/java/apiDocs/org/apache/axis/attachme
nts/package-summary.html
http://tomcat.apache.org/tomcat-5.5-doc/index.html
http://ws.apache.org/axis/java/index.html
195