Sei sulla pagina 1di 91

UniversitàFacoltà

Degli Studi di Trieste


di Ingegneria
Corso di Laurea Specialistica in Ingegneria Informatica

Tesi di laurea in reti di calcolatori

Progetto e realizzazione dell'infrastruttura

di controllo in una farm per la rilevazione di

attacchi web a siti remoti

RELATORE
Prof. Alberto Bartoli

CORRELATORE LAUREANDO
Ing. Eric Medvet Enrico Sorio

Anno Accademico 2007/2008


Ai miei genitori
Indice

1 Introduzione 5
2 Scenario 7
2.1 Scopo del progetto . . . . . . . . . . . . . . . . . . . . . . 7
2.2 Web Defacement . . . . . . . . . . . . . . . . . . . . . . . 7
2.2.1 Denzione e tipologia . . . . . . . . . . . . . . . . 7
2.2.2 Tipologie di attacchi . . . . . . . . . . . . . . . . . 9
2.2.3 Motivazioni . . . . . . . . . . . . . . . . . . . . . . 11
2.2.4 Statistiche sulla diusione . . . . . . . . . . . . . . 11
2.3 Struttura del progetto . . . . . . . . . . . . . . . . . . . . 13

3 Tecnologia e architettura 15
3.1 Tecnologie utilizzate . . . . . . . . . . . . . . . . . . . . . 15
3.1.1 Enterprise Java Beans . . . . . . . . . . . . . . . . 15
3.1.2 Java Persistence API . . . . . . . . . . . . . . . . . 16
3.1.3 Shoal . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.1.4 Ehcache . . . . . . . . . . . . . . . . . . . . . . . . 17
3.1.5 Implementazioni utilizzate . . . . . . . . . . . . . . 17
3.2 Entità utilizzate . . . . . . . . . . . . . . . . . . . . . . . . 17
3.3 Struttura del controllore . . . . . . . . . . . . . . . . . . . 18
3.3.1 Gestione delle istanze . . . . . . . . . . . . . . . . 18
3.3.2 Gestione degli utenti e dei proli . . . . . . . . . . 19
3.3.3 Gestione degli alert . . . . . . . . . . . . . . . . . . 19
3.3.4 Repair Thread . . . . . . . . . . . . . . . . . . . . 19

4 Funzionamento del controllore 21


4.1 Gestione delle istanze . . . . . . . . . . . . . . . . . . . . . 21
4.1.1 Istanza facente parte di un gruppo . . . . . . . . . 21
4.1.2 Istanza singola . . . . . . . . . . . . . . . . . . . . 22
4.1.3 Motivazioni della scelta . . . . . . . . . . . . . . . 22

1
INDICE 2

4.1.4 Informazioni a disposizione . . . . . . . . . . . . . 23


4.1.5 Aggiornamento elenco istanze . . . . . . . . . . . . 23
4.1.6 Gestione degli errori di connessione . . . . . . . . . 24
4.1.7 Indici di carico e prestazione . . . . . . . . . . . . 25
4.2 Gestione dei task . . . . . . . . . . . . . . . . . . . . . . . 25
4.2.1 Creazione del task . . . . . . . . . . . . . . . . . . 26
4.2.2 Terminazione del task . . . . . . . . . . . . . . . . 26
4.2.3 Checkpoint del task . . . . . . . . . . . . . . . . . 27
4.2.4 Modica del task . . . . . . . . . . . . . . . . . . . 27
4.2.5 Migrazione del task . . . . . . . . . . . . . . . . . . 27
4.2.6 Modalità di gestione delle properties dei task . . . 27
4.3 Utenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
4.4 Warden e Warden Prole . . . . . . . . . . . . . . . . . . 29
4.5 Alert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
4.5.1 Tipologie di alert . . . . . . . . . . . . . . . . . . . 31
4.5.2 Politica di fetch e dispatch . . . . . . . . . . . . . . 32
4.5.3 Sottoscrizione alle notiche . . . . . . . . . . . . . 34
4.6 Gestione degli snapshot . . . . . . . . . . . . . . . . . . . 35
4.7 Repair Thread . . . . . . . . . . . . . . . . . . . . . . . . 37
4.7.1 Importanza del repair thread . . . . . . . . . . . . 37
4.7.2 Algoritmo del Repair Thread . . . . . . . . . . . . 39
4.7.3 Processo del migration reapir . . . . . . . . . . . . 39
4.7.4 Selezione dell'istanza da controllare . . . . . . . . . 40

5 Implementazione del Controllore 43


5.1 Interfaccia programmatica . . . . . . . . . . . . . . . . . . 43
5.1.1 Modalità di comunicazione . . . . . . . . . . . . . 43
5.1.2 Informazioni esposte . . . . . . . . . . . . . . . . . 44
5.1.3 Metodi esposti . . . . . . . . . . . . . . . . . . . . 44
5.2 Task Periodici . . . . . . . . . . . . . . . . . . . . . . . . . 49
5.2.1 InstanceTimerBean . . . . . . . . . . . . . . . . . . 51
5.2.2 AlertTimerBean . . . . . . . . . . . . . . . . . . . 52
5.2.3 RepairThreadBean . . . . . . . . . . . . . . . . . . 52
5.3 MessageDriven Bean . . . . . . . . . . . . . . . . . . . . . 52
5.4 Diagramma delle classi . . . . . . . . . . . . . . . . . . . . 53
5.5 Console (GoldrakeShell) . . . . . . . . . . . . . . . . . . . 57
5.5.1 Comandi supportati . . . . . . . . . . . . . . . . . 57
5.6 Problemi incontrati e soluzioni adottate . . . . . . . . . . 59
5.6.1 Errori di connessione verso le istanze . . . . . . . . 59
5.6.2 Accesso a metodi di bean da parte di entity bean . 61
5.6.3 Utilizzo di shoal sul controllore . . . . . . . . . . . 62
3 INDICE

6 Conclusioni 63
6.1 Obiettivi raggiunti . . . . . . . . . . . . . . . . . . . . . . 63
6.2 Conclusioni soggettive . . . . . . . . . . . . . . . . . . . . 64
6.3 Sviluppo futuro . . . . . . . . . . . . . . . . . . . . . . . . 64

Appendices 67
A Congurazione di Glasssh 67
A.1 Risorse JDBC . . . . . . . . . . . . . . . . . . . . . . . . . 67
A.2 Risorse JMS . . . . . . . . . . . . . . . . . . . . . . . . . 67
A.3 Congurazione JavaMail . . . . . . . . . . . . . . . . . . . 68
A.4 Congurazione dell'ip di ascolto . . . . . . . . . . . . . . . 68
A.5 Backup della congurazione . . . . . . . . . . . . . . . . . 69

B Speciche e Requisiti 71
B.1 Requisiti Goldrake . . . . . . . . . . . . . . . . . . . . . . 71
B.1.1 Denizioni . . . . . . . . . . . . . . . . . . . . . . 71
B.1.2 Generale . . . . . . . . . . . . . . . . . . . . . . . 72
B.1.3 Scalabilità . . . . . . . . . . . . . . . . . . . . . . 72
B.1.4 Istanze . . . . . . . . . . . . . . . . . . . . . . . . 72
B.1.5 Controllore . . . . . . . . . . . . . . . . . . . . . . 73
B.1.6 Utenti . . . . . . . . . . . . . . . . . . . . . . . . . 74
B.1.7 Task . . . . . . . . . . . . . . . . . . . . . . . . . . 74
B.1.8 Task simulati . . . . . . . . . . . . . . . . . . . . . 77
B.1.9 Aggregator . . . . . . . . . . . . . . . . . . . . . . 77
B.1.10 Alert . . . . . . . . . . . . . . . . . . . . . . . . . 78
B.1.11 Alert e utenti . . . . . . . . . . . . . . . . . . . . . 78
B.1.12 Feedback degli utenti . . . . . . . . . . . . . . . . . 79
B.1.13 Interfaccia graca . . . . . . . . . . . . . . . . . . . 79
B.2 Speciche Goldrake . . . . . . . . . . . . . . . . . . . . . . 81
B.2.1 Generali . . . . . . . . . . . . . . . . . . . . . . . 81
B.2.2 Database del controllore . . . . . . . . . . . . . . 82
B.2.3 Controllore . . . . . . . . . . . . . . . . . . . . . . 85
B.2.4 Istanze . . . . . . . . . . . . . . . . . . . . . . . . . 87
Capitolo 1
Introduzione
L'impatto negativo che un defacement, cioè l'accesso non autorizzato e
la possibile conseguente modica di un sito internet, può avere su una
organizzazione è reso evidente dalla grande rilevanza del web nella vi-
ta quotidiana di imprese e persone. Il defacement consiste nella sosti-
tuzione della home page originale di un sito web con un contenuto arbi-
trario, molto spesso di rivendicazione o di propaganda politico/religiosa.
Questo viene fatto nella maggior parte dei casi per puro divertimento,
come dimostrano le indagini statistiche annuali di Zone-h, archivio on-
line di web-defacement. Recentemente questo tipo di attacchi è diventato
inoltre parte di una più ampia strategia volta alla realizzazione di true
on-line o phising.

Partendo da queste considerazioni si è cercato di sviluppare un sis-


tema capace di garantire un controllo, periodico ed automatizzato, di
siti remoti per poterne rilevare ed interpretare le modiche  sospette e
segnalarle in tempi rapidi agli amministratori.

Il progetto si inserisce in un contesto più ampio: si basa infatti sugli


algoritmi di anomaly detection, realizzati presso il laboratorio di  Reti
di calcolatori del DEEI Università di Trieste allo scopo di rilevare le
modiche sospette nelle pagine analizzate. Vista la complessità, alla
realizzazione di questo sistema hanno collaborato ben tre tesisti. Si è
pertanto suddiviso il lavoro in tre componenti: controllore centrale, nodi
di elaborazione, interfaccia utente.
Obiettivo della presente tesi sono stati la progettazione e lo sviluppo
del controllore e cioè la componente deputata a:

• controllare lo stato dei vari nodi di elaborazione coinvolti; questi


possono essere in numero variabile, da poche unità a varie decine,
e lavorano in maniera indipendente, coordinati dal controllore

5
1. Introduzione 6

• suddividere il lavoro fra essi

• reperire le informazioni relative al monitoraggio da trasmettere agli


utenti

• far interagire l'interfaccia utente con l'insieme dei nodi di elabo-


razione

Il sistema è stato realizzato, secondo le speciche, su piattaforma


Java EE usando Glasssh v2 come application server e PostgreSQL come
motore database.
Capitolo 2
Scenario
2.1 Scopo del progetto
Questo progetto ha lo scopo di realizzare un'infrastruttura software in
grado di rilevare, in maniera automatica, attacchi informatici di tipo
 web defacement , segnalandone l'accaduto all'amministratore del sito.
Ciò consente di eettuare un intervento tempestivo sulla risorsa dan-
neggiata. L'importanza di correggere subito l'anomalia risulta evidente
se si pensa quanti e quali danni, economici e giuridici, la modica non
autorizzata di un sito possa causare.
Nello specico il software ha lo scopo di rilevare ed analizzare gli
attacchi dei malintenzionati, tramite il monitoraggio delle pagine web,
quindi analizzarli sfruttando algoritmi precedentemente sviluppati nel
laboratorio di  Reti di calcolatori del D.E.E.I.  Università di Trieste.
Tali informazioni vengono rese accessibili all'utente tramite un'inter-
faccia graca ricca ed intuitiva.

2.2 Web Defacement


2.2.1 Denzione e tipologia
Il web defacement ad un sito internet, che mira a modicare il suo aspet-
to esteriore, è un'azione compiuta solitamente da system crackers che,
ottenendo un accesso non autorizzato ad un server sostituiscono il sito
(o parti di esso) con una loro versione.
Le nalità che ci si pregge 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

7
2. Scenario 8

• Spamming: si inseriscono ben evidenti elementi pubblicitari, come


dei link a siti commerciali

• Avviso: si desidera per far notare al webmaster che il sito è vul-


nerabile ed è stato bucato

• Trua

Nei primi punti di questo elenco si parla di defacement nella sua ac-
cezione più classica ( defacement sostitutivo ), e cioè la sostituzione dei
contenuti originari del sito con testi e/o immagini di varia natura, con
l'obbiettivo di minare la credibilità del sito colpito, che dimostra così di
essere vulnerabile.

Figura 2.1: Esempio di defacement di tipo sostitutivo

L'ultimo punto identica invece i defacement additivi e cioè quelli


solitamente non visibili ai visitatori che si propongono quindi di non mod-
icare l'aspetto esteriore del sito ma di aggiungere delle parti nascoste,
con gli obiettivi più disparati: un defacement di questo tipo potrebbe
ad esempio far parte di una più ampia azione di phishing (cambiando
la pagina del sito in cui esiste il form per l'immissione di dati sensibili
con numero di carte di credito, reindirizzandola verso una pagina per-
sonale allo scopo di carpire le informazioni) o tentare di collaborare alla
diusione di malware.
9 Web Defacement

2.2.2 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, per le quali possiamo vedere nell'immagine 2.2 le
frequenze stimate di utilizzo (vedi [1]):

Figura 2.2: Tipologie di attacchi

• File inclusion (24%): si verica quando uno script richiede come


parametro il nome di un le 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 materi-
ale illecito all'interno di server non protetti in maniera adeguata
per 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 trascu-
rano le più elementari norme di sicurezza. Accade così che pro-
2. Scenario 10

grammatori sbadati si dimentichino di vericare le credenziali di


