Università degli Studi di Padova
←
→
Trascrizione del contenuto della pagina
Se il tuo browser non visualizza correttamente la pagina, ti preghiamo di leggere il contenuto della pagina quaggiù
Università degli Studi di Padova Dipartimento di Matematica "Tullio Levi-Civita" Corso di Laurea in Informatica Studio e applicazione di tecnologie alternative a Java in ambito Enterprise Tesi di Laurea Triennale Relatore Prof. Mauro Conti Laureando Paolo Broglio Anno Accademico 2018-2019
Paolo Broglio: Studio e applicazione di tecnologie alternative a Java in ambito Enterprise, Tesi di Laurea Triennale, c Luglio 2019.
Dedicato alla mia famiglia.
Sommario Il presente documento descrive il lavoro svolto durante il periodo di stage, della durata di circa trecento ore, dal laureando Paolo Broglio presso l’azienda Infocert S.p.A. L’obiettivo dello stage consisteva nel ricercare, analizzare e utilizzare linguaggi di programmazione alternativi a Java per la realizzazione di software utilizzato in ambito Enteprise. In primo luogo era richiesta un’analisi del panorama tecnologico per quanto concerne i linguaggi di programmazione che permettono di produrre software eseguibile su Java Virtual Machine. Come compito correlato è stata vista come possibilità l’utilizzo di Application Server alternativi a JBoss, lo standard de facto per Infocert S.p.A. In seguito allo studio di cui sopra è stato richiesto di implementare un microservizio la cui funzionalità principale fosse quella di rendere disponibile via interfaccia REST tutte le operazioni possibili esposte da una Certification Authority preesistente. v
Ringraziamenti Innanzitutto, vorrei ringraziare il Prof. Mauro Conti, relatore della mia tesi, per la disponibilità dimostratami durante il percorso che si è concluso con la mia Laurea. Desidero ringraziare i miei genitori e tutti i miei amici e colleghi per avermi sostenuto sempre nelle mie scelte, facendomi superare tutti i momenti di difficoltà che ho incon- trato durante il mio percorso accademico. Padova, Luglio 2019 Paolo Broglio vii
Indice 1 Introduzione 1 1.1 Il futuro digitale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.2 L’azienda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.3 L’idea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.4 Organizzazione del testo . . . . . . . . . . . . . . . . . . . . . . . . . . 2 2 Obiettivi del progetto 3 2.1 Studio e analisi dei linguaggi eseguibili su JVM . . . . . . . . . . . . . 3 2.2 Sviluppo di un prodotto software utilizzando le tecnologie scelte . . . . 3 2.3 Analisi e studio delle performance . . . . . . . . . . . . . . . . . . . . 3 2.4 Obiettivi collaterali . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 3 Descrizione dello stage 5 3.1 Introduzione al progetto . . . . . . . . . . . . . . . . . . . . . . . . . . 5 3.1.1 Temi trattati . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 3.1.2 Sviluppo del prodotto software . . . . . . . . . . . . . . . . . . 5 3.2 Analisi preventiva dei rischi . . . . . . . . . . . . . . . . . . . . . . . . 7 3.3 Requisiti e milestones . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 3.3.1 Requisiti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 3.3.2 Milestones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 3.4 Pianificazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 4 Studio e analisi delle tecnologie 9 4.1 Linguaggi di programmazione JVM compatibili . . . . . . . . . . . . . 9 4.1.1 Organizzazione dello studio . . . . . . . . . . . . . . . . . . . . 9 4.1.2 Kotlin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 4.1.3 Groovy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 4.1.4 Scala . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 4.1.5 Clojure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 4.2 Enterprise application framework . . . . . . . . . . . . . . . . . . . . . 13 4.3 Conclusione dell’analisi . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 5 Ambiente e strumenti 15 5.1 Ambiente di lavoro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 5.2 Strumenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 5.2.1 Organizzativi e di documentazione . . . . . . . . . . . . . . . . 15 5.2.2 Sviluppo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 6 Analisi dei requisiti 17 ix
x INDICE 6.1 Consolidamento dei requisiti . . . . . . . . . . . . . . . . . . . . . . . . 17 6.1.1 Requisiti del sistema . . . . . . . . . . . . . . . . . . . . . . . . 17 6.2 Casi d’uso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 6.3 Tracciamento dei requisiti . . . . . . . . . . . . . . . . . . . . . . . . . 20 7 Progettazione 23 7.1 Progettazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 7.1.1 Architettura . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 7.1.2 Classi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 7.2 Design Pattern utilizzati . . . . . . . . . . . . . . . . . . . . . . . . . . 28 7.2.1 Abstract Factory . . . . . . . . . . . . . . . . . . . . . . . . . . 28 7.2.2 Dependency Injection . . . . . . . . . . . . . . . . . . . . . . . 28 8 Sviluppo 29 8.1 Struttura del progetto . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 8.2 Sviluppo modulo REST . . . . . . . . . . . . . . . . . . . . . . . . . . 29 8.2.1 Definizione delle risorse . . . . . . . . . . . . . . . . . . . . . . 29 8.2.2 Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 8.3 Sviluppo modulo CORE . . . . . . . . . . . . . . . . . . . . . . . . . . 31 8.3.1 Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 8.3.2 Connector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 8.4 Sviluppo modulo CONNECTOR . . . . . . . . . . . . . . . . . . . . . 32 8.4.1 Decoder ed Encoder . . . . . . . . . . . . . . . . . . . . . . . . 33 8.4.2 Client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 9 Verifica e validazione 35 9.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 9.1.1 Test di Unità . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 9.1.2 Test di Integrazione . . . . . . . . . . . . . . . . . . . . . . . . 36 9.1.3 Test di performance . . . . . . . . . . . . . . . . . . . . . . . . 36 10 Conclusioni 41 10.1 Consuntivo finale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 10.2 Raggiungimento degli obiettivi . . . . . . . . . . . . . . . . . . . . . . 41 10.2.1 Studio delle tecnologie alternative a Java su JVM . . . . . . . . 41 10.2.2 Sviluppo prodotto software con le tecnologie scelte . . . . . . . 41 10.2.3 Analisi delle performance . . . . . . . . . . . . . . . . . . . . . 41 10.3 Conoscenze acquisite . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 10.4 Valutazione personale . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 A Appendice A 43 A.1 Specifiche IETF di messaggi PKIX . . . . . . . . . . . . . . . . . . . . 43 A.1.1 Certification Request - PKCS10 . . . . . . . . . . . . . . . . . . 43 Glossary 45 Acronyms 49 Bibliografia 51
Elenco delle figure 3.1 CA-PROXY mette in comunicazione RA e CA. . . . . . . . . . . . . . 6 3.2 Pianificazione stage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 6.1 Koraca Use Cases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 7.1 Architettura del Proxy . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 7.2 Modulo REST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 7.3 Modulo REST: bean risposta/richiesta . . . . . . . . . . . . . . . . . . 24 7.4 Modulo CORE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 7.5 Modulo CONNECTOR . . . . . . . . . . . . . . . . . . . . . . . . . . 27 9.1 Tempo totale di risposta. . . . . . . . . . . . . . . . . . . . . . . . . . 37 9.2 Tempo medio di risposta. . . . . . . . . . . . . . . . . . . . . . . . . . 37 9.3 Utilizzo della CPU. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 9.4 Utilizzo della RAM. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 Elenco delle tabelle 4.1 Confronto Linguaggi di Programmazione. . . . . . . . . . . . . . . . . 10 4.2 Confronto Framework. . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 6.1 Tabella dei requisti funzionali . . . . . . . . . . . . . . . . . . . . . . . 18 6.2 Tabella dei requisti di sicurezza . . . . . . . . . . . . . . . . . . . . . . 18 6.3 Tabella del tracciamento dei requisti funzionali . . . . . . . . . . . . . 21 6.4 Tabella del tracciamento dei requisiti qualitativi . . . . . . . . . . . . 21 xi
xii ELENCO DELLE TABELLE
Capitolo 1 Introduzione 1.1 Il futuro digitale Il contesto applicativo cui ho dovuto fare riferimento durante lo svolgimento dello stage è quello dell’ufficio digitale, ovvero ottenere la completa informatizzazione degli strumenti e dei processi che vanno a costituire un ufficio. L’eliminazione della carta come materia prima per lo svolgimento di queste attività è uno degli obiettivi che si pone questa trasformazione, ottenendo non solo la riduzione dell’utilizzo di questo materiale, ma anche una velocizzazione e una affidabilità che al giorno d’oggi risultano indispensabili. In particolare per quanto riguarda la mia esperienza di stage mi sono dovuto concentrare nell’ambito della Firma Digitale[g] . 1.2 L’azienda Infocert S.p.A. è una delle più importanti Certification Authority a livello europeo e fornisce servizi di firma digitale, Posta Elettronica Certificata (PEC)[g] , Sistema Pubblico di Identità Digitale (SPID)[g] , e fatturazione elettronica. L’obiettivo principale dell’azienda è quello di rendere disponibili tutti gli strumenti per la creazione di un ufficio digitale, fornendo ai propri clienti soluzioni paperless. Queste vengono fornite ad altre aziende e a professionisti come: ∗ Commercialisti; ∗ Avvocati e notai; ∗ Liberi professionisti e Partite IVA. 1.3 L’idea Il progetto di stage è nato da un bisogno dell’azienda: valutare e mettere in pratica tecnologie alternative a Java per lo sviluppo di applicazioni web. La scelta del linguaggio di programmazione è stata associata alla ricerca una soluzione alternativa all’application server JBoss[g] per la creazione di un Microservizio[g] utilizzando le tecnologie scelte. Infine si è pensato di eseguire delle comparazioni in termini di performance tra l’applicativo sviluppato e uno preesistente. 1
2 CAPITOLO 1. INTRODUZIONE 1.4 Organizzazione del testo Il secondo capitolo descrive gli obiettivi finali del progetto di stage; Il terzo capitolo descrive lo stage; Il quarto capitolo tratta lo studio e l’analisi delle tecnologie oggetto del progetto di stage; Il quinto capitolo approfondisce lo studio dei linguaggi basati su Java Virtual Machine (JVM)[g] e le alternative in ambito enterprise; Il sesto capitolo tratta l’analisi dei requisiti del software; Il settimo capitolo tratta la progettazione del software; L’ottavo capitolo tratta l’evoluzione dello sviluppo del software; Il nono capitolo approfondisce il periodo di verifica e validazione; Il decimo capitolo contiene le conclusioni. In merito alla stesura del testo sono state adottate le seguenti convenzioni tipografi- che: ∗ gli acronimi, le abbreviazioni e i termini ambigui o di uso non comune menzionati vengono definiti nel glossario, situato alla fine del documento; ∗ per la prima occorrenza dei termini riportati nel glossario viene utilizzata la seguente nomenclatura: parola [g] ; ∗ i termini in lingua straniera o facenti parti del gergo tecnico sono evidenziati con il carattere corsivo.
Capitolo 2 Obiettivi del progetto In questo capitolo verranno illustrati gli obiettivi principali e quelli collaterali scaturiti dal colloquio con il tutor aziendale. 2.1 Studio e analisi dei linguaggi eseguibili su JVM Lo studio delle tecnologie alternative a quelle standard aziendali, come Java e JBoss è stato l’obiettivo principale di questo progetto. Si è pensato di rivolgere l’attenzione non solo al linguaggio di programmazione ma anche ad un application server differente ed eventualmente a Framework[g] per la creazione di applicazioni web . 2.2 Sviluppo di un prodotto software utilizzando le tecnologie scelte In seguito all’analisi di cui al punto precedente si è pensato di sviluppare un applicativo utilizzando le tecnologie scelte. Per la scelta di quale software sviluppare, si è pensato, in accordo col tutor aziendale, di creare un prodotto simile ad uno preesistente sviluppato con le tecnologie standard. 2.3 Analisi e studio delle performance Come conclusione dello sviluppo dell’applicativo si è pensato di eseguire uno studio delle performance eseguendo un paragone con il software originale. In questo modo si è pensato di rendere evidenti le differenze tra le due scelte tecnologiche sfruttando dati oggettivi. 2.4 Obiettivi collaterali Di seguito sono elencati tutti gli obiettivi secondari ma necessari allo svolgimento del progetto di stage. 3
4 CAPITOLO 2. OBIETTIVI DEL PROGETTO ∗ Metodologia di sviluppo Agile: dal momento che il processo di sviluppo del software all’interno dell’azienda sfrutta la metodologia Agile[g] , si è pensato di approfondire e utilizzarla specificatamente nelli svolgimento del progetto di stage; ∗ Certificati e firma digitale: essendo i servizi di punta dell’azienda, si è valutato di studiare e approfondire la tecnologia della firma digitale, con lo scopo di utilizzare queste conoscenze per lo sviluppo dell’applicativo previsto. L’attenzione è stata posta all’intero argomento Public Key Infrastructure (PKI)[g] .
Capitolo 3 Descrizione dello stage Questo capitolo ha lo scopo di illustrare il contenuto dello stage, completo di requisiti e pianificazione. 3.1 Introduzione al progetto 3.1.1 Temi trattati Lo stage ha previsto l’inserimento dello studente nel team operativo LEGALCERT che si occupa di firma digitale. Gli argomenti trattati sono stati principalmente: ∗ Linguaggi di programmazione basati su JVM, alternativi a Java (Kotlin, Scala, Clojure, Groovy); ∗ tecnologie per la realizzazione di microservizi in ambito enterprise (Spring Boot, ecc.); ∗ metodologia di sviluppo Agile; ∗ PKI. 3.1.2 Sviluppo del prodotto software Per mettere in pratica lo studio e l’analisi delle tecnologie, e l’approfondimento sulla PKI e la firma digitale, si è pensato di procedere con la realizzazione di un microservizio, prendendo spunto da un altro servizio preesistente, sviluppato con le tecnologie standard aziendali. Tale servizio deve soddisfare i seguenti requisiti: ∗ Deve mettere in comunicazione una Registration Authority (RA)[g] e una Certifi- cation Authority (CA); ∗ deve rendere disponibili le operazioni di emissione, revoca, sospensione e riattivazione di un certificato; ∗ deve essere configurabile e agnostico agli attori che ci interagiscono; ∗ deve poter rimpiazzare senza nessuna modifica il servizio preesistente. 5
6 CAPITOLO 3. DESCRIZIONE DELLO STAGE In seguito allo sviluppo è stato chiesto di creare una Test Suite[g] di carico per analizzare le performance del microservizio sviluppato, creando dei grafici di comparazione col prodotto interno all’azienda. Il microservizio prende il nome di CA-PROXY. Figura 3.1: CA-PROXY mette in comunicazione RA e CA.
3.2. ANALISI PREVENTIVA DEI RISCHI 7 3.2 Analisi preventiva dei rischi Durante la fase di analisi iniziale sono stati individuati alcuni possibili rischi. Si è quindi proceduto a elaborare delle possibili soluzioni per far fronte a tali rischi. 1. Argomenti sconosciuti Descrizione: Utilizzo di tecnologie mai studiate, come quelle relative alla JVM, alternative a Java, e alcuni strumenti di sviluppo e gestione di progetto. Soluzione: coinvolgimento di Product Owner in ambito SCRUM per l’organizzazione del progetto e introduzione di attività di studio delle nuove tecnologie. 2. Tecnologie emergenti Descrizione: Alcune delle tecnologie, oggetto di studio dello stage, sono emergenti nell’azienda e quindi i membri del team in cui lo studente è inserito non possono contribuire attivamente alla formazione dello studente stesso. Soluzione: Sessioni di pair programming e condivisione dei risultati di studio da parte dello studente. 3.3 Requisiti e milestones 3.3.1 Requisiti Si farà riferimento ai requisiti secondo le seguenti notazioni: ∗ min: per i requisiti minimi, vincolanti in quanto obiettivo primario richiesto dal committente; ∗ max: per i requisiti massimi (comprendenti quelli desiderabili e opzionali), non vincolanti o strettamente necessari, ma dal riconoscibile valore aggiunto; ∗ for: per gli obiettivi formativi, rappresentanti valore aggiunto non strettamente competitivo. Le sigle precedentemente indicate saranno seguite da una coppia sequenziale di numeri, identificativo del requisito. Sono stati previsti i segunti requisiti: Minimi ∗ min01: analisi dei linguaggi JVM compatibili in ottica enterprise; ∗ min02: realizzazione di un microservice con un linguaggio JVM compatibile; ∗ min03: utilizzo di tool di sviluppo Git, Maven, Jenkins; ∗ min04: report finale di analisi delle performance. Massimi ∗ max01: Interfacciamento completo del microservizio realizzato con gli attuali sistemi PKI.
8 CAPITOLO 3. DESCRIZIONE DELLO STAGE Formativi ∗ for01: comprensione dei sistemi di cifratura e firma digitale; ∗ for02: utilizzo della metodologia Agile in ambito aziendale; ∗ for03: collegato a min01. Studio dei linguaggi di programmazione compatibili con JVM in ottica enterprise. 3.3.2 Milestones Di seguito è riportato l’elenco delle milestone previste nell’arco temporale dello sta- ge. Ad ogni milestone è stato associato un oggetto deliverable prodotto entro ogni corrispondente scadenza. Le milestone fissate sono le seguenti: 1. Fine seconda settimana: creazione del microservizio utilizzando le tecnologie scelte durante le attività di studio della prima settimana; 2. Fine terza settimana: compatibilità del microservizio con le correnti interfacce REST di RACA, implementate tramite mock ; 3. Fine quarta settimana: appresa conoscenza di ASN.1 e PKI Message; 4. Fine quinta settimana: prodotto che presenta una comunicazione minima verso la Certification Authority; 5. Fine sesta settimana: prodotto che permetta l’emissione, la revoca, la riattivazione e la sospensione dei certificati; 6. Fine settima settimana: compatibilità con attuale Registration Authority; 7. Fine ottava settimana: report contenente risultati di analisi delle performance del prodotto. Il report deve avere un confronto con le performance dell’attuale tencologia utilizzata: RACA. 3.4 Pianificazione Di seguito è riportato il diagramma di Gantt relativo alle attività svolte durante lo stage. Figura 3.2: Pianificazione stage
Capitolo 4 Studio e analisi delle tecnologie 4.1 Linguaggi di programmazione JVM compatibili In questa sezione verranno presentati i linguaggi di programmazione alternativi a Java che possono essere usati per creare programmi eseguibili su Java Virtual Machine. Le versioni sono state analizzate al momento dell’inizio del periodo di stage, nel novembre 2017. 4.1.1 Organizzazione dello studio Aspetti analizzati Di seguito sono enumerati tutti i parametri e gli aspetti presi in considerazione per poter attuare un confronto significativo ed effettuare una scelta per la prosecuzione del progetto. ∗ Tipizzazione: Statica - Dinamica; ∗ Paradigma: OOP - Funzionale; ∗ Interoperabilità con Java: Bassa - Media - Alta. Discriminante necessaria in ottica di utilizzo del linguaggio studiato per integrarlo con software preesistenti sviluppati con Java; ∗ Altri aspetti: presenti nello studio, ma non inseriti nella tabella di comparazione perché di secondaria importanza. Risorse e materiale di riferimento Di seguito sono elencate le risorse prese come riferimento per eseguire lo studio: ∗ Kotlin: Documentazione di Kotlin1 , Kotlin in Action2 ; ∗ Scala: Documentazione di Scala3 , Functional Programming in Scala4 ; 1 Kotlin Documentation. url: https://kotlinlang.org/docs/reference/. 2 SvetlanaIsakova Dmitry Jemerov. Kotlin in Action. Manning, 2017. 3 Scala Documentation. url: https://docs.scala-lang.org/. 4 Rúnar Bjarnason Paul Chiusano. Functional Programming in Scala. Manning, 2014. 9
10 CAPITOLO 4. STUDIO E ANALISI DELLE TECNOLOGIE ∗ Clojure: Documentazione di Clojure5 ; ∗ Groovy: Documentazione di Groovy6 . Tabella 4.1: Confronto Linguaggi di Programmazione. Nome Tipizzazione Paradigma Interoperabilità Java Versione Kotlin Statica OOP Alta v1.1.50 Scala Statica Fun/OOP Alta v2.12.3 Groovy Dinamica OOP Media v2.4.9 Clojure Dinamica Fun Media v1.8.0 4.1.2 Kotlin Vantaggi ∗ Pensato per essere un linguaggio di programmazione semplice e volto alla pro- duttività. Uno degli aspetti più interessanti in questo senso è la rimozione ove possibile delle Cerimonie[g] ; ∗ Mantiene i concetti di OOP, aggiungendo proprietà del Paradigma Funzionale, per esempio l’immutabilità e le higher order function; ∗ Sviluppato e mantenuto da JetBrains, azienda famosa per IntelliJIDEA. Inoltre è stato reso Open Source, il che ha contribuito alla creazione di strumenti creati dalla comunità di GitHub; ∗ L’elevata interoperabilità con Java rappresenta un altro punto di forza, permet- tendo di utilizzare qualsiasi libreria scritta in Java senza alcuna difficoltà; ∗ Le risorse di riferimento come la documentazione sono chiare e ben strutturare, offrendo una buona esperienza per chi deve consultare le specifiche del linguaggio. Svantaggi ∗ La maturità del linguaggio è un aspetto fondamentale nel caso di un’azienda che ha bisogno di tecnologie molto stabili. JetBrains si è prodigata molto in tal senso ma per raggiungere il livello di Java ci vuole ancora tempo, sia per le ottimizzazioni in fatto di compilazione sia per il supporto a determinate librerie sviluppate utilizzando proprio Java. Va comunque fatto presente che Google ha deciso di sceglierlo come linguaggio de facto per lo sviluppo di applicazioni per sistema operativi Android, il che ha portato una notevole crescita nel numero di aziende che hanno iniziato ad utilizzarlo per i propri prodotti software. 5 Clojure Documentation. url: http://clojure-doc.org/. 6 Groovy Documentation. url: http://groovy-lang.org/documentation.html.
4.1. LINGUAGGI DI PROGRAMMAZIONE JVM COMPATIBILI 11 Conclusioni Kotlin è stato più volte considerato come il successore di Java in diversi contesti (oltre al supporto per Android, anche Pivotal ha iniziato a raccomandarlo rispetto a Java), ed è considerato da esperti del settore un "linguaggio su cui scommettere"7 . Un aspetto da non sottovalutare riguarda alcuni costrutti del linguaggio, quali ad esempio le Data Class che permettono di creare strutture dati immutabili, con un numero di righe di codice irrisorio (da una ad un numero che corrisponde alla cardinalità dei campi di classe). In seguito all’analisi Kotlin si è rivelato essere un buon candidato per il progetto di stage. 4.1.3 Groovy Vantaggi ∗ La tipizzazione dinamica offre un vantaggio notevole in termini di produttività (questo è dovuto al fatto che i linguaggi di questo tipo sono maggiormente concisi). Un aspetto interessante è la possibilità di utilizzare la tipizzazione statica tramite l’utilizzo di annotazioni specifiche, offrendo flessibilità allo sviluppatore; ∗ Il manutentore è Apache Foundation che ha reso Open Source il linguaggio; ∗ La documentazione è un ulteriore punto di forza, molto chiara e ben approfondita. Svantaggi ∗ Groovy possiede molteplici annotazioni specifiche per l’utilizzo del linguaggio, come quelle inerenti alla tipizzazione di cui sopra. Questo rappresenta anche uno difetto, in quanto le annotazioni, se non utilizzate come documentazione del codice, rischiano di risultare invasive; ∗ Non è un linguaggio di programmazione che "riscuote successo" alla pari di Scala oppure Kotlin e nella comunità Open Source rimane in una cerchia abbastanza ristretta; ∗ La parziale interoperabilità con Java è un difetto non trascurabile dal momento che è una discriminante molto importante per questo studio. Conclusioni Groovy è un linguaggio che presenta una sintassi che non si discosta molto da quella di Java (come nel caso di Kotlin), facilitando un’eventuale migrazione verso questo ultimo. Per contro lo scarso interesse riscontrato nella comunità Open Source non lo mette in buona luce come candidato. Inoltre in azienda è parzialmente utilizzato per la scrittura di test automatici grazie al framework SoapUI, che però è in dismissione, cercando di favorire librerie sviluppate in Java. 4.1.4 Scala Vantaggi ∗ La possibilità di adottare il paradigma funzionale senza rinunciare alla program- mazione orientata agli oggetti fa di Scala il tratto distintivo più importante. Il 7 Dmitry Jemerov, Kotlin in Action.
12 CAPITOLO 4. STUDIO E ANALISI DELLE TECNOLOGIE concetto di base per cui le funzioni sono cittadini di primo ordine porta notevoli benefici, testabilità in primis; ∗ L’ecosistema di Scala è stato reso Open Source, e la comunità che lo circonda esorta gli utilizzatori a contribuire alla sua crescita. In questo caso il linguaggio è stato creato da ricercatori della Scuola Politecnica di Losanna, ambiente che è stato determinante per la progettazione del linguaggio; ∗ Il supporto è costante, la documentazione è ampia e approfondita. Da non sotto- valutare la presenza di innumerevoli risorse come libri, articoli e conferenze che trattano Scala in ogni suo aspetto. Svantaggi ∗ Scala è considerato un linguaggio di programmazione che presenta una curva di apprendimento ripida a causa del paradigma funzionale e per una sintassi nettamente diversa da Java. Nonostante la quantità di risorse di apprendimento disponibili, perfezionare la conoscenza del linguaggio non è facile e il tempo richiesto potrebbe essere molto. Conclusioni Scala è un linguaggio dalle ottime potenzialità a causa di tutti i pregi che presenta grazie ad una progettazione eseguita con cognizione di causa per quanto riguarda la qualità del software e la produttività8 . La maturità e il largo utilizzo, soprattutto in realtà in cui efficienza ed efficacia sono di massima importanza, sono proprietà fondamentali e in questo caso soddisfatte in pieno. La ripida curva di apprendimento è l’unico ostacolo evidenziato nel corso dell’analisi. 4.1.5 Clojure Vantaggi ∗ Utilizza il paradigma funzionale, essendo un dialetto del linguaggio LISP[g] . Questa proprietà porta notevoli benefici come nel caso di Scala; ∗ Come per gli altri linguaggi, anche in questo caso è la comunità Open Source a far maturare l’ecosistema; ∗ L’obiettivo principale è rendere più semplice la creazione di applicazioni concor- renti e parallele, sfruttando l’immutabilità e alcuni costrutti che sono specifici di questo linguaggio, come gli atoms. Svantaggi ∗ Obbliga a utilizzare esclusivamente il paradigma funzionale, quindi manca di flessibilità rispetto a Scala; ∗ La sintassi di Clojure è estremamente differente da quella di Java, obbligando lo sviluppatore ad un periodo di formazione che sicuramente supererebbe quello richiesto per Scala; 8 Paul Chiusano, Functional Programming in Scala.
4.2. ENTERPRISE APPLICATION FRAMEWORK 13 ∗ Manca un supporto stabile per Integrated Development Environment (IDE) come Eclipse e IntelliJIDEA. L’editor di testo più indicato è Emacs, che risulterebbe estraneo alle regole di sviluppo aziendali. Conclusioni Clojure è molto interessante perché tra tutti i linguaggi analizzati è quello che obbliga a ragionare solamente col paradigma funzionale. Come precedentemente descritto, questo aspetto porta anche degli svantaggi, e nel dominio applicativo cui questo progetto fa capo, non risulta essere una buona soluzione. Inoltre la migrazione da Java richiederebbe una quantità di tempo eccessiva. Il mancato supporto a strumenti di sviluppo che sono standard per l’azienda è un ulteriore discriminante da prendere in considerazione. 4.2 Enterprise application framework In questa sezione verranno presentati i framework e le librerie analizzate come alterna- tive a Java Enterprise Edition e all’application server JBoss. Gli aspetti analizzati sono: ∗ Enterprise: Sì - No. Specifica se la libreria o il framework analizzato è utlizzabile in ambito enterprise; ∗ JPA: Sì - No. Uno dei requisiti di questa analisi è la possibilità di utilizzare Java Persistence API (JPA) per poter usufruire della persistenza su una base di dati; ∗ Documentazione: Insufficiente - Buona - Ottima; ∗ Integrazione: nome del linguaggio utilizzabile. Questo aspetto è fondamentale per poter scegliere un framework che possa essere integrabile con i linguaggi analizzati; ∗ Altri aspetti: presenti nello studio, ma non inseriti nella tabella di comparazione perché di secondaria importanza. Tabella 4.2: Confronto Framework. Nome Enterprise JPA Documentazione Integrazione Spring Sì Sì Ottima Kotlin/Scala Grails Sì Sì Ottima Groovy Play No Sì Buona Java/Scala 4.3 Conclusione dell’analisi Di seguito sono riportati i risultati dell’analisi, completi delle tecnologie scelte per la prosecuzione del progetto di stage:
14 CAPITOLO 4. STUDIO E ANALISI DELLE TECNOLOGIE ∗ Kotlin: in prima istanza Scala è risultato essere migliore sotto molti aspetti, ma a causa della ripida curva di apprendimento si è pensato di sceglier Kotlin. L’interoperabilità con Java e la somiglianza con la sua sintassi ne fanno un linguaggio ottimo da utilizzare come alternativa; ∗ Spring: è notoriamente l’alternativa più famosa a Java EE. Spring è sviluppato e manutenuto da Pivotal, che ha reso Open Source il progetto Spring Boot, per la creazione di microservizi. Spring si è rivelato essere molto affidabile in seguito all’analisi eseguita, largamente utilizzato e integrabile sia con Java, sia con Kotlin. La documentazione è chiara e ben strutturata, ricca di esempi con listati di Java e Kotlin.
Capitolo 5 Ambiente e strumenti In questo capitolo verranno illustrati l’ambiente di lavoro e gli strumenti utilizzati. 5.1 Ambiente di lavoro L’ambiente di lavoro scelto è la distribuzione Linux denominata Kubuntu nella sua versione 16.04. 5.2 Strumenti 5.2.1 Organizzativi e di documentazione ∗ Jira: strumento organizzativo usato per la gestione di progetto, in particolare per la metodologia di sviluppo Scrum. Fa parte della suite messa a disposizione di Atlassian e usata internamente all’azienda; ∗ Confluence: strumento facente parte della suite messa a disposizione da Atlas- sian, usato per la gestione della documentazione. Usato internamente all’azienda. 5.2.2 Sviluppo ∗ IntelliJ IDEA: IDE sviluppato e mantenuto da Jetbrains, usato per la codifica del software; ∗ JDK 1.8: Kit di sviluppo per il linguaggio di programmazione Java comprendente strumenti come il compilatore javac, il tool documentale javadoc e altri. La JDK versione 1.8 distribuita da Oracle; ∗ Spring Boot: framework per la creazione di microservizi. È prodotto e mantenuto da Pivotal; ∗ Kotlin: linguaggio di programmazione Open Source mantenuto da Jetbrains; ∗ GitLab: server e repository per il versionamento del codice sorgente; ∗ Jenkins: server e strumento di Continuous Integration (CI) per l’automatizza- zione della fase di build del progetto. 15
Capitolo 6 Analisi dei requisiti Questo capitolo approfondisce l’analisi dei requisiti in merito alla creazione del microservizio 6.1 Consolidamento dei requisiti Di seguito verrà espanso e consolidato il requisito min02: realizzazione di un microservizio con un linguaggio eseguibile da JVM. Il codice dei requisiti è così strutturato R(F/S)(OB/DE/OP) X.Y.Z dove: R = requisito F = funzionale S = sicurezza OB = obbligatorio (necessario) DE = desiderabile OP = opzionale X = requisito di primo livello Y = requisito di secondo livello Z = requisito di terzo livello 6.1.1 Requisiti del sistema Nelle tabelle 6.1 e 6.2 sono riassunti i requisiti e il loro tracciamento con gli use case delineati in fase di analisi. 17
18 CAPITOLO 6. ANALISI DEI REQUISITI Tabella 6.1: Tabella dei requisti funzionali Requisito Descrizione RFOB-1.0.0 Il sistema deve emettere un certificato RFOB-1.1.0 Deve accettare un PKCS10 RFOB-2.0.0 Il sistema deve revocare un certificato RFOB-2.1.0 Deve accettare un serial number che identifica il certificato RFOB-3.0.0 Il sistema deve sospendere un certificato RFOB-3.1.0 Deve accettare un serial number che identifica il certificato RFOB-4.0.0 Il sistema deve riattivare un certificato RFOB-4.1.0 Deve accettare un serial number che identifica il certificato RFOB-5.0.0 Il sistema deve permettere di configurare una Certification Authority RFOB-5.1.0 Deve permettere di configurare la codifica della richiesta da mandare alla Certification Authority RFOB-5.2.0 Deve permettere di configurare la decodifica della risposta ricevuta dalla Certification Authority RFOB-5.3.0 Deve permettere di configurare i parametri per comunicare con la Certification Authority Tabella 6.2: Tabella dei requisti di sicurezza Requisito Descrizione RSOB-1.0.0 I parametri di comunicazione con Certification Authority sono cifrati RSOB-1.1.0 La cifratura deve essere eseguita in modo simmetrico RSOB-1.1.1 Deve usare l’algoritmo AES-256 RSOB-2.0.0 Il sistema deve firmare digitalmente le richiesta con un PKCS12 RFOB-2.1.0 Il PKCS12 è appartenente ad un Registration Authority Officer autorizzato
6.2. CASI D’USO 19 6.2 Casi d’uso Per lo studio dei casi di utilizzo del prodotto sono stati creati dei diagrammi. I diagrammi dei casi d’uso (in inglese Use Case Diagram) sono diagrammi di tipo Unified Modeling Language (UML) dedicati alla descrizione delle funzioni o servizi offerti da un sistema, così come sono percepiti e utilizzati dagli attori che interagiscono col sistema stesso. Figura 6.1: Koraca Use Cases UC1: Emissione di un nuovo certificato Attori Principali: Registration Authority, Certification Authority. Precondizioni: La Registration Authority è autorizzata all’operazione. Descrizione: È possibile emettere un nuovo certificato. Postcondizioni: Il sistema è pronto per permettere una nuova interazione. UC2: Revoca di un certificato Attori Principali: Registration Authority, Certification Authority. Precondizioni: La Registration Authority è autorizzata all’operazione. Descrizione: È possibile revocare un certificato. Postcondizioni: Il sistema è pronto per permettere una nuova interazione. UC3: Riattivazione di un nuovo certificato Attori Principali: Registration Authority, Certification Authority. Precondizioni: La Registration Authority è autorizzata all’operazione. Descrizione: È possibile riattivare un certificato.
20 CAPITOLO 6. ANALISI DEI REQUISITI Postcondizioni: Il sistema è pronto per permettere una nuova interazione. UC4: Sospensione di un nuovo certificato Attori Principali: Registration Authority, Certification Authority. Precondizioni: La Registration Authority è autorizzata all’operazione. Descrizione: È possibile sospendere un certificato. Postcondizioni: Il sistema è pronto per permettere una nuova interazione. 6.3 Tracciamento dei requisiti Da un’attenta analisi dei requisiti e dei casi d’uso effettuata sul progetto è stata stilata la tabella che traccia i requisiti in rapporto agli use case. Sono stati individuati diversi tipi di requisiti e si è quindi fatto utilizzo di un codice identificativo per distinguerli. Nelle tabelle 6.3 e 6.4 sono riassunti i requisiti e il loro tracciamento con gli use case delineati in fase di analisi.
6.3. TRACCIAMENTO DEI REQUISITI 21 Tabella 6.3: Tabella del tracciamento dei requisti funzionali Requisito Descrizione Use Case RFOB-1.0.0 Il sistema deve emettere un certificato UC1 RFOB-1.1.0 Deve accettare un PKCS10 UC1 RFOB-2.0.0 Il sistema deve revocare un certificato UC2 RFOB-2.1.0 Deve accettare un serial number che identifica il UC2 certificato RFOB-3.0.0 Il sistema deve sospendere un certificato UC4 RFOB-3.1.0 Deve accettare un serial number che identifica il UC4 certificato RFOB-4.0.0 Il sistema deve riattivare un certificato UC3 RFOB-4.1.0 Deve accettare un serial number che identifica il UC3 certificato Tabella 6.4: Tabella del tracciamento dei requisiti qualitativi Requisito Descrizione Use Case RSOB-1.0.0 I parametri di comunicazione con Certification UC1-2-3-4 Authority sono cifrati RSOB-1.1.0 La cifratura deve essere eseguita in modo simmetrico UC1-2-3-4 RSOB-1.1.1 Deve usare l’algoritmo AES-256 UC1-2-3-4 RSOB-2.0.0 Il sistema deve firmare digitalmente le richiesta con un UC1-2-3-4 PKCS12 RFOB-2.1.0 Il PKCS12 è appartenente ad un Registration Authority UC1-2-3-4 Officer autorizzato
Capitolo 7 Progettazione In questo capitolo verrà illustrata la progettazione del software tramite diagrammi UML e relative descrizioni. 7.1 Progettazione 7.1.1 Architettura Figura 7.1: Architettura del Proxy 23
24 CAPITOLO 7. PROGETTAZIONE 7.1.2 Classi Package REST Figura 7.2: Modulo REST Figura 7.3: Modulo REST: bean risposta/richiesta Di seguito verranno descritte le classi del package REST: CertificateController e CertificateControllerImpl: Punto di entrata per le ri- chieste che hanno come scopo le operazioni sui certificati delineate nei requisiti, ovvero emissione, revoca, sospensione e riattivazione;
7.1. PROGETTAZIONE 25 CertificateManager e CertificateManagerImpl: Facade per permettere al pac- kage REST di inoltrare le richieste al package CORE dell’applicazione; UpdateRequest: Classe immutabile usata per deserializzare il payload JSON conte- nuto nella richiesta di sospensione e riattivazione del certificato; RevokeRequest: Classe immutabile usata per deserializzare il payload JSON conte- nuto nella richiesta di revoca del certificato; EmissionRequest: Classe immutabile usata per deserializzare il payload JSON contenuto nella richiesta di emissione; CertificateEmissionRestResponse: Classe immutabile usata per la serializzazione della risposta di emissione del certificato in un payload JSON; CertificateRevokeRestResponse: Classe immutabile usata per la serializzazione della risposta di revoca del certificato in un payload JSON. CertificateUpdateRestResponse: Classe immutabile usata per la serializzazione della risposta di sospensione o riattivazione del certificato in un payload JSON.
26 CAPITOLO 7. PROGETTAZIONE Package CORE Figura 7.4: Modulo CORE Di seguito verranno descritte le classi del package CORE: CertificateEmitterService e CertificateEmitterServiceImpl: Interfaccia e re- lativa implementazione che rende più granulare l’operazione di emissione di un certificato; CertificateRevokerService e CertificateRevokerServiceImpl: Interfaccia e re- lativa implementazione che rende più granulare le operazioni di revoca, sospen- sione e riattivazione di un certificato;
7.1. PROGETTAZIONE 27 SecurityManager: Classe che si occupa della decifrare il token usato per la connes- sione alla Certification Authority richiesta dalla Registration Authority; ConnectorFactory e ConnectorFactoryImpl: Abstract factory che si occupa del- la creazione della classe che verrà usata per eseguire le chiamate alla Certification Authority; EmissionRequest: Classe immutabile usata per deserializzare il payload JSON contenuto nella richiesta di emissione; ConnectorManager: Interfaccia che viene implementata da un Connector esponendo i metodi per l’emissione, la revoca, la riattivazione e la sospensione del certificato; Package CONNECTOR Figura 7.5: Modulo CONNECTOR Di seguito verranno descritte le classi del package CONNECTOR: SignacertConnectorManager: Classe che implementa l’interfaccia ConnectorMa- nager che contiene la logica per istanziare un CAClient del tipo Signacert; CAClient: Interfaccia che deve essere implementata da un client per una specifica Certification Authority;
28 CAPITOLO 7. PROGETTAZIONE ClientCache: Incapsula la logica per la gestione di una cache che permette di ottenere un’istanza di un CAClient data una specifica chiave; SignacertClient: Implementazione di CAClient che contiene i parametri di connessio- ne alla Certification Authority denominata Signacert e che esegue la trasmissione e la ricezione dei dati; SignacertRequestEncoder: Classe che ha come scopo la codifica in PKIMessage della richiesta; SignacertRequestDecoder: Classe che ha come scopo la decodifica della risposta della Certification Authority Signacert in un modello interpretabile dal software. 7.2 Design Pattern utilizzati Di seguito sono elencati i design pattern applicati nella progettazione e conseguente sviluppo del software. 7.2.1 Abstract Factory Applicato nel package CORE per la produzione di istanze delle classi che implementano ConnectorManager. La creazione viene decisa tramite un identificativo che rappresenta univocamente una specifica Certification Authority all’interno del software tramite il nome della classe. Ogniqualvolta è necessario aggiungere una CA supportata è sufficiente implementare l’interfaccia ConnectorManager. Una richiesta indirizzata a quella specifica CA si realizzerà con la creazione dell’istanza di quella classe tramite la factory. 7.2.2 Dependency Injection Usata in tutti i package del software per diminuire l’accoppiamento tra le classi e sfruttando le interfacce con relative implementazioni. Si è usato il sistema di Dependency Injection proprio del framework di Spring Boot.
Capitolo 8 Sviluppo In questo capitolo viene trattato lo sviluppo dell’applicativo, package per package, seguendo la progettazione di cui ai capitoli precedenti. 8.1 Struttura del progetto Il progetto è stato strutturato seguendo le linee guida di sviluppo interne all’azienda Infocert S.p.A. Per questo motivo si è pensato di creare un modulo root e tre sotto- moduli, corrispondenti ai package definiti nel periodo di progettazione. Di seguito è riportata l’alberatura delle cartelle di primo livello. 8.2 Sviluppo modulo REST Il modulo REST contiene le classi necessarie alla definizione delle API RESTful dell’applicativo. 8.2.1 Definizione delle risorse La definizione delle risorse REST è fatta tramite le classi che presentano il suffisso Controller. Il codice include l’utilizzo delle annotation Java necessarie per poter creare la documentazione di Swagger API. @RequestMapping ( path = arrayOf ( " " ) , method = arrayOf ( RequestMethod . POST ) , consumes = arrayOf ( MediaType . APP LIC AT ION _J SON _VA LU E ) , produces = arrayOf ( MediaType . APP LIC AT ION _J SON _VA LU E ) ) @ApiOperation ( value = " Emit c e r t i f i c a t e " , response = C e rt E m is s i on R e st R e sp o n se :: class ) fun emitCertificate ( @RequestHeader ( value = " r a c a −t o k e n " ) racaToken : String , @RequestBody certEmissionRequest : CertEmissionRequest ) : ResponseEntity < Any > 29
30 CAPITOLO 8. SVILUPPO Di seguito l’implementazione relativa. override fun emitCertificate ( @RequestHeader ( value = " k o r a c a −t o k e n " ) koracaToken : String , @RequestBody certEmissionRequest : CertEmissionRequest ) : ResponseEntity < Any > = Eithers . getRightOrLeft ( certificateManager . emitCertificate ( certEmissionRequest , racaToken ) . peek { result -> logger . info ( result . toString () ) } . map { result -> Responses . ok ( C e rt E m is s i on R e st R e sp o n se ( Base64 . getEncoder () . encodeToString ( result . certificate ?. encoded ) ) ) }. peekLeft { error -> logger . error ( error . message ) } . mapLeft { error -> Responses . badRequest ( error ) } ) L’utilizzo delle Data Class del linguaggio Kotlin hanno velocizzato di molto la creazione di classi per definire strutture immutabili utilizzate per la rappresentazione di oggetti JSON; di seguito un esempio della semplicità di queste strutture. data class Cer tS tat us Res tR esp ons e @JsonCreator constructor ( val status : String , @Nullable val reason : Int ? , val certificate : String ? )
8.3. SVILUPPO MODULO CORE 31 8.2.2 Manager Le classi che presentano il suffisso Manager sono addette all’incapsulamento della logica necessaria per interfacciarsi col modulo CORE ove vivono le classi Service che contengono la vera e propria logica di business. @Component class Cer tif ic ate Ma nag erI mp l ( @Autowired val c e r t i fi c a t e E m i t t er S e r v i c e : CertificateEmitterService , @Autowired val c e r t i fi c a t e R e v o k er S e r v i c e : CertificateRevokerService , @Autowired val c e r t i f i c a t e S t a t u s R e t r i e v e r S e r v i c e : CertificateStatusService , @Autowired @Qualifier ( " k o r a c a c o n f i g " ) @KoracaConfig ( Property . CONNECTOR_KEY ) private val keyStorePassword : String ) : CertificateManager { private val logger = LoggerFactory . getLogger ( javaClass ) override fun emitCertificate ( certEmissionRequest : CertEmissionRequest , racaToken : String ) : Either < KoracaError , CertEmissionResult > = getConnectorConfig ( racaToken ) . peek { connector -> logger . info ( "Got c o n n e c t o r : $ { connector . json }") } . flatMap { connector -> c e r t i f ic a t e E m i t t e rS e r v i c e . emit ( connector , certEmissionRequest ) } . peek { result -> logger . info ( result . certificate . toString () ) } 8.3 Sviluppo modulo CORE Il modulo CORE contiene la logica di business dell’applicativo. 8.3.1 Service Le classi Service sono responsabili di prendere in carico le richieste che provengono dall’interfaccia REST e di delegare la manipolazione dei dati ad un Connector.
32 CAPITOLO 8. SVILUPPO 8.3.2 Connector Questa classe si occupa della creazione dell’implementazione di un ConnectorManager ricevendo come input un ConnectorConfig. Quest’ultimo è un oggetto costruito tramite la deserializzazione di un koraca-token: un oggetto JSON che è cifrato in modo simmetrico con una chiave AES-256. fun decrypt ( b64Token : String , key : String ) : Either < KoracaError , ConnectorConfig > = ‘try ‘ { Base64 . getDecoder () . decode ( b64Token ) } . toEither () . mapLeft { error -> KoracaError ( Errors . GeneralErrors . INVALID_CONNECTOR_CONFIG , error . message . orEmpty () ) } . flatMap { encryptedCfg -> Cyphers . decrypt ( encryptedCfg , key ) } . flatMap { json -> unmarshall ( json ) } Di seguito il metodo che si occupa della deserializzazione. private fun unmarshall ( json : String ) : Either < KoracaError , ConnectorConfig > = ‘try ‘ { ConnectorConfig ( Gson () . fromJson ( json , JsonObject :: class . java ) ) } . toEither () . peekLeft { error -> logger . error ( error . message . orEmpty () ) } . mapLeft { error -> KoracaError ( Errors . GeneralErrors . INTERNAL_SERVER_ERROR , error . message . orEmpty () ) } . peek { cfg -> logger . info ( " U n m a r s h a l l e d j s o n t o c o n n e c t o r c o n f i g : " + cfg . toString () ) } . map { cfg -> cfg } La creazione della corretta implementazione di ConnectorManager è stata realizzata utilizzando la classe ApplicationContext che consente di recuperare tutte le classi annotate come @Component che si sono registrate nel container Spring. @Autowired private lateinit var context : ApplicationContext // ... return Option . of ( connectorRegister . getConnectorClass ( connectorConfig . json [ " @type " ]. asString ) ) . toEither ( KoracaError ( Errors . GeneralErrors . INVALID_CONNECTOR ) ) . map { clazz -> context . getBean ( clazz ) as ConnectorManager } 8.4 Sviluppo modulo CONNECTOR All’interno di questo package è presente un’unica implementazione di ConnectorMa- nager : SignacertConnectorManager, che utilizza come Certification Authority quella denominata Signacert, utilizzata da Infocert S.p.A.
8.4. SVILUPPO MODULO CONNECTOR 33 8.4.1 Decoder ed Encoder Le principali e più interessanti classi del package sono SignacertRequestEncoder e Signa- certResponseDecoder. Queste si occupano rispettivamente di codificare e decodificare messaggi nel formato ASN.1 denominati PKI Message. fun e n c o d e C e r t R e v o c a t i o n R e q u e s t ( cer tRevoc ationR eques t : CertR evoca tionRe quest ? , raoCert : X509Certificate , caDN : String , signerPrivateKey : PrivateKey ) : Either < KoracaError , ASN1Primitive > { val pkiMessage = ASN1EncodableVector () val pkiHeader = ASN1EncodableVector () try { // Building PKI MESSAGE HEADER pkiHeader . add ( ASN1Integer (2) ) pkiHeader . add ( GeneralName ( GeneralName . directoryName , raoCert . subjectX500Principal . name ) ) pkiHeader . add ( GeneralName ( GeneralName . directoryName , caDN )) // Protection Algorithm pkiHeader . add ( DERTaggedObject ( true , 1 , AlgorithmIdentifier ( ASN1ObjectIdentifier ( OIDHelper . sha 1With R SAEnc ryptio n . oid ) , DERNull . INSTANCE ) ) ) // Sender Nonce pkiHeader . add ( DERTaggedObject ( true , 5 , DEROctetString ( BCUtil . generateNonce () ) ) ) // Setting PKIHeader in PKI Message pkiMessage . add ( DERSequence ( pkiHeader ) ) val revReqContent = ASN1EncodableVector () val revDetails = ASN1EncodableVector () val certTemplateBuilder = CertTemplateBuilder () // Building template throughout serial number certTemplateBuilder . setSerialNumber ( ASN1Integer ( cer tRevoc ation Reques t !!. serial ) ) revDetails . add ( certTemplateBuilder . build () ) // // Omittted // } catch ( exception : Exception ) { logger . warn ( exception . message , exception ) return left ( KoracaError ( SignacertError . INVALID_STATUS_REQUEST , exception . message . orEmpty () ) ) } }
34 CAPITOLO 8. SVILUPPO 8.4.2 Client Una volta codificato il PKI Message è necessario utilizzare il SignacertClient per aprire una connessione tramite Socket per poter inviare e ricevere dati verso e dalla Certification Authority Signacert. fun sendToCa ( dataToSend : ByteArray ?) : ByteArray { LOGGER . info ( "CA URL i s : $ { t h i s . c a U r l } \n CA p o r t i s : $ { t h i s . caPort }") try { Socket ( this . caUrl , this . caPort ) . use { serverSocket -> DataOutputStream ( serverSocket . getOutputStream () ) . use { socketOut -> DataInputStream ( serverSocket . getInputStream () ) . use { socketIn -> serverSocket . soTimeout = this . caTimeout serverSocket . tcpNoDelay = true socketOut . writeInt ( dataToSend !!. size + 1) socketOut . write (0 x0 ) socketOut . write ( dataToSend ) socketOut . flush () val byteToRead = socketIn . readInt () - 1 val type = socketIn . readByte () LOGGER . info ( String . format ( "CA r e s p o n s e t y p e :% d" , type ) ) val buffer = ByteArray ( byteToRead ) socketIn . readFully ( buffer ) if ( LOGGER . isTraceEnabled ) { LOGGER . trace ( Base64 . getEncoder () . encodeToString ( buffer ) ) } return buffer } } } } catch ( e : IOException ) { LOGGER . error ( e . message , e ) throw RuntimeException ( e . message , e ) } }
Capitolo 9 Verifica e validazione Questo capitolo tratta la verifica e la validazione del prodotto software. 9.1 Introduzione L’attività di verifica e validazione sono state attuate tramite la creazione di test di: ∗ unità: per la verifica puntuale di classi e componenti; ∗ integrazione: per verificare l’efficacia dell’intero flusso applicativo; ∗ performance: per verificare la resilienza del software quando sottoposto a grandi carichi di richieste. Per la scrittura ed esecuzione dei test di unità e integrazione è stato usato il framework JUnit v4, mentre per i test di performance il framework TestNG. 9.1.1 Test di Unità Il modulo signacert-connector contiene la maggior parte della logica di business meritevole di essere verificata grazie ad una suite di test di unità. Encoder e Decoder I primi test sono stati scritti per verificare l’efficacia delle classi che si occupano della codifica di una richiesta e della decodifica di una risposta. ∗ Encoding: i test a proposito dell’encoding sono stati fatti utilizzando parametri statici per la creazione di istanze di una classe rappresentante il modello di richiesta inviata da una Registration Authority. In seguito viene invocato il metodo di encoding della classe sottoposta a test SignacertRequestEncoding. Essendo di complicata interpretazione, l’oggetto risultante dalla codifica è soggetto ad una verifica manuale e visiva nel formato ASN.1 per verificare la presenza o l’assenza di tutti i campi richiesti facendo riferimento al documento RFC-2459; ∗ Decoding: è stata usata la rappresentazione in base64 di una risposta valida e una non valida di una Certification Authority nel caso di emissione di certificato. In seguito all’ottenimento del array di byte creato a partire dalla stringa si è 35
36 CAPITOLO 9. VERIFICA E VALIDAZIONE invocato il metodo della classe SignacertResponseDecoding e verificata la corret- tezza campo per campo dell’oggetto restituito dal metodo. Sono stati creati più test per verificare il corretto comportamento del software nel caso di problemi e casi limite. SignacertClient La verifica dell’efficacia della classe che si occupa della comunicazione con la Certification Authority è stata eseguita anche tramite un test di unità che, tramite l’utilizzo di un mock della stessa Certification Authority, ha verificato anche la resilienza del software in caso di ritardi oppure errori nella comunicazione. Infatti il mock è stato reso configurabile nei tempi di risposta o nella restituzione di errori, per esempio di indisponibilità, mettendo la classe sotto test in condizione di rispondere correttamente all’eccezione. 9.1.2 Test di Integrazione Il test di integrazione più importante verifica la comunicazione col prodotto sviluppato e il dialogo tra quest’ultimo e una Certification Authority. Il test deve essere eseguito una volta che il software è in esecuzione in un server(che può essere locale oppure remoto); il cuore del test sta nella simulazione di un’interazione tra una Registration Authority e il prodotto tramite la creazione ed esecuzione di una richiesta HTTP contenente i parametri necessari per l’emissione, la revoca, la riattivazione e la sospensione di un certificato. 9.1.3 Test di performance I test di performance sono stati eseguiti paragonando KORACA (CA-PROXY) e RACA, ovvero il software preesistente. I test sono stati parametrizzati per poter essere cambiati nel numero di chiamate e numero di thread paralleli. Sono state prese in considerazione le seguenti combinazioni: ∗ Chiamate / Numero Thread paralleli: 100/1, 100/2, 100/3, 100/4, 100/5, 100/10, 1000/5. I grafici prodotti rappresentano in ordine di apparizione: ∗ Tempo totale di risposta in minuti; ∗ Tempo medio di risposta in minuti; ∗ Utilizzo della CPU, in percentuale; ∗ Utilizzo della RAM, in percentuale.
9.1. INTRODUZIONE 37 Figura 9.1: Tempo totale di risposta. Figura 9.2: Tempo medio di risposta.
38 CAPITOLO 9. VERIFICA E VALIDAZIONE Figura 9.3: Utilizzo della CPU. Figura 9.4: Utilizzo della RAM. Conclusioni In seguito ai test di performance sono state tratte le seguenti conclusioni in merito al comportamento del prodotto software sviluppato: ∗ Per quanto riguarda i tempi di risposta i due software si comportano nello stesso modo, senza nette differenze in termini di tempo. Al crescere del numero di thread paralleli e mantenendo costante il numero di chiamate i tempi di risposta si stabilizzano tra 0.1 e 0.2. Quando invece il numero di chiamate arriva a 1000, i tempi si allungano notevolmente; ∗ In merito all’utilizzo della CPU anche in questo caso il comportamento è simile e piuttosto prevedibile. La crescita del numero di chiamate e del numero di thread
Puoi anche leggere