Tesi di Laurea sulla Sicurezza delle Reti Informatiche: Le vulnerabilità
Tesi Zorzin
1. UNIVERSITÀ DEGLI STUDI DI TRIESTE
FACOLTÀ DI INGEGNERIA
Corso di laurea specialistica in Ingegneria Informatica
Tesi di laurea in
“programmazione di reti di calcolatori”
Progetto e realizzazione dell'infrastruttura di
gestione in una farm per la rilevazione di
attacchi web a siti remoti
Laureando: Relatore:
Prof. Alberto Bartoli
Andrea Zorzin
Correlatori:
Ing. Eric Medvet
Ing. Giorgio Davanzo
anno accademico 2007/2008
2.
3. Le anime più forti sono quelle temprate dalla sofferenza,
i caratteri più solidi sono cosparsi di cicatrici
(Gibran Kahlil Gibran)
4.
5. Indice
Introduzione .........................................................................................................1
1. Scenario ........................................................................................................2
1.1 Scopo del progetto .............................................................................2
1.2 Requisiti interfaccia grafica ................................................................3
1.2.1 Definizioni......................................................................................3
1.2.2 Descrizione ad alto livello – quello che deve fare .........................3
1.2.3 Descrizione dettagliata - requisiti .................................................4
1.2.4 Alimentazione da back-end ...........................................................7
1.3 Web defacement ................................................................................8
1.3.1 Tipologie di attacchi ....................................................................10
1.3.2 Motivazione degli attacchi ..........................................................13
1.3.3 Statistiche sulla diffusione ..........................................................14
1.3.4 Tempo di reazione al defacement...............................................15
1.4 Struttura del progetto ......................................................................16
2. Uso dell’interfaccia .....................................................................................17
2.1 Casi d’uso..........................................................................................17
2.2 Descrizione delle pagine...................................................................19
Dashboard ........................................................................................19
Pagina “Elenco Warden” ..................................................................20
Pagina “Dettagli Warden” ................................................................20
Pagina “Dettagli Risorsa” ..................................................................21
Pagina “Dettagli Reading” ................................................................23
Pagina “Dettagli Alert” .....................................................................24
6. Componente “Header” .....................................................................25
3. Implementazione software dell’interfaccia ...............................................26
3.1 Tecnologie e strumenti utilizzati ......................................................26
3.2 Facelets.............................................................................................27
3.3 Funzionamento della parte grafica ..................................................29
3.3.1 Il componente “WardenTable” ...................................................29
3.3.2 Il componente “AlertTable” ........................................................30
3.3.3 Il componente “ResourceTable” .................................................30
3.3.4 Il componente “ReadingTable” ...................................................31
3.3.5 Il componente “ContactPanel” ...................................................31
3.3.6 Il componente “ImagePanel” ......................................................32
3.3.7 Gestione dell’internazionalizzazione...........................................34
3.3.8 Regole di navigazione ..................................................................37
3.4 Funzionamento della connessione con il back-end .........................39
3.4.1 Comunicazione fra interfaccia e backing bean ...........................39
3.4.2 Diagramma delle classi ................................................................40
3.4.3 Comunicazione fra backing bean e controller .............................47
3.4.4 Metodi esposti dal controller ......................................................48
Metodi per la gestione delle istanze (InstanceCtrlBean) ............50
Metodi per la gestione dei task (TaskCtrlBean) ..........................52
Metodi per la gestione dei Warden (WardenBean) ....................54
Metodi per la gestione degli Alert (AlertCtrlBean) .....................54
3.5 Test cross-browser ...........................................................................56
7. 4. Conclusioni .................................................................................................59
4.1 Obiettivi raggiunti.............................................................................59
4.2 Quantificare il lavoro ........................................................................59
4.3 Conclusioni soggettive......................................................................59
4.4 Stato attuale del lavoro ....................................................................60
5. Ringraziamenti............................................................................................61
6. Bibliografia..................................................................................................63
8.
9. Introduzione
Un numero enorme di organizzazioni in tutto il mondo basa il proprio
business sulla rete e sulle tecnologie web per le proprie operazioni
quotidiane; di conseguenza, l’immagine e la solidità di una organizzazione
dipendono anche dalla qualità della sua presenza in rete. Ogni attacco che
punti a corrompere il contenuto di un sito Internet può quindi causare seri
danni sia a tali entità che ai relativi utenti o clienti.
In questi ultimi anni gli attacchi di questo tipo sono alquanto comuni, una
stima del 2005 attesta a 490000 i siti violati con questa tecnica [4] che prende
il nome di defacement.
La relativa facilità con cui un attaccante può modificare il contenuto o le
sembianze di un sito web, assieme alla crescente integrazione tra utenti,
organizzazioni ed Internet, dimostrano l’urgente necessità di metodi atti a
risolvere tale problema.
Seguendo tali motivazioni abbiamo progettato e realizzato un’infrastruttura
di gestione per rilevare tali attacchi; ciò allo scopo di offrire un servizio di
“sorveglianza” atto a riscontrare e segnalare all’amministratore del sito
eventuali intrusioni di malintenzionati.
L’infrastruttura si compone di tre parti: le istanze remote che hanno il
compito di scaricare i dati dei siti, analizzarli, catalogarli e, nel caso di
sospetto defacement, segnalarne la condizione. Il controller riceverà tale
segnalazione ed avviserà l’utente legato alla risorsa monitorata, inoltre esso
ha il compito di dirigere il lavoro e scambiare le informazioni fra le istanze
remote e l’interfaccia grafica.
L’interfaccia grafica, realizzata in questa tesi, permetterà all’utente di
amministrare le risorse da monitorare e fornirà le informazioni necessarie a
gestire il tutto.
Punto di partenza di questo lavoro sono stati gli algoritmi di analisi statistiche
delle pagine web realizzati presso il laboratorio di “Reti di calcolatori” del
D.E.E.I.
Il progetto è stato realizzato utilizzando la tecnologia Java Enterprise Edition
e l’application server Glassfish; per quanto riguarda la parte grafica è stato
adottato il framework Ajax ICEFaces basato su JSF.
1
10. 1. Scenario
1.1 Scopo del progetto
Questo progetto ha lo scopo di realizzare un'architettura distribuita che
consenta di far cooperare fra di loro un numero arbitrario di nodi di calcolo,
detti istanze, coordinati da un controllore.
Questa infrastruttura è in grado di rilevare, in maniera automatica, attacchi
informatici di tipo “web defacement” segnalandone l’accaduto
all’amministratore del sito consentendo, di fatto, un intervento tempestivo
sulla risorsa danneggiata.
L’importanza di correggere subito l’anomalia risulta evidente se si pensa
quanti e quali danni, economici e giuridici, la modifica non autorizzata di un
sito possa causare.
Figura 1: Con e senza LSDD...
2
11. L'idea di fondo, su cui si basa il sistema, è l' “anomaly detection”, ovvero si
cerca di implementare un sistema in grado di valutare la bontà di una risorsa,
senza conoscerne a priori il contenuto effettivamente pubblicato. In una fase
preliminare la risorsa viene monitorata da sensori appositamente studiati,
capaci di ottenere un profilo attraverso una serie di misure; al termine di una
fase iniziale di learning, è possibile monitorare tale risorsa e inviare un
allarme nel caso in cui essa si allontani dal profilo costruito.
Tali algortimi di controllo, precedentemente sviluppati nel laboratorio di
“Reti di calcolatori” del D.E.E.I. – Università di Trieste, sono implementati
all'interno del nodo di calcolo (istanza) che si occupa di effettuare il
download delle pagine sottoposte a monitoring, darle in input ai sensori
presenti e ottenere un output.
Infine tali informazioni vengono rese accessibili all’utente tramite
un’interfaccia grafica di tipo RIA (Rich Internet Application).
1.2 Requisiti interfaccia grafica
1.2.1 Definizioni
Risorsa: pagina web visualizzabile in un browser. Ogni risorsa è
associata ad un URL. Nel caso la risorsa sia un documento HTML, essa
include anche tutte le informazioni necessarie al browser per la sua
visualizzazione (immagini, javascript, CSS etc).
Warden: unità di servizio acquistabile dai clienti del sistema.
WardenProfile: elementi che definiscono la QoS del Warden. Ogni
Warden ha esattamente un WardenProfile e questo è immutabile.
Task: processo di monitoraggio di una risorsa. Ogni Task appartiene
esattamente ad un Warden.
Reading: immagine di una risorsa ad un dato istante.
1.2.2 Descrizione ad alto livello – quello che deve fare
L’interfaccia deve permettere all’utente di vedere e, dove possibile,
modificare tutte le varie informazioni che l’applicazione mette a disposizione.
Questo nel modo più intuitivo e comodo possibile.
Le informazioni che l’utente può vedere sono molteplici, come un elenco di
Warden, un elenco delle Risorse monitorate, un elenco dei Reading ed un
elenco degli Alert.
3
12. Interagendo con tali elementi, l’utente potrà richiedere il monitoraggio di
nuove pagine, richiedere la creazione di nuovi Warden e controllare lo stato
degli attuali elementi monitorati.
1.2.3 Descrizione dettagliata - requisiti
L’interfaccia grafica è costituita dalle seguenti parti:
Dashboard
Elenco warden
Scheda warden
Scheda risorsa
Scheda reading
Scheda alert
Profilo utente
Ogni pagina contiene uno o più di questi componenti:
Elenco dei warden
Elenco delle risorse monitorate
Elenco dei reading
Elenco degli alert
Un utente deve poter vedere (e modificare dove previsto) tutte e sole le
informazioni ivi contenute.
Per favorire la navigazione fra le pagine, a disposizione dell’utente, c’è una
barra di navigazione dinamica posta nella parte alta della pagina.
In alto a destra si possono notare il nome dell’utente loggato e un link per
accedere al “profilo utente”.
La dashboard è essenzialmente l’homepage della struttura, contiene un
pannello raffigurante gli alert pendenti, se presenti, e un pannello contente
l’elenco degli Warden posseduti dall’utente.
Da essa si può accedere a tutte le altre zone della struttura.
Il profilo utente è un pannello popup che raggruppa le informazioni
dell’utente loggato, contiene i dati fondamentali all’identificazione dello
stesso.
L’elenco dei warden è costituito da una tabella contenente quello che noi
abbiamo definito warden. Il warden è il “contenitore” dei task ad esso
4
13. associati, l’utente non conoscerà l’esistenza dei task in quanto verranno
visualizzati con il nome di reading.
I warden che appaiono nell’elenco sopra citato hanno un nome, se
disponibile, la data e l’ora in cui è stato effettuato l’ultimo reading associato
al warden in questione, l’url della risorsa a cui è riferito l’ultimo reading e
un’immagine (snapshot) della risorsa.
Teoricamente si immagina che un utente disponga di pochi warden, se ce ne
sono molti, è disponibile un link “see all”.
La scheda warden, alla quale si arriva cliccando su un warden summary,
contiene le seguenti informazioni:
1. Nome (editabile direttamente)
2. Intervallo di monitoraggio minimo del warden.
3. Elenco di alert-summary relativi a questo warden, se ce ne sono.
4. Elenco paginato di risorse monitorate.
La scheda risorsa, alla quale si arriva cliccando su un resource summary,
contiene le seguenti informazioni:
1. Url (non è editabile)
2. Link/bottone/i (indicante anche lo stato attuale) per interrompere il
monitoraggio ed eliminare la risorsa.
3. Gruppi di opzioni di notifica alert (editabile). Ad esempio: zero/uno o
più numeri di cellulare per sms; zero/uno o più indirizzi email per le
mail.
4. Elenco paginato dei reading summary in ordine di data.
La scheda reading, alla quale si arriva cliccando su un reading summary od in
un alert summary, contiene le seguenti informazioni:
1. Immagine grande (600x400)
2. Immagini piccole dei reading precendeti (ad es. 3) e successivi, con
date, tempo download, kb
3. Data di download, tempo di download, kb, numero di sottorisorse
4. Elenco eventuali alert-summary sollevati per questo reading
modificato in 2 elenchi alert pendenti ed evasi
5. Headers richiesta
6. Headers risposta
5
14. La scheda reading, alla quale si arriva cliccando su un alert summary,
contiene le seguenti informazioni:
1. Immagine grande (600x400) dello snapshot del reading che ha fatto
scattare l'alert.
2. Immagini piccole di reading precedenti (ad es., precedente, 5 prima, 10
prima), con date, kb, tempo download.
3. Bottone per dire che è un falso alert.
4. Informazioni di notifica dell'alert, tipo alert, data e ora del rilevamento.
5. Informazioni specifiche dell’alert.
Profilo utente, permette di cambiare password, email per le combinazioni
principali, eventualmente nome utente, eventualmente numero di cellulare
predefinito.
Elenco risorse, dove ogni elemento è linkato alla corrispondente scheda
risorsa e mostra il seguente tipo di informazioni:
1. Url
2. Immagine (240x160) dell'ultimo snapshot della risorsa (linkata alla
scheda reading)
3. Data e ora ultimo reading
4. Elenco degli ultimi 3 <date, download time, reading size>
5. Bottoni per vedere lo stato della risorsa, stopparla ed eliminarla.
Elenco reading, ognuno linkato alla scheda reading, in ordine di data di
download decrescente, mostra il seguente tipo di informazioni:
1. Immagine (300x200)
2. Data di download, tempo di download, kb
3. Bottone per segnalare che il reading è negativo/positivo o da
dimenticare. Quando premuto, questo bottone, come quello dell'alert,
deve dare un qualche feedback.
Elenco alert, ognuno linkato alla corrispondente scheda alert, mostra il
seguente tipo di informazioni:
1. Immagine (300x200) snapshot che ha causato l'alert.
2. Miniature (150x100) delle ultime immagine di snapshot “buoni” e
precedenti a quella sopra. Inseriti in ordine temporale a creare una
fascia orizzontale.
3. Url risorsa (linkata alla scheda risorsa)
4. Data e ora del download
6
15. 5. Tipo di alert
6. Informazioni di notifica dell'alert
7. Altre info sintetiche specifiche dell'alert
1.2.4 Alimentazione da back-end
L’interfaccia grafica viene alimentata dai dati provenienti dal controllore,
esso espone una serie di interfacce EJB (Enterprise Java Bean) remote dalle
quali è possibile ricevere i dati provenienti da un database o direttamente
dalle istanze remote.
L’interfaccia non può e non deve contattare direttamente un database o le
istanze remote, per ottenere i dati necessari sono stati definiti apposti
metodi da richiamare come descritto ne capitolo “4.3 Funzionamento della
connessione con il back-end”.
7
16. 1.3 Web defacement
L’azione di web defacement ad un sito internet mira a modificare il suo
aspetto esteriore; è un'azione compiuta solitamente da system crackers i
quali, ottenendo un accesso non autorizzato ad un server sostituiscono il sito
(o parti di esso) con una loro versione.
Le finalità che ci si prefigge nel tentativo di eseguire un defacement possono
essere di diverso tipo:
Propaganda: un hacker cambia in parte o del tutto la pagina di un
sito, ideologicamente avverso, per screditarlo o denigrarlo.
Spamming: vengono inseriscono evidenti riferimenti ad elementi
pubblicitari, come dei link a siti commerciali.
Avviso: si fa notare al webmaster che il sito da lui gestito è
vulnerabile ed è stato violato.
Truffa o phishing: questo tipo di attacco ha lo scopo di carpire
informazioni riservate, come username e password all’utente.
Nei primi punti di questo elenco si parla di defacement nella sua accezione
più classica (defacement sostitutivo), cioè la sostituzione dei contenuti
originari del sito con testi e/o immagini di varia natura.
L'obbiettivo di tale attacco è quello di minare la credibilità del sito colpito,
dimostrando così che esso è vulnerabile.
L'ultimo punto identifica invece i defacement additivi e cioè quelli
solitamente non visibili ai visitatori, essi si propongono di non modificare
l'aspetto esteriore del sito ma di aggiungere delle parti nascoste,
perseguendo gli obiettivi più disparati: un defacement di questo tipo
potrebbe, ad esempio, far parte di una più ampia azione di phishing (lo scopo
potrebbe essere quello di cambiare la pagina originaria, in cui esiste il form
per l'immissione di dati sensibili, reindirizzando l’output verso una pagina
personale allo scopo di carpire le informazioni) oppure cercare di diffondere
malware o virus.
8
18. 1.3.1 Tipologie di attacchi
Un defacement può essere attuato in vari modi; tralasciando le tecniche che
si basano su operatori disonesti, si evidenziano di seguito alcune delle strade
più sfruttate, è necessario specificare che tutti i numeri qui citati sono stime
[1]:
Figura 3: Grafico di diffusione degli attacchi
File inclusion (24%): si verifica quando uno script richiede come
parametro il nome di un file da includere nella sua esecuzione. Se
non vengono previsti adeguati controlli, un malintenzionato può
indicare uno script appositamente realizzato e residente su un altro
server, ottenendo così la possibilità di eseguire del codice
direttamente sulla macchina attaccata.
FTP Server intrusion (12%): nonostante possa apparire come una
tecnica prevedibile, sfrutta il protocollo FTP per caricare materiale
illecito all'interno di server non protetti in maniera adeguata per
10
19. esempio, accedendo a server per i quali sono rimaste attive
username e password di default.
Web Application bugs (10%): una buona fetta di responsabilità
spetta alle applicazioni scritte in malo modo, nelle quali si trascurano
le più elementari norme di sicurezza. Accade così che programmatori
sbadati si dimentichino di verificare le credenziali di accesso
all'interno di tutte le pagine che dovrebbero essere protette, oppure
semplifichino i controlli di accesso al punto tale da renderli inutili.
Attack against the administrator (10%): solitamente sfruttano il
social engineering per ottenere illecitamente username e password
dell'amministratore; più rari sono i casi in cui l'attaccante riesce a
'sniffare' il traffico di rete del gestore del sistema e ottenere le
password necessarie per compiere il defacement.
Web Server intrusion (8%): si applica sfruttando gli errori di
programmazione esistenti all'interno delle applicazioni server,
cercando solitamente di ottenere privilegi superiori a quelli che
effettivamente dovrebbero spettare.
SQL Injection (7%): molto simile al File inclusion utilizza predicati SQL
per compiere operazioni non lecite sul databse. Per esempio, si
ipotizzi una verifica di credenziali basata sul fatto che la seguente
query ritorni almeno una tupla:
SELECT _ FROM tblUs e r s WHERE password=passedPassword
E' però possibile che un utente malintenzionato digiti come password
del codice sql del tipo:
' pippo ' or 1=1
poiché la seconda condizione si verifica sempre, la query ritornerà
tutte le tuple del database e l'attaccante avrà libero accesso al sito
attaccato.
Man in the Middle (4%): effettivamente è una strategia molto
difficile da attuare. Richiede infatti un discreto accesso alle risorse di
11
20. rete della macchina server o di chi vi si collega come amministratore,
ma diventa banalmente applicabile all'interno di grosse reti aziendali.
DNS poisoning (2%): ancor più difficile del Man in the Middle, è
comunque una strada a volte percorribile; lo si effettua convincendo
un DNS ad indirizzare i richiedenti la pagina attaccata verso un
indirizzo IP diverso da quello lecitamente registrato. Per la
definizione data tale operazione non è propriamente un defacement,
in accordo con quanto stabilito dagli stessi gestori di Zone-H [2] (i
quali, comunque, tempo fa sono stati soggetti ad un attacco di
questo tipo).
12
21. 1.3.2 Motivazione degli attacchi
Zone-H [2] è un web site nato nel 2002 come un semplice mirror per i
defacement rilevati, nel tempo ha aumentato le sue funzionalità, diventando
punto di riferimento mondiale per tale tipologia di crimine informatico. Ogni
anno pubblica delle statistiche sull'evoluzione dei defacement fornendo dati
utili sia a livello tecnico, sia per indagare l'aspetto culturale del fenomeno;
interessante ad esempio è analizzare quali siano le motivazioni che portano
alla realizzazione di defacement.
Come si può notare dal grafico il puro divertimento (inteso anche come sfida,
volontà di dimostrare la proprio bravura) rimane il motivo principale che
spinge alla messa in atto di un defacement, anche se non sono da
sottovalutare le motivazioni politiche e la volontà di rivalsa verso alcuni web
site [1].
Figura 4: Motivazioni degli hackers
13
22. 1.3.3 Statistiche sulla diffusione
Come sopra accennato, Zone-H [2] è una strumento molto utile per
analizzare, l'evoluzione del fenomeno defacement. Attraverso i suoi
resoconti annuali è possibile ottenere delle statistiche sull'evoluzione di
questo fenomeno che fanno capire come il suo rilievo sia in costante crescita.
Figura 5: Andamento dei defacement rilavati dal 2002 al 2004 [1]
14
23. 1.3.4 Tempo di reazione al defacement
Un ulteriore dato di analisi interessante riguarda la durata di un defacement.
Un defacement risulta essere un evento molto grave per un web site e i suoi
amministratori, ma la sua gravità e le possibili ricadute aumentano
notevolmente con l'aumentare del tempo necessario perché gli
amministratori prendano provvedimenti; nell'analisi compiuta in si è potuto
rilevare come su 62000 defacement monitorati la velocità di reazione fosse
davvero bassa.
L'analisi dei 62000 defacement rilevati da Zone-H [2] in 49 giorni corrisponde
a circa 1250 nuove URL al giorno, il che fa capire quale sia la rilevanza del
fenomeno.
Dai dati raccolti in questo studio si può verificare come la reazione ad un
defacement avvenga entro la stessa giornata solo nel 25% dei casi, entro una
settimana in circa il 50%, con un tempo medio di reazione di 72.4 ore, come
si può vedere nella figura sottostante. Il 37% dei defacement risultava
addirittura non corretto dopo quasi due settimane. I tempi di reazione
risultano essere assolutamente troppo lunghi, vista la rilevanza che un
defacement può avere.
Tutti i numeri fin qui citati sono da considerarsi stime [1].
Figura 6: Tempo di reazione ad un defacement
15
24. 1.4 Struttura del progetto
Il progetto, vista la sua notevole complessità, è stato suddiviso in tre parti. La
parte con cui avrà a che fare l’utente è costituita dall’interfaccia grafica, essa
comunicherà con il “controllore” per scambiare informazioni destinate
all’utente o che l’utente fornirà a quest’ultimo. Il “controllore” sarà in
contatto con le istanze remote, le quali avranno il compito di monitorare le
risorse degli utenti e fornire il loro stato al “controllore”.
Tutto ciò può essere riassunto con un semplice schema:
Figura 7: Struttura del progetto
16
25. 2. Uso dell’interfaccia
2.1 Casi d’uso
L’interfaccia grafica è facilmente descritta dallo schema delle pagine da cui si
compone:
Dashboard
See All
Warden Summary
Click link Resource
Click riga Alert
Click riga
se presente
Warden
Warden Detail
(Alert Summary | Resource Summary)
C
t Sn l i c k
er
Al ap lin
ga ente
Resource
Click riga
sh k
ri s ot
ick re
Cl e p
s
Click link Resource
Click riga
Reading
Resource Detail Reading Detail
Alert Detail
Figura 8: Schema dell'interfaccia
L’utente, dopo aver effettuato il login accede alla Dashboard dove può
controllare se è presente qualche “Alert” nelle risorse da lui controllate e
vedere l’elenco dei propri “Warden”.
L’elenco degli alert appare solo se questi ultimi sono presenti, mentre
l’elenco warden contiene un numero ridotto di Warden; in quanto si suppone
che l’utente non abbia bisogno di gestire molti di questi ultimi.
17
26. Se dovesse esserci la necessità di visualizzare un elenco di molti warden, sul
lato destro c’è un link per visitare la pagina denominata “Warden Summary”
che contiene l’elenco completo degli warden dell’utente, con la possibilità di
chiederne di nuovi, se il suo profilo lo prevede.
18
27. 2.2 Descrizione delle pagine
Dashboard
Questa è la prima pagina che si presenta all’utente quando esegue il login, in
essa viene presentato l’elenco degli warden appartenenti all’utente e, se
presenti, gli alert pendenti associati alle risorse monitorate.
Figura 9: Dashboard
La prima informazione che appare è data da un pannello a scomparsa legato
alla presenza di alert, nel caso non ci sia nessuna risorsa che segnala alert il
pannello non verrà disegnato e l’utente ne ignorerà la presenza.
L’utente cliccando sulla riga dell’alert accederà alla pagina “dettagli alert”,
mentre cliccando sull’immagine dello snapshot si potrà arrivare direttamente
alla pagina “dettagli reading”.
Nella parte bassa della pagina si può osservare l’elenco degli warden, in fase
di progettazione è stato calcolato che teoricamente un utente avrà un
numero limitato di warden, perciò il componente visualizza un massimo di
tre elementi. Se l’utente possiede molti warden è disponibile un link posto
nel bordo nell’angolo in alto a destra del pannello. Cliccando su di esso si
accede alla pagina “elenco warden”.
19
28. Pagina “Elenco Warden”
In questa pagina viene riutilizzato il componente “WardenTable” popolato
con tutti i warden dell’utente; nella bordo superiore del pannello è inserito
un bottone che permette all’utente di chiedere un nuovo warden
all’amministratore del sistema.
Nell’angolo in alto a destra ci sono anche due link per ordinare la tabella per
nome o per risorse occupate.
Figura 10: Elenco warden
Pagina “Dettagli Warden”
In questa pagina ci sono almeno due pannelli sempre visibili, se ne aggiunge
un altro in caso di alert pendenti.
Il primo pannello contiene le informazioni generali del warden, in particolare
il nome e l’intervallo di monitoraggio minimo. Il nome può essere cambiato
dall’utente cliccando sul link “cambia nome”, questa azione apre un pannello
popup costituito da un componente “input text” e due bottoni “salva” e
“annulla”; l’intervallo di monitoraggio invece è specificato nel warden profile
che l’utente non ha il permesso di modificare.
20
29. Il secondo pannello è costituito dall’elenco delle risorse monitorate dal
warden selezionato; nel bordo superiore sono inseriti un paginatore, utile nel
caso di molte risorse monitorate, e un pulsante per creare un nuovo task.
Premendolo si apre un pannello popup che richiede di inserire l’url della
risorsa da monitorare e il tempio di campionamento.
Tali informazioni sono replicate anche nella parte bassa del pannello.
Figura 11: Dettagli warden
Pagina “Dettagli Risorsa”
Quando l’utente clicca su una risorsa contenuta nel componente
“WardenTable” viene mandato in questa pagina, qui troverà una serie di
pannelli che forniranno varie informazioni, la prima e più importante è l’url
della risorsa monitorata ed è inserita nel primo pannello disponibile.
Il secondo pannello espone lo stato del task e un pulsante “stop” per
terminare il monitoraggio della risorsa.
Successivamente l’utente può vedere i contatti a cui arriveranno le notifiche
nel caso in cui la risorsa generi degli alert. Nel bordo di questo pannello
21
30. compare anche un pulsante in modo che l’utente possa inserire altri contatti
o modificare quegli esistenti.
Nella parte bassa della pagina compare l’elenco dei reading legati alla risorsa,
i dati che compariranno qui saranno i reading effettuati nel giorno indicato
dalla data che compare nel bordo del pannello. Questo elenco è paginato sia
per dati sia per data, cioè l’utente vedrà per default i dati del giorno corrente,
volendo potrà vedere i dati dei giorni precedenti cliccando sui bottoni
antistanti la data. Volendo vedere i reading di una data specifica è disponibile
un componente “calendar”, esso permette appunto di selezionare il giorno di
cui si desidera vedere i dati raccolti specificando una data nota.
Nel bordo a destra c’è anche un bottone che servirà all’utente per applicare
le azioni di feedback richieste nel “template” sottostante.
Figura 12: Dettagli risorsa
22
31. Pagina “Dettagli Reading”
Anche questa pagina è costituita da una serie di pannelli ma, a differenza
delle precedenti, non contiene particolari “template” ma racchiude una serie
di informazioni relative al reading selezionato.
Oltre a vedere l’immagine ad alta risoluzione del reading l’utente, ha a
disposizione un elenco contenente i reading precedenti e successivi a quello
selezionato. Il numero di reading qui disponibili può essere selezionato
dall’utente da una combo box contenente dei valori predefiniti, nello
specifico: 1, 3 e 5. Nella parte bassa sella pagina compaiono anche gli headers
delle request e delle response.
Figura 13: Dettagli reading
23
32. Pagina “Dettagli Alert”
Figura 14: Dettagli alert
Quando un utente clicca su una riga della tabella degli alert giunge nella
pagina di dettaglio. La prima cosa che salta all’occhio è l’immagine dello
snapshot che ha causato l’alert, esso ha uno sfondo rosso proprio per attirare
l’attenzione dell’utente. A lato è presente un pannello contenente le
informazioni legate allo snapshot e al relativo download e un pulsante per
avvisare il sistema che quello rilevato non è un alert.
Il pannello successivo è un elenco degli snapshot precedenti allo snapshot
considerato. Il numero di elementi in questo pannello sono selezionabili
dall’utente tramite una lista.
In basso c’è una tabella che raccoglie delle ulteriori informazioni utili
dell’alert.
24
33. Componente “Header”
Questo componente è particolare rispetto agli altri, è il pezzo che compare in
tutte le pagine e costituisce l’header del sito.
Figura 15: Header
Nella parte sinistra compare il logo dell’applicazione e nasconde un bottone
che, una volta premuto riconduce alla homepage. Dal lato destro è posto un
pannello per la selezione della lingua con cui si vuole visualizzare l’interfaccia.
Il meccanismo con cui viene gestita la localizzazione a livello background
verrà analizzato in seguito, in questa sezione ci limitiamo ad evidenziare che
le bandiere ricoprono dei pulsanti, l’unica bandiera “attiva” è quella relativa
alla lingua corrente dell’interfaccia. Se l’utente seleziona un'altra lingua la
bandiera corrispondente diventerà attiva e la predente prenderà un aspetto
grigio.
Figura 16: Pannello della selezione della lingua dell'interfaccia
Sotto a questa sezione si potrà notare un altro pannello che racchiude il
nome utente della persona loggata e una serie di link necessari per accedere
al profilo utente, alla guida del programma e al logout.
Figura 17: Pannello utente
Se l’utente clicca sul link denominato “Impostazioni” si apre un pannello
popup in cui l’utente potrà modificare tutte le impostazioni collegate al
proprio profilo.
25
34. 3. Implementazione software dell’interfaccia
3.1 Tecnologie e strumenti utilizzati
Per parlare delle tecnologie utilizzate bisogna distinguere le due parti che
compongono l’interfaccia; per quanto riguarda la parte grafica, la tecnologia
predominante è Java Server Faces che è stata utilizzata sfruttando la libreria
ICEfaces. Essa consiste in un framework Ajax open source che permette agli
sviluppatori di applicazioni Java EE di creare applicazioni RIA (Rich Internet
Application) lato server in puro java. Dal punto di vista prettamente grafico,
tale libreria mette a disposizione una “collezione” abbastanza nutrita di
componenti grafici.
Per come la libreria è implementata, il meccanismo Ajax è completamente
trasparente allo sviluppatore.
Si può dire che la libreria sia composta da tre parti:
1. Il framework ICEfaces che estende JSF
2. La parte Ajax
3. La suite dei componenti grafici
Inoltre, nel progetto è stata aggiunta la libreria denominata Facelets che è
sempre parte di ICEFaces e permette di costruire “template” di componenti
personalizzati e riutilizzabili.
Per quanto riguarda il back-end, i dati vengono passati sfruttando gli
Enterprise Java Bean (EJB). In pratica ad ogni azione sull’interfaccia
corrisponde un metodo nel back-end che comunica con uno o più metodi
“local” che forniscono le informazioni gestite dal Controller a cui l’interfaccia
è legata.
Dal punto di vista hardware il progetto è stato fatto eseguire, in locale,
avvalendoci di macchine virtuali VirtualBox.
26
35. 3.2 Facelets
Facelets è semplicemente un altro framework da affiancare ad ICEFaces, esso
permette di creare dei propri componenti o, come chiamati più volti in
questo testo, dei template.
Per utilizzare i facelets bisogna seguire una procedura, per così dire, di
installazione; per prima cosa bisogna inserire il runtime delle librerie facelets
nel progetto. Bisogna quindi creare, in WEB-INF, una cartella, ad esempio
“facelets”, in cui inserire il file “tags.taglib.xml” nel quale andranno inseriti i
nuovi tag con cui chiamare i componenti che verranno creati.
Questo file andrà così riempito:
<!DOCTYPE facelet-taglib PUBLIC quot;-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//ENquot;
quot;http://java.sun.com/dtd/facelet-taglib_1_0.dtdquot;>
<facelet-taglib>
<namespace>TemplateNameSpace</namespace>
<tag>
<tag-name>myTemplate</tag-name>
<source>../template/myTemplateTable.jspx</source>
</tag>
<tag>
<tag-name>myTemplate2</tag-name>
<source>../template/myTemplateTable2.jspx</source>
</tag>
…
</facelet-taglib>
Come si può vedere, per prima cosa, si specifica un namespace necessario a
richiamare i template dalle pagine.
Quindi <tag-name> specifica il nome del tag che si creerà, <source> specifica
il percorso in cui si trova il file .jspx in cui è descritto il nuovo componente.
Fatto ciò va dichiarata la libreria nel file “web.xml” inserendo le seguenti
righe:
27
36. <context-param>
<param-name>facelets.LIBRARIES</param-name>
<param-value>
/WEB-INF/facelets/tags.taglib.xml
</param-value>
</context-param>
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.jsp</param-value>
</context-param>
Quindi si modifica il file “faces-config.xml” aggiungendo:
<application>
<view-handler>
com.icesoft.faces.facelets.D2DFaceletViewHandler
</view-handler>
</application>
Infine va creata una cartella in “WEB-INF”, ad esempio chiamata “template”,
nella quale andrà inserito il file .jspx che definirà il componente.
In questo modo:
<span xmlns:ice=quot;http://www.icesoft.com/icefaces/componentquot;
xmlns:f=quot;http://java.sun.com/jsf/corequot;>
<ice:outputText value=quot;#{testo}quot;/>
...
</span>
Quando si vorrà utilizzare il componente esso dovrà essere richiamato, da
una pagina .jsp, in questo modo:
<div xmlns:zorzin=quot;TemplateNameSpacequot;>
<zorzin:myTemplateTable testo=quot;hello world from facelets!quot;/>
</div>
28
37. 3.3 Funzionamento della parte grafica
L’interfaccia è stata progettata e sviluppata tenendo ben presente la
possibilità che, in futuro, si vogliano effettuare delle modifiche, anche
radicali, della struttura. Nel realizzarla quindi sono stati creati una serie di
“template” con lo scopo di facilitare il riutilizzo del codice o lo spostamento
dei pannelli ora esistenti.
Di seguito verrà analizzata la struttura e i componenti che compongono i
“template” sopra citati:
3.3.1 Il componente “WardenTable”
Questo componente viene “presentato” subito all’utente che effettua il login
nell’applicazione. Permette di illustrare i warden che esso possiede corredati
da numerose informazioni.
Come si può vedere dalla figura in questo componente vengono presentati
vari dati. Un warden viene creato senza nome ma ha un intervallo di
monitoraggio minimo (sampling period) specificato nel warden profile e non
modificabile dall’utente. In ogni riga di questa tabella viene esposto lo
snapshot dell’ultimo reading effettuato, tale immagine è racchiusa in un
pannello che assume un diverso colore a seconda del tipo dello snapshot, la
data, l’ora del download e i kilobyte scaricati in un dato tempo.
Nella suddetta riga vengono illustrati anche l’url della risorsa di cui è stato
catturato lo snapshot, il suo nome (se l’utente lo ha specificato), il suo
intervallo di monitoraggio, le opzioni d notifica (cioè se viene inviata, ad
esempio, una mail al verificarsi dell’evento alert), alcune informazioni legate
sempre al reading, infine la quantità di risorse occupate rispetto alle risorse
disponibili specificate nel warden profile.
Tutte le informazioni fin qui illustrate sono esposte utilizzando il componente
<ice:output Text> che permette di scrivere a video delle stringhe o dei valori
numerici reperiti dal backing bean associato ed allineate usando dei tag html
29
38. di tipo <table>. Questa scelta è stata dettata dal fatto che, in ogni caso, a
livello di browser, il componente “table” di icefaces viene “tradotto” come
una “table” html ma quest’ultima è risultata essere più comoda da utilizzare
per il programmatore.
Per quanto riguarda il pannello contenente l’immagine è costituito da un
template di cui si parlerà successivamente, esso è denominato “ImagePanel”.
3.3.2 Il componente “AlertTable”
Questo componente viene usato più volte nell’interfaccia, raccoglie tutti gli
alert non ancora visitati dall’utente.
E’ costituito da una serie di tabelle html annidate, la più esterna in realtà è
costituita da un componente <ice:dataTable> a due colonne che poi viene
renderizzato come se fosse una tabella html; all’interno di questo
componente c’è una tabella orizzontale per disegnare i quattro snapshot
precedenti, ed in basso una verticale per contenere le informazioni da fornire
all’utente. All’estrema destra compare l’immagine della pagina che ha
causato l’alert, il pannello usato come sfondo è colorato in rosso per attirare
l’attenzione dell’utente. Questo colore viene fornito da un css legato al
pannello e cambiato dinamicamente da un backing bean.
3.3.3 Il componente “ResourceTable”
Questo componente descrive lo stato e da alcune informazioni sulla risorsa
monitorata.
30
39. All’estrema sinistra si possono notare un’icona ed un pulsante, l’icona cambia
colore a seconda dello stato di monitoraggio della risorsa; sarà verde se essa
è correntemente monitorata, grigia se l’azione di monitoraggio non è in
corso.
Il blocco centrale illustra l’url della risorsa monitorata, la data e l’ora
dell’ultimo reading e alcuni dati derivanti dagli ultimi tre reading.
All’estrema destra si trova il già citato pannello “ImagePanel” contenente
l’immagine dell’ultimo reading.
3.3.4 Il componente “ReadingTable”
Questo componente, costruito sempre come gli altri già descritti, ha il
compito di fornire all’utente i dati utili per valutare i reading “catturati” nel
periodo temporale scelto.
La tabella è divisa in tre zone, la parte all’estrema sinistra racchiude tre radio
button per le segnalazioni dell’utente; la parte centrale offre le classiche
informazioni associate al reading, quali data e ora di download, il tempo
necessario ad effettuarlo e la dimensione di quest’ultimo.
Infine sulla destra si trova il pannello “ImagePanel” che serve ad illustrare
l’immagine del reading relativo alla riga in questione.
3.3.5 Il componente “ContactPanel”
31
40. Questo componente è leggermente diverso dagli altri, ha lo scopo di fornire
una lista dei contatti a cui verrà inviata una segnalazione in caso di alert.
Tale componente viene utilizzato solamente nella scheda “dettagli risorsa”,
l’utente avrà immediatamente a disposizione l’informazione che legala
notifica degli alert alla risorsa monitorata.
Il componente è essenzialmente una tabella di tre colonne, in essa
compaiono: metodo di notifica, destinazione (e-mail o sms) e un pulsante per
rimuovere tale contatto.
3.3.6 Il componente “ImagePanel”
Questo componente è molto importante, costituisce l’intelaiatura in cui viene
inserita l’immagine e le informazioni ad essa collegate. Viene utilizzato ogni
volta che appare un’immagine di uno snapshot nell’interfaccia; la sua
costruzione risulta essere abbastanza semplice:
<jsp:root xmlns:jsp=quot;http://java.sun.com/JSP/Pagequot; version=quot;2.0quot;>
<jsp:directive.page contentType=quot;text/htmlquot; pageEncoding=quot;UTF-8quot;/>
<span xmlns:ice=http://www.icesoft.com/icefaces/component
xmlns:f=quot;http://java.sun.com/jsf/corequot;>
<ice:panelGroup style=quot;text-align:centerquot; styleClass=quot;#{personalStyle}quot;>
<ice:panelGrid columns=quot;1quot; >
<ice:graphicImage value=quot;#{image}quot; alt=quot;#{alt}quot; width=quot;#{width}quot; height=quot;#{height}quot;
title=quot;#{tip}quot; style=quot;border:nonequot;/>
<ice:outputText value=quot;#{datetime}quot; styleClass=quot;snapshotPanelTextquot; />
<ice:outputText value=quot;#{kb} kb #{msgs.per} #{time} #{msgs.seconds}quot;
styleClass=quot;snapshotPanelTextquot;/>
</ice:panelGrid>
</ice:panelGroup>
</span>
</jsp:root>
Tralasciando le prime righe di codice si può notare come il componente sia
costituito da tre elementi, un “ice:graphicImage” che serve a contenere
l’immagine e due campi di testo (“ice:outputText”).
Quello che è più interessante notare è che, essendo molto generico, c’è il
bisogno di poter specificare all’esterno le sorgenti dati.
Per farlo si va a specificare un “nome”, come se si trattasse di una variabile,
al posto del dato. Ad esempio, in “ice:graphicImage” l’attributo value ha
come valore la seguente sintassi:
value=quot;#{image}quot;
32
41. Questo equivale a dire che il valore del componente graphicImage dovrà
essere preso dalla variabile image che verrà specificata quando il
componente “ImagePanel” verrà chiamato nelle pagine jsp in cui
compariranno delle immagini.
In questo modo:
<prefisso:nome_del_template image=quot;dato_staticoquot; />
<prefisso:nome_del_template image=quot;#{sorgente_dati}quot; />
Per sorgente dati si intende la chiamata ad un metodo legato ad un backing
bean, ciò si può vedere applicato in un caso pratico nell’esempio sottostante.
Questo pezzo di codice è quello che il programmatore deve inserire nella
pagina jsp in cui dovrà apparire il componente “ImagePanel” che conterrà
l’immagine:
<zorzin:Image image=quot;#{warden.value.imagePanel.thumbailImage}quot;
datetime=quot;#{warden.value.imagePanel.downloadDateTime}quot;
kb=quot;#{warden.value.imagePanel.downloadedKb}quot; time=quot;#{warden.value.imagePanel.downloadTime}quot;
tip=quot;#{msgs.destReadingDet}quot; alt=quot;reading mini snapshotquot; width=quot;240pxquot; height=quot;160pxquot;
personalStyle=quot;snapshotBackPanel#{warden.value.imagePanel.color}quot;/>
Analizzando in dettaglio una stringa:
image=quot;#{warden.value.imagePanel.thumbailImage}quot;
L’immagine che verrà inserita nel componente è specificata dalla variabile
“image”, la stringa contenuta nel virgolettato significa: prendi la variabile
thunbailImage dall’oggetto ImagePanel contenuto nell’oggetto riga value che
compone la tabella warden.
L’immagine viene fornita dal backing bean come byte array, questo perché il
componente fornito da ICEFaces accetta come input l’array di byte o una
stringa.
33
42. 3.3.7 Gestione dell’internazionalizzazione
Come è logico aspettarsi, un’interfaccia deve anche includere un metodo per
adattare i propri messaggi alla lingua preferita dall’utente. In questo
momento l’interfaccia può visualizzare due lingue, inglese ed italiano,
volendo sarà facile includere nuovi file di lingua che dovranno includere le
traduzioni.
Per abilitare l’internazionalizzazione si procede in questo modo: si va a
specificare nel file di configurazione “faces-config.xml” un blocco di questo
tipo:
<application>
<locale-config>
<default-locale>en</default-locale>
<supported-locale>en</supported-locale>
<supported-locale>it</supported-locale>
</locale-config>
<resource-bundle>
<base-name>LanguagePack.messages</base-name>
<var>msgs</var>
</resource-bundle>
</application>
Il blocco <locale-config> serve a dire quale sarà la lingua di default con cui
dovrà apparire l’interfaccia nel caso non siano disponibili altre lingue
supportate. Tale procedimento verrà effettuato in automatico in base alla
lingua con cui è impostato il browser.
Il secondo blocco serve a specificare dove si trovino i file contenenti le
traduzioni e il nome della variabile da chiamare per inserire il testo nelle
pagine.
Il testo verrà riferito nelle pagine jsp che compongono l’interfaccia in questo
modo:
<ice:outputText value=”#{msgs.StringaTradotta}”/>
Inoltre, volendo dare modo all’utente di cambiare la lingua a proprio
piacimento, nel componente “Header”, di cui si è già discusso, sono stati
posti dei bottoni per il cambio della lingua.
Il codice che sta, nella pagina, dietro al bottone è:
34
43. <ice:commandButton action=quot;#{Header.btnEnglish_action}quot; title=quot;Englishquot;
id=quot;btnEnglishquot; binding=quot;#{Header.btnEnglish}quot; styleClass=quot;btnHeaderquot;/>
Il commandButton, fornito da ICEFaces, ha i seguenti parametri:
action: rappresenta l’azione legata alla pressione del bottone; in
questo caso l’azione è definita nel metodo btnEnglish_action posto nel
backing bean Header.
title: è l’etichetta che appare passando il puntatore del mouse sul
bottone.
binding: è il modo per collegare l’elemento grafico al backing bean. In
pratica invece di chiamare un metodo, nel backing bean si va a creare
l’oggetto HtmlCommandButton (in questo caso) con i metodi get e set,
e si associa l’oggetto al componente grafico.
styleClass: specifica il nome dello stile da applicare all’elemento.
Il codice che sta nella classe java legata alla pagina e viene chiamato
all’azione del bottone è:
public String btnEnglish_action() {
sb1.changeLanguage(Locale.ENGLISH);
setLanguageImg(Locale.ENGLISH);
return null;
}
…nel SessionBean…
public void changeLanguage(Locale locale){
FacesContext.getCurrentInstance().getViewRoot().setLocale(locale);
}
Il secondo metodo chiamato (setLanguageImg) serve a cambiare l’immagine
della lingua selezionata.
In alcuni casi si è dimostrato necessario ottenere delle stringhe localizzate
anche a livello di codice java; per chiamare le traduzioni in questo caso le
cose si complicano un pochino, la classe che se ne occupa è posta nel
package “usergoldrakeice7.utils” e la classe si chiama appunto “Utils”, il
metodo che si occupa delle stringe è:
35
44. public static String getMessageResourceString( String bundleName, String key, Object params[], Locale locale){
String text = null;
ResourceBundle bundle = ResourceBundle.getBundle(bundleName, locale, getCurrentClassLoader(params));
try{
text = bundle.getString(key);
} catch(MissingResourceException e){
text = quot;?? key quot; + key + quot; not found ??quot;;
}
if(params != null){
MessageFormat mf = new MessageFormat(text, locale);
text = mf.format(params, new StringBuffer(), null).toString();
}
return text;
}
Essendo un metodo statico la chiamata è molto semplice:
Utils.getMessageResourceString(quot;LanguagePack.messagesquot;, quot;navReadingDetailquot;, null, locale);
I file che contengono le stringe per l’internazionalizzazione sono specificati
nel package LanguagePack e sono chiamati “messages_it” e “messages_en”.
Come si può notare dagli esempi soprastanti il pezzo di stringa del nome che
precede l’underscore è quello che viene usato nello specificare la sorgente
dati.
36
45. 3.3.8 Regole di navigazione
Un metodo per spostarsi da una pagina all’altra in JSF è usare le cosiddette
“regole di navigazione”, in pratica si crea una regola che collega una pagina
all’altra e si associa una stringa ad un’azione di un componente. Ad esempio
si può associare la stringa “pagina2” ad un bottone posto nella pagina1; alla
pressione del bottone, se la regola è stata correttamente mappata nel file di
configurazione “faces-config.xml”, l’utente verrà indirizzato alla pagina2.
Per specificare l’azione associata al bottone ci sono diversi modi, in questo
progetto ne sono stati usati due, uno è quello più semplice di specificare una
stringa statica posta proprio nella pagina jsp.
<ice:commandButton … action=”pagina2” … />
L’altro è quello di associare un metodo all’azione:
<ice:commandButton … action=”#{BackingBean.action_onButtonPress}” … />
Nella classe java del backing bean specificato nella stringa sarà contenuto il
metodo “action_onButtonPress” che avrà come valore di ritorno una stringa;
essa verrà interpretata dal framework e, se la stringa sarà stata mappata nel
file sopra citato, verrà caricata la pagina di destinazione.
public String action_onButtonPress(){
…
return “pagina2”;
}
37
46. Le regole di navigazione del progetto possono essere riassunte in uno
schema:
Figura 18: Regole di navigazione
Un esempio di dichiarazione di regola di navigazione è:
<navigation-rule>
<from-view-id>/HomePage.jsp</from-view-id>
<navigation-case>
<from-outcome>seeAllWarden</from-outcome>
<to-view-id>/WardenSummary.jsp</to-view-id>
</navigation-case>
</navigation-rule>
38
47. 3.4 Funzionamento della connessione con il back-end
La comunicazione fra l’interfaccia vera e propria, il back-end e la sorgente
dati è piuttosto articolata.
3.4.1 Comunicazione fra interfaccia e backing bean
Per iniziare parliamo della connessione fra le prime due parti: l’interfaccia è
costituita da file .jsp (o derivati), tutti gli elementi che devono interagire con
l’utente o visualizzare dati hanno un riferimento specifico ad una sorgente
dati che si trova nel back-end, più nello specifico esso è chiamato backing-
bean o managed-bean che è costituito semplicemente da una classe java
legata al progetto “war” da una definizione specificata nel file di
configurazione “faces-congfig.xml” posto in “Web Pages/WEB-INF/”.
Per poter ottenere qualsiasi tipo di dato è necessario che la sorgente sia
prima dichiarata nel suddetto file di configurazione, diventando così un
managed-bean.
<managed-bean>
<managed-bean-name>Header</managed-bean-name>
<managed-bean-class>usergoldrakeice7.Header</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
Quindi si andrà ad inserire una chiamata al metodo che dovrà fornire il dato
con una sintassi particolare, ad esempio:
…nel file .jsp…
<ice:outputText value=”#{Header.string}” />
…nel managed bean - Header…
public String getString(){
return “esempio”;
}
Come è normale immaginare, i dati veri e propri dovranno provenire da una
sorgente dati esterna.
39
55. 3.4.3 Comunicazione fra backing bean e controller
Parliamo quindi della connessione fra managed-bean e la sorgente dati che è
costituita dal “controller”.
Come detto precedentemente, l’interfaccia grafica non può accedere
direttamente alle istanze remote, esse possono venir comandate solo dal
controller tramite l'invocazione di metodi remoti.
L'invocazione di tali metodi remoti (remote procedure call o RPC) è una
tecnica che permette di eseguire del codice a distanza tra due macchine
diverse collegate tra loro da una rete, rendendo così la differenza tra
chiamate locali e remote il minore possibile.
In questo software ciò è stato reso possibile tramite un particolare costrutto
della tecnologia EJB noto come remote stateless session bean.
Uno stateless session bean consiste in un'interfaccia java che definisce i
metodi richiamabili remotamente, essa deve essere condivisa tra chiamato e
chiamante ed una classe java nota solo al chiamante che implementa la
suddetta interfaccia. Questo tecnologia rende la differenza tra chiamate
locali e remote estremamente ridotta, consistente nel solo fatto che i
parametri passati alle funzioni sono passati per valore invece che per
riferimento come di solito con gli oggetti Java; se però i dati passati
appartengono ad un tipo nativo di Java o ad un oggetto immutabile, come ad
esempio le stringhe, la differenza diventa nulla.
Le informazioni scambiate fra il controller e l’interfaccia vengono gestite
esclusivamente da metodi @EJB forniti da interfacce remote implementate
sul controller e che permettono di fornire dati provenienti da database e
dalle istanze remote.
Per utilizzare tali metodi bisogna specificare che l’oggetto è un’istanza
remota, quindi lo si usa come un normale metodo java.
Ad esempio:
@EJB
private TaskCtrlRemote taskObj;
private void someMethod(){
taskObj.someRemoteMethod();
}
47
56. 3.4.4 Lazy Loading
Il lazy loading è un design pattern che viene applicato per caricare
dinamicamente i dati che servono, e solo essi, nel momento in cui vengono
richiesti. Si può immaginare, ad esempio, di popolare una tabella caricando
dei dati da un database o da una qualsiasi sorgente dati; se viene chiamato il
metodo per ottenerli, tutti i dati verranno consegnati all’interfaccia. Se i dati
sono pochi va tutto bene, mentre se i dati sono molti l’applicazione risulterà
essere molto lenta. Per ovviare a tale problema si può ricorrere al lazy
loading, basta modificare il metodo che fornisce i dati definendo due
parametri, il primo per dire da quale record partire, il secondo per specificare
quanti record dare.
In questo progetto il caricamento è stato così implementato:
protected PagedListDataModel onePageDataModel;
private PersistentFacesState state;
private int pageSize=3;
public DataModel getData() {
state = PersistentFacesState.getInstance();
if(onePageDataModel == null){
onePageDataModel = new LocalDataModel(pageSize);
}
return onePageDataModel;
}
private class LocalDataModel extends PagedListDataModel {
public LocalDataModel(int pageSize) {
super(pageSize);
}
public DataPage fetchPage(int startRow, int pageSize) {
// call enclosing managed bean method to fetch the data
return getItems(startRow, pageSize);
}
}
Dalla pagina viene chiamato il metodo getData, la variabile pageSize
rappresenta quanti record verranno visualizzati sulla tabella in ogni pagina.
Una volta richiamato il costruttore LocalDataModel viene eseguita la
48
57. funziona getItems, alla quale vengono passati i parametri citati
precedentemente, startRow e pageSize.
Il metodo getItems avrà al suo interno il necessario per provvedere al
caricamento ma la gestione di tale operazione verrà affidata alla classe
“PagedListDataModel” definita nel progetto.
Per ulteriori dettagli e informazioni segnaliamo il tutorial di ICEFaces sul lazy
loading [5].
49
58. 3.4.5 Metodi esposti dal controller
Metodi per la gestione delle istanze (InstanceCtrlBean)
Utilizzati dal controllore stesso per gestire internamente le informazioni sulle
istanze e dall'interfaccia utente per elencare quali siano quelle attive
public InstanceCtrl getInstanceByUri(URI uri) throws InstanceNotFoundException;
public InstanceCtrl getInstanceById(long id) throws InstanceNotFoundException;
Fornisce l'istanza identificata dai suoi identificativi univoci: l'uri o l'id
public List<InstanceCtrl> getAllInstances();
public List<InstanceCtrl> getAllInstancesSingle();
Fornisce l'elenco di tutte le istanza, nel primo caso di qualsiasi tipo esse
siano, sia singole che appartenenti ad un gruppo clusterizzato; nel secondo
caso invece presenta l'elenco di tutte le istanze di tipologia single; da notare
che questi metodi non distinguono lo stato in cui si trova l'istanza (attivo,
fallito, fermata).
public List<InstanceGroup> getAllInstanceGroup();
Permette di ottenere la lista dei gruppi di istanze presenti nel sistema.
public List<InstanceCtrl> getActiveInstances();
public List<InstanceCtrl> getActiveInstancesOfGroup(InstanceGroup group);
public List<InstanceCtrl> getActiveSingleInstances();
Permette di ottenere la lista di tutte le istanze attive nel momento
dell'interrogazione; nel primo caso di qualsiasi tipo esse siano, nel secondo
solo quelle di tipologia autonoma, nel terzo fra quelle appartenenti ad uno
specificato gruppo di istanze.
public void registerInstanceSingle(URI uri, String ip, int port)
throws InstanceDuplicateUriException,InstanceCtrlException;
public void registerInstanceGroup(URI uri, String ip, int port, InstanceGroup group)
throws InstanceDuplicateUriException, InstanceCtrlException;
50
59. Questi metodi permettono di registrare nel sistema una nuova istanza
fornendo i dati necessari.
Per l'istanza singola bisogna fornire la uri univoca, l'ip e la porta a cui tale
istanze risponde, nel casi invece della creazione di una istanza appartenente
ad un gruppo si indica anche il gruppo di appartenenza. In ambo i casi viene
sollevata una eccezione nel caso in cui si cerchi di registrare due istanze
caratterizzate da identificativi uguali.
public void disableInstance(URI uri) throws InstanceNotFoundException;
Permette di impostare lo stato di una istanza su halted; solitamente tale
azione viene effettuata in automatico dagli algoritmi di fallimento/recupero
delle istanze in caso di errore, tuttavia può risultare utile in alcune attività di
manutenzione.
51
60. Metodi per la gestione dei task (TaskCtrlBean)
public void createTask(String url, int samplingPeriod, Warden w) throws TaskCtrlException;
public void createTask(String urlS, int samplingPeriod, Warden w, InstanceCtrl i)
throws TaskCtrlException;
Attraverso questi metodi è possibile invocare la creazione di un nuovo task;
nel primo caso passando semplicemente i parametri fondamentali (url,
sampling period e warden), nel secondo caso impostando anche l'istanza su
cui il task deve essere eseguito.
public void terminateTask(TaskDescriptorCtrl t) throws TaskCtrlException;
public void modifyTask(TaskDescriptorCtrl t, String url, Integer samplingPeriod, Warden w)
throws TaskCtrlException;
Permettono di terminare il task indicato o di modificarlo indicando il
parametro che si intende variare (url, sampling period) il task precedente
viene bloccato ed avviata la esecuzione dello stesso con i parametri
modificati.
public TaskDescriptorCtrl getTaskById(long id) throws TaskCtrlNotFoundException;
Permette di ottenere il riferimento ad un task a partire dall'id identificativo.
public SnapshotCtrl getSnapshotById(long id, InstanceCtrl I, boolean full)
throws TaskCtrlException;
public SnapshotCtrl getLastSnapshotOfTask(TaskDescriptorCtrl tdc, boolean full)
throws TaskCtrlException;
public List<SnapshotCtrl> getLastsSnapshotOfTask(TaskDescriptorCtrl tdc, int quantity,
boolean full) throws TaskCtrlException;
public List<SnapshotCtrl> getSnapshotByDate(TaskDescriptorCtrl tdc, Date date,
boolean full) throws TaskCtrlException;
public List<SnapshotCtrl> getSnapshotsBeforeId(TaskDescriptorCtrl tdc, long id,
long quantity, boolean full) throws TaskCtrlException;
public List<SnapshotCtrl> getSnapshotsAfterId(TaskDescriptorCtrl tdc, long id,
long quantity, boolean full) throws TaskCtrlException;
Sono le varie modalità con cui gli snapshot sono accessibili: o attraverso l'id,
o recuperando l'ultimo rilevato dall'istanza per un dato task, o reperendo
52
61. tutti gli snapshot rilevati in una tale data o recuperando le n istantanee
rilevate prima o dopo di un dato snapshot.
public List<SnapshotCtrl> forceTaskOutcomes(TaskDescriptorCtrl tdc, List<SnapshotBase> list)
throws TaskCtrlException;
Metodo centrale che permette all'utente di catalogare gli alert ricevuti come
corretti o falsi positivi, accetta una lista di snapshot (opportunamente
impostati per essere riconosciuti come falsi positivi o meno) e il task di
riferimento.
In uscita presenta gli snapshot la cui catalogazione è risultata modificata in
seguito alle variazioni determinate dai feedback inviati.
53
62. Metodi per la gestione dei Warden (WardenBean)
public List<UserData> getAllUsers();
Fornisce l'elenco di tutti gli utenti registrati nel sistema
public List<WardenProfile> getAllWardenProfiles();
Fornisce tutti i WardenProfile presenti nel sistema
public Warden getWardenById(long id) throws WardenException;
public List<Warden> getAllWarden();
public List<Warden> getWardenByUser(UserData ui);
Permette di ottenere i warden in base all'id, all'utente proprietario, o tutti
indifferentemente.
public void createWarden(Warden wParent, WardenProfile wProfile, UserCustomer uCustomer)
throws WardenException;
Permette di creare i sotto-warden definendo quale sia il warden-parent, a
quale profilo si debba riferire e quale sia l'utente associato.
Metodi per la gestione degli Alert (AlertCtrlBean)
public AlertWithTaskAbstractCtrl getAlertById(long id) throws AlertCtrlException;
Questo metodo restituisce l'alert associato ad un certo id.
public List<AlertWithTaskAbstractCtrl> getAlertsFrom(Date date,TaskDescriptorCtrl task);
public List<AlertWithTaskAbstractCtrl> getAlertsFromLazyLoad(Date date,
TaskDescriptorCtrl t, int start, int end);
Questo metodo restituisce gli alert di un determinato task generati dopo una
certa data con e senza lazy load.
public List<AlertWithTaskAbstractCtrl> getPendingAlertsOfTask(TaskDescriptorCtrl task);
public List<AlertWithTaskAbstractCtrl>
getPendingAlertsOfTaskLazyLoad(TaskDescriptorCtrl task, int startRow, int pageSize);
Questo metodo permette di ottenere tutti gli alert pendenti associati ad uno
specifico task con e senza lazy load.
54
63. public void createAlertSubscriptionMail(TaskDescriptorCtrl task, UserData user)
throws AlertSubscriptionException;
public void createAlertSubscriptionMail(TaskDescriptorCtrl task, UserData user, String mail)
throws AlertSubscriptionException;
public void createAlertSubscriptionSms(TaskDescriptorCtrl task, UserData user, String sms)
throws AlertSubscriptionException;
Questi metodi permetto di creare delle sottoscrizioni agli alert relativi ad uno
specifico task; sia di tipologia mail che sms permettendo fra l'altro di
specificare un indirizzo email o numero sms alternativo rispetto a quello
predefinito dell'utente con cui viene creata la sottoscrizione.
public void createInstanceAlertSubscriptionEmail(InstanceCtrl instance, UserAdmin user)
throws AlertSubscriptionException;
public void createInstanceAlertSubscriptionEmail(InstanceCtrl instance, UserAdmin user, String mail)
throws AlertSubscriptionException;
Questi metodi permettono di creare delle sottoscrizioni agli alert relativi ad
una specifica istanza; l'utente associato deve essere uno UserAdmin, visto
che solo gli utenti amministratori conoscono e hanno possibilità di operare
sulle istanze fisiche, viene data anche qui la possibilità di personalizzare
l'indirizzo di destinazione della notifica.
public void removeAlertSubscription(AlertSubscription alertSubscription)
throws AlertSubscriptionException;
Attraverso questo metodo viene data la possibilità di eliminare ogni tipo di
sottoscrizione ad un alert; fornendo metodi generici:
public void save(Object o) throws Exception;
Permette di invocare il salvataggio di un oggetto di tipo entity, se noto al
controllore, sul database.
55
64. 3.5 Test cross-browser
Come di consuetudine, nella fase finale del progetto bisogna procedere al
test dell’applicazione sviluppata. Mentre in una normale applicazione
software si può procedere con degli “unit testing”, in un’interfaccia web
bisogna testare la corretta visualizzazione dei contenuti.
Per fare questo sono stati scelti i principali web browser odiernamente
diffusi, per apprezzare meglio il concetto basta osservare il seguente grafico:
Figura 26: Diffusione dei principali browser web a marzo 2009 [3]
Il browser su cui è stata sviluppata l’interfaccia è Firefox (versione 3.0.6), per
il test sono stati scelti:
Microsoft Internet Explorer (versione 7 e 8RC1)
Apple Safari (versione 4 beta)
Google Chrome (versione 1.0.154.48)
Opera (versione 9.63)
Il test consiste nell’aprire i vari applicativi e visualizzare l’homepage del sito
per poi procedere alla normale navigazione come farebbe un utente.
Per quanto riguarda Firefox, essendo il browser su cui è stata sviluppata
l’applicazione, non sono stati riscontrati problemi.
Per Safari, Chrome e Opera, essi sono risultati molto simili, c’è stato solo
qualche piccolo problema legato all’applicazione dello stile descritto nel
foglio CSS in quanto il comportamento differiva leggermente da Firefox. Tali
problemi sono stati risolti molto rapidamente e l’aspetto dell’interfaccia è del
tutto identico a Firefox.
Solo in Opera non è stato possibile ottenere l’effetto “border-radius”
applicato tramite CSS agli angoli dei pannelli; con questo browser quindi
l’utente vedrà gli angoli squadrati.
56
65. Effetto “border-radius”
Ok Non applicabile
Tabella 1: Effetto quot;border-radiusquot;
Il discorso è risultato essere un po’ diverso parlando del browser Microsoft, il
problema più evidente era quello legato al posizionamento dei pannelli che
compongono l’interfaccia, normalmente tutto è allineato al centro, in questo
caso tutto risultava essere collassato a sinistra.
Il problema è stato risolto mettendo una proprietà “text-align:center” nello
stile “backStyle” che viene richiamato nel pannello più esterno che funge da
contenitore degli altri pannelli, i quali risultavano essere allineati in modo
errato. Tale proprietà è necessaria solo in IE e non crea “disturbi” negli altri
browser.
Altri “difetti” di minore importanza sono legati al fatto di non applicare
correttamente gli stili in alcuni casi particolari, come ad esempio il passaggio
del mouse sulle righe delle tabelle; lo sfondo cambia ma non vengono
sottolineati i link cliccabili dall’utente, oppure il puntatore del mouse non
cambia forma sulle immagini cliccabili.
Infine, si nota fortemente come la versione 7 non riesca a disegnare i bottoni
correttamente, mentre in IE8 tale problema sembra essere superato.
Problema di visualizzazione dei bottoni in IE
Bottone corretto Bottone errato
disegnato da Firefox disegnato da IE7
Tabella 2: Problema di visualizzazione dei bottoni in IE
Per quanto riguarda la navigazione e le azioni che l’utente può fare il
comportamento risulta essere quello atteso in tutti i browser provati.
57
67. 4. Conclusioni
4.1 Obiettivi raggiunti
Quasi tutti gli obiettivi sono stati raggiunti, con ancora una piccola quantità di
lavoro dovrebbero venire completati tutti i dettagli.
Al momento manca l’albero degli elementi della pagina scaricata nella
sezione “dettagli reading”; solo per le piccole immagini poste nelle zone
“reading before/next” manca la funzione di venir inviati alla pagina del
reading associato in caso di click su un’immagine.
4.2 Quantificare il lavoro
Il lavoro svolto è stato immane, la curva di apprendimento della tecnologia e
del framework ICEFaces è piuttosto ripida, questo fatto è dovuto anche alla
mancanza di una documentazione adeguata e a dei tutorial approssimativi
forniti dal sito del produttore. In pratica non si smette mai di scoprire cose
nuove. Mote richieste, apparentemente semplici, dato lo stato acerbo della
tecnologia, si sono dimostrate più ardue del previsto e, a volte, si trovano
difetti o cose perfettibili, nell’implementazione della libreria.
4.3 Conclusioni soggettive
Con questo progetto ho avuto modo di approfondire molte cose sulle
tecnologie Java e scoprirne di nuove, soprattutto scoprirne di nuove.
Anche se il progetto si è dimostrato un “generatore di nervosismo” alla fine
posso dire di essere soddisfatto di aver scelto di lavorare su esso.
Un notevole problema è stato causato da un evento accaduto dopo un paio
di mesi dalla partenza del progetto; all’inizio era stata scelto, come
framework jsf, la libreria “Woodstock” di Sun. Dopo aver fatto un discreto
sforzo per apprendere il suo funzionamento siamo stati costretti a sostituirla
con ICEFaces visto che Sun stessa, per problemi legati alla crisi economica, ha
scelto di abbandonare questa libreria non fornendo più supporto e non
garantendo più sviluppo. In pratica, nei mesi successivi, tutti i progetti che si
appoggiavano su di essa, sono stati costretti a migrare ad ICEFaces o verso
altri framework.
Noi abbiamo scelto di abbandonare il lavoro fatto in circa due mesi e mezzo
e, con esso, il know how acquisito visto che ICEFaces è completamente
59
68. diverso come approccio. Ciò ci ha costretto a ricominciare lo studio e la
progettazione da zero.
4.4 Stato attuale del lavoro
Le tre componenti del progetto sono state integrate e il sistema funziona
monitorando poche decine di pagine, anche con un periodo di
campionamento breve fra lettura e lettura.
Al momento è in fase di test il funzionamento del sistema monitorando
centinaia di risorse su molte istanze.
Probabilmente per la data della laurea vera e propria si riuscirà ad ottenere
una versione pienamente funzionante e testata del progetto.
60
69. 5. Ringraziamenti
Per prima cosa penso sia doveroso ringraziare il prof. Bartoli per la
disponibilità dimostrata, non solo negli ultimi mesi di tesi ma anche in tutti
questi anni; ringrazio anche tutti i docenti incontrati nel mio cammino
universitario, molti di essi sono risultati essere utili fonti di conoscenza.
Un ringraziamento in particolare va, oltre al prof. Bartoli, ai prof. Fermeglia,
Tuzzi e Tessarotto.
Grazie a Giorgio ed Eric per i consigli, le discussioni e la compagnia durante il
periodo di tesi.
Grazie a tutti gli amici che hanno lavorato e condiviso con me questi anni di
studio, Alessandro, Alexia, Bruno, Giancarlo, ecc…
Un ringraziamento particolare va ai miei “compagni di sventure” in questa
tesi e non solo in questa tesi visti numerosi esami e progettini che abbiamo
affrontato assieme, Enrico e Marco.
Grazie alla mia famiglia, in un modo o nell’altro ci siamo “sopportati” in tutti
questi anni.
Grazie a Giulio, fonte inesauribile di consigli e chiacchierate più o meno
tecniche.
Grazie a Giorgia e Manuela che, non so come, mi sopportano da parecchi
anni.
Il grazie più grande va alla mia migliore amica, Kri, la persona più preziosa che
ho incontrato in questi anni, con cui ho diviso moltissimi momenti e con cui,
come compagna per la vita, spero di poterne condividere molti altri. Grazie di
cuore, tesoro mio!
Infine un grazie generale a tutti quelli che non ho citato ma hanno condiviso
qualcosa con me.
61
71. 6. Bibliografia
[1] Valutazione di algoritmi di anomaly detection per la rilevazione
automatica delle intrusioni in siti web, tesi di laurea, Giorgio
Davanzo, 2006.
[2] Zone-h: http://www.zone-h.org
[3] MarketShare:
http://marketshare.hitslink.com/report.aspx?qprid=0
[4] Zone-H. B. Members. Statistics on web servers attacks for year
2005. 2006
[5] ICEFaces – lazy loading tutorial:
http://facestutorials.icefaces.org/tutorial/dataTable-JPA-
tutorial.html
Java Server Faces in action – Kito D. Mann
More on CSS – Eric Meyer
NetBeans: http://www.netbeans.org/
NetBeans tutorial: http://www.netbeans.org/kb/60/web/
ForumSun:
http://forums.sun.com/thread.jspa?messageID=10240129
JIRA forum: http://jira.icefaces.org/browse/ICE-3013
Developinjava: http://developinjava.com/
ICEFaces: http://www.icefaces.org
ICEFaces forum:
http://www.icefaces.org/JForum/forums/list.page
Documentazione icefaces:
http://www.icesoft.com/developer_guides/icefaces/tld/
index.html
63