accesso all'interno di tutte le pagine che dovrebbero essere protette,
oppure semplichino 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 `sniare' il traco 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 pro-


grammazione esistenti all'interno delle applicazioni server, cercan-
do solitamente di ottenere privilegi superiori a quelli che eettiva-
mente 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 verica di credenziali basata sul fatto che la seguente
query ritorni almeno una tupla

1 SELECT * FROM tblUsers WHERE password=passedPassword

E' però possibile che un utente malintenzionato digiti come pass-


word del codice sql del tipo

1 ’pippo’ or 1=1

poichè la seconda condizione si verica sempre, la query ritornerà


tutte le tuple del database e l'attaccante avrà libero accesso al sito
attaccato.

• Man in the Middle (4%): eettivamente è una strategia molto dif-


cile da attuare. Richiede infatti un discreto accesso alle risorse di
rete della macchina server o di chi vi si collega come amministra-
tore, ma diventa banalmente applicabile all'interno di grosse reti
aziendali.

• DNS poisoning (2%): ancor più dicile del Man in the Middle,
è comunque una strada a volte percorribile; lo si eettua convin-
cendo un DNS ad indirizzare i richiedenti la pagina attaccata ver-
so un indirizzo IP diverso da quello lecitamente registrato. Per
la denizione data tale operazione non è propriamente un deface-
ment, in accordo con quanto stabilito dagli stessi gestori di Zone-H
(i quali, comunque, tempo fa sono stati soggetti ad un attacco di
questo tipo. . . ).
11 Web Defacement

2.2.3 Motivazioni
Zone-H è un web site nato nel 2002 come un semplice mirror per i deface-
ment rilevati, nel tempo ha aumentato le sue funzionalità, diventando
punto di riferimento mondiale per tale tipologia di crimine informati-
co. Ogni anno pubblica delle statistiche sull'evoluzione dei defacement
fornendo dati utili sia a livello tecnico, sia per indagare l'aspetto cul-
turale del fenomeno; interessante ad esempio è analizzare quali siano le
motivazioni che portano alla realizzazione di defacement.

Come si può notare dal graco il puro divertimento (inteso anche


come sda, 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.

Figura 2.3: Motivazioni degli hack

2.2.4 Statistiche sulla diusione


2.2.4.1 Numero di defacement

Come sopra accennato, Zone-H è una strumento molto utile per analiz-
zare, l'evoluzione del fenomeno defacement. Attraverso i suoi resocon-
ti annuali è possibile ottenere delle statistiche sull'evoluzione di questo
fenomeno che fanno capire come il suo rilievo sia in costante crescita.
2. Scenario 12

Figura 2.4: Andamento dei defacemente rilevati dal 2000 al 2005

2.2.4.2 Tempo di reazione

Un ulteriore dato di analisi interessante riguarda la durata di un deface-


ment.

Un defacement risulta essere un evento molto grave per un web site


e i suoi amministratori, ma la sua gravità e le possibili ricadute au-
mentano notevolmente con l'aumentare del tempo necessario perché gli
amministratori prendano provvedimenti; nell'analisi compiuta [2] si è po-
tuto rilevare come su 62000 defacement monitorati la velocità di reazione
fosse davvero bassa.

L'analisi dei 62000 defacement rilevati da zone-h in 49 giorni cor-


risponde 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ò vericare 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 gura 2.5. 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.
13 Struttura del progetto

Figura 2.5: Tempo di reazione ad un defacement

2.3 Struttura del progetto


Il progetto ha come nalità quello 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.

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 eettivamente pub-
blicato. In una fase preliminare la risorsa viene monitorata da sensori
appositamente studiati, capaci di ottenere un prolo attraverso una serie
di misure; al termine di una fase iniziale di learning, è possibile moni-
torare tale risorsa e inviare un allarme nel caso in cui essa si allontani
dal prolo costruito.

Tali algoritmi di controllo sono implementati all'interno del nodo di


calcolo (istanza) che si occupa di prelevare le risorse da monitorare e
utilizzarle per la generazione del prolo.

Le parti che compongono questo progetto possono essere così sinte-


tizzate:

1. Nodo di elaborazione (istanza)


2. Scenario 14

2. Controllore che coordina il lavoro di uno o più nodi di elaborazione


ed avvisare i proprietari dei siti web dei defacement rilevati

3. Interfaccia graca che permette agli utenti, essenzialmente i pro-


prietari dei siti web e gli amministratori di questo progetto, di
colloquiare con il controllore per ottenere informazioni sullo stato
delle risorse monitorate e per aggiungere nuovi siti da controllare

Figura 2.6: Struttura del progetto


Capitolo 3
Tecnologia e architettura
3.1 Tecnologie utilizzate
Per sviluppare questo progetto sono state impiegate alcune tecnologie
software che ne facilitano lo sviluppo; qui di seguito vengono elencate,
spiegandone l'utilità.

3.1.1 Enterprise Java Beans


Gli Enterprise Java Beans (EJB) sono una tecnologia standard che per-
mette di sviluppare la business logic di un programma all'interno del-
l'architettura Java EE delegando la responsabilità di fornire alcune fun-
zionalità comuni all'application server, cioè il programma responsabile
dell'esecuzione degli EJB. Le speciche per gli EJB deniscono diverse
proprietà che questi devono rispettare, tra cui la persistenza, il sup-
porto alle transazioni, la gestione della concorrenza e della sicurezza e
l'integrazione con altre tecnologie, come JMS, JNDI, e CORBA.
Le speciche EJB intendono fornire una metodologia standard per
implementare la logica di funzionamento delle applicazioni di tipo en-
terprise, per realizzare applicazioni di questo tipo è necessario arontare
una serie di problematiche tecniche che possono rivelarsi molto comp-
lesse e laboriose da risolvere. Gli Enterprise JavaBean intendono fornire
una soluzione a questi problemi in modo da semplicare lo sviluppo di
questo tipo di applicazioni.
Le speciche EJB descrivono in dettaglio come realizzare un applica-
tion server che fornisca le seguenti funzionalità: persistenza, elaborazione
delle transazioni, controllo della concorrenzialità, programmazione ad
eventi tramite il Java Message Service, servizio di directory per elencare
e nominare gli EJB (JNDI), invocazione di procedure remote.

15
3. Tecnologia e architettura 16

Inoltre le speciche deniscono il ruolo del contenitore di Enterprise


JavaBean e di come far comunicare il contenitore con gli EJB.
Esistono tre tipi di Enterprise JavaBean:

• EJB di Entità (Entity EJB): il suo scopo è di inglobare gli oggetti


sul lato server che memorizzano i dati. Gli entity bean forniscono
la caratteristica della persistenza dei dati (persistenza gestita dal
contenitore o persistenza gestita dal bean)

• EJB di sessione (Session EJB): gestiscono l'elaborazione delle infor-


mazioni sul server. Generalmente sono una interfaccia tra i client
e i servizi oerti dai componenti disponibili sul server. Ne esistono
di due tipi:

≻ con stato (stateful). I bean di sessione con stato sono oggetti


distribuiti che posseggono uno stato. Lo stato non è persis-
tente, però l'accesso al bean è limitato ad un unico client.

≻ senza stato (stateless). I bean di sessione senza stato sono


oggetti distribuiti senza uno stato associato, questa caratter-
istica permette un accesso concorrente alle funzionalità oerte
dal bean. Non è garantito che il contenuto delle variabili di
istanza si conservi tra diverse chiamate ai metodi del bean.

• EJB guidati da messaggi (Message driven EJBs): sono gli uni-


ci bean con funzionamento asincrono. Tramite il Java Message
Service (JMS), si iscrivono a un argomento (topic) o a una co-
da (queue) e si attivano alla ricezione di un messaggio inviato
all'argomento o alla coda a cui sono iscritti, non richiedono una
istanziazione da parte dei client.

3.1.2 Java Persistence API


La Java Persistence API (JPA) è un framework che permette la gestione
dati su un database relazionale tramite l'utilizzo di normali oggetti java.
All'interno di questo progetto JPA è stato utilizzato per il salvataggio di
tutte le informazioni necessarie all'analisi delle pagine Web

3.1.3 Shoal
Shaol è un framework Java open source per il clustering, può essere
utilizzato per aggiungere ad un sistema esistente funzionalità di load
balancing e fault tolerance; le applicazioni che usano Shoal possono con-
dividere dati, comunicare attraverso messaggi con altri nodi e noticare
17 Entità utilizzate

eventi importanti come l'unione, lo spegnimento e il fallimento di uno


dei nodi.
Questo framework viene utilizzato dal progetto glasssh (vedi 3.1.5)
per implementare il clustering del suo application server, uno dei beneci
dati dall'utilizzo di shoal è che vengono astratti tutti i dettagli realtivi
alla rete e alle modalità di comunicazione su di essa (in realtà shoal
utilizza JXTA per la comunicazione peer-to-peer). Shoal può poi essere
usato sia in applicazione Java EE sia in applicazione Java SE.
L'uso di questo strumento nel nostro ambito permette a più istanze di
comunicare tra loro in maniera automatizzata dati condivisi, la notica
dell'aggiunta o della rimozione di un altro nodo di elaborazione (a causa
di uno spegnimento o di un guasto).
Vedi https://shoal.dev.java.net/

3.1.4 Ehcache
E' una libreria scritta in java utilizzata per realizzare il caching di oggetti,
utilizzabile in ambiente Java EE
Vedi http://ehcache.sourceforge.net/

3.1.5 Implementazioni utilizzate


Alcune di queste tecnologie, come ad esempio gli EJB, presentano delle
speciche che possono essere implementate da più programmi diversi,
permettendo quindi una scelta tra alternative più o meno compatibili
tra loro, le implementazioni da noi scelte ed utilizzate nel progetto sono
state:

1. Glasssh 2 (https://glasssh.dev.java.net/): Questo programma è


la reference implementation dello standard EJB e fornisce, tramite
l'inclusione al suo interno di Toplink Essentials, anche il supporto
a JPA.

2. PostgreSQL (http://www.postgresql.org/) : Per la gestione dei dati


è stato scelto l'utilizzo di questo database relazionale, anche se,
grazie all'uso di JPA, il codice dell'applicativo sviluppato è del
tutto indipendente dalla scelta del DBMS.

3.2 Entità utilizzate


Per meglio comprendere le componenti del sistema che saranno spiegate
è necessario chiarire quali siano le entità che entrano in gioco e quale sia
il loro signicato.
3. Tecnologia e architettura 18

• Task: processo di monitoraggio di una risorsa, ogni Task appartiene


esattamente ad un Warden

• Risorsa: pagina web visualizzabile in un browser, ogni risorsa è


associata a 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

• WardenProle: elementi che deniscono la QoS del Warden, ogni


Warden ha esattamente un WardenProle e questo è immutabile

• Task: processo di monitoraggio di una risorsa. Ogni Task appar-


tiene esattamente ad un Warden

• Snapshot: istantanea di una risorsa ad un dato istante

• Aggregator: algoritmo per catalogare i reading in normali o anoma-


li

3.3 Struttura del controllore


La parte del progetto di cui si occupa questa tesi è la progettazione e
l'implementazione dell'infrastruttura di controllo (il controllore); anal-
izzerò quindi in maniera più dettagliata quali siano le attività principali
che sono a lui demandate.
Per capire quanto segue è utile analizzare quale sia la scalabilità con
cui è stato progettato questo sistema:

1. Istanze: alcune centinaia

2. Risorse: migliaia o poche decine di migliaia per istanza, in dipen-


denza della potenza dell'istanza.

3. Warden: migliaia (spiegato meglio in seguito)

3.3.1 Gestione delle istanze


Il controllore è l'unico elemento del sistema che possiede nozione di tutte
le istanze che collaborano allo svolgimento del monitoring; deve quindi
poter conoscere in ogni momento il loro stato di salute il carico di lavoro
a cui sono sottoposte, lo spazio ancora disponibile sulla loro memoria
secondaria.
Il controllore è l'unica modalità di interazione fra gli utenti e le is-
tanze, le quali possono essere comandate solo attraverso il controllore
19 Struttura del controllore

stesso, anche interfaccia graca (che è uno dei due moduli del control-
lore) non può colloquiare direttamente con le istanze ma solo attraverso
la sua mediazione.

3.3.2 Gestione degli utenti e dei proli


E' demandata al controllore la gestione degli utenti, suddivisi in varie
tipologie e dei proli associati a tali utenti che deniscono quali siano le
tipologie e la quantità di task creabili, e la tipologia di allarmi ricevibili.

3.3.3 Gestione degli alert


E' responsabilità del controllore il reperimento da ogni istanza degli even-
tuali alert relativi a situazioni anomale sui siti monitorati e conseguente-
mente l'invio di questi verso gli utenti responsabili.
Gli alert possono essere di due macro tipologie

• alert che riguardano i siti sottoposti a monitoring (task)

• alert che riguardano lo stato / problemi di esecuzione dell'istanza


stessa

3.3.4 Repair Thread


Il controllore deve garantire la coerenza fra le informazioni presenti sul
suo database locale e quello distribuito sui vari nodi. Questa funzione è
demandata al repair thread.
In particolare, quando si eseguono operazioni che coinvolgono più
database (ad esempio db del controllore e db dell'istanza oppure db del
controllore più i db di due istanze), invece di fare una transazione dis-
tribuita si procede in modo ottimistico, facendo in modo che ogni singolo
database sia integro (transazioni indipendenti non distribuire), e poi la
coerenza tra database si verica in background, attraverso il controllo
periodico eettuato dal repair thread.
Capitolo 4
Funzionamento del
controllore
Verranno ora analizzati nel dettaglio i vari elementi che vengono gestiti
direttamente dal controllore:

Preventivamente all'analisi dei vari componenti è necessario denire


quello che è stato l'approccio di fondo seguito nella progettazione di tutto
il sistema: ogni istanza opera esclusivamente da server, ciò implica che
un'istanza non può invocare operazioni di altre istanze e un'istanza non
può nemmeno invocare operazioni sul controllore.

Quindi tutti i dati necessario all'attività del controllore forniti dalle


varie istanze sono reperiti attraverso un processo di polling costante da
parte del controllore

4.1 Gestione delle istanze


Con il termine istanza si intende il nodo di elaborazione che si occupa di
eettuare il download delle pagine dei siti monitorizzati, di analizzarle e
di fornire quindi l'output generato dai sensori.

Ogni istanza è identicata univocamente da una uri, convenzional-


mente di questo tipo lsdd:NomeIstanza.
Esistono due tipologie di istanza:

4.1.1 Istanza facente parte di un gruppo


Un gruppo di istanze è un insieme di nodi caratterizzati dalla presen-
za nella stessa struttura sica (dipartimento, datacenter, laboratorio)
che quindi condividono la medesima connettività e risultano essere as-

21
4. Funzionamento del controllore 22

similabili per caratteristiche che sono gestite in modo unitario (istanze


attive/non attive, indici di carico, migrazione di task tra istanze).

L'implementazione del gruppo si basa su shoal che, come spiegato in


precedenza, è un framework di clustering che fornisce due caratteristiche
di grande utilità: la notica di join o leave al gruppo e la cache condivisa.
Grazie a queste due caratteristiche è infatti possibile che:

1. ogni nodo, facente parte dello stesso gruppo shoal, riceva le noti-
che di join e leave (concretamente accensione e spegnimento, o
in caso guasto) in modo da mantenere una lista dei nodi operativi
costantemente aggiornata

2. vengono propagate all'interno del gruppo le informazioni relative


agli indici di carico e di prestazione di ognuna delle istanze, at-
travero il sistema della cache condivisa

4.1.2 Istanza singola


Una istanza singola identica invece un singolo calcolatore (dal super-
computer alla semplice workstation) che può risiedere in una qualsiasi
locazione raggiungibile dal controllore e che entra a far parte dei nodi di
elaborazione in maniera totalmente autonoma.

Un nodo singolo non ha necessità di implementare l'infrastruttura di


clustering e le informazioni in suo possesso sono solo quelle relative al
suo stato interno.

4.1.3 Motivazioni della scelta


L'eettiva utilità di queste due tipologie risulta abbastanza chiara, per-
mette infatti in fase di test di utilizzare pochi nodi conosciuti e di cui è
ben noto lo stato, mentre in fase di produzione sarà possibile assegnare
i lavori ad un altissimo numero di nodi, lasciando al sistema le scelta
del nodo da utilizzare e la scoperta di nuovi nodi disponibili in maniera
totalmente trasparente.

In secondo luogo sarà possibile utilizzare anche calcolatori non di-


rettamente sotto il proprio controllo, ad esempio in atto, e quindi
non inseribili in una struttura controllata, come quella necessaria per
un insieme di istanze clusterizzate .

La possibilità poi di gestire più gruppi di istanze permette anche di


raggruppare i calcolatori a disposizione secondo ben determinati criteri,
permettendo così di distribuire i lavori seguendo politiche più articolate.
23 Gestione delle istanze

4.1.4 Informazioni a disposizione


Ovviamente ogni denizione di istanza sul controllore ha bisogno di al-
cune informazioni che permettono di individuarla, contattarla e gestirla
nel migliore dei modi; alcune di queste informazioni sono comuni ad ogni
tipo di istanza, mentre altre sono speciche per le istanze singole e di
gruppo.
Le informazioni comuni sono:

• URI: permette di identicare univocamente l'istanza

• IP: indirizzo ip o nome dns che permette di contattare l'istanza

• Port: porta alla quale l'istanza risponde

• Status: lo stato dell'istanza (active o halted)

• Number of failure: numero dei tentativi di connessione con l'istanza


che non hanno dato un buon esito, utile come vedremo in seguito
per la politica di gestione del fallimento dell'istanza

• Indici di carico: gli indici che permettono di conoscere quale sia lo


stato di attività di un'istanza (usato per selezionare quella su cui
avviare i prossimi lavori)

• Data degli ultimi alert ricevuti: per ogni istanza viene memorizzata
la data dell'ultimo allarme ricevuto di ogni tipologia. Sarà poi
utilizzata per il reperimento dei successivi alert.

• Data dell'ultima esecuzione del repair thread

Ci sono invece alcuni dati che sono caratteristici di ogni tipo di istanza:
Per quanto riguarda l'istanza singola semplicemente uno username e
una password che possono venire utilizzati per fare in modo che il con-
trollore si autentichi sul nodo, evitando così collegamenti non autorizzati
(attualmente non implementato).
Per quanto riguarda l'istanza facente parte di un gruppo invece ven-
gono solamente fornite le cosiddette informazioni di bootstrap, e cioè
l'indirizzo ip e la porta di un nodo sicuramente attivo da usare come
punto di partenza, oltre a questo vengono fornite anche qui una coppia
username e password (in questo caso condivise a livello di gruppo) per
autenticare il controllore su ogni singola istanza.

4.1.5 Aggiornamento elenco istanze


Il controllo ovviamente riguarda solo le istanze facenti parte di un grup-
po, visto che le istanze singole si assumono attive nchè non avviene un
fallimento durante una connessione.
4. Funzionamento del controllore 24

Bisogna fare una distinzione riguardo al momento in cui avviene


questo aggiornamento: in fase di boot, di reboot o di normale esecuzione.
Nella fase di boot il controllore cerca di contattare lo starting node, cioè
il nodo associato alla denizione del gruppo e che si reputa quindi sicu-
ramente disponibile, da questo si cerca quindi di reperire la lista dei nodi
attivi a lui noti e di registrarli sul controllore.
In fase di reboot, o durante la normale esecuzione del controllore
avviene un controllo periodico, comandato da un timer congurabile,
che contatta uno dei nodi attivi (selezionato a caso) di ogni gruppo, da
questo riceve la lista delle istanze attive che viene confrontata con quella
presente sul controllore, vengono così apportate le opportune modiche.
La lista delle istanze attive viene generata in automatico da ogni nodo
attraverso shoal; ogni istanza rimane in ascolto degli eventi noticati da
shoal relativi all'intero gruppo. Il sistema è stato così realizzato per
evitare di inserire il controllore fra i membri del gruppo shoal (problema
spiegato in maggior dettaglio nella sezione 5.6.3 nella pagina 62)

4.1.6 Gestione degli errori di connessione


Uno degli aspetti più critici riguarda la gestione degli errori di connes-
sione, quando si cerca di contattare un'istanza e questa non risponde,
può essere dovuto ad un errore momentaneo, ad un problema di connes-
sione non permanente o, nei casi peggiori, ad una vero e proprio falli-
mento dell'istanza stessa. Per questo motivo si è adottata la seguente
procedura:
Durante il collegamento con una istanza vengono eettuati sequen-
zialmente tre tentativi di connessione, se tutti questi tre tentativi avessero
dato esito negativo viene incrementato un contatore globale dei fallimen-
ti relativo all'istanza. Quando questo contatore risulta maggiore di un
parametro congurabile (di default 3) l'istanza viene reputata compro-
messa e quindi contrassegnata come stato halted, e non più utilizzata
per l'avvio di nuovi lavori e la ricezione degli alert.
Se in un qualsiasi momento, precedente al raggiungimento del nu-
mero limite di fallimenti, l'istanza risulta nuovamente raggiungibile viene
azzerato il contatore globale e tutto procede normalmente.
Ovviamente tale approccio è uguale sia per i gruppi di istanze che
per le istanze singole, la dierenza sostanziale risiede nella modalità di
riattivazione dell'istanza:
Nel caso di istanza facente parte di un gruppo si attende che l'is-
tanza fallita ritorni disponibile e la sua presenza venga quindi noti-
cata alle istanze compagne, che poi la comunicheranno al controllore
una volta interpellate, nel caso invece di istanza singola verrà eettuato
periodicamente un tentativo di connessione manuale.
25 Gestione dei task

4.1.7 Indici di carico e prestazione


Ogni istanza mantiene dinamicamente due indici di carico, il cui signi-
cato è uniforme sulle diverse istanze e permette di valutare la potenza di
calcolo attualmente utilizzata e la percentuale della memoria secondaria
in uso.
Questi sono i due elementi che permettono di decidere quale sia il no-
do da selezionare per l'esecuzione dei prossimi task. Il loro reperimento
da parte del controllore avviene periodicamente, contestualmente con il
controllo dell'esistenza di nuovi nodi nei gruppi di istanza o contestual-
mente al tentativo di riconnessione con un nodo considerato compromes-
so.
Ogni nodo memorizza i propri indici di carico e prestazione nella
cache distribuita (fornita dal sistema di clustering) condivisa a livello di
gruppo di istanze, e fornisce due metodi per reperirli, uno che li fornisce
in base all'istanza selezionata e l'altro che fornisce tutti gli indici di tutte
le istanze note. Questo è possibile appunto perchè il nodo leggendo e
scrivendo sulla cache distribuita ha accesso agli indici di tutte le istanze
del suo stesso gruppo, quindi ogni istanza facente parte del gruppo è un
punto d'accesso valido per ottenere i dati di tutti i nodi.

4.2 Gestione dei task


Centrali nell'attività del controllore sono le operazioni sui task, nella
fattispecie la possibilità di creare, modicare, fare il checkpoint e migrare
uno o più task,
Il task, è l'unità base di lavoro presente su di una istanza, indica
quale sia la risorsa da monitorare e con quali parametri.
Esistono due rappresentazioni del task dierenti, una per l'istanza e
una per il controllore, vista la necessità di gestire informazioni dierenti,
elemento comune però è l'id che permette di identicare univocamente
il medesimo task sull'istanza e sul controllore.
Un oggetto task sul controllore è caratterizzato da questi elementi:

• Id: identica univocamente il task nel sistema

• Url: indirizzo da monitorare

• Sampling period: periodo di campionamento

• Instance: istanza su cui il task è in esecuzione

• Last instance: informazioni relative all'istanza precedente su cui


risiedeva il task (nel caso di migrazione avvenuta)
4. Funzionamento del controllore 26

• Last alert date: informazioni relative alla data degli ultimi alert di
entrambi i tipi rilevati (network e content)

• Active: permette di sapere se il task è attualmente attivo o meno

• Properties: permette di estendere le caratteristiche di base del task


inserendo proprietà aggiuntive, non previste inizialmente

E' interessante notare che l'id del task non identica il task univocamente
solo nel database del controllore, ma sull'intero sistema (controllore e
istanze) per fare questo bisogna garantire che i task creati sull'istanza
utilizzino il medesimo id del controllore per evitare situazioni di conitto.
Gli attributi di un task sono immutabili, qualora sorgesse la neces-
sità di variare alcuni attributi di un task (ad esempio il sampling period),
occorre terminare il task e crearne un altro con valori opportuni per gli
attributi.

4.2.1 Creazione del task


Per eettuare la creazione di un task devono essere forniti alcuni parametri,
nella fattispecie l'url da monitorare, il sampling period, il set di aggrega-
tori da utilizzare (non ancora implementato); questi ultimi due parametri
possono variare in un range di valori denito dal warden prole. Deve
essere anche indicato su quale warden si vuole che il task venga creato.
La creazione del task avviene in due momenti: per prima cosa viene
creato l'oggetto sul controllore, con contestuale denizione dell'indice
univoco, questo poi viene passato in blocco all'istanza selezionata per
l'esecuzione che avvierà il monitoring.
Il task risulterà appartenente ad uno dei warden associati all'utente
che sta eettuando le operazioni.
La creazione di un task può avvenire anche in maniera automatizzata,
fornendo una lista di url da monitorare, un sampling period applicato ad
ognuno di questi task ed il warden sul quale creare questi task.

4.2.2 Terminazione del task


Il controllore invoca la terminazione di un task sull'istanza che ne sta
curando l'esecuzione. Una volta terminata l'esecuzione sull'istanza anche
il controllore aggiorna lo stato del proprio oggetto catalogandolo come
terminato. Come sopra accennato, lo stato di un task è immodicabile,
quindi la terminazione è un'azione non annullabile; l'unico modo per
riprendere l'esecuzione è la creazione di un nuovo task con i medesimi
parametri.
27 Gestione dei task

4.2.3 Checkpoint del task


Il checkpoint è la terminazione di un task e la creazione di un task del
tutto identico a quello precedente; può servire per contenere le dimensioni
dei dati e per facilitare l'esecuzione di task simulati.

4.2.4 Modica del task


Vista l'immutabilità del task, in caso di modica, questo viene terminato
e ne viene creato un altro del tutto identico al precedente, permettendo
di modicare alcuni attributi selezionati.

4.2.5 Migrazione del task


Con migrazione di un task, si intende il suo spostamento da un'istanza
di esecuzione ad un'altra. Questo può avvenire per varie ragioni: per
prestazioni, cioè il task può essere forzato a migrare su un'altra istanza;
quando l'indice di carico dell'istanza su cui risiede diventa "eccessivo",
la migrazione può avvenire anche per fault-tolerance, cioè nel caso in cui
un'istanza sia considerata compromessa poiché non più raggiungibile, il
task viene quindi costretto a migrare su di una istanza attiva.
La migrazione viene realizzata però in modo tale che sia possibile
ricostruire la storia del task, cioè risalire alle varie istanze che nel corso
del tempo lo hanno ospitato e che quindi contengono informazioni su
di lui. Ogni task sull'istanza possiede due informazioni fondamentali
per realizzare ciò: linkFrom (l'istanza da cui il task proviene), linkTo
(l'istanza verso cui il task è stato migrato). Quindi la migrazione di un
task avviene attraverso alcuni passi:

1. Sul controllore viene selezionato il task da migrare

2. Sull'istanza di destinazione viene creato il task

3. Sull'istanza di provenienza viene fermato il task e impostata la


proprietà linkTo

4. Sull'istanza di destinazione viene impostata la proprietà linkFrom

5. Sul controllore viene aggiornata l'informazione relativa all'istanza


su cui è in esecuzione il task

4.2.6 Modalità di gestione delle properties dei task


Le property aggiuntive dei task sono una tipologia particolare di dato,
queste infatti possono essere aggiornate sia dal lato controllore sia dal
4. Funzionamento del controllore 28

lato istanza (ad esempio un'istanza può decidere che sia preferibile uti-
lizzare un certo algoritmo di rendering per la generazione dei thumbnail
della pagina e quindi salvare tale congurazione fra le proprietà aggiun-
tive) . Questa possibilità di modica delle informazioni da ambo i lati
rende più complicata la gestione dell'aggiornamento dei dati, si è scelto
quindi di procedere in questo modo:

• le property nel momento in cui vengono richieste dall'utente ven-


gono caricate direttamente dall'istanza in cui è presente il task

• quando si cerca di impostare il valore di una property viene per


prima cosa interrogata l'istanza su cui risiede il task

≻ se il valore della property sull'istanza è variato da quello noto


al controllore viene lanciata un'eccezione

≻ se il valore della property sull'istanza è il medesimo noto al


controllore il valore viene cambiato (prima sull'istanza e poi
sul controllore)

Bisogna notare che le property del task vengono caricate dall'istanza solo
alla prima richiesta di visualizzazione da parte del client, per limitare le
connessioni superue verso le istanze

4.3 Utenti
Gli utenti sono un elemento noto solamente al controllore, le istanza lo
ignorano completamente, quindi l'associazione task-utente, o più corret-
tamente task-warden-utente (come sarà meglio esplicitato in seguito) è
mantenuta dal controllore.

Il sistema realizzato contempla tre tipologie di utenti:

1. Administrator: sono gli amministratori del progetto e hanno ac-


cesso a tutte le risorse

2. Customer user: sono gli utenti nali del sistema, decidono quali
risorse vogliono monitorare, con che frequenza, con che modalità e
di quali vogliono ricevere le notiche degli allarmi.

3. Customer administrator: sono dei clienti intermedi, coloro con i


quali gli utenti nali interagiscono per aquisire i loro warden (slot
di monitoring)
29 Warden e Warden Prole

4.4 Warden e Warden Prole


Per prima cosa è opportuna capire cosa si intende con questi due termini.
Il warden è l'unità aquistabile da un utente che gli permette di moni-
torare, secondo certi criteri, un numero massimo di risorse; la modalità
con cui questo monitoring può avvenire è denito invece dal warden
prole. Un utente non può monitorare alcuna risorsa se non ha a sua
disposizione un warden, a cui associare i task, che abbia ancora risorse
disponibili.
Il warden prole contiene queste informazioni:

• Sampling period minimo: il minimo periodo di campionamento con


cui possono essere creati i task

• Massimo numero di task: il numero massimo di task creabili

• Modalità di invio alert disponibili: le modalità con cui gli alert


rilevati possono essere inviati agli utenti interessati

Ogni warden invece possiede al suo interno:

• Un riferimento ad un warden prole, che ne denisce le caratteris-


tiche

• Un riferimento ad un utente che ne è proprietario

• Un riferimento ad un warden parent

• La lista dei task avviati

Fra i warden esiste una relazione di parentela, infatti ogni warden deve
possedere un riferimento ad un altro warden (detto parent), mentre quel-
li che non possiedono un tale riferimento vengono detti root-warden,
i warden invece che sono collegati ad un root-warden vengono detti
warden-sons.

Figura 4.1: Schema della gerarchia dei warden


4. Funzionamento del controllore 30

I root-warden sono solo dei contenitori per i sotto-warden e quindi


vengono utilizzati per ripartire fra utenti dierenti le risorse presenti in
un warden principale. Un root-warden non potrà quindi possedere task,
ma potrà solo avere tanti warden-sons, nchè la somma dei task permes-
si dai proli dei waren-sons eguaglino la dimensione del root-warden. Un
warden-root può essere assegnato solamente ad un customer-administrator
perchè una ulteriore espansione di questa gerarchia è impossibile, visto
che un warden non può essere contemporaneamente di ambo le tipologie
root e son.
Nell'esempio riportato in gura ipotizziamo che la struttura dei War-
den Prole sia questa:

Nome Max Task # Min Sampling Period Notication Type

WP Big 30 15 mail
WP Little1 20 20 mail
WP Little2 10 20 mail
WP Little3 10 10 mail
WP Little4 10 20 mail, sms

Tabella 4.1: Esempio di warden prole

Figura 4.2: Esempio di gerarchia di warden e associazioni con i proli

In questo caso sarà possibile avere due Warden-Son, legati al WP


Little 2, e un Warden-Son legato al WP Little 1, non sarebbe possibile
il contrario. Sarà parimenti impossibile utilizzare per i due warden-son
il prole Little3 al posto del Little2, visto che, pur possedendo lo stesso
numero massimo di task creabili, è caratterizzato da un sampling period
minore di quello del root-warden. Anche il prole Little4 non sarebbe
in questo caso utilizzabile poichè, pur soddisfacendo i requisiti a livello
di tasks number e sampling period, permetterebbe di creare delle alert
notication non permesse dal root-warden.
31 Alert

L'utilità concreta di una strutturazione di questo tipo è la possibilità


da parte di un potenziale cliente di rivendere porzioni del warden, da
lui stesso acquistato ai suoi rispettivi clienti; in questa ottica risulta
quindi anche chiaro il perchè esistano oltre ai customer users (utenti
nali) anche dei customer administrator che sono appunto dei clienti
intermedi che rivendono porzioni di warden.
Per realizzare questa strategia viene esposto un metodo che partendo
dal root-warden, dal warden prole desiderato e da un customer user
controlla la coerenza delle informazioni di prolo e in caso aermativo
crea un nuovo warden associato all'utente indicato.
La relazione che lega quindi ogni warden con il suo prolo è di tipo
uno a uno, qualsiasi sia il tipo di warden in analisi, ogni utente invece
può possedere un numero potenzialmente illimitato di warden.

4.5 Alert
Elemento fondamentale del sistema è l'alert; l'obiettivo di fondo del sis-
tema è la corretta generazione ed invio di alert che permettono di venire
a conoscenza di situazioni anomale e consentono all'utente di prendere
gli opportuni provvedimenti.

4.5.1 Tipologie di alert


Gli alert sono generati delle istanze, quando vengono rilevate condizioni
anomale, e possono essere di tre tipologie:

Network alert Questo alert indica un problema durante il download


di una pagina web; ad esempio l'impossibilità di contattare il server
remoto, o un errore HTTP restituito dal server (errori di tipo 400 e 500)
Le informazioni contenute sono: la data dell'errore, il messaggio di errore
stesso, il task che l'ha generato, lo snapshot dello stato della risorsa nel
momento in cui è stato generato l'errore (in questo, caso a seconda del
tipo di errore, l'istantanea della pagina potrebbe essere assente del tutto)
e l'identicativo dell'istanza su cui tale errore è stato generato.

Content alert Questo alert viene invece generato quando l'istanza cat-
aloga un reading come anomalo, cosa che potrebbe indicare un deface-
ment. Le informazioni contenute sono: la data dell'errore, il messaggio
di errore stesso, il task che l'ha generato, lo snapshot dello stato del-
la risorsa nel momento in cui è stato generato l'errore e l'identicativo
dell'istanza su cui tale errore è stato generato.
4. Funzionamento del controllore 32

Instance alert Questo alert riguarda invece degli errori dovuti, non alle
risorse monitorate, ma allo stesso nodo di elaborazione; per ora l'unico
tipo di alert che può essere inviato riguarda l'incapacità di eseguire l'anal-
isi di una risorsa, secondo la cadenza prevista, dovuto, ad esempio, ad un
sovraccarico dell'istanza stessa. Le informazioni qui contenute sono: la
data dell'errore, il messaggio di errore stesso e l'identicativo dell'istanza
su cui tale errore è stato generato.
Queste tipologie di alert possono venire immediatamente divise in due
gruppi: quelle di pertinenza degli utenti nali (user customer o customer
administrator che siano) e quelle di pertinenza degli amministratori del
sistema; risulta chiaro che gli alert di tipo network e content interessano
gli utenti nali, che possono recepire informazioni relative allo stato delle
risorse da loro monitorate, mentre gli alert di istanza sono di interesse
solo degli amministratori del sistema.

4.5.2 Politica di fetch e dispatch


Come precedentemente spiegato, la politica di fondo prevede che le is-
tanze non contattino mai il controllore, ma avvenga sempre il contrario;
ciò avviene anche per il controllo degli alert che, a cadenza periodica,
contattano le istanze e prelevano gli alert generati.
Un'istanza permette di reperire gli alert fornendo una data di parten-
za, cioè vengono forniti tutti gli alert generati da una certa data in
poi; questo permette di minimizzare il traco sulla rete. Risulta ovvio
che, per utilizzare un sistema di questo tipo, il controllore deve pot-
er memorizzare la data dell'ultimo alert ricevuto, per ogni tipologia,
in modo da richiedere solo quelli più nuovi e non ancora analizzati; per
questo, insieme alle altre informazioni tipiche dell'istanza, vengono anche
memorizzate le date degli ultimi content/network/instance alert ricevuti.
Oltre alle informazioni relative agli alert, sopra elencate (fornite di-
rettamente dalle istanze), ve ne sono alcune che vengono aggiunte dal
controllore per implementare le politiche di gestione interna; vengono
aggiunte tre informazioni sostanziali:

Pending Un alert viene considerato pendente no a quando l'utente re-


sponsabile del task associato non lo visualizza sull'interfaccia (ne prende
cioè atto e prende le opportune decisioni). Un alert, appena viene re-
cuperato dall'istanza da parte del controllore, risulta essere pendente e
permane in questo stato no ad un'azione dell'interfaccia utente

Notication date Inne la notication date serve per memorizzare,


nel caso in cui l'algortimo di dispatchment abbia ritenuto fosse il caso
33 Alert

di inviare un alert all'utente, la data e l'ora in cui tale alert è stato


eettivamente inoltrato.

Alert state L'alert, una volta recepito ed elaborato dall'algoritmo dal


controllore, può trovarsi in uno di questi stati:

NEW Quando l'alert è appena stato ricevuto dall'istanze ed è in


attesa di essere sottoposto all'algoritmo di dispatchment

PROCESSED Quando l'alert è stato correttamente processato dal-


l'algoritmo e non è stato ritenuto opportuno inoltrarlo all'utente (vedi
algoritmo spiegato nel prossimo paragrafo)

DISPATCHED Quando l'alert è stato analizzato dall'algoritmo e


questo ha ritenuto che le condizioni fossero tali da inoltrarlo all'utente.
Bisogna notare che quest'ultimo stato viene impostato sempre sia nel
caso in cui sia stata eettivamente inviata una notica (mail o sms) all'u-
tente, poichè esistono delle sottoscrizioni relative a questo task/istanza,
sia nel caso in cui non sia stato inviato nulla, non esistendo nessuna sot-
toscrizione legata a tale task/istanza. Quindi se fosse necessario reperire
l'elenco delle notiche eettivamente inviate sarebbe necessario utiliz-
zare entrambe le informaizoni state e notication date che permettono
appunto di selezionare solo gli alert inviati.
Questa scelta è stata adottata per rendere possibile la selezione di
tutti gli alert che sarebbero stati meritevoli di una notica a prescindere
dalle sottoscrizioni congurate, visto che l'algoritmo di dispatch si basa
appunto sul concetto di reading successivo e di alert pendente (non
ancora visualizzato/analizzato dall'utente responsabile.)

Algoritmo di dispatch Subito dopo la ricezione degli alert, di tutti tre


i tipi, da un'istanza da parte del controllore, questi vengono immediata-
mente elaborati dall'algoritmo di dispatchment che decide se sia il caso
o meno di inviarli all'utente. L'idea di fondo dell'algoritmo prevede che
deve essere noticato all'utente solo un alert, se è pending e se non è
corrispondente ad un altro pending alert (con corrispondente si intende
relativo allo stesso task e generato in due reading consecutivi).
L'algoritmo procede quindi in questo modo (come indicato in gu-
ra 4.3 nella pagina seguente): per prima cosa analizza solo e unicamente
gli alert ancora pendenti, ordinati per data di ricezione e raggruppati per
task, se un alert risulta essere il primo (quindi gli alert a lui precedenti
sono tutti non più pendenti) procede all'invio e contrassegna l'alert come
inviato, in caso contrario controlla che non sia già stato elaborato e che
4. Funzionamento del controllore 34

Figura 4.3: Algoritmo di dispatch degli alert

sia eettivamente di un reading successivo e in tal caso procede all'invio,


altrimenti no. Il concetto di reading successivo è stato concretizzato in
questo modo: la dierenza fra la data di generazione di questo alert e
del precedente deve essere maggiore del sampling period del task (più
un certo coeciente di tolleranza). Questo margine può essere anche
abbastanza elevato (ad esempio un 60% del sampling period), visto che,
se glasssh nella schedulazione di eventi periodici non riesce ad eseguire
il codice entro un margine strettissimo, salta direttamente alla prossima
esecuzione.

4.5.3 Sottoscrizione alle notiche


Le notiche degli alert possono essere di varie tipologie e la possibilità
di accedervi è denita dal prolo associato al warden di cui fanno parte
i task. Le notiche possono essere per ora di due tipi: mail e sms.
L'invio di una notica all'utente desiderato è legata non solo all'algo-
ritmo di dispatchment, sopra spiegato, ma anche alla presenza o meno di
una sottoscrizione; la sottoscrizione permette di associare ad uno speci-
co utente uno specico task o anche una specica istanza, in modo che
possa ricevere gli alert relativi.
Questa gestione permette di associare ad un task (o ad una istanza)
anche più utenti, a patto che questi abbiano il permesso di accedere a
35 Gestione degli snapshot

tali alert, secondo questi criteri di visibilità:

• content e network alert: visibili a tutti gli utenti administrator, al


customer user, associato al warden di cui fa parte il task, e al cus-
tomer administrator associato al warden-parent cui fa riferimento
il warden di cui sopra.

• instance alert: visibili a tutti gli utenti administrator

Secondo questi criteri, ogni utente che ne ha facoltà può decidere di


creare o meno una sottoscrizione al task (o istanza). Come politica di
fondo l'interfaccia, in fase di creazione di un task, crea anche una serie
di sottoscrizioni fra il task e il customer user associato al warden, men-
tre gli altri utenti interessati potranno autonomamente creare un'altra
sottoscrizione.
E' anche possibile in fase di creazione di una sottoscrizione indicare
un recapito (mail o telefonico) alternativo per l'alert, visto che il sistema
utilizza per default le informazioni di contatto associate ad ogni utente.

4.6 Gestione degli snapshot


Con snapshot si intende l'istantanea di una risorsa in un dato istante:
viene generato dall'istanza a cadenza periodica (il sampling period del
task) e viene memorizzato sull'istanza stessa. Al suo interno è contenuto
tutto l'albero degli elementi che compongono la pagina, tutti gli header
ottenuti, sia in request che in response, il content type, il tempo e la data
di download. Oltre a questo, sono contenute anche una serie di infor-
mazioni aggiuntive (SnapshotExtention), fra le quali la rappresentazione
graca dello snapshot, sia in versione thumbnail che ad alta risoluzione.
Lo snapshot risulta essere fondamentale, sia dal punto di vista del
sistema che dal punto di vista dell'utente:

• dal punto di vista dell'utente, per valutare con un colpo d'occhio lo


stato delle risorse monitorate e per comprendere se l'alert generato
dai sensori sia un falso positivo o meno (e quindi poi interagire con
il sistema modicando la catalogazione dello snapshot attraverso il
feedback)

• dal punto di vista del sistema, poichè è l'elemento che viene analiz-
zato dai sensori e dall'aggregatore per valutare la presenza o meno
di un defacement

Lo snapshot risulta essere uno degli elementi che determinano maggior-


mente la crescita di dimensione dei dati memorizzati dall'istanza, proprio
per questo ogni istanza implementa delle politiche per la cancellazione
4. Funzionamento del controllore 36

degli snapshot antichi. Per lo stesso motivo potrebbero minare notevol-


mente la scalabilità del sistema, se dovessero essere memorizzati anche
sul database del controllore; proprio per questo motivo il controllore ne
gestisce solo una minima parte. Il controllore riceve degli snapshot solo
nel momento in cui rileva degli alert che, nel caso di network e con-
tent, contengono al loro interno anche l'istantanea della risorsa che lo
ha generato, questi, vista la loro importanza, vengono memorizzati nel
database locale del controllore.
Tuttavia l'interfaccia graca, per sua denizione, ha necessità di rap-
presentare un gran numero di snapshot, ad esempio i reading precedenti
ad un alert generato, o l'ultimo reading rilevato in ordine di tempo; per
permettere questo, visto che l'interfaccia graca può contattare solo il
controllore, questo si occupa di ricevere e inoltrare alle istanze le richieste
relative agli snaphot necessari per poi fornirli all'interfaccia.
Per limitare il più possibile lo spreco di banda è stato scelto di
implementare due meccanismi.

Snapshot Light
Si è deciso di permettere da parte dell'istanza l'invio di due tipologie di
snapshot, una completa di tutti gli elementi che compongono la pagina
(l'albero degli elementi) e una invece senza queste informazioni aggiun-
tive, con solo gli elementi di base e la rappresentazione graca in versione
thumbnail; così facendo nella maggior parte dei casi (costruzione delle
pagine di sommario) vengono richiesti gli snapshot in versione light e,
solo e unicamente quando necessario, quelli full. Visto che una pagina,
a seconda della sua complessità, può risultare molto pesante in termini
di sottoelementi la dierenza risulta evidente.

Caching degli snapshot


Il secondo approccio che si è deciso di adottare è quello del caching, fare
cioè in modo che gli snapshot ricevuti dalle istanza vengano temporanea-
mente tenuti in memoria sul controllore, in modo da fornirli direttamente
all'interfaccia che li richiede, senza ripetere inutili chiamate remote verso
i nodi di elaborazione. Per fare questo è stata utilizzata la libreria java
ehcache che permette appunto di gestire il caching di oggetti generici,
questo caching viene fatto solitamente in memoria e, in caso si ecceda
il numero massimo di elementi congurato, viene utilizzata la memoria
secondaria.
Come ogni sistema di caching, anche questo permette di associare ad
ogni oggetto immagazzinato una chiave, in modo da poter controllare
rapidamente la sua presenza in memoria e, in caso, di estrarlo dalla
37 Repair Thread

cache stessa; in questo caso la chiave scelta è stata la coppia <Istanza,


Id_snapshot>, visto che, a dierenza dei task i cui id sono globalmente
univoci a livello di sistema, può tranquillamente vericarsi che su due
istanze vi siano due snapshot caratterizzati dallo stesso id.
Gli snapshot possono essere richiesti in vari modi:

• l'ultimo snapshot rilevato relativo ad un task

• gli ultimi n snapshot relativi ad un task

• gli n snapshot precedenti ad un dato snapshot (utile ad esempio


per vedere la situzione precedente ad un alert)

• gli n snapshot successivi ad un dato snapshot (utile ad esempio per


vedere come si è evoluta la situzione dopo un alert)

• tutti gli snapshot generati in un a tale data

Per realizzare il caching e il reperimento degli snapshot necessari si è


deciso, come politica di base, che le istanze restituiscano sempre degli
array di id e, solo in seguito ad una seconda chiamata, gli snapshot veri
e propri, in modo tale da ottimizzare il fetch limitando il prelievo a solo ed
unicamente quegli snapshot che non sono presenti nella cache locale (ad
esempio potrebbe succedere che alcuni snapshot siano già presenti perchè
richiesti con chiamate di tipo lastSnapshotOf e poi vengano nuovamente
richiesti in una richiesta del tipo by date).

4.7 Repair Thread


4.7.1 Importanza del repair thread
Il database del controllore deve contenere informazioni sulle entità non
note alle istanze: Warden, WardenProle, Utenti. In linea teorica sarebbe
possibile non memorizzare alcuna informazione sui task in tale database.
Basterebbe memorizzare i task solo sulle istanze ed associare ad ogni task
un identicativo del warden a cui appartiene. Questo approccio tuttavia
non è accettabile:
Alcune informazioni devono essere disponibili agli utenti anche in
momenti di temporanea inaccessibilità di alcune istanze (ad esempio non
è pensabile che un utente, nel momento in cui eettua il login, non veda
l'elenco di tutti i suoi task, perché alcuni di essi risiedono su istanze
irraggiungibili temporaneamente).
Alcune informazioni devono essere ottenibili dall'interfaccia graca
rapidamente (ad esempio non è pensabile dover contattare tutte le istanze
per scoprire quali siano i task di un dato warden).
4. Funzionamento del controllore 38

Il controllo degli accessi deve essere centralizzato, pertanto il con-


trollore deve avere l'elenco completo dei task; ciò implica che occorre
mantenere sul database del controllore una tabella task potenzialmente
molto grande (ad esempio per 100 istanze con 10000 task l'una otteniamo
1 milione)
E ' quindi necessario memorizzare sul database del controllore alcune
informazioni relative ad ogni singolo task. Ciò introduce due problemi
molto importanti:

1. Scalabilità: occorre mantenere sul database del controllore una


tabella task con almeno 1 milione di record (100 istanze per 10000
task, come nell'esempio di prima)

2. Coerenza tra i database: ogni operazione di modica a un task, in-


vocata dal controllore, deve aggiornare in modo atomico il database
del controllore ed il database dell'istanza coinvolta. Guasti o mal-
funzionamenti durante l'esecuzione dell'operazione possono intro-
durre incoerenze tra il database del controllore e il database dell'is-
tanza; fra l'altro l'utente che ha provocato la modica non conosce
l'esito dell'operazione

Il problema della scalabilità si risolve minimizzando la quantità di in-


formazioni relative ad un task che sono mantenute nel database del
controllore.
Il problema di coerenza tra i database si potrebbe risolvere incap-
sulando ogni operazione di modica ad un task in una transazione dis-
tribuita. Anche prescindendo dal costo in termini di prestazioni, questo
approccio non è accettabile per alcuni motivi:

• Complessità:

≻ la gestione dei commit distribuiti è molto complicata ed è


impensabile programmarla esplicitamente

≻ Java EE supporta automaticamente le transazioni centraliz-


zate (un solo database) ma non quelle distribuite (più database)

• L'uso delle transazioni atomiche distribuite non previene le inco-


erenze tra i database e non risolve l'incertezza dell'utente in caso
di guasto, questo approccio garantisce solo che, quando il guasto
viene risolto, il sistema automaticamente riporti i due database
nello stesso stato (tra l'altro, è anche possibile che, sino a quando
non si risolve il guasto su uno dei due lati, la riga del task su cui
si stava operando rimanga inutilizzabile sull'altro lato)

Il problema di coerenza tra i database quindi si risolve in questo modo:


39 Repair Thread

• Ogni operazione di modica dei Task deve essere implementata sul


lato controllore seguendo questo ordine:

≻ Invocazione operazione su Istanza

≻ Se andata a buon ne, aggiornamento del database del con-


trollore

≻ Se è stato ottenuto un errore, viene noticato all'utente che


non è a conoscenza dell'esito dell'operazione

• Periodicamente viene eseguito il repair thread

4.7.2 Algoritmo del Repair Thread


Il repair thread sul controllore analizza, in modo asincrono, il database
del controllore e il database di ogni istanza. Assumendo di controllare
i task sull'istanza A, il processo avviene come indicato in gura 4.4, e
cioè:
La prima cosa controllata è se un task, presente su una istanza, è
assente sul database del controllore. Vengono poi fatti dei controlli per
vericare che non vi sia stato un errore durante un processo di migrazione
di un task e, in tal caso, viene avviato un processo di migration repair.
In seguito viene controllato se lo stato di attività di un task, riportato
dall'istanza, sia incongruente con quella del controllore.

4.7.3 Processo del migration reapir


Il processo di migrazione di un task da un'istanza A ad un'istanza B
viene implementato sul controllore in questo modo:

1. Viene selezionato l'oggetto task sul controllore

2. Viene creato il task sull'istanza B

3. Viene terminato il task sull'istanza A e viene collegato all'istanza


B

4. Sull'istanza B il task appena creato viene collegato all'istanza A

5. Inne vengono aggiornati i dati sul database del controllore

Nel caso in cui avvenga un errore in un qualche punto di questo proced-


imento il repair thread opererà in questo modo:

• Se il task su A è terminato e collegato a B (errore fra 1 e 2)

≻ se B è collegato ad A viene aggioranto il database del control-


lore
4. Funzionamento del controllore 40

Figura 4.4: Algoritmo del repair thread

≻ se B non è collegato ad A viene collegato e aggiornato il


database del controllore

• Se il task su A è terminato e collegato ad un'altra istanza viene


terminato il task su B (migrazione multipla)

• Se il task su A non è terminato si procede terminando il task su A e


collegandolo a B, collegando il task creato su B ad A, aggiornando
il database del controllore

4.7.4 Selezione dell'istanza da controllare


Fra le informazioni che il database del controllore conserva, relativamente
alle istanze, viene anche memorizzata l'ultima data in cui è eseguito il
thread su tale istanza. Nella scelta di quale istanza controllare, quindi,
si selezionano le istanze il cui stato risulta attivo, fra queste viene data
precedenza a quelle su cui non è mai stato eseguito un repair thread e,
41 Repair Thread

se non ve ne fossero, si selezionano quelle il cui controllo eettuato è più


lontano nel tempo.
Capitolo 5
Implementazione del
Controllore
Il controllore nella sua normale esecuzione non prevede direttamente
la possibilità di interagire in maniera interattiva con l'utente (per la
creazione dei task etc.), visto che non espone nessuna user interface; l'u-
nica modalità di comunicazione sono i metodi remoti che si è scelto di
esporre e che permettono di avviare procedure ed ottenere informazioni
sullo stato di esecuzione del sistema.

5.1 Interfaccia programmatica


5.1.1 Modalità di comunicazione
Come precedentemente spiegato, l'istanza è sprovvista sia di interfaccia
graca che di interfaccia a linea di comando e può venir comandato, solo
dal controllore tramite l'invocazione di metodi remoti. L'invocazione di
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 al contempo la dierenza tra chiamate locali
e remote la minore possibile.
In particolare nel nostro programma questo è stato reso possibile
tramite un particolare costrutto della tecnologia EJB noto come remote
stateless session bean. Uno stateless session bean consiste in un'interfac-
cia java che denisce i metodi richiamabili remotamente, che deve essere
condivisa tra chiamato e chiamante ed una classe java, nota solo al chia-
mante, che implementa la suddetta interfaccia. Questo tecnologia rende
la dierenza tra chiamate locali e remote estremamente ridotta, per il
solo fatto che i parametri passati alla funzioni sono passati per valore,

43
5. Implementazione del Controllore 44

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 dierenza diventa nulla.

5.1.2 Informazioni esposte


I metodi esposti sono raggruppati in alcuni remote bean a seconda del-
l'aspetto del controllore che gestiscono, questi sono:

InstanceCtrlBean gesitione delle istanze, registrazione di nuove istanze,


ricezione delle liste delle istanze presenti nel sistema e dei gruppi di
istanze

TaskCtrlBean gestione di tutte le operazioni sui task e ricezione degli


snapshot

WardenBean creazione dei warden-son e ricezione degli elenchi dei


warden presenti nel sistema

AlertCtrlBean creazione e rimozione delle sottoscrizioni degli alert e


ricezione delle liste di alert presenti sul controllore

CommonMethod altri metodi di generica utilità

5.1.3 Metodi esposti


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.

1 public InstanceCtrl getInstanceByUri(URI uri) throws


InstanceNotFoundException;
2 public InstanceCtrl getInstanceById(long id) throws
InstanceNotFoundException;

Fornisce l'istanza identicata dai suoi identicativi univoci: l'uri o


l'id

1 public List<InstanceCtrl> getAllInstances();


2 public List<InstanceCtrl> getAllInstancesSingle();

Fornisce l'elenco di tutte le istanze, nel primo caso di qualsiasi tipo


esse siano, sia singole che appartenenti ad un gruppo; nel secondo caso
invece presenta l'elenco di tutte le istanze di tipologia single; da notare
45 Interfaccia programmatica

che questi metodi non distinguono lo stato in cui si trova l'istanza (attivo,
fallito, fermata).

1 public List<InstanceGroup> getAllInstanceGroup();

Permette di ottenere la lista dei gruppi di istanze presenti nel sistema.

1 public List<InstanceCtrl> getActiveInstances();


2 public List<InstanceCtrl> getActiveInstancesOfGroup(
InstanceGroup group);
3 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 specicato gruppo di istanze.

1 public void registerInstanceSingle(URI uri, String ip,


int port) throws InstanceDuplicateUriException,
InstanceCtrlException;
2 public void registerInstanceGroup(URI uri, String ip,
int port, InstanceGroup group) throws
InstanceDuplicateUriException, InstanceCtrlException;

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 identicativi uguali.

1 public void disableInstance(URI uri) throws


InstanceNotFoundException;

Permette di impostare lo stato di una istanza su halted; solitamente


tale azione viene eettuata in automatico dagli algoritmi di fallimen-
to/recupero delle istanze in caso di errore, tuttavia può risultare utile in
alcune attività di manutenzione.

Metodi per la gestione dei task (TaskCtrlBean)


1 public void createTask(String url, int samplingPeriod,
Warden w) throws TaskCtrlException;
2 public void createTask(String urlS, int samplingPeriod,
Warden w, InstanceCtrl i) throws TaskCtrlException;
5. Implementazione del Controllore 46

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.

1 public void createTasksFromList(List<String> urls, int


samplingPeriod, Warden w) throws
TaskCreationException;
2 public void createTasksFromList(List<String> urls, int
samplingPeriod, Warden w, InstanceCtrl i) throws
TaskCtrlException;

Questi metodi permettono, simmetricamente a quelli sopra riportati,


di creare un insieme di task partendo da una lista di stringhe (url),
specicando o meno l'istanza sulla quale si vuole che venga avviata
l'esecuzione.

1 public void terminateTask(TaskDescriptorCtrl t) throws


TaskCtrlException;
2 public void modifyTask(TaskDescriptorCtrl t, String url,
Integer samplingPeriod, Warden w) throws
TaskCtrlException;

Permettono di terminare il task indicato o di modicarlo, indicando


il parametro che si intende variare (url, sampling period); il task prece-
dente viene bloccato ed avviata l'esecuzione dello stesso con i parametri
modicati.

1 public void migrateTask(TaskDescriptorCtrl t,


InstanceCtrl instanceTo) throws
TaskMigrationException;

Permette di migrare il task da un'istanza ad un'altra, essendo una


procedura piuttosto articolata può essere lanciata una eccezione di tipo
task migration; una situazione erronea sarà poi appianata dal repair
thread.

1 public TaskDescriptorCtrl getTaskById(long id) throws


TaskCtrlNotFoundException;

Permette di ottenere il riferimento ad un task a partire dall'id iden-


ticativo
47 Interfaccia programmatica

1 public SnapshotCtrl getSnapshotById(long id,


InstanceCtrl i, boolean full) throws
TaskCtrlException;
2 public SnapshotCtrl getLastSnapshotOfTask(
TaskDescriptorCtrl tdc, boolean full) throws
TaskCtrlException;
3 public List<SnapshotCtrl> getLastsSnapshotOfTask(
TaskDescriptorCtrl tdc, int quantity, boolean full)
throws TaskCtrlException;
4 public List<SnapshotCtrl> getSnapshotByDate(
TaskDescriptorCtrl tdc, Date date, boolean full)
throws TaskCtrlException;
5 public List<SnapshotCtrl> getSnapshotsBeforeId(
TaskDescriptorCtrl tdc, long id, long quantity,
boolean full) throws TaskCtrlException;
6 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 at-
traverso l'id, o recuperando l'ultimo rilevato dall'istanza per un dato
task, o reperendo tutti gli snapshot rilevati in una tale data, o recu-
perando le n istantanee rilevate prima o dopo di un dato snapshot.

1 public List<SnapshotCtrl> forceTaskOutcomes(


TaskDescriptorCtrl tdc, List<SnapshotBase> list)
throws TaskCtrlException;

Metodo centrale che permette all'utente di catalogare gli alert rice-


vuti come corretti o falsi positivi, accetta una lista di snapshot (oppor-
tunamente impostati per essere riconosciuti come falsi positivi o meno) e
il task di riferimento. In uscita presenta gli snapshot la cui catalogazione
è risultata modicata in seguito alle variazioni determinate dai feedback
inviati.

1 public Properties getProperiesOfTaskFromIstance(


TaskDescriptorCtrl t) throws TaskCtrlException;
2 public void setPropertyOfTaskOnInstance(
TaskDescriptorCtrl t, String key, String value)
throws TaskCtrlException;

Permettono di ottenere ed impostare delle proprietà aggiuntive a liv-


ello di task. Il primo metodo fornisce tutte le properites associate ad un
certo task, mentre il secondo permette di impostare il valore di una ben
denita propery (o nel caso sia nuova di crearla).
5. Implementazione del Controllore 48

Metodi per la gestione dei Warden (WardenBean)

1 public List<UserData> getAllUsers();

Fornisce l'elenco di tutti gli utenti registrati nel sistema

1 public List<WardenProfile> getAllWardenProfiles();

Fornisce tutti i WardenProle presenti nel sistema

1 public Warden getWardenById(long id) throws


WardenException;
2 public List<Warden> getAllWarden();
3 public List<Warden> getWardenByUser(UserData ui);

Permette di ottenere i warden in base all'id, all'utente proprietario,


o tutti indierentemente

1 public void createWarden(Warden wParent, WardenProfile


wProfile, UserCustomer uCustomer) throws
WardenException;

Permette di creare i sotto-warden denendo quale sia il warden-


parent, a quale prolo si debba riferire e quale sia l'utente associato.

Metodi per la gestione degli Alert (AlertCtrlBean)

1 public AlertWithTaskAbstractCtrl getAlertById(long id)


throws AlertCtrlException;

Questo metodo restituisce l'alert associato ad un certo id

1 public List<AlertWithTaskAbstractCtrl> getAlertsFrom(


Date date, TaskDescriptorCtrl task);

Questo metodo restituisce gli alert di un determinato task generati


dopo una certa data

1 public List<AlertWithTaskAbstractCtrl>
getPendingAlertsOfTask(TaskDescriptorCtrl task);

Questo metodo permette di ottenere tutti gli alert pendenti associati


ad uno specico task.
49 Task Periodici

1 public void createAlertSubscriptionMail(


TaskDescriptorCtrl task, UserData user) throws
AlertSubscriptionException;
2 public void createAlertSubscriptionMail(
TaskDescriptorCtrl task, UserData user, String mail)
throws AlertSubscriptionException;
3 public void createAlertSubscriptionSms(
TaskDescriptorCtrl task, UserData user, String sms)
throws AlertSubscriptionException;

Questi metodi permettono di creare delle sottoscrizioni agli alert rel-


ativi ad uno specico task, sia di tipologia mail che sms, permettendo fra
l'altro di specicare un indirizzo email o numero sms alternativo rispetto
a quello predenito dell'utente con cui viene creata la sottoscrizione.

1 public void createInstanceAlertSubscriptionEmail(


InstanceCtrl instance, UserAdmin user) throws
AlertSubscriptionException;
2 public void createInstanceAlertSubscriptionEmail(
InstanceCtrl instance, UserAdmin user, String mail)
throws AlertSubscriptionException;

Questi metodi permettono di creare delle sottoscrizioni agli alert rel-


ativi ad una specica istanza; l'utente associato deve essere uno User-
Admin. Visto che solo gli utenti amministratori conoscono e hanno pos-
sibilità di operare sulle istanze siche, viene data anche qui la possibiltà
di personalizzare l'indirizzo di destinazione della notica.

1 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
1 public void save(Object o) throws Exception;

Permette di invocare il salvataggio di un oggetto di tipo entity, se


noto al controllore, sul database.

5.2 Task Periodici


La maggior parte degli algoritmi necessari per l'implementazione del con-
trollore è stata eettuata attravero degli ejb stateless, nel caso però di
5. Implementazione del Controllore 50

azioni cadenzate nel tempo si è deciso di utilizzare l'EJB Timer Service


che permette di eseguire chiamate a metodi, ad un istante specico di
tempo, o in intervalli periodici.
Questo si è reso necessario in alcuni casi: per la ricezione degli alert
dalle istanze, per il controllo dello stato delle istanze (perlomeno per
quelle appartenenti ad un gruppo), per reperire gli indici di carico dalle
varie istanze, per eseguire il repair thread.
Questo viene fatto attraverso un metodo del bean che permette di in-
vocare la creazione del timer e un metodo contrassegnato dalla property
@Timeout che contiene il codice eseguito allo scadere del timer. Nel-
l'esempio qui riportato viene gestito il timer relativo al controllo delle
istanze.

1 public void setupInstanceTimer(){


2 TimerService tmrSrv = sessionCtx.getTimerService();
3 Timer instanceTimer = tmrSrv.createTimer(0,
Configuration.getInstanceCheckTime(), null);
4 }
5
6 @Timeout
7 public void checkInstanceTimerTimeout(Timer t){
8 TimerService tmrSrv = sessionCtx.getTimerService();
9 List<InstanceGroup> groups = instanceBeanRemote.
getAllInstanceGroup();
10
11 if (t.getInfo() == null)
12 {
13 ...
14 }
15 }

In alcuni casi particolari i timer vengono anche utilizzati per simulare


un sistema multi-thread; l'uso dei thread in Java EE è fortemente scon-
sigliato, questo limite può essere aggirato utilizzando dei timer one-shot
che vengono fatti partire in un medesimo istante, simulando quindi (se
le risorse del container lo permettono) una esecuzione parallela.
Ciò è stato utilizzato, ad esempio, nel codice necessario al reperimen-
to degli alert dalle varie istanze, qui si è diviso il numero di istanze per il
numero di timer paralleli che si desiderava creare e poi si sono distribuite
le istanze suddivise ai timer eettivamente istanziati.

1 @Timeout
2 public void checkAltertTimerTimeout(Timer t){
3 TimerService tmrSrv = sessionCtx.getTimerService();
4 int numberOfTimers = Configuration.getNumberOfThread()
;
51 Task Periodici

5 if (t.getInfo() == null)
6 {
7 //Main timer
8 ArrayList<ArrayList<InstanceCtrl>> instanceDivision
= instanceLocal.getDividedInstances(
numberOfTimers);
9 for (int j=0; j<numberOfTimers; j++ )
10 if (instanceDivision.get(j).size()>0)
11 tmrSrv.createTimer(0, instanceDivision.get(j));
12 }
13 else
14 {
15 ArrayList<InstanceCtrl> instList = (ArrayList<
InstanceCtrl>) t.getInfo();
16 for (InstanceCtrl ic : instList) {
17 dispatchTaskAlert(ic, ContentAlertCtrl.class);
18 dispatchTaskAlert(ic, NetworkAlertCtrl.class);
19 dispatchInstanceAlert(ic);
20 }
21 }
22 }

Ognuno di questi timer fornisce, come si può vedere nel codice di


esempio, un metodo utilizzato per poterlo avviare; come risulta ovvio
questo deve essere richiamato una sola volta, plausibilmente nel momento
in cui il sistema viene fatto partire, per questo motivo viene utilizzata
una ServletListener (unico componente presente nella sezione war del
progetto) che sulla base delle informazioni di congurazione presenti nel
le conguration.properites avvia o meno i timer relativi.

5.2.1 InstanceTimerBean
Questo task periodico contiene al suo interno una serie di funzionalità:
sia il controllo della presenza di nuovi nodi nei gruppi di istanze (at-
traverso il sistema dell'auto-discovery implementato attraverso il frame-
work Shoal), sia il reperimento degli indici di carico necessario per le
logiche di scelta dell'istanza di esecuzione.
La logica di esecuzione procede quindi in questo modo:

• Se esiste perlomeno un gruppo di istanze nel sistema, viene creato


un timer one-shot per la gestione di ogni gruppo di istanze

In questo caso, se il gruppo non presenta nessuna istanza atti-


va, il sistema prova a collegarsi allo starting-node denito nelle
congurazioni del gruppo.
5. Implementazione del Controllore 52

Se invece vi sono istanze attive, ne seleziona una a caso e la contatta


per ricevere l'elenco delle istanze, una volta ricevuta aggiorna la
lista dei nodi conosciuti segnando come fermate le istanze non più
presenti nella nuova lista e registrando (o tornandone a segnare lo
stato attivo) le istanze nuove o precedentemente fermate.

In ambo i casi vengono chiesti all'istanza anche gli indici di carico


di tutte le istanze del gruppo.

• Per ognuna delle istanze singole viene creato un timer one-shot


deputato al controllo degli indici di carico e dello stato

In questo caso vengono contattate non sole istanze considerate at-


tive, ma anche quelle reputate compromesse; in tal modo è possibile
fare un ulteriore controllo se tale un'istanza considerata compro-
messa si di nuovo raggiungibile.

5.2.2 AlertTimerBean
Come sopra spiegato, questo algoritmo cerca di avviare un certo numero
(precongurato) di thread paralleli, utilizzando il sistema dei timer one-
shot, che si occupano di contattare tutte le istanze presenti nel sistema
e quindi riceve e inoltrare gli alert di ogni tipologia presenti.

5.2.3 RepairThreadBean
Il repair thread invece, per denizione, si limita a controllare la coerenza
di una istanza per ogni esecuzione, anche per limitare l'insorgere di prob-
lemi legati alla concorrenza. In questo caso quindi non vi sono problemi
di parallelizzazione delle esecuzioni. In realtà, però, viene ugualmente
utilizzato un timer one-shot per meglio gestire gli errori di connessione,
come verrà meglio spiegato in seguito.

5.3 MessageDriven Bean


Nel progetto è stato anche deciso di utilizzare dei message driven bean,
un particolare tipo di bean in grado di eseguire determinate operazioni in
relazione alla ricezione di un messaggio JMS. Esso quindi non risponde
alle richieste di un client ma agisce in relazione all'evento "ricezione di
un messaggio".
La ricezione, a secondo del dominio scelto, avviene nel nostro caso,
attraverso una coda (esiste anche la tipologia topic), quindi il MDB non
è altro che un client JMS che opera in fase di ricezione su una coda. Nel
sistema questo tipo di approccio è stato adottato nella parte relativa al
dispatch degli alert attraverso mail.
53 Diagramma delle classi

E' stato creato un MailerBean associato alla coda jms/MailQueue


che, alla ricezione di un messaggio, invoca il metodo onMessage che
appunto provvede all'invio della mail.

1 @MessageDriven(mappedName = "jms/MailQueue",
activationConfig = {
2 @ActivationConfigProperty(propertyName = "
acknowledgeMode", propertyValue = "Auto-acknowledge
"),
3 @ActivationConfigProperty(propertyName = "
destinationType", propertyValue = "javax.jms.Queue"
)
4 })
5 public class MailerBean implements MessageListener...

E' stato inserito nel bean CommonMethod un metodo sendJMSMes-


sageToMailQueue che viene utilizzato dal sistema per inserire nella coda
dei messaggi le nuove mail da inviare.
All'interno di questo bean è stato necessario inserire due risorse ag-
giuntive:

1 @Resource(name = "jms/MailQueue)
2 private Queue mailQueue;
3 @Resource(name = "jms/MailQueueFactory")
4 private ConnectionFactory mailQueueFactory;

che sono state utilizzate per ottenre una connessione alla coda e per
poter inserirvi nuovi elementi.

5.4 Diagramma delle classi


Viene qui riportata lo schema delle classi utilizzate nel controllore e
nell'interfaccia con le relative relazioni che le legano.

Come si può notare dalla gura 5.1 si sono create delle classi per la
gestione degli alert, delle sottoscrizioni a questi, per i task e i warden.
Nel caso degli alert si è deciso di denire una classe base (astratta),
che implementa le informazioni di base relative agli allarmi, (la data,
l'errore che l'ha causato, il fatto se sia pendente o meno) poi si è cre-
ata una classe che la estende, aggiungendo le caratteristiche necessarie,
(snapshot e task per gli alert content e network) e inne una classe per
ogni tipologia di alert (network, content, instance) che aggiunge le query
necessarie per ottenere le informazioni desiderate.
Per le alertSubscription si è seguito il medesimo approccio, in modo
da permettere l'implementazione di varie tipologie di sottoscrizione.
5. Implementazione del Controllore 54

Nella gura 5.2 il graco delle classi presenta invece la gestione delle
informazioni relative alle istanze, in cui viene sempre usato l'approc-
cio di creare una classe astratta e le sottoclassi relative alle due tipolo-
gie (single e grouped). Ad ogni istanza di tipo gruppo è associata una
InstanceGroup e ad ogni InstanceGroup sono associato da 0 a n istanze.

Tutte queste classi sono state contrassegnate dall'annotazione @En-


tity che permette di utilizzare JPA per realizzare, direttamente dalla
denizione delle classi, la struttura del database sul motore scelto; sono
stati utilizzati alcuni attributi particolari di JPA per congurare il com-
portamento del framework di persistenza durante la denizione delle
tabelle, nella fattispecie

1 @Inheritance(strategy=InheritanceType.SINGLE_TABLE)

per permettere di persistere le classi estese nella stessa tabella in cui


è memorizzata la classe genitore senza usare foreing key

1 @GeneratedValue(strategy = GenerationType.IDENTITY)

per utilizzare le sequenze automatiche di postgresql nella creazione


degli id (così facendo si ha una sequenza per ogni tabella, altrimenti si
avrebbe una sequenza generale per tutto il database)

Sono state utilizzate altre annotazioni per denire la tipologia da


utilizzare per memorizzare dati in quel campo, per denire dei vincoli
(unique etc.), o il nome da usare nella colonna.
55 Diagramma delle classi

Figura 5.1: Schema UML delle classi (alert e task)


5. Implementazione del Controllore 56

Figura 5.2: Schema UML delle classi (istanze)


57 Console (GoldrakeShell)

5.5 Console (GoldrakeShell)


Terminata la fase iniziale di sviluppo dell'architettura del controllore, si
è reso necessario un periodo di test per vericare il corretto funziona-
mento di tutte le parti, soprattutto quelle che prevedevano una continua
interazione con una o più istanze.
Per poter eettuare queste prove in tempi rapidi, senza dover og-
ni volta creare appositi programmi di test, si è deciso di sviluppare un
client semplicato alternativo alla interfaccia web prevista dal proget-
to; la scelta è caduta su una shell interattiva, sul modello delle console
unix/linux come ad es. la bash.

Figura 5.3: L'interfaccia principale della shell

L'utilizzo di questa console risulta non propriamente banale ed è


ovviamente indirizzata solo agli sviluppatori o agli amministratori del
sistema.
I comandi devono essere impartiti in modalità testuale e non sono
previste modalità di interazione, nel senso che tutti i parametri di es-
ecuzione devono essere forniti assieme al comando stesso; è possibile
ottenere l'elenco dei comandi supportati da questa shell e, per ogni co-
mando impartito, viene fornito un esempio schematico di quale sia la
modalità corretta di invocazione.

5.5.1 Comandi supportati


I comandi per ora supportati all'inteno della shell sono:

man: lista dei comandi supportati

inst_list: lista delle istanze registrate nel sisteam


5. Implementazione del Controllore 58

Figura 5.4: Elenco dei comandi e suggerimenti sui parametri

inst_create: denizione di una nuova istanza di tipo singolo (uri ip


port)

inst_group_create: denizione di un nuovo gruppo di istanze

inst_disable: imposta su halted lo stato di una istanza

task_create: crea un task sulla base dei parametri (url, sampling pe-
riod, warden)

task_create_le: crea un grouppo di task partendo da un le di testo


contenente un insieme di url, sampling period e warden vengono
passati come parametri

task_list: elenca i task per il warden selezionato

task_terminate: termina il task indicato (id)

task_migrate: migra il task dall'istanza su cui sta girando su di un'al-


tra indicata

alert_list: elenca gli alert per il task indicato

alert_not_pending: imposta tutti gli alert pendenti del task indicato


come non più pendenti

alert_subs: crea una alert subscription (task utente)

snapshot_last: mostra i dati relativi all'ultimo snapshot rilevato dal-


l'istanza, compreso l'outcome
59 Problemi incontrati e soluzioni adottate

snapshot_save: salva l'ultimo snapshot dell'istanza sotto forma di ogget-


to snapshot serializzato e di immagine di anteprima png

Il reperimento dell'ultimo snapshot permette di ottenere questo output:

Figura 5.5: Snapshot ottenuto attraverso la shell

Mentre questo è il thumbnail del sito generato a partire dall snapshot:

Figura 5.6: Thumbnail ottenuti (bassa risoluzione ed alta risoluzione)

5.6 Problemi incontrati e soluzioni adottate


5.6.1 Errori di connessione verso le istanze
Una delle attività più comuni da parte del controllore è ovviamente il
collegamento con i vari nodi di elaborazione registrati, per gestire i task
o per reperire informazioni; uno dei principali problemi con cui ci si è
scontrati è stato relativo alla gestione degli errori nel collegamento con
le istanze remote. Tale errore può avvenire su due livelli:

1. ip e porta di destinazione non raggiungibile


5. Implementazione del Controllore 60

2. ip e porta raggiungibile, ma sul container non risulta in esecuzione


l'applicazione richiesta

In ambo i casi nella fase di lookup del metodo remoto, sembra che glass-
sh catturi delle eccezioni che diventano non più intercettabili in maniera
programmatica.
Nel primo caso vengono generate a cadenza regolare delle connection
time out, nel secondo caso viene invece generata una runtime exception,
sempre non intercettabile.
Se ciò avviene durante una normale chiamate ad uno stateless ejb il
problema è relativamente poco grave, in quanto nonostante l'eccezione
di più basso livello non sia catturabile viene intercettata una NamingEx-
ception e il resto del codice può essere correttamente eseguito.
Quando però il codice di connessione si trova all'interno del metodo
di timeout di un timer, questo può provocare la morte del timer stesso,
visto che, per specica, quando il container riceve dal timer due eccezioni
non gestite viene automaticamente eliminato (come si può vedere dal log
seguente).

1 ’TimedObject = TimerTestBean’ ’Application = TestEJB’ ’


BEING_DELIVERED’ ’PERIODIC’ ’Container ID =
80350805994635266’ ’Fri Nov 07 12:06:47 CET 2008’ ’
1000’ ;2;|EJB5119:Expunging timer
2 [’10@@1226054096629@@server@@domain1’ ’TimedObject =
TimerTestBean’ ’Application = TestEJB’ ’
BEING_DELIVERED’ ’PERIODIC’ ’Container ID =
80350805994635266’ ’Fri Nov 07 12:06:47 CET 2008’ ’
1000’ ] after [2] failed deliveries|#]

Per evitare questo si sono adottate due stragie:

Socket
Per evitare la generazione a cadenza regolare di un gran numero di con-
necion time out si è deciso di aprire, preventivamente ad un tentativo di
lookup, un socket in direzione dell'ip e porta selezionato; se l'apertura
avviene senza alcun problema la procedura di lookup continua normal-
mente, se invece viene catturata una eccezione (in questo caso gestibile)
viene abortita la procedura e incrementato il contatore dei fallimenti di
connessione dell'istanza.
Questa logica, insieme alle altre logiche di fallimento delle connes-
sioni e conteggio degli errori, è stata inserita in un metodo del bean
CommonMethod in modo tale da uniformare il comportamento in tutto
il sistema.
61 Problemi incontrati e soluzioni adottate

Timer one-shot
Il secondo approccio adottato riguarda invece le connessioni create all'in-
terno di procedure temporizzate; per evitare che un qualsiasi problema
di connessione possa far terminare il processo temporizzato (con tutto
ciò che ne consegue) si è scelto di avviare, ogniqualvolta si vogliano con-
tattare delle istanze, un timer one-shot creato dal timer principale che si
occupa di avviare eettivamente la connessione.
Questo approccio rende le eccezioni non gestibili secondarie, visto che
il timer one-shot è sacricabile, dato che verrebbe ugualmente terminato
anche dopo una esecuzione senza errori.

5.6.2 Accesso a metodi di bean da parte di entity bean


In alcuni casi risulta necessario ad oggetti di tipo entity bean l'accesso a
metodi esposti da bean stateless, ad esempio nel caso della gestione delle
extended property dei task questo è fondamentale visto che le property
sono caricate dinamicamente dalle istanze. Purtroppo, all'interno di en-
tity bean, non è possibile iniettare un ejb; la soluzione adottata è stata
quindi quella di inserire all'interno dell'entity interessata un eld priva-
to realtivo all'ejb di cui si vogliono richiamare i metodi marcato come
@transient. Attraverso un metodo setBean questo campo viene valoriz-
zato da parte del codice chiamante con un riferimento esistente all'ejb, in
tal modo i metodi dell'ejb diventano disponibili all'interno dell'oggetto
entity.
Stralcio del codice attraverso cui viene fornito un riferimento ad un
oggetto task

1 TaskDescriptorCtrl t = taskBean.getTaskById(id);
2 t.setTaskBean(taskBean);
3 return t;

a questo punto all'interno del metodo getExtendedProperty sarà disponi-


bile un taskBean attraverso cui operare

1 public Properties getExtendedProperties() {


2 if (taskBean != null)
3 {
4 try {
5 taskBean.getProperiesOfTaskFromIstance(this);
6 return extendedProperties;
7 }
8 catch (TaskCtrlException ex)
9 {
10 ...
11 return extendedProperties;
5. Implementazione del Controllore 62

12 }
13 ...

5.6.3 Utilizzo di shoal sul controllore


Un altro problema che si è presentato è stato legato all'utilizzo del frame-
work di clustering shoal. Nel progetto iniziale tutti i nodi facenti parte
del sistema dovevano partecipare al cluster:

• tutte le istanze di un dato gruppo come nodi attivi (core)

• il controllore come noto osservatore (spectator)

Così facendo il controllore avrebbe dovuto vedersi noticare tutti gli


eventi di aggiunta/fallimento nodi al cluster e, in tal modo, mantenere
aggiornata una lista interna con tutti i nodi attivi. In linea di princi-
pio questo approccio funzionava correttamente, almeno no al momento
in cui non si cercava di fare delle invocazioni di metodi remoti da con-
trollore verso un'altro nodo entrambi facenti parte del cluster; in questo
caso le chiamate fallivano poichè vi era il tentativo di utilizzare una
transazione distribuita (non supportata). Questo comportamento era
probabilmente dovuto all'utilizzo di shoal da parte del nostro sistema e
contemporaneamente da glasssh che lo utilizza per il suo cluster interno.
Per risolvere il problema si è deciso di variare lievemente l'architet-
tura togliendo il controllore dai nodi del cluster e facendo stare ogni istan-
za in ascolto degli eventi relativi a join/failure degli altri nodi; tenendo
così aggiornata una lista interna dei nodi attivi. In tal modo il control-
lore non viene noticato in tempo reale delle modiche degli stati dei
vari nodi che compongono il sistema, ma può periodicamente contattare
un nodo qualsiasi per farsi fornire la situazione aggiornata. Il problema
delle transazioni distribuite in questo scenario non si pone, visto che per
specica le istanze non devono comunicare fra di loro.
Capitolo 6
Conclusioni
6.1 Obiettivi raggiunti
Basandosi su quanto riportato nel documento delle speciche e dei requi-
siti, si può dire che la maggior parte degli obbiettivi che questa parte del
progetto si proponeva di raggiungere sono stati ottenuti; nella fattispecie
il sistema attualmente permette la:

• Gestione delle operazioni base sui task (creazione, terminazione,


migrazione, checkpoint)

• Gestione delle istanze, sia di tipo singolo, sia appartenenti ad un


cluster

• Gestione delle connessioni con le istanze e dei problemi a questo


legati (errori di connessione etc.)

• Reperimento e dispacciamento degli alert relativi sia a task che ad


istanze

• Reperimento degli snapshot dalle istanze e gestione del caching

• Gestione dei warden e warden-prole, con relative relazioni gerar-


chiche

In sostanza sono stati realizzati tutti i componenti basilari per permettere


l'avvio e la gestione di un sistema di monitoring.
Sono stati eettuati alcuni test con un numero limitato di istanze
(3) e di task (30) e il sistema ha funzionato correttamente per alcuni
giorni, prima di accusare problemi dovuti alla mancanza di spazio sulla
memoria secondaria; sono ora in corso test con numeri decisamente più
elevati di task.

63
6. Conclusioni 64

In realtà il sistema necessita ancora di alcuni elementi perchè possa


soddisfare completamente i requisiti.
Vi sono soprattutto alcune parti che, seppur implementate e tes-
tate, necessitano di veriche più approfondite, vista la necessità di un
alto numero di nodi e task per appurarne il corretto funzionamento:
sono il repair thread e l'aggiornamento dinamico dell'elenco delle istanze
clusterizzate.

6.2 Conclusioni soggettive


Dal mio punto di vista, il progetto è risultato sicuramente interessante
e ha portato alla mia attenzione un problema attuale come quello dei
defacement. Questo progetto è poi stato una ottima possibilità per avere
a che fare per la prima volta con la tecnologia java enterprise e le sue
caratteristiche, sono rimasto sinceramente aascinato dalla possibilità di
astrazione fra base di dati e gestione dei dati stessi attraverso i paradigmi
della oop.
Potrebbe essere interessante considerare alternative al container scel-
to durante lo sviluppo, Glasssh, che è sembrato alcune volte non molto
adabile e dal comportamento non sempre predicibile.
E' stato poi decisamente formativo partecipare allo sviluppo di un
progetto partendo da un insieme di speciche e requisiti e soprattutto
suddividendo il lavoro fra più persone, con le inevitabili complicazioni
dovute alla collaborazione e condivisione di idee e punti di vista talvolta
divergenti.

6.3 Sviluppo futuro


Come accennato, il sistema, seppur funzionante, necessita di ulteriore
sviluppo e ulteriori migliorie, i punti a mio avviso meritevoli di interesse
sono:

• la security e la gestione di tutte le tipologie di utenti

• il disaccoppiamento dei dati utilizzati fra controller e gui in modo


da poter implementare facilmente diverse tipologie di interfaccia

• l'implementazione di tutte le tipologie di notiche (attualmente le


notiche via sms non sono funzionanti)

• la realizzazione di politiche di pulizia per diminuire l'utilizzo di


memoria secondaria.
65 Sviluppo futuro

Sicuramente fondamentale sarà anche l'individuazione della migliore e


più semplice modalità per creare, congurare e distribuire nuove istanze.
Un problema non facilmente risolvibile, ma meritevole di interesse,
sarebbe quello di cercare una modalità che riduca la quantità di codice da
scrivere, per il passaggio degli oggetti fra le varie componenti del progetto
(istanza - controllore e controllore - interfaccia); allo stato attuale per
ogni oggetto, condiviso fra due componenti, è stato necessario scrivere
un'interfaccia e tre classi (con codice parzialmente sovrapponibile), fra
l'altro fra loro non trasformabili attraverso il metodo del cast.
Appendice A
Congurazione di Glasssh
Per la corretta esecuzione dell'applicazione è necessario eettuare alcune
congurazioni sul container Galsssh.

A.1 Risorse JDBC


E' necessario creare due componenti: il connection pool all'interno del
quale inserire le proprietà di connessione al database

Figura A.1: Connection Pool

Bisogna poi associare a questa connection pool la risorsa JDBC real-


mente utilizzata.

A.2 Risorse JMS


E' necessario creare due componenti per la gestione della coda, nella fat-
tispecie la coda vera e propria jms/MailQueue e jms/MailQueueFactory
questa viene utilizzata per l'invio della posta.

67
A. Congurazione di Glasssh 68

Figura A.2: Risorse JMS

A.3 Congurazione JavaMail


E' necessario congurare una sessione javamail utilizzata per l'invio della
posta

Figura A.3: Sessione JavaMail

A.4 Congurazione dell'ip di ascolto


E' inne necessario congurare glasssh in modo tale che rimanda in
ascolto sull'ip della macchina, congurazione di default sotto windows
mentre manualmente necessaria sotto linux; questa congurazione è nec-
essario impotare un nuovo IIOP Listener.

Figura A.4: IIOP Listener


69 Backup della congurazione

A.5 Backup della congurazione


Per permettere una più rapida applicazione di tali conguazioni è sta-
to eettuato un dump della congurazione di glasssh attraverso lo
strumento asadmin per poi poterlo facilmente ripristinare.
E' suciente posizionare il le .zip generato con il backup nella
directory backups del dominio e poi eseguire

1 asadmin> restore-domain nome_dominio


Appendice B
Speciche e Requisiti
Viene qui riportato il documento dei requisiti e delle speciche dal
quale si è partiti per lo sviluppo del progetto.

(Documento redatto dal relatore prof. A. Bartoli, dal correlatore prof.


E. Medvet e dal dott. G. Davanzo).
B.1 Requisiti Goldrake
B.1.1 Denizioni

• Risorsa: pagina web visualizzabile in un browser. Ogni risorsa è


associata an 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.

• WardenProle: elementi che deniscono la QoS del Warden. Ogni


Warden ha esattamente un WardenProle e questo è immutabile.

• Task: processo di monitoraggio di una risorsa. Ogni Task appar-


tiene esattamente ad un Warden.

• Reading: immagine di una risorsa ad un dato istante.

• Aggregator: algoritmo per catalogare i reading in normali o anoma-


li.

71
B. Speciche e Requisiti 72

B.1.2 Generale
1. Non deve essere legato ad alcun sistema operativo.

2. Deve essere possibile analizzare i Task anche dopo la loro termi-


nazione ed indipendentemente dalla versione del software utilizza-
to. In particolare, se la rappresentazione interna di un Task include
informazioni il cui formato dipende dalla versione del software (ad
esempio, oggetti Java serializzati quali sensor e aggregator) queste
informazioni devono essere utilizzabili in ogni versione del sistema.

3. Consiste di:

• una o più istanze, tipicamente molte più di una.

• un controllore.

Ogni istanza eettua il monitoraggio di un insieme di risorse, il control-


lore (o controllori) coordinano il sistema.

B.1.3 Scalabilità
1. Istanze: Alcune centinaia.

2. Risorse: Migliaia o poche decine di migliaia per istanza, in dipen-


denza della potenza dell'istanza.

3. Warden: Migliaia

B.1.4 Istanze
1. Ogni istanza funziona in modo del tutto autonomo, indipendente-
mente dalla presenza o meno di altre istanze o di controllori.

2. Ogni istanza è controllabile esclusivamente in maniera program-


matica.

3. Deve essere possibile creare nuove istanze rapidamente e con min-


imo intervento di un operatore.

4. Deve essere possibile aggiornare il software di tutte le istanze rap-


idamente e con minimo intervento di un operatore.

5. Ogni istanza mantiene dinamicamente due indici di carico, il cui


signicato deve essere uniforme sulle diverse istanze e deve avere
un signicato relativo alla potenza di calcolo e di memorizzazione
dell'istanza stessa
73 Requisiti Goldrake

• cpuLoadIndex (esempio: 0.75 signica che l'istanza funziona


al 75% delle proprie capacità di calcolo)

• storageLoadIndex (esempio: 0.75 signica che l'istanza ha


consumato il 75% delle proprie capacità di memorizzazione)

6. Ogni istanza mantiene dinamicamente alcuni indici di prestazione,


il cui signicato deve essere uniforme sulle diverse istanze e deve
avere un signicato assoluto

• fetchShortTermThroughput (esempio: 500 signica che l'is-


tanza ha prelevato nell'ultimo minuto circa 500 reading)

• fetchLongTermThroughput (esempio: 50000 signica che l'is-


tanza ha prelevato nell'ultimo giorno circa 50000 reading)

• globalReadings (esempio: 50000 signica che l'istanza ha prel-


evato 50000 reading da quando è stata inserita nel sistema)

• databaseSize (esempio: 2.7 signica che l'istanza sta utiliz-


zando 2.7 GB della propria memoria secondaria)

B.1.5 Controllore
1. Il controllore costituisce l'unica modalità di interazione con il sis-
tema per gli utenti.

2. Il controllore consiste di due moduli:

• interfaccia graca, accessibile agli utenti;

• core, accessibile esclusivamente in maniera programmatica dal-


l'interfaccia graca

3. Gli utenti interagiscono con l'interfaccia graca. Questa interagisce


con il core. Questo interagisce con le istanze. L'interfaccia graca
non deve accedere alle istanze bypassando il core.

4. Il controllore implementa la nozione di WardenProle, che è del


tutto sconosciuta alle istanze.

5. Il controllore deve visualizzare l'elenco delle istanze esistenti e di


quelle attualmente attive.

6. Per ogni istanza, il controllore deve acquisire automaticamente le


seguenti informazioni:

• variazioni attiva/inattiva, ritardo contenuto entro pochissimi


minuti.
B. Speciche e Requisiti 74

• cpuLoadIndex, ritardo contenuto entro pochissimi minuti.

• storageLoadIndex, ritardo contenuto entro qualche ora. (no-


ta: sono acquisiti automaticamente solo gli indici di carico,
non gli indici di prestazione).

• instance alert, ritardo contenuto entro qualche ora

B.1.6 Utenti
1. Sono divisi in tre categorie disgiunte:

• Amministratori (operatori di Goldrake).

• Amministratori Clienti (AC)

• Utenti Clienti (UC)

2. Un AC può essere associato a più Warden, ognuno con il proprio


WardenProle. Il controllore deve associare costantemente un AC
al Warden che sta impersonando.

3. I diritti delle categorie sono i seguenti:

• Un Amministratore può operare su ogni risorsa; può aggiun-


gere/rimuovere AC; può aggiungere/rimuovere UC (associati
ad un UC).

• Un AC può operare su tutte le risorse del/dei warden cor-


rispondenti; può aggiungere/rimuovere suoi UC.

• Un UC può operare solo sulle risorse che sono state da lui


inserite nel sistema.

B.1.7 Task
1. Un task consiste di un descrittore e dati, come segue:

• descrittore:

≻ id del Warden a cui appartiene il Task,

≻ URL della risorsa,

≻ samplingPeriod,

≻ startingTime, endingTime (possibly NULL),

≻ status: inProgress/completed, (descrive se il task è anco-


ra in corso oppure no)

≻ type: onLine/simulated, (descrive se il monitoraggio avviene


in tempo reale sulla risorsa reale oppure su un archivio
raccolto in precedenza; vedi i task simulati più sotto)
75 Requisiti Goldrake

≻ setOfAggregators.

• dati:

≻ sequenza di reading della risorsa. Ogni reading contiene:

∗ informazioni necessarie per visualizzare completamente


la risorsa in un browser (immagini, javascript, CSS
etc.) ;

∗ istante a cui è stato prelevato il reading;

∗ HTTP response ottenuta per ogni HTTP request uti-


lizzata per prelevare il reading.

∗ per ogni aggregator del setOfAggregators,

· outcome: normal/anomalous;

· eventuale feedback (vedi più sotto il feedback di


utenti; occorre indicare se l'outcome è stata alter-
ata da un utente oppure no).

· values of sensorList

• sequenza di alert generati, come segue:

≻ per ogni aggregator del setOfAggregators

∗ link ad ogni reading per il quale è stato generato un


content alert

∗ descrizione dell'alert

∗ link ad ogni reading per il quale è stato generato un


network alert

∗ descrizione dell'alert

2. Gli attributi di un task sono immutabili. Qualora sorgesse la ne-


cessità di variare alcuni attributi di un task (ad esempio il sam-
plingPeriod oppure il setOfAggregators), allora occorre terminare
il task e crearne un altro con i valori opportuni per gli attribu-
ti. Operazioni del genere possono essere facilitate dall'interfaccia
graca del controllore.

3. Le operazioni su un task sono:

(a) creazione.

• Può essere invocata da un A, AC, UC.

• input: URL da monitorare, samplingPeriod, setOfAggre-


gators

≻ samplingPeriod può essere variato tra estremi pres-


sati in base al WardenProle
B. Speciche e Requisiti 76

≻ setOfAggregators contiene elementi ssati dal War-


denProle. Alcuni WardenProle possono permettere
all'utente che crea il task di includere zero o più ag-
gregator predeniti della forma "sucient condition".
Alcuni WardenProle, disponibili solo agli Amminis-
tratori, possono permettere all'utente che crea il task
di scegliere a proprio piacimento gli aggregator da
inserire nel setOfAggregators.

• Il task appartiene al Warden associato all'utente che ha


creato il task.

• L'istanza su cui eseguire il task è scelta automaticamente


dal controllore (in base a politiche al momento non spec-
icate, che si basano sugli indicatori di carico e sul War-
denProle).

• E' possibile eettuare una creazione in batch di un in-


sieme di task: l'utente specica il link di partenza ed un
insieme di criteri di ammissione da passare ad un crawler;
al termine del crawl, sarà fornito l'elenco delle risorse indi-
viduate e sarà possibile creare automaticamente un task
per ognuna di esse, eventualmente eliminandone alcune
manualmente.

(b) terminazione

• può essere invocata da un A, AC, UC.

(c) checkpoint

• può essere invocata da un A, AC, UC.

• termina il task e ne crea un altro del tutto identico al


precedente. Può servire per contenere le dimensioni dei
dati e per facilitare l'esecuzione di task simulati.

(d) modica

• può essere invocata da un A, AC, UC.

• termina il task e ne crea un altro del tutto identico al


precedente, permettendo di modicare alcuni attributi
selezionati.

(e) migrazione per prestazioni

• può essere invocata solo da un A.

• Un task può essere forzato a migrare su un'altra istanza


quando il cpuLoadIndex dell'istanza su cui risiede il task
diventa "eccessivo". La decisione su quando eettuare
77 Requisiti Goldrake

una migrazione e verso quale istanza viene presa dal con-


trollore (non dalle istanze). Ciò può avvenire manual-
mente, su decisione dell'operatore, oppure automatica-
mente.

(f ) migrazione per fault-tolerance

• può essere invocata solo da un A.

• Un task può essere forzato a migrare su un'altra istanza


quando l'istanza su cui risiede si guasta.

B.1.8 Task simulati


1. Un task può essere simulato. Un task simulato è associato a un al-
tro task non simulato e terminato. Un task simulato valuta il com-
portamento di uno o più aggregator sui dati (sequenza di reading)
già raccolti dal task associato.

2. Le operazioni possibli su un task simulato sono le stesse di quelle


possibili su un task non simulato. L'unica dierenza tra i due è
che un task simulato non genera alert.

3. La creazione di task simulati è permessa solo ad alcuni Warden-


Prole.

B.1.9 Aggregator
1. Un aggregator consiste delle seguenti informazioni:

• Nome

• ClasseCheImplementaAlgoritmo

• VersioneAlgoritmo

• EventualiParametri

• SensorList

• unique-ID

2. Un Aggregator riceve un array di numeri prodotti dalla rispet-


tiva SensorList e produce un valore di tipo enumerato: Normal,
Anomalous, Learning.

3. Un Aggregator può essere aggiunto o rimosso solo da un Ammin-


istratore. La rimozione di un Aggregator implica che non sarà
più possibile creare Task che utilizzano quell'AggregatorModel.
Sarà però possibile continuare ad utilizzare le informazioni storiche
associate ad eventuali Task che hanno usato l'Aggregator rimosso.
B. Speciche e Requisiti 78

B.1.10 Alert
1. Un'istanza può generare varie tipologie di alert:

• content alert, corrispondente ad un reading catalogato come


anomalo da un aggregator

• network alert, corrispondente ad un reading il cui prelievo


ha generato una condizione di errore (network error, HTTP
response con errore, numero elevato di network error consec-
utivi...)

• instance alert, corrispondente a situazioni anomale relative al


funzionamento dell'istanza nel suo complesso (indici di carico
che superano una soglia predenita, ...)

2. Un'istanza genera alert per un reading r non appena si verica una


delle condizioni seguenti:

• content alert, quando l'output dell'aggregator applicato ad r è


Anomalous e l'output sul reading precedente non era Anoma-
lous

• network alert, quando il prelievo di r ha generato una con-


dizione di errore ed il prelievo del reading precedente non ha
generato una condizione di errore

• instance alert, quando l'istanza rileva la situazione anomala.

3. Content alert e network alert sono associati al Task che ha causato


il prelievo del reading corrispondente. Instance alert non sono
associati a nessun Task.

B.1.11 Alert e utenti


1. Gli alert sono visibili agli utenti come segue:

• content alert e network alert: agli A ed agli AC/UC che


possono accedere al Task

• instance alert, solo agli A

2. Un utente può eettuare operazioni di subscribe / unsubscribe per


gli alert che può vedere. L'utente sceglie il metodo di trasmissione
dell'alert tra quelli disponibili nel proprio WardenProle. Alcuni
WardenProle devono supportare l'invio di alert agli utenti tramite
email, SMS.
79 Requisiti Goldrake

3. Un alert deve contenere informazioni esplicative sulla natura del-


l'alert (network alert e instance alert sono indipendenti dagli ag-
gregator e dalla sensorList, mentre i content alert non lo sono).

4. Il controllore deve:

• acquisire un alert entro pochissimi minuti dalla sua gener-


azione.

• inviare ad ogni utente gli alert di sua pertinenza entro pochissi-


mi minuti dalla loro generazione

5. Ogni utente deve "vedere" ogni alert di sua pertinenza. L'inter-


faccia graca mantiene evidenza, per ogni utente, degli alert in-
viati all'utente e non ancora visti. Ciò avviene in modo analogo ai
messaggi mail letti/non letti dei comuni programmi mail client.

B.1.12 Feedback degli utenti


1. Un utente può modicare la catalogazione di una sequenza di read-
ing anomali fornita da un aggregator. Ciò può avvenire solo in
questo caso:

• l'utente si collega all'interfaccia graca all'istante t_0;

• il reading più recente disponibile sull'interfaccia è relativo a


un istante "molto vicino" a t_0;

• questo reading è anomalo. In questo caso l'utente può de-


cidere di catalogare come normale il reading. Se i reading
immediatamente precedenti sono anch'essi anomali (sequenza
di reading anomali che non contiene reading normali) allo-
ra l'utente può catalogare come normali tutti i reading della
sequenza.

2. Questo feedback sarà utilizzato dall'aggregator corrispondente per


modicare il proprio stato interno di di conseguenza.

3. Il feedback fornito dagli utenti deve essere memorizzato nel Task


corrispondente.

B.1.13 Interfaccia graca


Deve orire le seguenti view:

1. Amministrativa (accessibile solo agli A)

• Gestione Utenti
B. Speciche e Requisiti 80

• Gestione Warden

• Gestione WardenProle

• Gestione Istanze

≻ Elenco delle istanze esistenti, con evidenziazione graca


di quelle attualmente attive.

≻ Elenco storico per una o più istanze, con possibilità di


variare la window temporale:

∗ attività/inattività

∗ indici di carico, indici di prestazioni

≻ Analisi di dettaglio dei log di un'istanza specicata, con


possibilità di variare la window temporale.

• Gestione Alert

≻ Funzionalità analoghe alla view Alert (più sotto), con in


più elenchi:

∗ Globale

∗ Per istanza

2. Alert

• Numero degli alert "recenti", con possibilità di variare la win-


dow temporale, con possibilità di separare content/network:

≻ per warden

≻ per task

• Analisi di dettaglio di singolo alert, con possibilità di

≻ visualizzazione contemporanea della view Reading per il


reading associato.

≻ feedback sui reading anomali (vedi alert, feedback)

3. Warden

• Elenco degli warden, con ricerca per nome (tramite auto-


completion)

• Analisi di dettaglio del singolo warden (prole).

4. Task (di un warden selezionato, di più warden selezionati, di tutti


i warden accessibili all'utente)

• Elenco dei task, con ricerca per URL (tramite auto-completion)

• Come sopra, ristretto ai soli task con alert "non ancora visti"
81 Speciche Goldrake

• Analisi di dettaglio del task selezionato, con storico dei dati,


con possibilità di passaggio alla view Reading.

• Operazioni sui task, come specicate più sopra.

5. Task simulati

• come sopra, ristretto ai soli task simulati

6. Reading

• Sequenza "navigabile" di reading, a partire da un reading


specicato

• Possibilità di evidenziare l'output degli aggregator associati


al Task a cui appartiene il reading (uno o più aggregator
selezionati)

• Possibilità di passare all'analisi di dettaglio del singolo alert

• Per ogni reading deve essere facilmente accessibile:

≻ contenuto visibile su browser

≻ sorgente HTML/Javascript.... di ogni singolo elemento


che compone lo reading della risorsa

≻ risposte HTTP corrispondenti

≻ immagine del contenuto visibile su browser

• risposte HTTP corrispondenti

In tutte le view (ad eccezione della view Amministrativa) deve essere


chiaramente evidenziato il Warden ed il Task nel contesto dei quali
l'utente sta operando.

B.2 Speciche Goldrake


B.2.1 Generali
1. Java EE, GlassFish application server

2. Le istanze fanno parte di un cluster GlassFish. La membership


(istanze attive) è gestita dal GlassFish clustering. La propagazione
degli indici di carico è gestita dalla distributed cache del GlassFish
clustering (da vericare).

3. Il core del controllore è membro del GlassFish cluster (in modo da


poter accedere agli indici di carico; per i soli ni della membership
potrebbe essere un client del membership service del cluster e non
essere membro del cluster).
B. Speciche e Requisiti 82

4. Controllore:

(a) L'interfaccia graca è scritta in JSF.

(b) Il core consiste di un insieme di bean accessibili al codice


dell'interfaccia graca

5. Ogni istanza accetta richieste attraverso stateless bean

6. L'accesso ai DB deve avvenire attraverso la persistence API (JPA),


sia sulle istanze sia sul core.

7. Ogni istanza opera esclusivamente da server. In particolare, ciò


implica che:

• una istanza non può invocare operazioni di altre istanze.

• una istanza non può invocare operazioni sul controllore.

8. Tutti i messaggi di interazione con gli utenti devono essere in


inglese.

B.2.2 Database del controllore


B.2.2.1 Premessa importante
Il DB del controllore deve contenere informazioni sulle entità non note
alle istanze: Warden, WardenProle, Utenti. In linea teorica sarebbe
possibile non memorizzare alcuna informazione sui Task nel DB del con-
trollore. Basterebbe memorizzare i Task solo sulle istanze ed associare
ad ogni Task un identicativo del Warden a cui appartiene. Questo
approccio però non è accettabile:

• Alcune informazioni devono essere disponibili agli utenti anche in


momenti di temporanea inaccessibilità di alcune istanze (non è
pensabile che un AC/UC eettui un login e non veda l'elenco di
tutti i suoi Task; è tollerabile che parti dell'archivio siano tem-
poraneamente indisponibili, ma almeno l'elenco delle risorse che il
Warden sta monitorando deve essere sempre disponibile).

• Alcune informazioni devono essere ottenibili dall'interfaccia graca


rapidamente (non è pensabile fare uno scan di tutte le istanze per
scoprire quali siano i Task di un dato Warden).

• Il controllo degli accessi deve essere centralizzato (pertanto il con-


trollore deve avere l'elenco completo dei task, poiché la granularità
del controllo è il task; ciò implica che occorre mantenere sul DB
del controllore una Tabella Task con almeno 1 M record, poiché
100 istanze per 10000 task per istanza fa 1 M.)
83 Speciche Goldrake

Occorre pertanto memorizzare sul DB del controllore alcune informazioni


relative ad ogni singolo Task. Ciò introduce due problemi molto impor-
tanti:

• Scalabilità (occorre mantenere sul DB del controllore una Tabella


Task con almeno 1 M record, poiché 100 istanze per 10000 task per
istanza fa 1 M)

• Coerenza tra i DB (ogni operazione di modica a un Task, invoca-


ta dal controllore, deve aggiornare in modo atomico il DB del con-
trollore ed il DB dell'istanza coinvolta. Guasti o malfunzionamenti
durante l'esecuzione dell'operazione possono introdurre incoerenze
tra il DB del controllore e il DB dell'istanza; inoltre, l'utente che
provocato la modica non conosce l'esito dell'operazione).

Il problema di Scalabilità si risolve minimizzando la quantità di infor-


mazioni relative ad un Task che sono mantenute nel DB del controllore.
Il problema di Coerenza tra i DB si potrebbe risolvere incapsulando
ogni operazione di modica ad un Task in una transazione distribuita.
Anche prescindendo dal costo in termini di prestazioni, questo approccio
non è accettabile:

• Complessità:

≻ la gestione dei commit distribuiti è molto complicata ed è


impensabile programmarla esplicitamente;

≻ Java EE supporta automaticamente le transazioni centraliz-


zate (un solo DB) ma non quelle distribuite (più DB).

≻ Esistono application server con estensioni in grado di gestire


transazioni distribuite, ma sono di solito a pagamento e nor-
malmente molto complessi

≻ Il sistema dovrà essere programmato e gestito anche da per-


sone che possono non avere familiarità con le sottigliezze della
fault-tolerance in ambito distribuito, per cui è bene evitare
queste problematiche.

• Inoltre, l'uso delle transazioni atomiche distribuite non previene le


incoerenze tra i DB e non risolve l'incertezza dell'utente in caso
di guasto. Questo approccio garantisce solo che quando il guasto
viene risolto, il sistema automaticamente riporta i due DB nello
stesso stato (tra l'altro, è anche possibile che sino a quando non
si risolve il guasto su uno dei due lati, la riga del Task su cui si
stava operando rimanga inutilizzabile sull'altro lato). Il problema
di Coerenza tra i DB si risolve come segue:
B. Speciche e Requisiti 84

• Le operazioni sui Task sono creazione, terminazione, migrazione,


feedback di utente

• Ogni operazione di modica dei Task deve essere implementata sul


lato controllore in questo modo:

≻ Invocazione operazione su Istanza

≻ Se OK, aggiornamento DB del controllore

≻ Se non-OK, notica all'utente "non so se l'operazione è stata


eseguita, please try again later"

• Periodicamente, un repair thread sul controllore analizza in modo


asincrono il DB del controllore e il DB di ogni istanza (un'istanza
ogni qualche ora, ad esempio)

≻ when esiste task T su istanza A e non esiste su controllore:


genera notica per gli amministratori (errore durante la creazione;
in questo caso la cosa più sensata è cancellare il task sull'is-
tanza);

≻ when esiste task T terminato su istanza A e il controllore


ritiene che T stia su A ma non sia terminato (errore durante
la terminazione; la cosa più sensata è cancellare il task);

≻ when esiste task T su istanza A e il controllore ritiene che T


stia su B: esegue repair della migrazione (errore durante la
migrazione; vedi note realizzative più sotto);

In altre parole, prima si aggiorna l'istanza e poi si aggiorna il controllore.


Le incoerenze possibili si risolvono caso per caso, quando ci sono, visto
che sono semplici da rilevare, interpretare, gestire.

B.2.2.2 Tabelle
• Schema da denire in maggiore dettaglio

• Tabella degli Utenti

• Tabella degli WardenProle

• Tabella degli Warden (l'unica informazione sui Task del Warden è


il task_id; nessuna informazione su quali istanze sono coinvolte)

• Tabella dei Task

≻ task id
85 Speciche Goldrake

≻ URL

≻ ID dell'istanza contenente l'ultimo chunk (o uno "vicino al-


l'ultimo")

≻ info di ACL

≻ data dell'ultimo network alert ricevuto per questo Task

≻ data dell'ultimo content alert ricevuto per questo Task

• Tabella degli Instance Alert

≻ instance id

≻ data dell'ultimo instance alert ricevuto da questa istanza

Da notare che gli alert risiedono sui DB delle istanze. Sul DB del control-
lore ci sono solo le informazioni necessarie per sincronizzare controllore
e istanze, per permettere cioè al controllore di prelevare dalle istanze
solo gli alert ancora non prelevati (ricordare che le istanze non possono
contattare il controllore ma sono contattate da quest'ultimo, ad istanti
ssati dall'interfaccia graca).

B.2.3 Controllore
B.2.3.1 Breve nota realizzativa sull'interfaccia graca
1. Il controllore può mostrare l'elenco dei Task, comprendente il solo
URL, rapidamente in quanto è disponibile nel DB locale.

2. Ogni altra informazione è prelevata dall'istanza. Per "ogni altra


informazione" si intende il descrittore del task, i reading, gli alert
etc.

3. Queste informazioni sono inserite nella sessione HTTP dell'utente


non appena sono state prelevate, in modo da essere richiamate in
seguito.

4. Pertanto, ogni volta che è necessario "prelevare" informazioni da


una istanza, prima si verica se sono nella sessione HTTP; se non
ci sono, si prelevano e si inseriscono

B.2.3.2 Rappresentazione
1. Un task consiste di un descrittore e dati (vedi requisiti).
B. Speciche e Requisiti 86

2. La migrazione di un task consiste nella migrazione del solo descrit-


tore sulla nuova istanza. I dati rimangono sulla istanza precedente.
A regime, quindi, un task può risiedere su più istanze. Intuiti-
vamente, la componente "attiva" del task risiede su di una sola
istanza, mentre l'archivio storico può risiedere su più istanze.

3. I dati di un task consistono di una sequenza di data-chunk, og-


nuno corrispondente ad un intervallo temporale. Data-chunk cor-
rispondenti a intervalli consecutivi risiedono, tipicamente, su is-
tanze diverse. Idealmente, l'unione di tutti i data-chunk (di uno
stesso task) dovrebbe formare un intervallo continuo senza sovrap-
posizioni. In pratica può accadere che:

• ci siano intervalli (sperabilmente brevi) non associati a nessun


chunk, in caso di guasto di un warden non gestito in maniera
fault-tolerant;

• ci siano intervalli (tipicamente brevi) associati a più chunk.


Questi intervalli corrispondono al tempo necessario per com-
pletare una ricongurazione per prestazioni: il descrittore
"vecchio" dovrà essere reso inerte solo dopo che è stato at-
tivato il descrittore "nuovo".

4. Ogni data-chunk contiene, oltre ai dati, l'indicazione di:

• task a cui appartiene;

• status: inProgress/completed (relativo al data-chunk, non al


task);

• numero d'ordine del data-chunk nel task;

• istanza su cui risiede il prossimo chunk (possibly NULL, se è


l'ultimo data-chunk del task)

• istanza su cui risiede il precedente chunk (possibly NULL, se


è il primo data-chunk del task)

B.2.3.3 Migrazione
La migrazione di un Task da un'istanza A ad un'istanza B deve essere
implementata sul controllore come segue:

1. su A: preleva descrittore

2. su B: crea descrittore

3. su A: termina e collega a B
87 Speciche Goldrake

4. su B: collega ad A

5. sul controllore: aggiorna la tabella dei Task

Se si verica un errore (guasto) durante l'operazione, all'operatore viene


mostrato il messaggio "non so se è stata eseguita".
Il tutto funziona perché:

• guasto tra 1 e 2, l'operazione non è stata eseguita;

• guasto tra 2 e 3, il repair thread rileverà, quando analizza l'istanza


B, che il controllore ritiene che il Task risiede su A mentre in realtà
risiede su B; pertanto il repair thread:

≻ verica su A se il task è terminato e collegato a B; se si, esegue


4 e 5;

≻ else, verica su A se il task è terminato e collegato a un'istanza


diversa da B; se si, elimina il Task da B;

≻ else (task su A non terminato), esegue 3, 4 e 5

• guasto tra 3 e 4 oppure tra 4 e 5, simile a quanto sopra

B.2.4 Istanze
B.2.4.1 Operazioni esportate
Ogni operazione viene eseguita in modo sincrono (il chiamante si blocca
sino alla ricezione della risposta).
Da incapsulare in stateless bean
Da ranare i parametri, in particolare quelli di ritorno e le eventuali
eccezioni

• createTask(IN task_id, IN altreComponentiDescrittore)

• terminateTask(IN task_id)

• per migrare un task da A verso B, si esegue getTaskDescr su A,


create su B, terminateAndLink su A, linkFrom su B (vedi le note
realizzative dei Task)

• terminateTaskAndLinkTo(IN task_id, IN instance_desc)

• linkFrom(IN task_id, IN instance_desc)

• getTaskDescr(IN task_id, OUT task_descr)

• getTaskDataChunk(IN task_id, OUT data_chunk)


B. Speciche e Requisiti 88

• getTaskLastReading(IN task_id, OUT reading)

• getActiveTasks(OUT setOfTaskIds) (insieme di task "attivi", per


i quali cioè c'è il descrittore)

• getActiveTasksOnLine(OUT setOfTaskIds) (come il precedente, sen-


za i task simulati)

• getActiveTasksSimulated(OUT setOfTaskIds) (come il precedente,


per i soli task simulati)

• getAllTasks(OUT setOfTaskIds) (insieme di tutti i task, anche di


quelli per i quali c'è solo un chunk e non un descrittore).

• getActiveWardens(OUT setOfWardenIds) (simile ai Task ma per


gli Warden, un Warden attivo è uno per il quale c'è almeno un
Task attivo)

• getAllWardens(OUT setOfWardenIds)

• getInstanceAlerts(IN date) (data dell'ultimo instance alert ricevu-


to; torna tutti quelli successivi a questa data)

• getContentAlerts(IN task_id, IN date) (idem, per il task speci-


cato)

• getNetworkAlerts(IN task_id, IN date) (idem, per il task speci-


cato)

B.2.4.2 Note realizzative


1. Ogni istanza contiene (almeno) uno scheduling thread ed un in-
sieme di message bean. I message bean sono tutti identici, ognuno
preleva un reading e lo valuta secondo quanto indicato nel messag-
gio di attivazione (ogni bean esegue automaticamente nel contesto
di un thread). Lo scheduling thread si sveglia ad istanti regolari
ed invia un messaggio opportuno ai vari bean, in base ai task in
corso.

2. L'indice di carico cpuLoadIndex potrebbe essere legato alla quan-


tità di tempo tra il completamento dell'ultimo message bean e il
prossimo risveglio dello scheduling thread: più è piccolo questo
tempo, maggiore è il load index.

3. Quando un message bean trova nella propria input queue più di un


messaggio, signica che l'istanza è sovraccarica.
Bibliograa

[1] Zone-H.org, Statistics report 2000-2005," http://www.zone-h.org/

[2] Alberto Bartoli Giorgio Davanzo Eric Medvet, On the Reaction Time
to Web Site Defacements 2008

[3] Giorgio Davanzo, Valutazione di algoritmi di anomaly detection per


la rilevazione automatica delle intrusioni in siti web 2006
[4] Mastering Enterprise Java Beans 3.0, Rima Pathel Sriganesh - Gerald
Brose, Wiley

[5] Glasssh ocial site https://glasssh.dev.java.net/


[6] Ehcache ocial site http://ehcache.sourceforge.net/
[7] Shoal ocial site https://shoal.dev.java.net/

89

Potrebbero piacerti anche