Università degli Studi di Padova
Dipartimento di Matematica "Tullio Levi-Civita"
Corso di Laurea in Informatica
Cloud Backup
Tesi di laurea triennale
Relatore
Prof. Tullio Vardanega
Laureando Nicola Tintorri
Anno Accademico 2017-2018
Nicola Tintorri: Cloud Backup, Tesi di laurea triennale, c Febbraio 2018.
Sommario
Il presente documento descrive il lavoro svolto dal laureando Nicola Tintorri durante il periodo di stage. Il tirocinante ha lavorato per un totale di 320 ore presso la sede principale di Miriade S.p.A. a Thiene (VI).
L’azienda ha richiesto la realizzazione di una piattaforma per permettere ai loro clienti di gestire, in trasparenza, il backup delle loro istanze Amazon Web Services (AWS) e/o Google Cloud Platform. L’azienda ha anche espresso il desiderio di un’architettura facilmente estendibile che permetta in futuro la gestione dei backup delle istanze di Microsoft Azure.
Maggiori informazioni sul contesto aziendale e di come il progetto di stage si renda utile nella strategia aziendale verranno fornite nel primo e nel secondo capitolo. Il terzo capitolo descrive le attività svolte, le tecnologie usate e il prodotto finale. Il quarto e ultimo capitolo contiene un bilancio sugli obiettivi raggiunti rispetto a quelli prefissati dall’azienda e una valutazione sulle conoscenze apprese dallo studente in questo periodo.
iii
Ringraziamenti
Innanzitutto, desidero esprimere la mia gratitudine nei confronti del Professor Tullio Vardanega per avermi seguito durante il periodo di stage ed avermi aiutato nella stesura
della tesi.
Desidero ringraziare i miei genitori e mia sorella per avermi sempre incoraggiato e motivato durante gli anni di studio.
Infine voglio ringraziare tutti gli amici conosciuti durante il corso di laurea che hanno reso questi anni di studio indimenticabili.
Padova, Febbraio 2018 Nicola Tintorri
v
Indice
1 Contesto aziendale 1
1.1 L’azienda Miriade S.p.A. . . 1
1.2 Prodotti offerti . . . 2
1.3 Metodo di lavoro . . . 3
1.3.1 Metodologia agile . . . 3
1.3.2 Processi aziendali . . . 3
1.3.3 Strumenti a supporto dei processi . . . 5
1.4 Rapporto con l’innovazione . . . 6
2 Lo stage nella strategia aziendale 7 2.1 Vantaggi aziendali . . . 7
2.2 Presentazione del progetto . . . 8
2.3 Aspettative aziendali . . . 9
2.3.1 Obiettivi aziendali . . . 9
2.3.2 Vincoli imposti . . . 10
2.4 Aspettative personali . . . 12
2.4.1 Criteri di scelta . . . 12
2.4.2 Scelta del progetto . . . 12
3 Resoconto dello stage 13 3.1 Pianificazione del lavoro . . . 13
3.2 Tecnologie utilizzate . . . 14
3.2.1 Spring . . . 14
3.2.2 Angular 4 . . . 14
3.2.3 Istanze . . . 15
3.2.4 Identity and Access Management . . . 16
3.2.5 JSON Web Token . . . 17
3.3 Analisi dei requisiti . . . 17
3.4 Progettazione . . . 21
3.4.1 Architettura . . . 21
3.4.2 Dependency Injection . . . 22
3.4.3 Back-end . . . 23
3.4.4 Front-end . . . 26
3.5 Codifica . . . 27
3.6 Verifica e validazione . . . 30
3.7 Prodotto finale . . . 32
3.7.1 Navbar . . . 32
3.7.2 Login . . . 32 vii
viii INDICE
3.7.3 Backup . . . 33
3.7.4 Scheduler . . . 33
3.7.5 Keys . . . 35
3.7.6 Instance . . . 35
4 Valutazione retrospettiva 37 4.1 Bilancio degli obiettivi . . . 37
4.2 Bilancio formativo . . . 38
4.3 Osservazione sulla formazione universitaria . . . 39
Glossario 41
Bibliografia 45
Elenco delle figure
1.1 Logo Miriade S.p.A. . . 1
1.2 Reparti tecnici . . . 2
1.3 Tecnologie utilizzate da Miriade S.p.A. . . 4
1.4 Relazione tra gli strumenti . . . 6
2.1 Vantaggi aziendali . . . 8
2.2 Vincoli imposti . . . 10
2.3 Tecnologie utilizzate per realizzare Cloud Backup . . . 11
3.1 Attività dello stage . . . 13
3.2 Principali elementi di Angular . . . 15
3.3 Backup incrementali con snapshot . . . 16
3.4 Use case principali . . . 18
3.5 Architettura . . . 22
3.6 Test di unità . . . 23
3.7 Richiesta HTTP per effettuare il login . . . 24
3.8 Richiesta HTTP per visualizzare la lista dei backup . . . 24
3.9 Esempio di comunicazione tra le componenti del backend . . . 25
3.10 Package backup . . . 26
3.11 Esempio di test in Postman . . . 31
3.12 Navbar . . . 32
3.13 Login fallito . . . 33
3.14 Lista dei backup AWS . . . 33
3.15 Inserimento scheduler . . . 34
3.16 Modifica scheduler . . . 34
3.17 Visualizza scheduler . . . 34
3.18 Credenziali AWS . . . 35
3.19 Credenziali Google Cloud Platform . . . 35
3.20 Inserimento instance . . . 36 ix
x ELENCO DELLE TABELLE
Elenco delle tabelle
2.1 Obiettivi suddivisi per categoria . . . 10 3.1 Obiettivi suddivisi per categoria . . . 14 4.1 Bilancio degli obiettivi . . . 37
Capitolo 1
Contesto aziendale
1.1 L’azienda Miriade S.p.A.
Figura 1.1: Logo Miriade S.p.A.
Miriade S.p.A. è una società di consulenza informatica veneta nata nel 2000. Ad oggi è presente nel territorio con due sedi, quella principale a Thiene (VI) e una a Padova.
Entro il primo trimestre del 2018 ne aprirà una terza a Milano. Composta da circa 40 professionisti, Miriade possiede elevate competenze in cloud, big data, app development e machine learning. Il dominio applicativo comprende una vasta gamma di clienti, tra i quali Diesel, Benetton Group, Calzedonia, Infocamere, Regione Veneto e importanti realtà del ramo sanitario.
Miriade è divisa in due settori, quello amministrativo e quello tecnico. I compiti principali del settore amministrativo sono quelli di definire le strategie e gli obiettivi aziendali, gestire il personale, gestire e amministrare le risorse economiche dell’azienda e pubblicizzare i servizi e i prodotti destinati alla vendita. Gli uffici che compongono il settore amministrativo sono il back office, il front office, l’ufficio marketing, l’ufficio acquisti e l’ufficio risorse umane.
Il settore tecnico invece si divide in cinque reparti, ciascuno con determinati compiti e competenze proprie. Nello specifico i reparti tecnici sono i seguenti:
• Sviluppatori: si occupano del ciclo di vita del software gestendo uno o più periodi dello stesso. Sviluppano applicazioni on demand (sia web che mobile) e portali aziendali (tipicamente B2B). Si occupano dell’integrazione di sistemi già esistenti con lo scopo di creare una nuova struttura funzionale che combina le potenzialità dei sistemi d’origine;
• Big Data: il reparto più giovane in termini di età. Si occupa della raccolta e dello studio di grandi volumi di dati e sviluppa modelli predittivi basati su machine learning;
1
2 CAPITOLO 1. CONTESTO AZIENDALE
• Sistemisti: configurano e gestiscono la rete interna dell’azienda, creano ambienti cloud, coordinano la migrazione di sistemi esistenti in cloud e gestiscono le istanze Amazon e Google utilizzando le console offerte dai rispettivi provider. Parte della loro attività si traduce nella configurazione delle reti dei clienti svolta presso le sedi degli stessi;
• Business Intelligence (BI): realizzano data warehouse con la possibilità di caricare dati da varie fonti aziendali eterogenee: viene realizzato, in questo modo, un archivio informatico che consente un’analisi dei dati aziendali più efficiente.
Costruiscono dashboard di reportistica;
• Database Administrator (DBA): si occupano dell’installazione, della gestione e della migrazione dei database dei clienti, sia SQL che NoSQL.
Figura 1.2: Reparti tecnici
1.2 Prodotti offerti
Miriade si occupa di consulenza informatica, di formazione e sviluppa dei prodotti interni destinati alla vendita. Inoltre il team di sviluppo realizza plugin, script e librerie interne per il proprio e per gli altri reparti tecnici. Sfruttando questi strumenti i reparti riescono a ridurre il tempo richiesto per lo sviluppo dei loro prodotti.
Per quanto riguarda la consulenza informatica, Miriade fornisce ai clienti soluzioni mirate a un più efficiente utilizzo delle tecnologie dell’informazione. Questo si traduce nella progettazione, nell’implementazione e nel mantenimento (correzione di errori e aggiunta di funzionalità) del prodotto software del cliente. In particolare, le principali richieste rivolte all’azienda riguardano lo sviluppo di applicazioni on demand (sia web che mobile), portali aziendali (per lo più B2B) e integrazione di sistemi.
La società offre anche formazione su tecnologie di cui gli sviluppatori possiedono una certificazione: Spring, framework utilizzato per la realizzazione di applicazioni Java, e Liferay, enterprise portal free e open source scritto in Java.
1.3. METODO DI LAVORO 3 Miriade ha cominciato recentemente a sviluppare i propri prodotti interni destinati alla vendita. Tramite la bacheca digitale interna all’azienda (Lavagna di Sughero) i dipendenti possono proporre le loro idee. Queste vengono valutate dai reparti tecnici e dall’area di amministrazione e, se considerate valide, cominciano a essere sviluppate.
Un esempio è dato da As One, una suite di funzionalità sviluppata sulla tecnologia Qlik Sense. Questa suite facilita la raccolta e l’elaborazione dei dati da parte degli analisti e consente ai manager di avere sempre sotto controllo l’andamento dell’azienda.
As One si suddivide in As One bot e As One analytics. Quest’ultimo è rivolto a chi si trova quotidianamente a contatto con l’analisi e l’elaborazione dei dati. Si tratta di una dashboard completamente ridisegnata per essere più user friendly possibile e che permetta a un analista di condividere le proprie analisi con il resto del team.
As One bot è un chat bot in real time che, ricorrendo alla tecnologia open di Telegram, si interfaccia con i dati elaborati in Qlik Sense. I manager possono utilizzare i comandi del bot per avere accesso alle informazioni più significative dell’azienda. In questo modo i più importanti indicatori aziendali (KPI) diventano raggiungibili ovunque e in qualunque situazione. As One bot è rivolto principalmente ai responsabili e ai dirigenti.
1.3 Metodo di lavoro
Nella presente sezione verranno descritti i processi aziendali e gli strumenti a supporto di essi che ho avuto modo di conoscere e utilizzare, durante il periodo di stage, lavorando nel team di sviluppo di Miriade.
1.3.1 Metodologia agile
La metodologia agile è utilizzata per lo sviluppo del software. Questa metodologia rientra nella categoria dei metodi iterativi: il periodo di ogni iterazione è di breve durata ed è chiamato sprint. All’inizio di ogni sprint il team fissa, assieme ai clienti, i nuovi incrementi che verranno aggiunti alla parte di software già esistente.
Il team di sviluppo di Miriade adopera una metodologia agile con sprint della durata media di due settimane. Il gruppo ha deciso di utilizzare questa metodologia per poter coinvolgere il cliente in tutto lo sviluppo. Non sempre i clienti sanno esattamente come dovrà essere di preciso il software. Con questo metodo i clienti possono valutare le nuove funzionalità aggiunte al prodotto dopo ogni sprint. Nel caso in cui i clienti non sono soddisfatti delle funzionalità attuali del software, possono richiedere al team di sviluppo di modificare o aggiungere eventuali requisiti che verranno presi in considerazione e discussi nei successivi sprint.
1.3.2 Processi aziendali
Sviluppo
Miriade si occupa di realizzare sia il back-end che il front-end dei propri prodotti. Nel dettaglio, il team di sviluppo utilizza Java e Spring per l’implementazione del back-end.
Spring è un framework Java che facilita lo sviluppo di applicazioni grazie a una gran quantità di pacchetti (come quelli per interfacciarsi con database SQL e NoSQL) e semplifica l’integrazione con altri framework Java (come Hibernate). Inoltre, Spring utilizza la Dependency Injection per ridurre l’accoppiamento tra le classi garantendo
4 CAPITOLO 1. CONTESTO AZIENDALE una più semplice verifica delle unità implementate. Per la gestione delle dipendenze e degli script di compilazione dei progetti Java Miriade utilizza Maven. La persistenza dei dati viene garantita tramite database relazionali e, in particolar modo, sfruttando le funzionalità offerte dal DBMS PostgreSQL.
Per il front-end vengono sviluppate principalmente single page application e per la loro realizzazione viene utilizzato il framework AngularJS. Molte volte i clienti richiedono anche l’applicazione mobile e quindi vengono sviluppate le applicazioni Android e iOS.
Figura 1.3: Tecnologie utilizzate da Miriade S.p.A.
Manutenzione
Questo processo viene attivato quando il codice del prodotto e la documentazione associata subiscono delle modifiche. L’obiettivo è la modifica del prodotto esistente preservandone l’integrità. Il processo finisce con il ritiro del prodotto software. Esistono tre tipi di manutenzione:
• correttiva: per correggere errori (bug) nel codice;
• adattiva: per adattare il prodotto alle esigenze dei clienti;
• evolutiva: per aggiungere funzionalità al prodotto software.
Gestione della configurazione
Il processo di gestione delle configurazioni contiene le attività che permettono di gestire le modifiche e le versioni del prodotto e assicurarne la sua completezza, correttezza e consistenza. A questo scopo, Miriade utilizza un repository per ogni progetto. Ogni oggetto deve essere controllato dal responsabile di progetto prima di poter essere inserito all’interno del repository.
Documentazione
Il processo di documentazione include tutte le attività che permettono di pianificare, sviluppare, scrivere e mantenere tutti i documenti relativi al prodotto software. Seppur
1.3. METODO DI LAVORO 5 Miriade preferisce valorizzare il software funzionante piuttosto che una documentazione articolata (secondo la mentalità agile), un minimo di documentazione è fondamentale per la manutenibilità del codice. Questo si traduce nel realizzare file di testo in cui vengono descritti i compiti e le funzionalità principali dei pacchetti (package) che costituiscono l’architettura del prodotto software.
1.3.3 Strumenti a supporto dei processi
Git e BitBucket
Per il versionamento del codice sorgente Miriade utilizza Git. In particolare la società utilizza BitBucket, servizio di hosting web-based, che fornisce i sistemi di versionamento Git e Mercurial.
Le motivazioni che hanno spinto la società a scegliere questo servizio sono molteplici. In primo luogo l’interfaccia è molto intuitiva e semplice da utilizzare. Un secondo motivo è che BitBucket si integra facilmente con Jira, strumento utilizzato per il tracciamento, permettendo di associare issue e task con i relativi commit. Per concludere, il servizio ha dei prezzi molto accessibili offrendo account gratuiti per gruppi di sviluppo fino a 5 persone come quello di Miriade.
Jira
Miriade utilizza Jira per il tracciamento di issue e task. Qualunque malfunzionamento e compito viene inserito all’interno del sistema di tracciamento e gli viene associato un codice univoco. Gli sviluppatori indicano che la issue è stata portata a termine associando il suo codice nella descrizione del commit su Git.
Jira si interfaccia molto bene con chi utilizza una metodologia agile: il prodotto offre una serie di funzionalità che aiutano a organizzare al meglio i task degli sprint.
Nexus
Nexus è uno strumento per l’archiviazione e la distribuzione di tutti i componenti utilizzati nella produzione del software. Miriade utilizza questo strumento come repository di pacchetti, soprattutto per le loro librerie interne.
Teamwork
Miriade utilizza Teamwork per la progettazione e la realizzazione dei diagrammi di Gantt. L’interfaccia utente Excel-like offre una progettazione veloce e confortevole.
Teamwork monitora l’avanzamento dei progetti e ti avvisa in caso di ritardi e se i costi superano il budget stabilito.
Bamboo
Bamboo è sviluppato da Atlassian ed è utilizzato per continuous building e
gls*continuous integration. L’utilizzo di questo strumento garantisce la build di un progetto dopo un commit e, in caso di errore, Bamboo provvede ad analizzare le cause che lo hanno generato. Un’altra funzionalità è la possibilità di automatizzare l’esecuzione dei test. Per concludere, Bamboo si integra molto bene con gli altri strumenti di Atlassian utilizzati da Miriade, ovvero BitBucket e Jira.
6 CAPITOLO 1. CONTESTO AZIENDALE
Figura 1.4: Relazione tra gli strumenti
1.4 Rapporto con l’innovazione
Miriade S.p.A. resta al passo con le novità e le tendenze del momento a livello di piattaforme, framework e strumenti. I dipendenti dei vari reparti tecnici conseguono annualmente delle certificazioni relative ai servizi offerti da Google Cloud Platform, AWS e Qlik. Queste certificazione vengono poi esposte all’ingresso della sede principale di Thiene per testimoniare come la società rimanga al passo con le novità. Un altro aspetto che sottolinea il buon rapporto di Miriade con l’innovazione è lo sviluppo di chat bot (come nel caso di As One bot, descritto nelle sezioni precedenti). Le chat bot stanno diventando una moda e considerarli nella strategia aziendale indica una propensione al rinnovamento. A testimoniare ciò, il tema delle chat bot è al centro di molti progetti interni e progetti di stage dell’azienda.
Durante le otto settimane di stage in cui ho lavorato presso la sede di Thiene, ho potuto osservare come l’area di sviluppo cerchi di restare aggiornata con le tecnologie. Nel periodo di pianificazione, precedente all’inizio dello stage, ho inserito nel piano di lavoro lo studio autonomo e l’utilizzo di AngularJS per la realizzazione dell’interfaccia utente.
A stage iniziato, il tutor, discutendo con gli altri sviluppatori, mi ha consigliato di sostituire AngularJS con Angular 4 perchè quest’ultimo è più recente e sarà sicuramente più utilizzato in futuro. Una seconda occasione si è presentata nella fase finale dello stage, quando Oracle ha rilasciato la versione 9 di Java: l’azienda ha comprato tre libri/manuali affinchè gli sviluppatori potessero studiare le nuove funzionalità aggiunte al linguaggio.
Capitolo 2
Lo stage nella strategia aziendale
2.1 Vantaggi aziendali
Gli studenti del corso di laurea di Informatica devono sostenere un periodo di stage la cui durata è compresa tra le 300 e le 320 ore. In questo periodo gli studenti hanno modo di vivere un’esperienza nel mondo del lavoro, sviluppare prodotti collaborando con un team e apprendere nuove tecnologie. Dall’altra faccia della medaglia, le aziende ottengono una serie di vantaggi economici nell’ospitare un tirocinante: l’azienda non è obbligata a pagare o rimborsare lo studente e l’assicurazione antinfortunistica è a completo carico dell’Università. L’azienda ottiene anche un’altra serie di vantaggi:
• i dipendenti dedicano la maggior parte del loro tempo nelle attività più importanti.
In particolare, molte aziende hanno progetti interessanti da sviluppare ma la mancanza di tempo non permette a loro di implementarli. Ad esempio, Miriade ha progetti interni relativi alla realizzazione di chat bot, dashboard di reportistica e piattaforme di vario genere. La mancanza di tempo obbliga il team di sviluppo della società a dedicare le ore settimanali ai progetti dei clienti che hanno una maggiore priorità. Quindi, uno stagista ha il compito di cominciare o continuare progetti messi in disparte e che rischierebbero di non essere mai più completati;
• tra gli obiettivi di uno stage c’è quello di poter verificare nuove tecnologie. La mancanza di tempo costringe un’azienda ad utilizzare, anno dopo anno, gli stessi linguaggi di programmazione e gli stessi framework. Passato del tempo, una tecnologia rischia di diventare obsoleta: non più aggiornata, non più integrata con nuove funzionalità e con una community meno attiva che offre meno aiuto.
Ad uno stagista può essere richiesto di studiare e utilizzare una nuova tecnologia nel suo progetto di stage e, successivamente, l’azienda può domandare un feedback su come si è trovato nell’utilizzarla: l’azienda può compararla con quelle da loro usate e valutare di adoperarla nei progetti futuri;
• il periodo di stage può essere considerato come un periodo di prova per lo studente:
se lo stagista mostra delle buone competenze allora l’azienda potrebbe valutare di assumerlo, al termine dello stage.
7
8 CAPITOLO 2. LO STAGE NELLA STRATEGIA AZIENDALE
Figura 2.1: Vantaggi aziendali
2.2 Presentazione del progetto
Miriade S.p.A. è partner di due tra i maggiori cloud provider a livello mondiale: Google e Amazon. I clienti dell’azienda utilizzano entrambe le soluzioni con soddisfazione, tuttavia le console di gestione sono complesse e necessitano di formazione specifica per il loro utilizzo, in particolar modo per la parte di gestione dei backup. Quello che l’azienda mi ha chiesto di sviluppare è una piattaforma che permetta agli utenti di collegare il proprio account Amazon e Google e di gestire in trasparenza il backup di tutte le loro istanze, tramite l’utilizzo delle API fornite dai provider. Per queste ragioni il progetto prende il nome di Cloud Backup.
2.3. ASPETTATIVE AZIENDALI 9 Miriade ha proposto questo progetto di stage per due motivi. In primo luogo, garantire l’integrità e la consistenza dei dati è fondamentale per i clienti in quanto un’azienda ottiene i suoi ricavi dalla loro elaborazione. Tramite i backup è possibile ripristinare la consistenza dei dati dopo dei malfunzionamenti o errori logici all’interno del software.
La realizzazione di backup in sistemi cloud è noiosa e richiede del tempo, il che rischia di diventare molto frustrante per il tecnico che deve compiere queste operazioni. Questo progetto nasce con lo scopo di automatizzare il backup delle istanze, lasciando al cliente la possibilità di inserire le caratteristiche del backup (di quale istanza farlo e ogni quanto farlo).
Un secondo motivo è che la società ha un team di sviluppo composto da solo cinque persone. Questo significa che la maggior parte delle ore settimanali vengono dedicate ai progetti dei clienti che, ovviamente, hanno una maggiore priorità. I primi mockup dell’interfaccia utente di Cloud Backup sono del 2014, quindi si tratta di un progetto la cui idea era stata concepita anni fa ma non c’è mai stato il tempo di svilupparla. È stato quindi proposto questo progetto di stage in quanto l’azienda non ha sufficiente tempo per implementare l’idea la quale rischiava di non essere mai più sviluppata.
2.3 Aspettative aziendali
2.3.1 Obiettivi aziendali
Ho redatto assieme al tutor aziendale un piano di lavoro in cui ho descritto, oltre lo scopo dello stage e la pianificazione del lavoro, gli obiettivi posti dall’azienda. Miriade ha mostrato fin da subito maggiore interesse per il back-end. Mi ha infatti chiesto più volte che il back-end fosse ben progettato e che, una volta implementato, gestisse tutte le possibili richieste del cliente relative ai backup delle sue istanze, sia di Amazon che di Google.
Ovviamente, Miriade mi ha chiesto di sviluppare un’interfaccia utente che sfruttasse il back-end realizzato. Se, inoltre, fosse avanzato del tempo, l’azienda ha espresso il desiderio di un’interfaccia avanzata e user-friendly. In questo caso sarebbe intervenuta la designer del team di sviluppo che, grazie all’esperienza maturata negli anni, avrebbe realizzato dei mockup che avrei dovuto seguire nel dettaglio per la realizzazione della nuova interfaccia. Quest’ultima sarebbe sicuramente apparsa con un migliore aspetto e sarebbe stata di più semplice utilizzo per gli utenti.
Il prodotto software è stato realizzato con le tecnologie scelte da me e il tutor nel primo periodo di stage e che ho dovuto studiare autonomamente nelle prime settimane.
Inoltre, il software è stato accompagnato da due documenti: Analisi dei Requisiti e Definizione di Prodotto.
Riassumendo, ho suddiviso gli obiettivi dell’azienda in tre categorie: obbligatori, desiderabili e facoltativi. Di seguito è presente una tabella che organizza gli obiettivi suddivisi per categoria:
10 CAPITOLO 2. LO STAGE NELLA STRATEGIA AZIENDALE
Obiettivi obbligatori
Apprendimento delle tecnologie richieste Realizzazione dell’architettura del sistema
Gestione dei backup degli account AWS Gestione dei backup degli account Google Realizzazione documento Analisi dei Requisiti Realizzazione documento Definizione di Prodotto
Obiettivi desiderabili
Realizzazione di un’intefaccia utente avanzata e user-friendly
Obiettivi falcoltativi
Nessun obiettivo facoltativo individuato Tabella 2.1: Obiettivi suddivisi per categoria
2.3.2 Vincoli imposti
Figura 2.2: Vincoli imposti
Vincoli temporali
Lo stage ha avuto una durata complessiva di 320 ore, distribuite equamente in 8 settimane, ciascuna della durata di 40 ore. L’orario di lavoro previsto era uguale a quello degli altri dipendenti di Miriade: dal lunedì al venerdì, ogni giorno iniziava alle 9.00 e terminava alle 18.00. Era prevista anche un’ora di pausa pranzo, solitamente alle 13.00, con l’intento di suddividere in due blocchi di quattro ore l’orario di lavoro.
2.3. ASPETTATIVE AZIENDALI 11
Vincoli tecnologici
Miriade S.p.A. ha proposto di utilizzare Angular 4 (più recente rispetto ad AngularJS) e Bootstrap per la realizzazione di un’interfaccia utente responsive. Per il back-end l’azienda ha richiesto l’utilizzo di Java e Spring framework. Per la persistenza dei dati ho utilizzato un database relazionale, sfruttando le funzionalità del DBMS MySQL.
L’azienda è comunque rimasta pronta a valutare eventuali proposte dello studente sulle tecnologie da utilizzare per la realizzazione di Cloud Backup (come, ad esempio, Node.js per la realizzazione del back-end). Però, tra gli obiettivi personali, avevo il desiderio di imparare nuove tecnologie: ho preferito utilizzare quelle proposte dalla società piuttosto che utilizzare quelle che già conoscevo. Inoltre, gli sviluppatori di Miriade possiedono certificazioni relative a Spring quindi ho sfruttato l’occasione per farmi spiegare come meglio utilizzare il framework.
Figura 2.3: Tecnologie utilizzate per realizzare Cloud Backup
Per il versionamento del codice ho utilizzato Git e il servizio BitBucket. Assieme a quest’ultimo ho utilizzato Jira, sistema di tracciamento delle issue: in questo modo ho potuto collegare i commit su Git con le issue risolte.
Per concludere, ho utilizzato le API fornite da Google e Amazon per la gestione dei backup delle istanze in cloud. Mi sono stati anche garantiti i privilegi per poter creare, visualizzare ed eliminare istanze.
Vincoli metodologici
Miriade S.p.A. è stata molto disponibile e comprensiva della mia situazione: la durata del viaggio, per raggiungere la sede di Thiene, è di 3 ore e, ovviamente, sono necessarie altrettante ore per il ritorno. La società mi ha dato la possibilità di lavorare due giorni da remoto mentre, nei restanti tre, mi presentavo in azienda. Quali giorni della settimana lavorare da remoto venivano decisi, ogni settimana, in base al calendario del tutor aziendale: se era in trasferta allora lavoravo da remoto altrimenti mi presentavo in azienda. In questo modo avevo la possibilità di chiedere direttamente al tutor eventuali chiarimenti sulle tecnologie utilizzate per lo sviluppo del prodotto. Quando invece lavoravo da remoto comunicavo con i tecnici dell’azienda tramite i servizi Google Hangouts e Gmail, utilizzando l’account Google creato il primo giorno di stage.
12 CAPITOLO 2. LO STAGE NELLA STRATEGIA AZIENDALE Durante il periodo in azienda, il tutor mi ha descritto le principali caratteristiche di alcune delle tecnologie che avrei dovuto utilizzare durante lo stage, in particolare Java e Spring framework. Inoltre, mi ha spiegato come utilizzare gli strumenti di Atlassian utilizzati dall’azienda, ovvero BitBucket per il versionamento e Jira per il tracciamento di issue e task.
2.4 Aspettative personali
2.4.1 Criteri di scelta
Di seguito è presente una lista dei criteri con cui ho filtrato le varie proposte di stage:
• ritengo che un informatico deve sempre rimanere al passo con le tecnologie e non limitarsi a quelle che già conosce. Infatti, l’informatica è un settore in rapida evoluzione e, per essere competitivi e trovare facilmente lavoro, rimanere al passo con l’innovazione è fondamentale. Questo aspetto è stato messo in risalto anche da Deloitte e Bip, due aziende di consulenza informatica, che sono venute a parlare in aula lo scorso anno accademico. Quindi, imparare tecnologie che vengono utilizzate al giorno d’oggi è uno degli aspetti più importanti che ho valutato nella scelta dello stage;
• non mi sono fissato nessun vincolo relativo alla distanza. Nel caso l’azienda fosse stata particolarmente distante, mi sarebbe però piaciuto lavorare qualche giorno da remoto;
• progetto di stage interessante e innovativo;
• nel mondo del lavoro, la maggior parte dei progetti è collaborativo piuttosto che individuale. Ho quindi cercato uno stage in cui sarei stato inserito all’interno di un team di sviluppo.
2.4.2 Scelta del progetto
Ogni anno si tiene a Padova StageIT. Si tratta di un’iniziativa che mira ad agevolare l’incontro tra le imprese e gli studenti che entreranno a breve in stage nel mondo del lavoro con specifico riferimento al settore ICT, favorendo un’occasione di conoscenza reciproca mediante colloqui individuali.
Ho partecipato a questo evento il 5 aprile 2017 presso Padova Fiere. Mi sono presentato dopo aver selezionato i progetti, da un documento contenente una lista di tutti i progetti di stage che sarebbero stati presentati all’evento, che meglio soddisfavano i miei criteri di scelta. Ho quindi avuto un primo contatto con le aziende che mi hanno fornito maggiori dettagli e chiarimenti sui progetti di stage selezionati. Questo mi ha permesso di restringere ulteriormente il numero di progetti e, alla fine, la scelta è ricaduta sul progetto Cloud Backup per i seguenti motivi:
• interesse personale per Java e Spring;
• interesse personale per il framework Angular;
• interesse personale per il cloud, in particolare per i servizi di AWS;
• l’incontro mi ha dato l’impressione di un’azienda molto preparata;
• progetto interessante e stimolante.
Capitolo 3
Resoconto dello stage
3.1 Pianificazione del lavoro
Prima dell’inizio dello stage, assieme al tutor aziendale, ho redatto un piano di lavoro in cui ho descritto la suddivisione in attività delle 320 ore totali del tirocinio, definendo, per ciascuna di essa, la sua durata.
In un primo momento ho studiato autonomamente le tecnologie che ho utilizzato per la realizzazione del prodotto richiesto: in particolare, ho familiarizzato con gli stream di Java 8 e ho studiato le principali funzionalità di Spring framework per la realizzazione del back-end. Inoltre, ho studiato le API di Google Cloud Platform e AWS per la gestione delle istanze e dei loro backup. Per il front-end, invece, ho familiarizzato con il framework Angular e la libreria Bootstrap, utilizzata per la realizzazione di interfacce responsive.
Successivamente, ho effettutato un’analisi dei requisiti per comprendere appieno il problema che l’azienda mi richiedeva di risolvere e ho individuato i principali casi d’uso, ovvero gli scenari di utilizzo del sistema da parte degli attori che si interfacciano con esso. Per concludere, ho progettato l’architettura del sistema, seguita dalla sua implementazione.
Figura 3.1: Attività dello stage
Riporto, di seguito, una tabella che riassume le attività che ho svolto durante lo stage e le ore dedicate a ciascuna di esse:
13
14 CAPITOLO 3. RESOCONTO DELLO STAGE
Durata in ore Attività
80 Studio autonomo delle tecnologie
10 Java
30 Spring Framework
10 API AWS
10 API Google
20 Angular 4
40 Analisi dei requisiti
50 Progettazione del sistema
50 Progettazione di un’interfaccia user friendly e del back-end per la gestione del backup di account AWS e Google
150 Realizzazione del sistema
50 Gestione backup per account AWS
50 Gestione backup per account Google
50 Realizzazione interfaccia grafica user friendly
Tabella 3.1: Obiettivi suddivisi per categoria
3.2 Tecnologie utilizzate
3.2.1 Spring
Spring è un framework open source per lo sviluppo di applicazioni Java. Nel mio progetto ho utilizzato Spring boot, il quale permette di ridurre la configurazione neces- saria a mettere online un server e permette una semplice realizzazione di applicazioni stand-alone.
Per l’implementezione del back-end, realizzato con Java e Spring, ho utilizzato Spring Tool Suite (STS): IDE costruito a partire da Eclipse il quale si integra molto bene con gli altri strumenti utilizzati durante lo stage: Maven (utilizzato per gestire le dipendenze di progetto) e Git.
3.2.2 Angular 4
Angular è un framework basato su Typescript, linguaggio sviluppato da Microsoft, e utilizzato per la realizzazione del front-end delle applicazioni web. I principali elementi di cui è composta un’applicazione realizzata con Angular sono:
• template: costituiscono la view dell’applicazione;
• component: sono le classi che gestiscono il cambiamento dinamico della view;
• service: forniscono funzionalità condivise tra i component. Nel mio caso specifico, ho utilizzato i service per fare richieste HTTP al back-end realizzato;
• moduli: raggruppano component logicamente correlati tra loro.
3.2. TECNOLOGIE UTILIZZATE 15
Figura 3.2: Principali elementi di Angular Fonte: https://angular.io/guide/architecture
3.2.3 Istanze
Un’istanza è un server virtuale sul quale vengono eseguite applicazioni. Usare istanze invece di server fisici permette di rimuovere i costi e il mantenimento dell’hardware, che è completamente gestito dal provider che, a sua volta, fornisce la garanzia che la macchina sarà sempre funzionante. Siccome un’istanza è una macchina virtuale, è possibile decidere le sue caratteristiche hardware, come la RAM e la potenza di calcolo; è inoltre possibile specificare il sistema operativo: a seconda del lavoro che l’istanza deve eseguire, potrebbe essere meglio installare Windows piuttosto che una distribuzione Linux.
Ogni istanza possiede un disco root ed, eventualmente, altri dischi utilizzati per l’archiviazione dei dati e per l’installazione di applicazioni. Fare il backup di un’istanza significa replicare le informazioni contenute in questi dischi in modo da poter in futuro ripristinare l’istanza ad uno stato precedente.
In cloud, esistono due modi per creare dei backup: creare delle image o fare degli snapshot. Fare uno snapshot significa eseguire una copia incrementale dei dati contenuti in un disco: solo i dati del disco che sono cambiati rispetto all’ultimo snapshot vengono salvati in quello nuovo. In questo modo lo spazio richiesto per l’archiviazione dei backup viene ridotto.
Un’image invece è un template dal quale è possibile lanciare una nuova istanza. In AWS, è possibile creare immediatamente l’image di una istanza che contiene le informazioni sulla mappatura di tutti i suoi dischi, le sue informazioni sul sistema operativo e sulle applicazioni installate. Per quanto riguarda gli snapshot, in Amazon non esiste un comando per creare automaticamente gli snapshot di ogni singolo disco associato all’istanza. In Google Cloud Platform invece è solo possibile creare image e snapshot di singoli dischi.
16 CAPITOLO 3. RESOCONTO DELLO STAGE
Figura 3.3: Backup incrementali con snapshot
Fonte: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSSnapshots.html In Cloud Backup un utente può scegliere se creare il backup di un’istanza tramite image o snapshot. Se viene scelta quest’ultima opzione, allora Cloud Backup realizzerà, in trasparenza, lo snapshot di tutti i dischi associati all’istanza. Se invece l’utente sceglie di creare il backup tramite image allora il sistema effettuerà delle operazioni diverse in base al provider a cui l’istanza appartiene: verrà creata l’image dell’istanza in Amazon mentre in Google verrà creata un’image per ogni singolo disco associato ad essa, in trasparenza.
3.2.4 Identity and Access Management
Identity and Access Management (IAM) è un servizio web reso disponibile sia da Amazon che da Google. Questo servizio permette di gestire le risorse cloud in sicurezza.
Usando IAM, infatti, è possibile controllare chi è autorizzato ad usare certe risorse.
Quando un utente crea il suo account, esso ha completo accesso ai servizi e alle risorse. Questo account è detto root user ed è possibile accedervi tramite l’email e la password utilizzati durante la fase di registrazione. Amazon e Google sconsigliano di utilizzare questo utente e incoraggiano a crare degli IAM User per ogni utente a cui vogliamo dare accesso a delle risorse e/o servizi. Quando creiamo un account, a questo vengono date delle limitazioni sui servizi e alle risorse a cui può accedere. Una volta creato l’utente, i provider restituiscono delle credenziali necessarie per eseguire le operazioni alle quali l’account appena creato ha accesso. In particolare, in AWS, vengono ritornate una access key e una secret key mentre in Google Cloud Platform vengono forniti un client id, un client secret e un access token. Quest’ultimo viene utilizzato per ottenere un refresh token che verrà utilizzato nelle chiamate alle API di Google. Di conseguenza, le credenziali che Cloud Backup richiederà all’utente, per gestire il backup delle istanze di Google, sono client id, client secret e refresh token.
3.3. ANALISI DEI REQUISITI 17
3.2.5 JSON Web Token
JSON Web Token (JWT) è uno standard che permette la trasmissione sicura dei dati, salvati in formato JSON. Il messaggio viene firmato utilizzando un algoritmo a chiave pubblica/privata oppure utilizzando un segreto e un algoritmo di hash. Un JWT è composto da tre parti: header, payload e signature.
Nel campo header sono contenute solitamente due informazioni, il tipo di token (JWT) e l’algoritmo usato per la firma. Il payload contiene eventuali dati che le due parti (front-end e back-end) devono scambiarsi. Inoltre, all’interno del payload, sono presenti degli attributi già impostati, tra i quali exp, che indica la scadenza del token. L’ultima parte, la firma (signature), è costruita applicando l’algoritmo scelto a cui viene passato, come parametro, l’header codificato, il payload codificato e il segreto (rappresentato da una stringa).
Nel mio progetto di stage, ho utilizzato il JWT per l’autenticazione degli utenti nelle varie richieste HTTP. Inoltre ho salvato, all’interno del payload, l’id del cliente che ho utilizzato a livello di back-end per impedire che il cliente potesse ottenere le informazioni di un secondo utente dell’azienda. Il token fornito dal back-end era creato in modo da scadere dopo 6 ore.
3.3 Analisi dei requisiti
Scopo del prodotto
Una volta terminato lo studio delle tecnologie, ho fatto delle riunioni interne con il tutor aziendale e un sistemista dell’azienda. Mi hanno spiegato i dettagli del prodotto che avrei dovuto realizzare. Quello che mi veniva richiesto era gestire i backup delle istanze in cloud, utilizzando uno schema "grandfather, father and son". Esso consiste nell’avere tre cicli di backup: giornaliero, settimanale e mensile. I backup all’interno dei cicli vengono gestiti secondo una politica FIFO (First In Fisrt Out), quindi, il backup più vecchio viene eliminato per lasciare spazio al più recente.
Gli utenti possono creare i propri scheduler, componenti che gestiscono i backup, stabilendo i cicli di ritenzione (giornaliero, settimanali, mensile) e, per ogni ciclo, quando fare il backup, il tipo di backup eseguito (image o snapshot) e la lunghezza della coda FIFO. L’utente può associare uno scheduler ad un’istanza affinchè si occupi della sua manutenzione. È chiaro che, in questo modo, l’utente può definire i propri scheduler a cui delega la gestione dei backup: la gestione diventa quindi trasparente all’utente in quanto non si deve più preoccupare di gestire image e snapshot delle istanze da console.
Tutte le informazioni ottenute dalle riunioni sono state organizzate in dei diagrammi dei caso d’uso. Ciascun caso d’uso è caratterizzato da attori che interagiscono con il sistema.
Attori
Un attore rappresenta un’entità esterna che interagisce con il sistema. Un attore non è solo un essere umano ma può essere un sistema software o un dispositivo hardware.
18 CAPITOLO 3. RESOCONTO DELLO STAGE Gli attori coinvolti nei miei casi d’uso sono stati suddivisi in attori primari e attori secondari. Gli attori primari sono i seguenti:
• utente non autenticato: utente che non ha ancora effettuato il login e che quindi non può sfruttare le funzionalità di Cloud Backup, le quali richiedono un autenticazione per poter essere utilizzate;
• utente autenticato: utente che ha effettuato correttamente il login. Questo utente ha la possibilità di utilizzare le funzionalità della piattaforma;
• time: questo attore rappresenta una componente software che, ad intervalli di 24 ore, effettua delle operazioni.
Gli attori secondari sono elencati nelle seguente lista:
• AWS: attore che rappresenta i servizi Amazon a cui vengono fatte le richieste, tra cui la creazione di un’image di un’istanza oppure la creazione di una snapshot di un disco;
• Google Cloud Platform: attore che rappresenta i servizi di Google a cui vengono fatte le richieste, tra cui la creazione di image e snapshot dei dischi.
Figura 3.4: Use case principali
3.3. ANALISI DEI REQUISITI 19
Casi d’uso principali
I casi d’uso descrivono le funzionalità di Cloud Backup. Nella lista dei principali use case, riportata di seguito, ognuno di essi è caratterizzato dalle seguenti informazioni:
un codice univoco, nome, lista degli attori, descrizione, precondizione e postcondizione, ovvero le condizioni prima e dopo l’esecuzione della funzionalità rappresentata del caso d’uso.
Caso d’uso UC1: Visualizza lista backup
• Attori: utente autenticato.
• Descrizione: un utente autenticato ha la possibilità di vedere i backup delle sue istanze, sia di Amazon che di Google.
• Precondizione: l’utente ha scelto la funzionalità del sistema per visualizzare i suoi backup.
• Postcondizione: l’utente ha visualizzato una lista dei suoi backup.
Caso d’uso UC2: Gestione scheduler
• Attori: utente autenticato.
• Descrizione: l’utente ha la possibilità di inserire un nuovo scheduler. Uno scheduler, che ha il compito di gestire i backup di un’istanza, è composto da un nome, una descrizione e cicli di ritenzione giornaliero, settimanale e mensile. Per i cicli di ritenzione settimanale e mensile è possibile specificare, rispettivamente, il giorno della settimana e il giorno del mese in cui fare il backup. Inoltre, l’utente può visualizzare, modificare o eliminare gli scheduler precedentemente creati.
• Precondizione: l’utente ha deciso di sfruttare la funzionalità del sistema per gestire gli scheduler.
• Postcondizione: l’utente ha gestito i suoi scheduler.
Caso d’uso UC3: Associa scheduler a istanza
• Attori: utente autenticato.
• Descrizione: l’utente ha la possibilità di associare uno scheduler a un’istanza.
A questo punto, lo scheduler gestisce i backup delle istanze in trasparenza, senza che l’utente si preoccupi della gestione tramite console.
• Precondizione: l’utente ha scelto la funzionalità del sistema per poter associare uno scheduler ad un’istanza.
• Postcondizione: l’utente ha associato un’istanza allo scheduler.
20 CAPITOLO 3. RESOCONTO DELLO STAGE Caso d’uso UC4: Gestisci i backup delle istanze
• Attori: time
• Descrizione: time causa l’avvio della gestione dei backup delle istanze secondo le caratteristiche dello scheduler a cui è associata. Se il numero di backup è maggiore della lunghezza del ciclo di ritenzione, viene eliminato il backup più datato per lasciare spazio a quello più recente (secondo la politica FIFO).
• Precondizione: l’utente ha creato degli scheduler e gli ha associato delle istanze da manutenere.
• Postcondizione: il sistema ha gestito i backup delle istanze.
Caso d’uso UC5: Errore gestione backup
• Attori: time
• Descrizione: time causa l’avvio della gestione dei backup delle istanze secondo le caratteristiche dello scheduler a cui è associata. Si potrebbero presentare delle situazioni che possono generare degli errori. Il sistema è in grado di gestire le seguenti situazioni anomale: mancano le credenziali del provider perchè l’utente non le ha ancora inserite, le credenziali non sono valide oppure esse non hanno sufficienti permessi per permettere al sistema di gestire le istanze.
• Precondizione: l’utente ha creato degli scheduler e gli ha associato delle istanze da manutenere.
• Postcondizione: si sono verificati dei problemi durante la gestione dei backup.
Il sistema notifica l’errore all’utente.
• Estensioni: UC4 - Gestisci i backup delle istanze.
Caso d’uso UC6: Gestisci i backup delle istanze AWS
• Attori: time
• Descrizione: time causa l’avvio della gestione dei backup delle istanze secondo le caratteristiche dello scheduler a cui è associata. Se il numero di backup è maggiore della lunghezza del ciclo di ritenzione, viene eliminato il backup più datato per lasciare spazio a quello più recente. In questo use case il sistema si interfaccia con AWS, sfruttando le credenziali (access key e secret key) inserite dall’utente.
• Precondizione: l’utente ha creato degli scheduler e gli ha associato delle istanze da manutenere. Inoltre, l’utente ha inserito access key e secret key valide e con sufficienti permessi per gestire istanze e backup.
• Postcondizione: il sistema ha gestito i backup delle istanze.
3.4. PROGETTAZIONE 21 Caso d’uso UC7: Gestisci i backup delle istanze Google Cloud Platform
• Attori: time
• Descrizione: time causa l’avvio della gestione dei backup delle istanze secondo le caratteristiche dello scheduler a cui è associata. Se il numero di backup è maggiore della lunghezza del ciclo di ritenzione, viene eliminato il backup più datato per lasciare spazio a quello più recente. In questo use case il sistema si interfaccia con Google Cloud Platform, sfruttando le credenziali (client id, client secret e refresh token) inserite dall’utente.
• Precondizione: l’utente ha creato degli scheduler e gli ha associato delle istanze da manutenere. Inoltre, l’utente ha inserito client id, client secret e refresh token validi e con sufficienti permessi per gestire istanze e backup.
• Postcondizione: il sistema ha gestito i backup delle istanze.
3.4 Progettazione
3.4.1 Architettura
Ho progettato un’architettura multi-tier con lo scopo di separare le funzionalità del software in più strati (o livelli) in comunicazione tra loro. Questo tipo di architettura può essere visto come una pila in cui la comunicazione è possibile solamente tra livelli adiacenti. I vantaggi ottenuti nell’adottare questo tipo di architettura sono la facilità di estensione, manutenzione e testabilità dell’applicazione realizzata. Ho individuato i seguenti livelli (elencati dalla cima della pila verso il fondo), ciascuno rappresentante un package a livello logico: front-end, controller, business logic e persistenza dei dati.
I livelli adicenti comunciano tra di loro scambiandosi degli oggetti; poichè Java è un linguaggio fortemente tipizzato, tali devono essere rappresentati da una classe. A questo scopo ho definito dei package ciascuno dei quali si occupa di rappresentare una classe di oggetti scambiati tra gli strati della pila. Ho definito un package DTO per rappresentare gli oggetti ricevuti o inviati dal controller al client, all’interno del body della richiesta e della risposta HTTP, e passati al livello business logic per poter essere elaborati. Per la comunicazione tra business logic e persistenza dei da- ti ho definito un package entity le cui classi reppresentano gli oggetti salvati del database.
L’architettura progettata, oltre ad essere multi-tier, aderisce ai principi REST: la comunicazione tra front-end e back-end avviene tramite protocollo HTTP e il formato del body delle richieste e delle risposte è JavaScript Object Notation (JSON). Inoltre, l’applicazione realizzata è stateless: nessuna informazione sulla sessione del client viene salvata nel back-end. Questo significa che ogni richiesta HTTP è indipendente dalle altre e ognuna di esse deve fornire tutte le informazioni necessarie al back-end affinchè quest’ultimo possa elaborarla. Queste informazioni, che comprendono il token di autenticazione, vengono salvate a livello di front-end.
22 CAPITOLO 3. RESOCONTO DELLO STAGE
Figura 3.5: Architettura
Ho definito un package, a livello di back-end, che gestisce le istanze in cloud con dei thread che vengono programmati ed eseguiti ogni giorno, secondo le politiche degli scheduler definiti dall’utente. Lo scopo di un thread è quello di creare il backup di un’istanza e, eventualmente, eliminare quello più datato.
3.4.2 Dependency Injection
Ho utilizzato la Dependency Injection per garantire una più semplice manutenibilità e testabilità del codice. Quello che bisogna fare per applicare questo design pattern è dichiarare le dipendenze di cui una componente ha bisogno. Quando questa componente verrà istanziata, un injector si prenderà carico di risolvere le sue dipendenze, iniettando un’istanza della classe che è stata specificata come dipendenza.
Questo modo di operare effettua un’inversione di controllo rispetto al tipico pattern visto per la programmazione procedurale. Consideriamo una classe A che è composta da un attributo di una classe B. Con un approccio procedurale, una classe A dovrebbe istanziare, durante la sua creazione, un oggetto di tipo B. Adoperarando la Dependency Injection, specificando la classe B tra le dipendenze della classe A, viene iniettato in quest’ultima un’istanza di B: si verifica un’inversione di controllo in quanto la classe B viene istanziata prima della classe A. Nel mio progetto di stage, l’inversione di controllo si traduce nell’iniettare le componenti dei livelli più bassi della pila progettata nelle componenti dei livelli più alti.
Questo modo di operare rende il codice anche facilmente testabile, in particolare, a livello di unità. Infatti, è possibile simulare il comportamento di una dipendenza tramite l’utilizzo di uno stub il quale sarà iniettato al suo posto. Ho deciso di adoperare questo design pattern anche per facilitare l’aggiunta di test a Miriade, che ha l’abitudine di definire delle suite di test automatici per i suoi progetti.
3.4. PROGETTAZIONE 23
Figura 3.6: Test di unità
3.4.3 Back-end
Controller
Lo scopo dei controller è quello di offrire degli end-point a cui il front-end farà delle richieste HTTP. Ogni end-point soddisfa le funzionalità che l’azienda mi ha chiesto di sviluppare durante le riunioni fatte con il tutor aziendale e un sistemista dell’azienda.
Ho definito i seguenti end-point REST:
• POST /login: permette di effettuare il login in Cloud Backup inserendo nel body delle richiesta la email e la password. Se le credenziali sono corrette allora il back-end risponde con un token di autenticazione che dovrà essere specificato come header nelle successive richiste;
• POST /keys: permette ad un utente di inserire le proprie credenziali. All’interno del body della richiesta deve essere specificato il provider a cui fanno riferimento le credenziali;
• PUT /keys/{provider}: permette ad un utente di aggiornare le credenziali del provider specificato;
• DELETE /keys/{provider}: permette ad un utente di eliminare le credenziali del provider specificato;
• GET /backups: permette ad un utente di ricevere una lista (eventualmente vuota) di tutti i suoi backup;
• GET /backups/{provider}: permette ad un utente di ricevere una lista di tutti i backup appartenenti al provider specificato;
• GET /backups/{provider}/{backup_id}: permette ad un utente di ricevere le informazioni del backup con l’id specificato e appartanente al provider indicato nel path della richiesta;
• GET /schedulers: permette ad un utente di ricevere una lista (eventualmente vuota) di tutti i suoi scheduler ;
• POST /schedulers: permette ad un utente di inserire un nuovo scheduler ;
24 CAPITOLO 3. RESOCONTO DELLO STAGE
• GET /schedulers/{scheduler_id}: permette ad un utente di ricevere tutte le informazioni di uno scheduler (nome, descrizione, cicli di ritenzione);
• PUT /schedulers/{scheduler_id}: permette di aggiornare le caratteristiche di uno scheduler ;
• DELETE /schedulers/{scheduler_id}: permette ad un utente di eliminare uno scheduler ;
• GET /schedulers/{scheduler_id}/instances: permette ad un utente di avere una lista (eventualmente vuota) delle istanze manutenute dallo scheduler con l’id specificato nel path della richiesta. Viene anche ritornata una lista, per ogni istanza, degli id dei backup creati dallo scheduler ;
• POST /schedulers/{scheduler_id}/instances: permette ad un utente di associare un’istanza ad uno scheduler affinchè quest’ultimo possa gestirne i backup;
• GET /schedulers/{scheduler_id}/instances/{provider}/{instance_id}: permette ad un utente di ricevere le informazioni dell’istanza associata allo scheduler e una lista (eventualmente vuota) degli id dei backup che lo scheduler ha fatto dell’istanza stessa;
• DELETE /schedulers/{scheduler_id}/instances/{provider}/{instance_id}: un utente può eliminare l’associazione tra scheduler e istanza.
Figura 3.7: Richiesta HTTP per effettuare il login
Figura 3.8: Richiesta HTTP per visualizzare la lista dei backup
3.4. PROGETTAZIONE 25 Tutti gli end-point, fatta eccezione per /login, necessitano di un token di autenticazione (JWT). Se questo token non è presente oppure non è valido (perchè la firma non è valida oppure è scaduto), allora l’utente riceverà un opportuno messaggio di errore. Questo controllo comune, per evitare che venga fatto all’interno di ogni controller, è fatto sfruttando le funzionalità di Spring framework (Filter Chain), che permette di filtrare le richieste ricevute e scartare quelle non valide, prima che queste raggiungano la classe controller. Questo modo di operare riduce l’accoppiamento tra le classi, rendendo il sistema facilmente estendibile e manutenibile.
Persistenza dei dati
Questo livello è fondamentale per l’applicazione in quanto ha lo scopo di salvare i dati sensibili che permettono il funzionamento di Cloud Backup. Una prima questione è stato decidere quale tipo di database scegliere per lo store dei dati, relazionale (SQL) o non relazionale (NoSQL). I database non relazionali traggono vantaggi quando bisogna elaborare una grande mole di dati poco strutturati. Nel mio caso invece, la natura dei dati era fortemente strutturata e quindi la mia scelta è ricaduta su un database relazione, che permette un’ottima organizzazione dei dati in tabelle. In particolare, ho utilizzato MySQL per la persistenza dei dati.
Lo scopo di questo livello è quello di creare un’interfaccia tra il database usato e il resto degli strati della pila rendendo indipendenti questi ultimi dal DBMS scelto.
Questo modo di operare sfrutta un design pattern chiamato DAO (Data Access Object).
Uno dei vantaggi fondamentali dell’adoperare questo design pattern è che rende molto semplice la migrazione verso un altro DBMS.
Business Logic
Questo livello contiene la logica con cui i dati vengono elaborati affinchè Cloud Backup funzioni correttamente. La sua più importante funzione è quella di mappare le entity, salvate nel database, con i DTO, ovvero gli oggetti che si scambiano front-end e back-end. Infatti, i request body non sempre corrispondono ad una entity: i dati provenienti dal database vengono aggregati in questo livello per realizzare l’oggetto che verrà successivamente ritornato, al cliente, nel response body. Viceversa, i request body possono contenere oggetti che non corrispondono direttamente ad una entity. Lo strato di business logic scompone il body della richiesta in entity affichè queste ultime possano essere salvate all’interno del database.
Figura 3.9: Esempio di comunicazione tra le componenti del backend
26 CAPITOLO 3. RESOCONTO DELLO STAGE
Gestione dei backup
Ho definito una serie di classi, all’interno del package backup, che hanno lo scopo di gestire il backup delle istanze. Ogni 24 ore vengono presi, ad uno ad uno, gli sche- duler. Per ogni scheduler, vengono programmati dei thread giornalieri, ciascuno con l’obiettivo di gestire un’istanza associata allo scheduler stesso. Questi thread creano inizialmente un backup dell’istanza e, se il numero di backup eccede la lunghezza del ciclo di ritenzione dello scheduler (giornaliero, settimanale o mensile), cancella il più datato. Questo processo viene ripetuto per ogni cliente dell’azienda.
Siccome la procedura di ritenzione non differisce tra le istanze, ma differisce il modo in cui vengono creati ed eliminati i backup nei provider, ho definito un’interfaccia BackupModule che viene implementata da due classi, AWSBackup e GoogleBackup. In base al provider dell’istanza da gestire, verrà istanziato a run-time il modulo corretto che ne gestirà i backup. Questo design pattern è detto factory e rende il back-end facilmente estendibile in futuro per permettere di fornire le stesse funzionalità anche con Microsoft Azure come provider. Infatti, sarà necessario unicamente implementa- re l’interfaccia con una classe MicrosoftModule che definisce i metodi per creare ed eliminare correttamente i backup di un’istanza.
Figura 3.10: Package backup
3.4.4 Front-end
Ho realizzato una single page application come interfaccia utente. A questo scopo ho utilizzato Angular 4, come mi era stato richiesto dall’azienda. Questo framework offre una funzionalità detta lazy loading che permette di ridurre il tempo di caricamento dell’applicazione. Questo è possibile perchè Angular non carica subito tutti i moduli che vengono invece caricati solo nel momento in cui l’utente richiede una funzionalità associata al modulo stesso. Questo modo di operare rende l’esperienza dell’utente migliore e più fluida, specialmente all’avvio dell’applicazione.
Ho implementato i seguenti moduli:
3.5. CODIFICA 27
• login: permette di effettuare il login in Cloud Backup;
• backup: permette di vedere i backup dell’utente autenticato;
• scheduler: permette di inserire, modificare ed eliminare uno scheduler ;
• keys: permette ad un utente di inserire le credenziali dei provider ;
• instance: permette di associare un’istanza ad uno scheduler.
Ho riportato degli screenshot dell’interfaccia utente nella sezione 3.7, nel quale ho fornito anche una descrizione del prodotto finale.
3.5 Codifica
Dependency Injection
La Dependency Injection è un design pattern il cui scopo è quello di semplificare lo sviluppo e migliorare la testabilità del codice. Tale design pattern è utilizzato sia in Spring che in Angular. Per utilizzare questo design pattern è sufficiente dichiarare le dipendenze di cui una componente ha bisogno. Quando questa componente verrà istanziata, un injector si prenderà carico di risolvere le sue dipendenze.
In Spring, le dipendenze vengono indicate con l’annotazione @Autowired: il para- metro contrassegnato da questa annotazione verrà iniettato da Spring, evitando che sia il programmatore a doversene occupare. Vediamo di seguito un esempio:
@ R e s t C o n t r o l l e r
@ R e q u e s t M a p p i n g (" / l o g i n ") p u b l i c c l a s s L o g i n C o n t r o l l e r {
@ A u t o w i r e d
p r i v a t e L o g i n S e r v i c e l o g i n S e r v i c e ; // M e t o d i
}
Listing 3.1: Dependency Injection in Java
In questo caso, la classe LoginController ha tra le sue dipendenze LoginService. Poichè loginService è decorato con l’annotazione @Autowired, l’injector di Spring si occuperà di iniettare correttamente il valore del campo dati.
In Angular la Dependency Injection viene usata con i service (forniscono funzionalità condivise tra i component) i quali vengono decorati con l’annotazione @Injectable().
Successivamente, all’interno dei decoratori @NgModule, utilizzati per decorare i moduli Angular, viene specificata una lista dei service che vengono utilizzati dal modulo e dalle sue componenti. Questa lista viene specificata nell’attributo providers del @NgModule.
Riporto di seguito un esempio facente riferimento al mio modulo Angular che gestisce i backup:
28 CAPITOLO 3. RESOCONTO DELLO STAGE
// U t i l i z z a n d o I n j e c t a b l e () q u e s t o s e r v i z i o p o t r a ’ e s s e r e i n i e t t a t o nei // m o d u l i che n e c e s s i t a n o d e l l e f u n z i o n a l i t a ’ o f f e r t e dal s e r v i c e
@ I n j e c t a b l e ()
e x p o r t c l a s s B a c k u p S e r v i c e {
c o n s t r u c t o r ( p r i v a t e h t t p : H t t p C l i e n t , p r i v a t e t o k e n S e r v i c e : T o k e n S e r v i c e ) { }
p u b l i c g e t A l l B a c k u p s () : O b s e r v a b l e < any > {
let h e a d e r s : H t t p H e a d e r s = n e w H t t p H e a d e r s () . set (’ A u t h o r i z a t i o n ’, t h i s. t o k e n S e r v i c e . g e t T o k e n () ) ;
r e t u r n t h i s. h t t p . get (‘ $ { url }/ b a c k u p s ‘, { h e a d e r s : h e a d e r s }) ; }
p u b l i c g e t A l l B a c k u p s P r o v i d e r ( p r o v i d e r : s t r i n g ) : O b s e r v a b l e < any > { let h e a d e r s : H t t p H e a d e r s = n e w H t t p H e a d e r s () . set (’ A u t h o r i z a t i o n ’,
t h i s. t o k e n S e r v i c e . g e t T o k e n () ) ;
r e t u r n t h i s. h t t p . get (‘ $ { url }/ b a c k u p s / $ { p r o v i d e r } ‘, { h e a d e r s : h e a d e r s }) ;
}
}
// S p e c i f i c h i a m o B a c k u p S e r v i c e n e l l a l i s t a p r o v i d e r s . Il s e r v i z i o p o t r a ’ // e s s e r e i n i e t t a t o n e l l e c o m p o n e n t i che c o s t i t u i s c o n o B a c k u p M o d u l e i m p o r t { B a c k u p S e r v i c e } f r o m ’ ../ s e r v i c e / b a c k u p . s e r v i c e ’;
@ N g M o d u l e ({
d e c l a r a t i o n s : [ B a c k u p C o m p o n e n t ] ,
i m p o r t s : [ b a c k u p R o u t e r , C o m m o n M o d u l e , P i p e M o d u l e ] ,
p r o v i d e r s : [ B a c k u p S e r v i c e ]
})
e x p o r t c l a s s B a c k u p M o d u l e { }
i m p o r t { B a c k u p S e r v i c e } f r o m ’ ../ s e r v i c e / b a c k u p . s e r v i c e ’;
@ C o m p o n e n t ({
s e l e c t o r : ’ b a c k u p s ’,
t e m p l a t e U r l : ’ b a c k u p . c o m p o n e n t . h t m l ’, s t y l e U r l s : [’ b a c k u p . c o m p o n e n t . css ’]
})
e x p o r t c l a s s B a c k u p C o m p o n e n t i m p l e m e n t s O n D e s t r o y { // C a m p i d a t i
c o n s t r u c t o r ( p r i v a t e b a c k u p S e r v i c e : B a c k u p S e r v i c e ) { // b a c k u p S e r v i c e v i e n e i n i e t t a t o da A n g u l a r . }
// M e t o d i
}
Listing 3.2: Dependency Injection in Angular